Material: Material appearance

Uses new material system for appearance

Each feature object now has a property called ShapeMaterial that
describes its physical properties. If it has a shape, it has a
material.

The ShapeColor attribute is replaced by a ShapeAppearance attribute.
This is a material list that describes all appearance properties, not
just diffuse color. As a list in can be used for all elements of a
shape, such as edges and faces.

A new widget is provided to allow the user to select materials in a
consistent fashion. It can also launch the material editor with its
more advanced capabilities.
This commit is contained in:
David Carter
2024-03-17 18:37:56 -04:00
committed by Chris Hennes
parent 252707a803
commit 495a96a0f5
121 changed files with 4682 additions and 1685 deletions
+9
View File
@@ -173,3 +173,12 @@ DocumentObject *GeoFeature::resolveElement(DocumentObject *obj, const char *subn
return sobj;
}
App::Material GeoFeature::getMaterialAppearance() const
{
return App::Material(App::Material::DEFAULT);
}
void GeoFeature::setMaterialAppearance(const App::Material& material)
{
Q_UNUSED(material)
}
+20
View File
@@ -27,6 +27,7 @@
#include "DocumentObject.h"
#include "PropertyGeo.h"
#include "MappedElement.h"
#include "Material.h"
namespace App
{
@@ -120,6 +121,25 @@ public:
* @return Base::Placement The transformation from the global reference coordinate system
*/
Base::Placement globalPlacement() const;
/**
* @brief Virtual function to get an App::Material object describing the appearance
*
* The appearance properties are described by the underlying features material. This can not
* be accessed directly from within the Gui module. This virtual function will return a
* App::Material object describing the appearance properties of the material.
*
* @return App::Material the appearance properties of the object material
*/
virtual App::Material getMaterialAppearance() const;
/**
* @brief Virtual function to set the appearance with an App::Material object
*
* The appearance properties are described by the underlying features material. This cannot
* be accessed directly from within the Gui module. This virtual function will set the
* appearance from an App::Material object.
*/
virtual void setMaterialAppearance(const App::Material& material);
protected:
std::pair<std::string, std::string> _getElementName(const char* name,
+238 -229
View File
@@ -24,7 +24,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <cstring>
#include <cstring>
#endif
#include "Material.h"
@@ -36,113 +36,123 @@ using namespace App;
// Material
//===========================================================================
Material::Material()
: shininess{0.9000f}
, transparency{}
: shininess {0.9000f}
, transparency {}
{
setType(STEEL);
setType(USER_DEFINED);
}
Material::Material(const Material& other)
: ambientColor(other.ambientColor)
, diffuseColor(other.diffuseColor)
, specularColor(other.specularColor)
, emissiveColor(other.emissiveColor)
, shininess(other.shininess)
, transparency(other.transparency)
, uuid(other.uuid)
, _matType(other._matType)
{
}
Material::Material(const char* MatName)
: shininess{0.9000f}
, transparency{}
: shininess {0.9000f}
, transparency {}
{
set(MatName);
}
Material::Material(const MaterialType MatType)
: shininess{0.9000f}
, transparency{}
: shininess {0.9000f}
, transparency {}
{
setType(MatType);
}
Material& Material::operator=(const Material& other)
{
if (this == &other) {
return *this;
}
_matType = other._matType;
ambientColor = other.ambientColor;
diffuseColor = other.diffuseColor;
specularColor = other.specularColor;
emissiveColor = other.emissiveColor;
shininess = other.shininess;
transparency = other.transparency;
uuid = other.uuid;
return *this;
}
void Material::set(const char* MatName)
{
if (strcmp("Brass",MatName) == 0 ) {
if (strcmp("Brass", MatName) == 0) {
setType(BRASS);
}
else if (strcmp("Bronze",MatName) == 0 ) {
else if (strcmp("Bronze", MatName) == 0) {
setType(BRONZE);
}
else if (strcmp("Copper",MatName) == 0 ) {
else if (strcmp("Copper", MatName) == 0) {
setType(COPPER);
}
else if (strcmp("Gold",MatName) == 0 ) {
// ambientColor.set(0.3f,0.1f,0.1f);
// diffuseColor.set(0.8f,0.7f,0.2f);
// specularColor.set(0.4f,0.3f,0.1f);
// shininess = .4f;
// transparency = .0f;
//// ambientColor.set(0.3f,0.1f,0.1f);
//// diffuseColor.set(0.22f,0.15f,0.00f);
//// specularColor.set(0.71f,0.70f,0.56f);
//// shininess = .16f;
//// transparency = .0f;
//// ambientColor.set(0.24725f, 0.1995f, 0.0745f);
//// diffuseColor.set(0.75164f, 0.60648f, 0.22648f);
//// specularColor.set(0.628281f, 0.555802f, 0.366065f);
//// shininess = .16f;
//// transparency = .0f;
else if (strcmp("Gold", MatName) == 0) {
setType(GOLD);
}
else if (strcmp("Pewter",MatName) == 0 ) {
else if (strcmp("Pewter", MatName) == 0) {
setType(PEWTER);
}
else if (strcmp("Plaster",MatName) == 0 ) {
else if (strcmp("Plaster", MatName) == 0) {
setType(PLASTER);
}
else if (strcmp("Plastic",MatName) == 0 ) {
else if (strcmp("Plastic", MatName) == 0) {
setType(PLASTIC);
}
else if (strcmp("Silver",MatName) == 0 ) {
else if (strcmp("Silver", MatName) == 0) {
setType(SILVER);
}
else if (strcmp("Steel",MatName) == 0 ) {
else if (strcmp("Steel", MatName) == 0) {
setType(STEEL);
}
else if (strcmp("Stone",MatName) == 0 ) {
// ambientColor.set(0.0f,0.0f,0.0f);
// diffuseColor.set(0.0f,0.0f,0.0f);
// specularColor.set(0.4f,0.3f,0.1f);
// shininess = .4f;
// transparency = .0f;
else if (strcmp("Stone", MatName) == 0) {
setType(STONE);
}
else if (strcmp("Shiny plastic",MatName) == 0 ) {
else if (strcmp("Shiny plastic", MatName) == 0) {
setType(SHINY_PLASTIC);
}
else if (strcmp("Satin",MatName) == 0 ) {
else if (strcmp("Satin", MatName) == 0) {
setType(SATIN);
}
else if (strcmp("Metalized",MatName) == 0 ) {
else if (strcmp("Metalized", MatName) == 0) {
setType(METALIZED);
}
else if (strcmp("Neon GNC",MatName) == 0 ) {
else if (strcmp("Neon GNC", MatName) == 0) {
setType(NEON_GNC);
}
else if (strcmp("Chrome",MatName) == 0 ) {
else if (strcmp("Chrome", MatName) == 0) {
setType(CHROME);
}
else if (strcmp("Aluminium",MatName) == 0 ) {
else if (strcmp("Aluminium", MatName) == 0) {
setType(ALUMINIUM);
}
else if (strcmp("Obsidian",MatName) == 0 ) {
else if (strcmp("Obsidian", MatName) == 0) {
setType(OBSIDIAN);
}
else if (strcmp("Neon PHC",MatName) == 0 ) {
else if (strcmp("Neon PHC", MatName) == 0) {
setType(NEON_PHC);
}
else if (strcmp("Jade",MatName) == 0 ) {
else if (strcmp("Jade", MatName) == 0) {
setType(JADE);
}
else if (strcmp("Ruby",MatName) == 0 ) {
else if (strcmp("Ruby", MatName) == 0) {
setType(RUBY);
}
else if (strcmp("Emerald",MatName) == 0 ) {
else if (strcmp("Emerald", MatName) == 0) {
setType(EMERALD);
}
else if (strcmp("Default",MatName) == 0 ) {
else if (strcmp("Default", MatName) == 0) {
setType(DEFAULT);
}
else {
@@ -153,185 +163,184 @@ void Material::set(const char* MatName)
void Material::setType(const MaterialType MatType)
{
_matType = MatType;
switch (MatType)
{
case BRASS:
ambientColor .set(0.3294f,0.2235f,0.0275f);
diffuseColor .set(0.7804f,0.5686f,0.1137f);
specularColor.set(0.9922f,0.9412f,0.8078f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.2179f;
transparency = 0.0000f;
break;
case BRONZE:
ambientColor .set(0.2125f,0.1275f,0.0540f);
diffuseColor .set(0.7140f,0.4284f,0.1814f);
specularColor.set(0.3935f,0.2719f,0.1667f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.2000f;
transparency = 0.0000f;
break;
case COPPER:
ambientColor .set(0.3300f,0.2600f,0.2300f);
diffuseColor .set(0.5000f,0.1100f,0.0000f);
specularColor.set(0.9500f,0.7300f,0.0000f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.9300f;
transparency = 0.0000f;
break;
case GOLD:
ambientColor .set(0.3000f,0.2306f,0.0953f);
diffuseColor .set(0.4000f,0.2760f,0.0000f);
specularColor.set(0.9000f,0.8820f,0.7020f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.0625f;
transparency = 0.0000f;
break;
case PEWTER:
ambientColor .set(0.1059f,0.0588f,0.1137f);
diffuseColor .set(0.4275f,0.4706f,0.5412f);
specularColor.set(0.3333f,0.3333f,0.5216f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.0769f;
transparency = 0.0000f;
break;
case PLASTER:
ambientColor .set(0.0500f,0.0500f,0.0500f);
diffuseColor .set(0.1167f,0.1167f,0.1167f);
specularColor.set(0.0305f,0.0305f,0.0305f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.0078f;
transparency = 0.0000f;
break;
case PLASTIC:
ambientColor .set(0.1000f,0.1000f,0.1000f);
diffuseColor .set(0.0000f,0.0000f,0.0000f);
specularColor.set(0.0600f,0.0600f,0.0600f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.0078f;
transparency = 0.0000f;
break;
case SILVER:
ambientColor .set(0.1922f,0.1922f,0.1922f);
diffuseColor .set(0.5075f,0.5075f,0.5075f);
specularColor.set(0.5083f,0.5083f,0.5083f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.2000f;
transparency = 0.0000f;
break;
case STEEL:
ambientColor .set(0.0020f,0.0020f,0.0020f);
diffuseColor .set(0.0000f,0.0000f,0.0000f);
specularColor.set(0.9800f,0.9800f,0.9800f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.0600f;
transparency = 0.0000f;
break;
case STONE:
ambientColor .set(0.1900f,0.1520f,0.1178f);
diffuseColor .set(0.7500f,0.6000f,0.4650f);
specularColor.set(0.0784f,0.0800f,0.0480f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.1700f;
transparency = 0.0000f;
break;
case SHINY_PLASTIC:
ambientColor .set(0.0880f,0.0880f,0.0880f);
diffuseColor .set(0.0000f,0.0000f,0.0000f);
specularColor.set(1.0000f,1.0000f,1.0000f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 1.0000f;
transparency = 0.0000f;
break;
case SATIN:
ambientColor .set(0.0660f,0.0660f,0.0660f);
diffuseColor .set(0.0000f,0.0000f,0.0000f);
specularColor.set(0.4400f,0.4400f,0.4400f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.0938f;
transparency = 0.0000f;
break;
case METALIZED:
ambientColor .set(0.1800f,0.1800f,0.1800f);
diffuseColor .set(0.0000f,0.0000f,0.0000f);
specularColor.set(0.4500f,0.4500f,0.4500f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.1300f;
transparency = 0.0000f;
break;
case NEON_GNC:
ambientColor .set(0.2000f,0.2000f,0.2000f);
diffuseColor .set(0.0000f,0.0000f,0.0000f);
specularColor.set(0.6200f,0.6200f,0.6200f);
emissiveColor.set(1.0000f,1.0000f,0.0000f);
shininess = 0.0500f;
transparency = 0.0000f;
break;
case CHROME:
ambientColor .set(0.3500f,0.3500f,0.3500f);
diffuseColor .set(0.9176f,0.9176f,0.9176f);
specularColor.set(0.9746f,0.9746f,0.9746f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.1000f;
transparency = 0.0000f;
break;
case ALUMINIUM:
ambientColor .set(0.3000f,0.3000f,0.3000f);
diffuseColor .set(0.3000f,0.3000f,0.3000f);
specularColor.set(0.7000f,0.7000f,0.8000f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.0900f;
transparency = 0.0000f;
break;
case OBSIDIAN:
ambientColor .set(0.0538f,0.0500f,0.0662f);
diffuseColor .set(0.1828f,0.1700f,0.2253f);
specularColor.set(0.3327f,0.3286f,0.3464f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.3000f;
transparency = 0.0000f;
break;
case NEON_PHC:
ambientColor .set(1.0000f,1.0000f,1.0000f);
diffuseColor .set(1.0000f,1.0000f,1.0000f);
specularColor.set(0.6200f,0.6200f,0.6200f);
emissiveColor.set(0.0000f,0.9000f,0.4140f);
shininess = 0.0500f;
transparency = 0.0000f;
break;
case JADE:
ambientColor .set(0.1350f,0.2225f,0.1575f);
diffuseColor .set(0.5400f,0.8900f,0.6300f);
specularColor.set(0.3162f,0.3162f,0.3162f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.1000f;
transparency = 0.0000f;
break;
case RUBY:
ambientColor .set(0.1745f,0.0118f,0.0118f);
diffuseColor .set(0.6142f,0.0414f,0.0414f);
specularColor.set(0.7278f,0.6279f,0.6267f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.6000f;
transparency = 0.0000f;
break;
case EMERALD:
ambientColor .set(0.0215f,0.1745f,0.0215f);
diffuseColor .set(0.0757f,0.6142f,0.0757f);
specularColor.set(0.6330f,0.7278f,0.6330f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.6000f;
transparency = 0.0000f;
break;
case USER_DEFINED:
break;
default:
ambientColor.set(0.3333f, 0.3333f, 0.3333f);
diffuseColor .set(0.8000f,0.8000f,0.9000f);
specularColor.set(0.5333f, 0.5333f, 0.5333f);
emissiveColor.set(0.0000f,0.0000f,0.0000f);
shininess = 0.9000f;
transparency = 0.0000f;
break;
switch (MatType) {
case BRASS:
ambientColor.set(0.3294f, 0.2235f, 0.0275f);
diffuseColor.set(0.7804f, 0.5686f, 0.1137f);
specularColor.set(0.9922f, 0.9412f, 0.8078f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.2179f;
transparency = 0.0000f;
break;
case BRONZE:
ambientColor.set(0.2125f, 0.1275f, 0.0540f);
diffuseColor.set(0.7140f, 0.4284f, 0.1814f);
specularColor.set(0.3935f, 0.2719f, 0.1667f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.2000f;
transparency = 0.0000f;
break;
case COPPER:
ambientColor.set(0.3300f, 0.2600f, 0.2300f);
diffuseColor.set(0.5000f, 0.1100f, 0.0000f);
specularColor.set(0.9500f, 0.7300f, 0.0000f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.9300f;
transparency = 0.0000f;
break;
case GOLD:
ambientColor.set(0.3000f, 0.2306f, 0.0953f);
diffuseColor.set(0.4000f, 0.2760f, 0.0000f);
specularColor.set(0.9000f, 0.8820f, 0.7020f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.0625f;
transparency = 0.0000f;
break;
case PEWTER:
ambientColor.set(0.1059f, 0.0588f, 0.1137f);
diffuseColor.set(0.4275f, 0.4706f, 0.5412f);
specularColor.set(0.3333f, 0.3333f, 0.5216f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.0769f;
transparency = 0.0000f;
break;
case PLASTER:
ambientColor.set(0.0500f, 0.0500f, 0.0500f);
diffuseColor.set(0.1167f, 0.1167f, 0.1167f);
specularColor.set(0.0305f, 0.0305f, 0.0305f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.0078f;
transparency = 0.0000f;
break;
case PLASTIC:
ambientColor.set(0.1000f, 0.1000f, 0.1000f);
diffuseColor.set(0.0000f, 0.0000f, 0.0000f);
specularColor.set(0.0600f, 0.0600f, 0.0600f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.0078f;
transparency = 0.0000f;
break;
case SILVER:
ambientColor.set(0.1922f, 0.1922f, 0.1922f);
diffuseColor.set(0.5075f, 0.5075f, 0.5075f);
specularColor.set(0.5083f, 0.5083f, 0.5083f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.2000f;
transparency = 0.0000f;
break;
case STEEL:
ambientColor.set(0.0020f, 0.0020f, 0.0020f);
diffuseColor.set(0.0000f, 0.0000f, 0.0000f);
specularColor.set(0.9800f, 0.9800f, 0.9800f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.0600f;
transparency = 0.0000f;
break;
case STONE:
ambientColor.set(0.1900f, 0.1520f, 0.1178f);
diffuseColor.set(0.7500f, 0.6000f, 0.4650f);
specularColor.set(0.0784f, 0.0800f, 0.0480f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.1700f;
transparency = 0.0000f;
break;
case SHINY_PLASTIC:
ambientColor.set(0.0880f, 0.0880f, 0.0880f);
diffuseColor.set(0.0000f, 0.0000f, 0.0000f);
specularColor.set(1.0000f, 1.0000f, 1.0000f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 1.0000f;
transparency = 0.0000f;
break;
case SATIN:
ambientColor.set(0.0660f, 0.0660f, 0.0660f);
diffuseColor.set(0.0000f, 0.0000f, 0.0000f);
specularColor.set(0.4400f, 0.4400f, 0.4400f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.0938f;
transparency = 0.0000f;
break;
case METALIZED:
ambientColor.set(0.1800f, 0.1800f, 0.1800f);
diffuseColor.set(0.0000f, 0.0000f, 0.0000f);
specularColor.set(0.4500f, 0.4500f, 0.4500f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.1300f;
transparency = 0.0000f;
break;
case NEON_GNC:
ambientColor.set(0.2000f, 0.2000f, 0.2000f);
diffuseColor.set(0.0000f, 0.0000f, 0.0000f);
specularColor.set(0.6200f, 0.6200f, 0.6200f);
emissiveColor.set(1.0000f, 1.0000f, 0.0000f);
shininess = 0.0500f;
transparency = 0.0000f;
break;
case CHROME:
ambientColor.set(0.3500f, 0.3500f, 0.3500f);
diffuseColor.set(0.9176f, 0.9176f, 0.9176f);
specularColor.set(0.9746f, 0.9746f, 0.9746f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.1000f;
transparency = 0.0000f;
break;
case ALUMINIUM:
ambientColor.set(0.3000f, 0.3000f, 0.3000f);
diffuseColor.set(0.3000f, 0.3000f, 0.3000f);
specularColor.set(0.7000f, 0.7000f, 0.8000f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.0900f;
transparency = 0.0000f;
break;
case OBSIDIAN:
ambientColor.set(0.0538f, 0.0500f, 0.0662f);
diffuseColor.set(0.1828f, 0.1700f, 0.2253f);
specularColor.set(0.3327f, 0.3286f, 0.3464f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.3000f;
transparency = 0.0000f;
break;
case NEON_PHC:
ambientColor.set(1.0000f, 1.0000f, 1.0000f);
diffuseColor.set(1.0000f, 1.0000f, 1.0000f);
specularColor.set(0.6200f, 0.6200f, 0.6200f);
emissiveColor.set(0.0000f, 0.9000f, 0.4140f);
shininess = 0.0500f;
transparency = 0.0000f;
break;
case JADE:
ambientColor.set(0.1350f, 0.2225f, 0.1575f);
diffuseColor.set(0.5400f, 0.8900f, 0.6300f);
specularColor.set(0.3162f, 0.3162f, 0.3162f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.1000f;
transparency = 0.0000f;
break;
case RUBY:
ambientColor.set(0.1745f, 0.0118f, 0.0118f);
diffuseColor.set(0.6142f, 0.0414f, 0.0414f);
specularColor.set(0.7278f, 0.6279f, 0.6267f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.6000f;
transparency = 0.0000f;
break;
case EMERALD:
ambientColor.set(0.0215f, 0.1745f, 0.0215f);
diffuseColor.set(0.0757f, 0.6142f, 0.0757f);
specularColor.set(0.6330f, 0.7278f, 0.6330f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.6000f;
transparency = 0.0000f;
break;
case USER_DEFINED:
break;
default:
ambientColor.set(0.3333f, 0.3333f, 0.3333f);
diffuseColor.set(0.8000f, 0.8000f, 0.9000f);
specularColor.set(0.5333f, 0.5333f, 0.5333f);
emissiveColor.set(0.0000f, 0.0000f, 0.0000f);
shininess = 0.9000f;
transparency = 0.0000f;
break;
}
}
+25 -17
View File
@@ -34,7 +34,8 @@ namespace App
class AppExport Material
{
public:
enum MaterialType {
enum MaterialType
{
BRASS,
BRONZE,
COPPER,
@@ -66,11 +67,14 @@ public:
//@{
/** Sets the USER_DEFINED material type. The user must set the colors afterwards. */
Material();
/** Defines the colors and shininess for the material \a MatName. If \a MatName isn't defined then USER_DEFINED is
* set and the user must define the colors itself.
/** Copy constructor. */
Material(const Material& other);
/** Defines the colors and shininess for the material \a MatName. If \a MatName isn't defined
* then USER_DEFINED is set and the user must define the colors itself.
*/
explicit Material(const char* MatName);
/** Does basically the same as the constructor above unless that it accepts a MaterialType as argument. */
/** Does basically the same as the constructor above unless that it accepts a MaterialType as
* argument. */
explicit Material(const MaterialType MatType);
//@}
@@ -97,22 +101,24 @@ public:
* \li Jade
* \li Ruby
* \li Emerald
* Furthermore there two additional modes \a Default which defines a kind of grey metallic and user defined that
* does nothing.
* The Color and the other properties of the material are defined in the range [0-1].
* If \a MatName is an unknown material name then the type USER_DEFINED is set and the material doesn't get changed.
* Furthermore there two additional modes \a Default which defines a kind of grey metallic and
* user defined that does nothing. The Color and the other properties of the material are
* defined in the range [0-1]. If \a MatName is an unknown material name then the type
* USER_DEFINED is set and the material doesn't get changed.
*/
void set(const char* MatName);
/**
* This method is provided for convenience which does basically the same as the method above unless that it accepts a MaterialType
* as argument.
* This method is provided for convenience which does basically the same as the method above
* unless that it accepts a MaterialType as argument.
*/
void setType(const MaterialType MatType);
/**
* Returns the currently set material type.
*/
MaterialType getType() const
{ return _matType; }
{
return _matType;
}
/** @name Properties */
//@{
@@ -122,24 +128,26 @@ public:
Color emissiveColor; /**< Defines the emissive color. */
float shininess;
float transparency;
std::string uuid;
//@}
bool operator==(const Material& m) const
{
return _matType==m._matType && shininess==m.shininess &&
transparency==m.transparency && ambientColor==m.ambientColor &&
diffuseColor==m.diffuseColor && specularColor==m.specularColor &&
emissiveColor==m.emissiveColor;
return _matType == m._matType && shininess == m.shininess && transparency == m.transparency
&& ambientColor == m.ambientColor && diffuseColor == m.diffuseColor
&& specularColor == m.specularColor && emissiveColor == m.emissiveColor
&& uuid == m.uuid;
}
bool operator!=(const Material& m) const
{
return !operator==(m);
}
Material& operator=(const Material& other);
private:
MaterialType _matType;
};
} //namespace App
} // namespace App
#endif // APP_MATERIAL_H
#endif // APP_MATERIAL_H
+4 -4
View File
@@ -30,25 +30,25 @@ Satin, Metalized, Neon GNC, Chrome, Aluminium, Obsidian, Neon PHC, Jade, Ruby or
<Documentation>
<UserDocu>Ambient color</UserDocu>
</Documentation>
<Parameter Name="AmbientColor" Type="Tuple"/>
<Parameter Name="AmbientColor" Type="Object"/>
</Attribute>
<Attribute Name="DiffuseColor" ReadOnly="false">
<Documentation>
<UserDocu>Diffuse color</UserDocu>
</Documentation>
<Parameter Name="DiffuseColor" Type="Tuple"/>
<Parameter Name="DiffuseColor" Type="Object"/>
</Attribute>
<Attribute Name="EmissiveColor" ReadOnly="false">
<Documentation>
<UserDocu>Emissive color</UserDocu>
</Documentation>
<Parameter Name="EmissiveColor" Type="Tuple"/>
<Parameter Name="EmissiveColor" Type="Object"/>
</Attribute>
<Attribute Name="SpecularColor" ReadOnly="false">
<Documentation>
<UserDocu>Specular color</UserDocu>
</Documentation>
<Parameter Name="SpecularColor" Type="Tuple"/>
<Parameter Name="SpecularColor" Type="Object"/>
</Attribute>
<Attribute Name="Shininess" ReadOnly="false">
<Documentation>
+116 -49
View File
@@ -25,12 +25,89 @@
// inclusion of the generated files (generated out of MaterialPy.xml)
#include "MaterialPy.h"
#include "MaterialPy.cpp"
#include <Base/PyWrapParseTupleAndKeywords.h>
using namespace App;
PyObject *MaterialPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
Color parseColor(PyObject* value)
{
Color cCol;
if (PyTuple_Check(value) && (PyTuple_Size(value) == 3 || PyTuple_Size(value) == 4)) {
PyObject* item;
item = PyTuple_GetItem(value, 0);
if (PyFloat_Check(item)) {
cCol.r = (float)PyFloat_AsDouble(item);
item = PyTuple_GetItem(value, 1);
if (PyFloat_Check(item)) {
cCol.g = (float)PyFloat_AsDouble(item);
}
else {
throw Base::TypeError("Type in tuple must be consistent (float)");
}
item = PyTuple_GetItem(value, 2);
if (PyFloat_Check(item)) {
cCol.b = (float)PyFloat_AsDouble(item);
}
else {
throw Base::TypeError("Type in tuple must be consistent (float)");
}
if (PyTuple_Size(value) == 4) {
item = PyTuple_GetItem(value, 3);
if (PyFloat_Check(item)) {
cCol.a = (float)PyFloat_AsDouble(item);
}
else {
throw Base::TypeError("Type in tuple must be consistent (float)");
}
}
}
else if (PyLong_Check(item)) {
cCol.r = PyLong_AsLong(item) / 255.0;
item = PyTuple_GetItem(value, 1);
if (PyLong_Check(item)) {
cCol.g = PyLong_AsLong(item) / 255.0;
}
else {
throw Base::TypeError("Type in tuple must be consistent (integer)");
}
item = PyTuple_GetItem(value, 2);
if (PyLong_Check(item)) {
cCol.b = PyLong_AsLong(item) / 255.0;
}
else {
throw Base::TypeError("Type in tuple must be consistent (integer)");
}
if (PyTuple_Size(value) == 4) {
item = PyTuple_GetItem(value, 3);
if (PyLong_Check(item)) {
cCol.a = PyLong_AsLong(item) / 255.0;
}
else {
throw Base::TypeError("Type in tuple must be consistent (integer)");
}
}
}
else {
throw Base::TypeError("Type in tuple must be float or integer");
}
}
else if (PyLong_Check(value)) {
cCol.setPackedValue(PyLong_AsUnsignedLong(value));
}
else {
std::string error =
std::string("type must be integer or tuple of float or tuple integer, not ");
error += value->ob_type->tp_name;
throw Base::TypeError(error);
}
return cCol;
}
PyObject* MaterialPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
{
// create a new instance of MaterialPy and the Twin object
return new MaterialPy(new Material);
@@ -45,28 +122,41 @@ int MaterialPy::PyInit(PyObject* args, PyObject* kwds)
PyObject* emissive = nullptr;
PyObject* shininess = nullptr;
PyObject* transparency = nullptr;
static const std::array<const char *, 7> kwds_colors{"DiffuseColor", "AmbientColor", "SpecularColor",
"EmissiveColor", "Shininess", "Transparency", nullptr};
static const std::array<const char*, 7> kwds_colors {"DiffuseColor",
"AmbientColor",
"SpecularColor",
"EmissiveColor",
"Shininess",
"Transparency",
nullptr};
if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "|OOOOOO", kwds_colors,
&diffuse, &ambient, &specular, &emissive, &shininess, &transparency)) {
if (!Base::Wrapped_ParseTupleAndKeywords(args,
kwds,
"|OOOOOO",
kwds_colors,
&diffuse,
&ambient,
&specular,
&emissive,
&shininess,
&transparency)) {
return -1;
}
if (diffuse) {
setDiffuseColor(Py::Tuple(diffuse));
setDiffuseColor(Py::Object(diffuse));
}
if (ambient) {
setAmbientColor(Py::Tuple(ambient));
setAmbientColor(Py::Object(ambient));
}
if (specular) {
setSpecularColor(Py::Tuple(specular));
setSpecularColor(Py::Object(specular));
}
if (emissive) {
setEmissiveColor(Py::Tuple(emissive));
setEmissiveColor(Py::Object(emissive));
}
if (shininess) {
@@ -86,18 +176,19 @@ std::string MaterialPy::representation() const
return {"<Material object>"};
}
PyObject* MaterialPy::set(PyObject * args)
PyObject* MaterialPy::set(PyObject* args)
{
char *pstr;
if (!PyArg_ParseTuple(args, "s", &pstr))
char* pstr;
if (!PyArg_ParseTuple(args, "s", &pstr)) {
return nullptr;
}
getMaterialPtr()->set(pstr);
Py_Return;
}
Py::Tuple MaterialPy::getAmbientColor() const
Py::Object MaterialPy::getAmbientColor() const
{
Py::Tuple tuple(4);
tuple.setItem(0, Py::Float(getMaterialPtr()->ambientColor.r));
@@ -107,18 +198,12 @@ Py::Tuple MaterialPy::getAmbientColor() const
return tuple;
}
void MaterialPy::setAmbientColor(Py::Tuple arg)
void MaterialPy::setAmbientColor(Py::Object arg)
{
Color c;
c.r = Py::Float(arg.getItem(0));
c.g = Py::Float(arg.getItem(1));
c.b = Py::Float(arg.getItem(2));
if (arg.size() == 4)
c.a = Py::Float(arg.getItem(3));
getMaterialPtr()->ambientColor = c;
getMaterialPtr()->ambientColor = parseColor(*arg);
}
Py::Tuple MaterialPy::getDiffuseColor() const
Py::Object MaterialPy::getDiffuseColor() const
{
Py::Tuple tuple(4);
tuple.setItem(0, Py::Float(getMaterialPtr()->diffuseColor.r));
@@ -128,18 +213,12 @@ Py::Tuple MaterialPy::getDiffuseColor() const
return tuple;
}
void MaterialPy::setDiffuseColor(Py::Tuple arg)
void MaterialPy::setDiffuseColor(Py::Object arg)
{
Color c;
c.r = Py::Float(arg.getItem(0));
c.g = Py::Float(arg.getItem(1));
c.b = Py::Float(arg.getItem(2));
if (arg.size() == 4)
c.a = Py::Float(arg.getItem(3));
getMaterialPtr()->diffuseColor = c;
getMaterialPtr()->diffuseColor = parseColor(*arg);
}
Py::Tuple MaterialPy::getEmissiveColor() const
Py::Object MaterialPy::getEmissiveColor() const
{
Py::Tuple tuple(4);
tuple.setItem(0, Py::Float(getMaterialPtr()->emissiveColor.r));
@@ -149,18 +228,12 @@ Py::Tuple MaterialPy::getEmissiveColor() const
return tuple;
}
void MaterialPy::setEmissiveColor(Py::Tuple arg)
void MaterialPy::setEmissiveColor(Py::Object arg)
{
Color c;
c.r = Py::Float(arg.getItem(0));
c.g = Py::Float(arg.getItem(1));
c.b = Py::Float(arg.getItem(2));
if (arg.size() == 4)
c.a = Py::Float(arg.getItem(3));
getMaterialPtr()->emissiveColor = c;
getMaterialPtr()->emissiveColor = parseColor(*arg);
}
Py::Tuple MaterialPy::getSpecularColor() const
Py::Object MaterialPy::getSpecularColor() const
{
Py::Tuple tuple(4);
tuple.setItem(0, Py::Float(getMaterialPtr()->specularColor.r));
@@ -170,15 +243,9 @@ Py::Tuple MaterialPy::getSpecularColor() const
return tuple;
}
void MaterialPy::setSpecularColor(Py::Tuple arg)
void MaterialPy::setSpecularColor(Py::Object arg)
{
Color c;
c.r = Py::Float(arg.getItem(0));
c.g = Py::Float(arg.getItem(1));
c.b = Py::Float(arg.getItem(2));
if (arg.size() == 4)
c.a = Py::Float(arg.getItem(3));
getMaterialPtr()->specularColor = c;
getMaterialPtr()->specularColor = parseColor(*arg);
}
Py::Float MaterialPy::getShininess() const
@@ -201,7 +268,7 @@ void MaterialPy::setTransparency(Py::Float arg)
getMaterialPtr()->transparency = arg;
}
PyObject *MaterialPy::getCustomAttributes(const char* /*attr*/) const
PyObject* MaterialPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}
+716 -41
View File
@@ -461,7 +461,7 @@ void PropertyEnumeration::setPyObject(PyObject *value)
hasSetValue();
}
else {
FC_THROWM(Base::ValueError, "'" << str
FC_THROWM(Base::ValueError, "'" << str
<< "' is not part of the enumeration in "
<< getFullName());
}
@@ -585,7 +585,7 @@ bool PropertyEnumeration::getPyPathValue(const ObjectIdentifier &path, Py::Objec
} else if (p == ".String") {
auto v = getValueAsString();
r = Py::String(v?v:"");
} else
} else
r = Py::Int(getValue());
return true;
}
@@ -2392,19 +2392,34 @@ unsigned int PropertyColorList::getMemSize () const
// PropertyMaterial
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TYPESYSTEM_SOURCE(App::PropertyMaterial , App::Property)
TYPESYSTEM_SOURCE(App::PropertyMaterial, App::Property)
PropertyMaterial::PropertyMaterial() = default;
PropertyMaterial::~PropertyMaterial() = default;
void PropertyMaterial::setValue(const Material &mat)
void PropertyMaterial::setValue(const Material& mat)
{
aboutToSetValue();
_cMat=mat;
_cMat = mat;
hasSetValue();
}
void PropertyMaterial::setValue(const Color& col)
{
setDiffuseColor(col);
}
void PropertyMaterial::setValue(float r, float g, float b, float a)
{
setDiffuseColor(r, g, b, a);
}
void PropertyMaterial::setValue(uint32_t rgba)
{
setDiffuseColor(rgba);
}
const Material& PropertyMaterial::getValue() const
{
return _cMat;
@@ -2417,6 +2432,20 @@ void PropertyMaterial::setAmbientColor(const Color& col)
hasSetValue();
}
void PropertyMaterial::setAmbientColor(float r, float g, float b, float a)
{
aboutToSetValue();
_cMat.ambientColor.set(r, g, b, a);
hasSetValue();
}
void PropertyMaterial::setAmbientColor(uint32_t rgba)
{
aboutToSetValue();
_cMat.ambientColor.setPackedValue(rgba);
hasSetValue();
}
void PropertyMaterial::setDiffuseColor(const Color& col)
{
aboutToSetValue();
@@ -2424,6 +2453,20 @@ void PropertyMaterial::setDiffuseColor(const Color& col)
hasSetValue();
}
void PropertyMaterial::setDiffuseColor(float r, float g, float b, float a)
{
aboutToSetValue();
_cMat.diffuseColor.set(r, g, b, a);
hasSetValue();
}
void PropertyMaterial::setDiffuseColor(uint32_t rgba)
{
aboutToSetValue();
_cMat.diffuseColor.setPackedValue(rgba);
hasSetValue();
}
void PropertyMaterial::setSpecularColor(const Color& col)
{
aboutToSetValue();
@@ -2431,6 +2474,20 @@ void PropertyMaterial::setSpecularColor(const Color& col)
hasSetValue();
}
void PropertyMaterial::setSpecularColor(float r, float g, float b, float a)
{
aboutToSetValue();
_cMat.specularColor.set(r, g, b, a);
hasSetValue();
}
void PropertyMaterial::setSpecularColor(uint32_t rgba)
{
aboutToSetValue();
_cMat.specularColor.setPackedValue(rgba);
hasSetValue();
}
void PropertyMaterial::setEmissiveColor(const Color& col)
{
aboutToSetValue();
@@ -2438,6 +2495,20 @@ void PropertyMaterial::setEmissiveColor(const Color& col)
hasSetValue();
}
void PropertyMaterial::setEmissiveColor(float r, float g, float b, float a)
{
aboutToSetValue();
_cMat.emissiveColor.set(r, g, b, a);
hasSetValue();
}
void PropertyMaterial::setEmissiveColor(uint32_t rgba)
{
aboutToSetValue();
_cMat.emissiveColor.setPackedValue(rgba);
hasSetValue();
}
void PropertyMaterial::setShininess(float val)
{
aboutToSetValue();
@@ -2452,36 +2523,135 @@ void PropertyMaterial::setTransparency(float val)
hasSetValue();
}
PyObject *PropertyMaterial::getPyObject()
const Color& PropertyMaterial::getAmbientColor() const
{
return _cMat.ambientColor;
}
const Color& PropertyMaterial::getDiffuseColor() const
{
return _cMat.diffuseColor;
}
const Color& PropertyMaterial::getSpecularColor() const
{
return _cMat.specularColor;
}
const Color& PropertyMaterial::getEmissiveColor() const
{
return _cMat.emissiveColor;
}
double PropertyMaterial::getShininess() const
{
return _cMat.shininess;
}
double PropertyMaterial::getTransparency() const
{
return _cMat.transparency;
}
PyObject* PropertyMaterial::getPyObject()
{
return new MaterialPy(new Material(_cMat));
}
void PropertyMaterial::setPyObject(PyObject *value)
void PropertyMaterial::setPyObject(PyObject* value)
{
App::Color cCol;
if (PyObject_TypeCheck(value, &(MaterialPy::Type))) {
setValue(*static_cast<MaterialPy*>(value)->getMaterialPtr());
}
else if (PyTuple_Check(value) && (PyTuple_Size(value) == 3 || PyTuple_Size(value) == 4)) {
PyObject* item;
item = PyTuple_GetItem(value, 0);
if (PyFloat_Check(item)) {
cCol.r = (float)PyFloat_AsDouble(item);
item = PyTuple_GetItem(value, 1);
if (PyFloat_Check(item)) {
cCol.g = (float)PyFloat_AsDouble(item);
}
else {
throw Base::TypeError("Type in tuple must be consistent (float)");
}
item = PyTuple_GetItem(value, 2);
if (PyFloat_Check(item)) {
cCol.b = (float)PyFloat_AsDouble(item);
}
else {
throw Base::TypeError("Type in tuple must be consistent (float)");
}
if (PyTuple_Size(value) == 4) {
item = PyTuple_GetItem(value, 3);
if (PyFloat_Check(item)) {
cCol.a = (float)PyFloat_AsDouble(item);
}
else {
throw Base::TypeError("Type in tuple must be consistent (float)");
}
}
setValue(cCol);
}
else if (PyLong_Check(item)) {
cCol.r = PyLong_AsLong(item) / 255.0;
item = PyTuple_GetItem(value, 1);
if (PyLong_Check(item)) {
cCol.g = PyLong_AsLong(item) / 255.0;
}
else {
throw Base::TypeError("Type in tuple must be consistent (integer)");
}
item = PyTuple_GetItem(value, 2);
if (PyLong_Check(item)) {
cCol.b = PyLong_AsLong(item) / 255.0;
}
else {
throw Base::TypeError("Type in tuple must be consistent (integer)");
}
if (PyTuple_Size(value) == 4) {
item = PyTuple_GetItem(value, 3);
if (PyLong_Check(item)) {
cCol.a = PyLong_AsLong(item) / 255.0;
}
else {
throw Base::TypeError("Type in tuple must be consistent (integer)");
}
}
setValue(cCol);
}
else {
throw Base::TypeError("Type in tuple must be float or integer");
}
}
else if (PyLong_Check(value)) {
cCol.setPackedValue(PyLong_AsUnsignedLong(value));
setValue(cCol);
}
else {
std::string error = std::string("type must be 'Material', not ");
std::string error = std::string(
"type must be 'Material', integer, tuple of float, or tuple of integer, not ");
error += value->ob_type->tp_name;
throw Base::TypeError(error);
}
}
void PropertyMaterial::Save (Base::Writer &writer) const
void PropertyMaterial::Save(Base::Writer& writer) const
{
writer.Stream() << writer.ind() << "<PropertyMaterial ambientColor=\""
<< _cMat.ambientColor.getPackedValue()
<< "\" diffuseColor=\"" << _cMat.diffuseColor.getPackedValue()
<< "\" specularColor=\"" << _cMat.specularColor.getPackedValue()
<< "\" emissiveColor=\"" << _cMat.emissiveColor.getPackedValue()
<< "\" shininess=\"" << _cMat.shininess
<< "\" transparency=\"" << _cMat.transparency
<< "\"/>" << endl;
<< _cMat.ambientColor.getPackedValue() << "\" diffuseColor=\""
<< _cMat.diffuseColor.getPackedValue() << "\" specularColor=\""
<< _cMat.specularColor.getPackedValue() << "\" emissiveColor=\""
<< _cMat.emissiveColor.getPackedValue() << "\" shininess=\"" << _cMat.shininess
<< "\" transparency=\"" << _cMat.transparency << "\"/>"
<< "\" uuid=\"" << _cMat.uuid << "\"/>" << endl;
}
void PropertyMaterial::Restore(Base::XMLReader &reader)
void PropertyMaterial::Restore(Base::XMLReader& reader)
{
// read my Element
reader.readElement("PropertyMaterial");
@@ -2493,24 +2663,28 @@ void PropertyMaterial::Restore(Base::XMLReader &reader)
_cMat.emissiveColor.setPackedValue(reader.getAttributeAsUnsigned("emissiveColor"));
_cMat.shininess = (float)reader.getAttributeAsFloat("shininess");
_cMat.transparency = (float)reader.getAttributeAsFloat("transparency");
if (reader.hasAttribute("uuid")) {
_cMat.uuid = reader.getAttribute("uuid");
}
hasSetValue();
}
const char* PropertyMaterial::getEditorName() const
{
if(testStatus(MaterialEdit))
if (testStatus(MaterialEdit)) {
return "Gui::PropertyEditor::PropertyMaterialItem";
}
return "";
}
Property *PropertyMaterial::Copy() const
Property* PropertyMaterial::Copy() const
{
PropertyMaterial *p= new PropertyMaterial();
PropertyMaterial* p = new PropertyMaterial();
p->_cMat = _cMat;
return p;
}
void PropertyMaterial::Paste(const Property &from)
void PropertyMaterial::Paste(const Property& from)
{
aboutToSetValue();
_cMat = dynamic_cast<const PropertyMaterial&>(from)._cMat;
@@ -2533,20 +2707,474 @@ PropertyMaterialList::~PropertyMaterialList() = default;
//**************************************************************************
// Base class implementer
PyObject *PropertyMaterialList::getPyObject()
PyObject* PropertyMaterialList::getPyObject()
{
Py::Tuple tuple(getSize());
for (int i = 0; i<getSize(); i++) {
for (int i = 0; i < getSize(); i++) {
tuple.setItem(i, Py::asObject(new MaterialPy(new Material(_lValueList[i]))));
}
return Py::new_reference_to(tuple);
}
Material PropertyMaterialList::getPyValue(PyObject *value) const {
if (PyObject_TypeCheck(value, &(MaterialPy::Type)))
void PropertyMaterialList::verifyIndex(int index) const
{
int size = getSize();
if (index < -1 || index > size) {
throw Base::RuntimeError("index out of bound");
}
}
void PropertyMaterialList::setSizeOne()
{
int size = getSize();
if (size < 1) {
setSize(1);
}
}
void PropertyMaterialList::setValue()
{
Material empty;
setValue(empty);
}
void PropertyMaterialList::setValue(const Material& mat)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material = mat;
}
hasSetValue();
}
void PropertyMaterialList::setValue(int index, const Material& mat)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index] = mat;
hasSetValue();
}
void PropertyMaterialList::setAmbientColor(const Color& col)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.ambientColor = col;
}
hasSetValue();
}
void PropertyMaterialList::setAmbientColor(float r, float g, float b, float a)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.ambientColor.set(r, g, b, a);
}
hasSetValue();
}
void PropertyMaterialList::setAmbientColor(uint32_t rgba)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.ambientColor.setPackedValue(rgba);
}
hasSetValue();
}
void PropertyMaterialList::setAmbientColor(int index, const Color& col)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].ambientColor = col;
hasSetValue();
}
void PropertyMaterialList::setAmbientColor(int index, float r, float g, float b, float a)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].ambientColor.set(r, g, b, a);
hasSetValue();
}
void PropertyMaterialList::setAmbientColor(int index, uint32_t rgba)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].ambientColor.setPackedValue(rgba);
hasSetValue();
}
void PropertyMaterialList::setDiffuseColor(const Color& col)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.diffuseColor = col;
}
hasSetValue();
}
void PropertyMaterialList::setDiffuseColor(float r, float g, float b, float a)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.diffuseColor.set(r, g, b, a);
}
hasSetValue();
}
void PropertyMaterialList::setDiffuseColor(uint32_t rgba)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.diffuseColor.setPackedValue(rgba);
}
hasSetValue();
}
void PropertyMaterialList::setDiffuseColor(int index, const Color& col)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].diffuseColor = col;
hasSetValue();
}
void PropertyMaterialList::setDiffuseColor(int index, float r, float g, float b, float a)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].diffuseColor.set(r, g, b, a);
hasSetValue();
}
void PropertyMaterialList::setDiffuseColor(int index, uint32_t rgba)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].diffuseColor.setPackedValue(rgba);
hasSetValue();
}
void PropertyMaterialList::setSpecularColor(const Color& col)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.specularColor = col;
}
hasSetValue();
}
void PropertyMaterialList::setSpecularColor(float r, float g, float b, float a)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.specularColor.set(r, g, b, a);
}
hasSetValue();
}
void PropertyMaterialList::setSpecularColor(uint32_t rgba)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.specularColor.setPackedValue(rgba);
}
hasSetValue();
}
void PropertyMaterialList::setSpecularColor(int index, const Color& col)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].specularColor = col;
hasSetValue();
}
void PropertyMaterialList::setSpecularColor(int index, float r, float g, float b, float a)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].specularColor.set(r, g, b, a);
hasSetValue();
}
void PropertyMaterialList::setSpecularColor(int index, uint32_t rgba)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].specularColor.setPackedValue(rgba);
hasSetValue();
}
void PropertyMaterialList::setEmissiveColor(const Color& col)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.emissiveColor = col;
}
hasSetValue();
}
void PropertyMaterialList::setEmissiveColor(float r, float g, float b, float a)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.emissiveColor.set(r, g, b, a);
}
hasSetValue();
}
void PropertyMaterialList::setEmissiveColor(uint32_t rgba)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.emissiveColor.setPackedValue(rgba);
}
hasSetValue();
}
void PropertyMaterialList::setEmissiveColor(int index, const Color& col)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].emissiveColor = col;
hasSetValue();
}
void PropertyMaterialList::setEmissiveColor(int index, float r, float g, float b, float a)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].emissiveColor.set(r, g, b, a);
hasSetValue();
}
void PropertyMaterialList::setEmissiveColor(int index, uint32_t rgba)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].emissiveColor.setPackedValue(rgba);
hasSetValue();
}
void PropertyMaterialList::setShininess(float val)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.shininess = val;
}
hasSetValue();
}
void PropertyMaterialList::setShininess(int index, float val)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].shininess = val;
hasSetValue();
}
void PropertyMaterialList::setTransparency(float val)
{
aboutToSetValue();
setSizeOne();
for (auto& material : _lValueList) {
material.transparency = val;
}
hasSetValue();
}
void PropertyMaterialList::setTransparency(int index, float val)
{
verifyIndex(index);
aboutToSetValue();
int size = getSize();
if (index == -1 || index == size) {
index = size;
setSize(index + 1);
}
_lValueList[index].transparency = val;
hasSetValue();
}
const Color& PropertyMaterialList::getAmbientColor() const
{
return _lValueList[0].ambientColor;
}
const Color& PropertyMaterialList::getAmbientColor(int index) const
{
return _lValueList[index].ambientColor;
}
const Color& PropertyMaterialList::getDiffuseColor() const
{
return _lValueList[0].diffuseColor;
}
const Color& PropertyMaterialList::getDiffuseColor(int index) const
{
return _lValueList[index].diffuseColor;
}
std::vector<App::Color> PropertyMaterialList::getDiffuseColors() const
{
std::vector<App::Color> list;
for (auto& material : _lValueList) {
list.push_back(material.diffuseColor);
}
return list;
}
const Color& PropertyMaterialList::getSpecularColor() const
{
return _lValueList[0].specularColor;
}
const Color& PropertyMaterialList::getSpecularColor(int index) const
{
return _lValueList[index].specularColor;
}
const Color& PropertyMaterialList::getEmissiveColor() const
{
return _lValueList[0].emissiveColor;
}
const Color& PropertyMaterialList::getEmissiveColor(int index) const
{
return _lValueList[index].emissiveColor;
}
double PropertyMaterialList::getShininess() const
{
return _lValueList[0].transparency;
}
double PropertyMaterialList::getShininess(int index) const
{
return _lValueList[index].transparency;
}
double PropertyMaterialList::getTransparency() const
{
return _lValueList[0].transparency;
}
double PropertyMaterialList::getTransparency(int index) const
{
return _lValueList[index].transparency;
}
Material PropertyMaterialList::getPyValue(PyObject* value) const
{
if (PyObject_TypeCheck(value, &(MaterialPy::Type))) {
return *static_cast<MaterialPy*>(value)->getMaterialPtr();
}
else {
std::string error = std::string("type must be 'Material', not ");
error += value->ob_type->tp_name;
@@ -2554,15 +3182,16 @@ Material PropertyMaterialList::getPyValue(PyObject *value) const {
}
}
void PropertyMaterialList::Save(Base::Writer &writer) const
void PropertyMaterialList::Save(Base::Writer& writer) const
{
if (!writer.isForceXML()) {
writer.Stream() << writer.ind() << "<MaterialList file=\"" <<
(getSize()?writer.addFile(getName(), this):"") << "\"/>" << std::endl;
writer.Stream() << writer.ind() << "<MaterialList file=\""
<< (getSize() ? writer.addFile(getName(), this) : "") << "\"/>"
<< std::endl;
}
}
void PropertyMaterialList::Restore(Base::XMLReader &reader)
void PropertyMaterialList::Restore(Base::XMLReader& reader)
{
reader.readElement("MaterialList");
if (reader.hasAttribute("file")) {
@@ -2575,30 +3204,47 @@ void PropertyMaterialList::Restore(Base::XMLReader &reader)
}
}
void PropertyMaterialList::SaveDocFile(Base::Writer &writer) const
void PropertyMaterialList::SaveDocFile(Base::Writer& writer) const
{
Base::OutputStream str(writer.Stream());
// Write the version. Versions should be negative. A non-negative value is a count
// and should be processed as a V0
int32_t version = -1;
str << version;
uint32_t uCt = (uint32_t)getSize();
str << uCt;
for (const auto & it : _lValueList) {
for (const auto& it : _lValueList) {
str << it.ambientColor.getPackedValue();
str << it.diffuseColor.getPackedValue();
str << it.specularColor.getPackedValue();
str << it.emissiveColor.getPackedValue();
str << it.shininess;
str << it.transparency;
// str << it.uuid.c_str();
}
}
void PropertyMaterialList::RestoreDocFile(Base::Reader &reader)
void PropertyMaterialList::RestoreDocFile(Base::Reader& reader)
{
Base::InputStream str(reader);
uint32_t uCt = 0;
str >> uCt;
std::vector<Material> values(uCt);
uint32_t value; // must be 32 bit long
int32_t version;
str >> version;
if (version < 0) {
RestoreDocFileV1(reader);
}
else {
uint32_t uCt = static_cast<uint32_t>(version);
RestoreDocFileV0(uCt, reader);
}
}
void PropertyMaterialList::RestoreDocFileV0(uint32_t count, Base::Reader& reader)
{
Base::InputStream str(reader);
std::vector<Material> values(count);
uint32_t value; // must be 32 bit long
float valueF;
for (auto & it : values) {
for (auto& it : values) {
str >> value;
it.ambientColor.setPackedValue(value);
str >> value;
@@ -2615,21 +3261,50 @@ void PropertyMaterialList::RestoreDocFile(Base::Reader &reader)
setValues(values);
}
void PropertyMaterialList::RestoreDocFileV1(Base::Reader& reader)
{
Base::InputStream str(reader);
uint32_t count = 0;
str >> count;
std::vector<Material> values(count);
uint32_t value; // must be 32 bit long
float valueF;
char valueS[37]; // UUID length is 36 including '-'s
for (auto& it : values) {
str >> value;
it.ambientColor.setPackedValue(value);
str >> value;
it.diffuseColor.setPackedValue(value);
str >> value;
it.specularColor.setPackedValue(value);
str >> value;
it.emissiveColor.setPackedValue(value);
str >> valueF;
it.shininess = valueF;
str >> valueF;
it.transparency = valueF;
// str >> valueS;
// it.uuid = valueS;
}
setValues(values);
}
const char* PropertyMaterialList::getEditorName() const
{
if(testStatus(NoMaterialListEdit))
if (testStatus(NoMaterialListEdit)) {
return "";
}
return "Gui::PropertyEditor::PropertyMaterialListItem";
}
Property *PropertyMaterialList::Copy() const
Property* PropertyMaterialList::Copy() const
{
PropertyMaterialList *p = new PropertyMaterialList();
PropertyMaterialList* p = new PropertyMaterialList();
p->_lValueList = _lValueList;
return p;
}
void PropertyMaterialList::Paste(const Property &from)
void PropertyMaterialList::Paste(const Property& from)
{
setValues(dynamic_cast<const PropertyMaterialList&>(from)._lValueList);
}
+120 -33
View File
@@ -467,7 +467,7 @@ public:
void Paste(const Property &from) override;
unsigned int getMemSize () const override;
bool isSame(const Property &other) const override {
if (&other == this)
return true;
@@ -954,7 +954,7 @@ public:
void Paste(const Property &from) override;
unsigned int getMemSize () const override{return sizeof(Color);}
bool isSame(const Property &other) const override {
if (&other == this)
return true;
@@ -1000,15 +1000,15 @@ protected:
Color getPyValue(PyObject *) const override;
};
/** Material properties
* This is the father of all properties handling colors.
*/
class AppExport PropertyMaterial : public Property
class AppExport PropertyMaterial: public Property
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
/**
* A constructor.
* A more elaborate description of the constructor.
@@ -1023,34 +1023,56 @@ public:
/** Sets the property
*/
void setValue(const Material &mat);
void setValue(const Material& mat);
void setValue(const Color& col);
void setValue(float r, float g, float b, float a = 0.0f);
void setValue(uint32_t rgba);
void setAmbientColor(const Color& col);
void setAmbientColor(float r, float g, float b, float a = 0.0f);
void setAmbientColor(uint32_t rgba);
void setDiffuseColor(const Color& col);
void setDiffuseColor(float r, float g, float b, float a = 0.0f);
void setDiffuseColor(uint32_t rgba);
void setSpecularColor(const Color& col);
void setSpecularColor(float r, float g, float b, float a = 0.0f);
void setSpecularColor(uint32_t rgba);
void setEmissiveColor(const Color& col);
void setEmissiveColor(float r, float g, float b, float a = 0.0f);
void setEmissiveColor(uint32_t rgba);
void setShininess(float);
void setTransparency(float);
/** This method returns a string representation of the property
*/
const Material &getValue() const;
const Material& getValue() const;
const Color& getAmbientColor() const;
const Color& getDiffuseColor() const;
const Color& getSpecularColor() const;
const Color& getEmissiveColor() const;
double getShininess() const;
double getTransparency() const;
PyObject *getPyObject() override;
void setPyObject(PyObject *) override;
PyObject* getPyObject() override;
void setPyObject(PyObject*) override;
void Save (Base::Writer &writer) const override;
void Restore(Base::XMLReader &reader) override;
void Save(Base::Writer& writer) const override;
void Restore(Base::XMLReader& reader) override;
const char* getEditorName() const override;
Property *Copy() const override;
void Paste(const Property &from) override;
Property* Copy() const override;
void Paste(const Property& from) override;
unsigned int getMemSize () const override{return sizeof(_cMat);}
bool isSame(const Property &other) const override {
if (&other == this)
unsigned int getMemSize() const override
{
return sizeof(_cMat);
}
bool isSame(const Property& other) const override
{
if (&other == this) {
return true;
}
return getTypeId() == other.getTypeId()
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
}
@@ -1060,41 +1082,106 @@ private:
};
/** Material properties
*/
class AppExport PropertyMaterialList : public PropertyListsT<Material>
*/
class AppExport PropertyMaterialList: public PropertyListsT<Material>
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
/**
* A constructor.
* A more elaborate description of the constructor.
*/
* A constructor.
* A more elaborate description of the constructor.
*/
PropertyMaterialList();
/**
* A destructor.
* A more elaborate description of the destructor.
*/
* A destructor.
* A more elaborate description of the destructor.
*/
~PropertyMaterialList() override;
PyObject *getPyObject() override;
void setValue();
void setValue(const std::vector<App::Material>& materials)
{
PropertyListsT<Material>::setValue(materials);
}
void setValue(const Material& mat);
void setValue(int index, const Material& mat);
void Save(Base::Writer &writer) const override;
void Restore(Base::XMLReader &reader) override;
void setAmbientColor(const Color& col);
void setAmbientColor(float r, float g, float b, float a = 0.0f);
void setAmbientColor(uint32_t rgba);
void setAmbientColor(int index, const Color& col);
void setAmbientColor(int index, float r, float g, float b, float a = 0.0f);
void setAmbientColor(int index, uint32_t rgba);
void SaveDocFile(Base::Writer &writer) const override;
void RestoreDocFile(Base::Reader &reader) override;
void setDiffuseColor(const Color& col);
void setDiffuseColor(float r, float g, float b, float a = 0.0f);
void setDiffuseColor(uint32_t rgba);
void setDiffuseColor(int index, const Color& col);
void setDiffuseColor(int index, float r, float g, float b, float a = 0.0f);
void setDiffuseColor(int index, uint32_t rgba);
void setSpecularColor(const Color& col);
void setSpecularColor(float r, float g, float b, float a = 0.0f);
void setSpecularColor(uint32_t rgba);
void setSpecularColor(int index, const Color& col);
void setSpecularColor(int index, float r, float g, float b, float a = 0.0f);
void setSpecularColor(int index, uint32_t rgba);
void setEmissiveColor(const Color& col);
void setEmissiveColor(float r, float g, float b, float a = 0.0f);
void setEmissiveColor(uint32_t rgba);
void setEmissiveColor(int index, const Color& col);
void setEmissiveColor(int index, float r, float g, float b, float a = 0.0f);
void setEmissiveColor(int index, uint32_t rgba);
void setShininess(float);
void setShininess(int index, float);
void setTransparency(float);
void setTransparency(int index, float);
const Color& getAmbientColor() const;
const Color& getAmbientColor(int index) const;
const Color& getDiffuseColor() const;
const Color& getDiffuseColor(int index) const;
std::vector<App::Color> getDiffuseColors() const;
const Color& getSpecularColor() const;
const Color& getSpecularColor(int index) const;
const Color& getEmissiveColor() const;
const Color& getEmissiveColor(int index) const;
double getShininess() const;
double getShininess(int index) const;
double getTransparency() const;
double getTransparency(int index) const;
PyObject* getPyObject() override;
void Save(Base::Writer& writer) const override;
void Restore(Base::XMLReader& reader) override;
void SaveDocFile(Base::Writer& writer) const override;
void RestoreDocFile(Base::Reader& reader) override;
const char* getEditorName() const override;
Property *Copy() const override;
void Paste(const Property &from) override;
Property* Copy() const override;
void Paste(const Property& from) override;
unsigned int getMemSize() const override;
protected:
Material getPyValue(PyObject *) const override;
Material getPyValue(PyObject*) const override;
void verifyIndex(int index) const;
void setSizeOne();
void RestoreDocFileV0(uint32_t count, Base::Reader& reader);
void RestoreDocFileV1(Base::Reader& reader);
};
+3 -4
View File
@@ -220,6 +220,7 @@ generate_from_xml(DocumentPy)
generate_from_xml(PythonWorkbenchPy)
generate_from_xml(ViewProviderPy)
generate_from_xml(ViewProviderDocumentObjectPy)
generate_from_xml(ViewProviderGeometryObjectPy)
generate_from_xml(ViewProviderExtensionPy)
generate_from_xml(WorkbenchPy)
generate_from_xml(SelectionObjectPy)
@@ -233,6 +234,7 @@ generate_from_py(FreeCADGuiInit GuiInitScript.h)
# The XML files
SET(FreeCADGui_XML_SRCS
ViewProviderDocumentObjectPy.xml
ViewProviderGeometryObjectPy.xml
ViewProviderPy.xml
ViewProviderExtensionPy.xml
PythonWorkbenchPy.xml
@@ -297,7 +299,6 @@ SET(Gui_UIC_SRCS
DlgChooseIcon.ui
DlgCreateNewPreferencePack.ui
DlgCustomizeSpNavSettings.ui
DlgDisplayProperties.ui
DlgInputDialog.ui
DlgKeyboard.ui
DlgMacroExecute.ui
@@ -407,7 +408,6 @@ SET(Dialog_CPP_SRCS
DlgActivateWindowImp.cpp
DlgCreateNewPreferencePackImp.cpp
DlgUnitsCalculatorImp.cpp
DlgDisplayPropertiesImp.cpp
DlgInputDialogImp.cpp
DlgMacroExecuteImp.cpp
DlgRunExternal.cpp
@@ -447,7 +447,6 @@ SET(Dialog_HPP_SRCS
DlgActivateWindowImp.h
DlgCreateNewPreferencePackImp.h
DlgUnitsCalculatorImp.h
DlgDisplayPropertiesImp.h
DlgInputDialogImp.h
DlgMacroExecuteImp.h
DlgRunExternal.h
@@ -490,7 +489,6 @@ SET(Dialog_SRCS
DlgActivateWindow.ui
DlgUnitsCalculator.ui
DlgAuthorization.ui
DlgDisplayProperties.ui
DlgInputDialog.ui
DlgAddProperty.ui
DlgLocationAngle.ui
@@ -900,6 +898,7 @@ SET(Viewprovider_CPP_SRCS
ViewProviderDocumentObject.cpp
ViewProviderDocumentObjectGroup.cpp
ViewProviderDocumentObjectPyImp.cpp
ViewProviderGeometryObjectPyImp.cpp
ViewProviderDragger.cpp
ViewProviderExtern.cpp
ViewProviderFeature.cpp
+2 -1
View File
@@ -785,7 +785,8 @@ void Command::_copyVisual(const char *file, int line, const App::DocumentObject
if(!from || !from->isAttachedToDocument() || !to || !to->isAttachedToDocument())
return;
static std::map<std::string,std::string> attrMap = {
{"ShapeColor","ShapeMaterial.DiffuseColor"},
// {"ShapeColor","ShapeMaterial.DiffuseColor"},
{"ShapeAppearance", "ShapeMaterial"},
// {"LineColor","ShapeMaterial.DiffuseColor"},
// {"PointColor","ShapeMaterial.DiffuseColor"},
{"Transparency","Transparency"},
+4 -2
View File
@@ -104,9 +104,11 @@ void StdCmdRandomColor::activated(int iMsg)
vpLink->ShapeMaterial.setDiffuseColor(objColor);
}
else if (view) {
if (auto color = dynamic_cast<App::PropertyColor*>(view->getPropertyByName("ShapeColor"))) {
auto appearance =
dynamic_cast<App::PropertyMaterial*>(view->getPropertyByName("ShapeAppearance"));
if (appearance) {
// get the view provider of the selected object and set the shape color
color->setValue(objColor);
appearance->setDiffuseColor(objColor);
}
}
};
-32
View File
@@ -62,7 +62,6 @@
#include "Control.h"
#include "Clipping.h"
#include "DemoMode.h"
#include "DlgDisplayPropertiesImp.h"
#include "DlgSettingsImageImp.h"
#include "Document.h"
#include "FileDialog.h"
@@ -1262,36 +1261,6 @@ bool StdCmdHideObjects::isActive()
return App::GetApplication().getActiveDocument();
}
//===========================================================================
// Std_SetAppearance
//===========================================================================
DEF_STD_CMD_A(StdCmdSetAppearance)
StdCmdSetAppearance::StdCmdSetAppearance()
: Command("Std_SetAppearance")
{
sGroup = "Standard-View";
sMenuText = QT_TR_NOOP("Appearance...");
sToolTipText = QT_TR_NOOP("Sets the display properties of the selected object");
sWhatsThis = "Std_SetAppearance";
sStatusTip = QT_TR_NOOP("Sets the display properties of the selected object");
sPixmap = "Std_SetAppearance";
sAccel = "Ctrl+D";
eType = Alter3DView;
}
void StdCmdSetAppearance::activated(int iMsg)
{
Q_UNUSED(iMsg);
Gui::Control().showDialog(new Gui::Dialog::TaskDisplayProperties());
}
bool StdCmdSetAppearance::isActive()
{
return (Gui::Control().activeDialog() == nullptr) &&
(Gui::Selection().size() != 0);
}
//===========================================================================
// Std_ViewHome
//===========================================================================
@@ -4123,7 +4092,6 @@ void CreateViewStdCommands()
rcCmdMgr.addCommand(new StdViewLoadImage());
rcCmdMgr.addCommand(new StdMainFullscreen());
rcCmdMgr.addCommand(new StdViewDockUndockFullscreen());
rcCmdMgr.addCommand(new StdCmdSetAppearance());
rcCmdMgr.addCommand(new StdCmdToggleVisibility());
rcCmdMgr.addCommand(new StdCmdToggleTransparency());
rcCmdMgr.addCommand(new StdCmdToggleSelectability());
+11 -8
View File
@@ -28,18 +28,22 @@
#include <memory>
#include <vector>
namespace Gui {
namespace Gui
{
class ViewProvider;
namespace Dialog {
namespace Dialog
{
class Ui_DlgMaterialProperties;
class DlgMaterialPropertiesImp : public QDialog
class GuiExport DlgMaterialPropertiesImp: public QDialog
{
Q_OBJECT
public:
explicit DlgMaterialPropertiesImp(const std::string& mat, QWidget* parent = nullptr, Qt::WindowFlags fl = Qt::WindowFlags());
explicit DlgMaterialPropertiesImp(const std::string& mat,
QWidget* parent = nullptr,
Qt::WindowFlags fl = Qt::WindowFlags());
~DlgMaterialPropertiesImp() override;
void setViewProviders(const std::vector<Gui::ViewProvider*>&);
QColor diffuseColor() const;
@@ -58,8 +62,7 @@ private:
std::vector<Gui::ViewProvider*> Objects;
};
} // namespace Dialog
} // namespace Gui
#endif // GUI_DIALOG_DLGMATERIALPROPERTIES_IMP_H
} // namespace Dialog
} // namespace Gui
#endif // GUI_DIALOG_DLGMATERIALPROPERTIES_IMP_H
+5 -3
View File
@@ -201,9 +201,11 @@ void AlignmentGroup::setAlignable(bool align)
}
// leaving alignment mode
else if (!align){
auto pColor = dynamic_cast<App::PropertyColor*>((*it)->getPropertyByName("ShapeColor"));
if (pColor)
pColor->touch(); // resets to color defined by property
auto pAppearance =
dynamic_cast<App::PropertyMaterial*>((*it)->getPropertyByName("ShapeAppearance"));
if (pAppearance) {
pAppearance->touch(); // resets to color defined by property
}
}
}
}
+3
View File
@@ -451,6 +451,9 @@ void StartupPostProcess::showMainWindow()
void StartupPostProcess::activateWorkbench()
{
// Always activate the material workbench
guiApp.activateWorkbench("MaterialWorkbench");
// Activate the correct workbench
std::string start = App::Application::Config()["StartWorkbench"];
Base::Console().Log("Init: Activating default workbench %s\n", start.c_str());
+155 -80
View File
@@ -23,17 +23,17 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/SoPickedPoint.h>
# include <Inventor/actions/SoRayPickAction.h>
# include <Inventor/actions/SoSearchAction.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoCamera.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoFont.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoSwitch.h>
# include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/actions/SoRayPickAction.h>
#include <Inventor/actions/SoSearchAction.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCamera.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoFont.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSwitch.h>
#endif
#include <Inventor/nodes/SoResetTransform.h>
@@ -41,13 +41,13 @@
#include <App/GeoFeature.h>
#include <App/PropertyGeo.h>
#include "ViewProviderGeometryObject.h"
#include "Application.h"
#include "Document.h"
#include "SoFCBoundingBox.h"
#include "SoFCSelection.h"
#include "View3DInventorViewer.h"
#include "ViewProviderGeometryObject.h"
#include "ViewProviderGeometryObjectPy.h"
using namespace Gui;
@@ -57,44 +57,59 @@ const App::PropertyIntegerConstraint::Constraints intPercent = {0, 100, 5};
ViewProviderGeometryObject::ViewProviderGeometryObject()
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
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;
}
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;
}
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
int initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
static const char *dogroup = "Display Options";
static const char *sgroup = "Selection";
static const char *osgroup = "Object Style";
static const char* dogroup = "Display Options";
static const char* sgroup = "Selection";
static const char* osgroup = "Object Style";
ADD_PROPERTY_TYPE(ShapeColor, (r, g, b), osgroup, App::Prop_None, "Set shape color");
ADD_PROPERTY_TYPE(Transparency, (initialTransparency), osgroup, App::Prop_None, "Set object transparency");
ADD_PROPERTY_TYPE(Transparency,
(initialTransparency),
osgroup,
App::Prop_None,
"Set object transparency");
Transparency.setConstraints(&intPercent);
App::Material mat(App::Material::DEFAULT);
mat.transparency = (float)initialTransparency / 100.0f;
ADD_PROPERTY_TYPE(ShapeMaterial,(mat), osgroup, App::Prop_None, "Shape material");
auto geometry = dynamic_cast<App::GeoFeature*>(getObject());
if (geometry) {
mat = geometry->getMaterialAppearance();
} else {
// This is handled in the material code when using the object appearance
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;
}
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;
}
mat.diffuseColor = App::Color(r,g,b);
}
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, (true), sgroup, App::Prop_None, "Set if the object is selectable in the 3d view");
ADD_PROPERTY_TYPE(Selectable,
(true),
sgroup,
App::Prop_None,
"Set if the object is selectable in the 3d view");
bool enableSel = hGrp->GetBool("EnableSelection", true);
Selectable.setValue(enableSel);
pcShapeMaterial = new SoMaterial;
pcShapeMaterial->diffuseColor.setValue(r, g, b);
pcShapeMaterial->transparency = float(initialTransparency);
setSoMaterial(mat);
pcShapeMaterial->ref();
pcBoundingBox = new Gui::SoFCBoundingBox;
@@ -115,44 +130,32 @@ ViewProviderGeometryObject::~ViewProviderGeometryObject()
void ViewProviderGeometryObject::onChanged(const App::Property* prop)
{
// Actually, the properties 'ShapeColor' and 'Transparency' are part of the property 'ShapeMaterial'.
// Both redundant properties are kept due to more convenience for the user. But we must keep the values
// consistent of all these properties.
// Actually, the properties 'ShapeColor' and 'Transparency' are part of the property
// 'ShapeMaterial'. Both redundant properties are kept due to more convenience for the user. But
// we must keep the values consistent of all these properties.
std::string propName = prop->getName();
if (prop == &Selectable) {
bool Sel = Selectable.getValue();
setSelectable(Sel);
}
else if (prop == &ShapeColor) {
const App::Color &c = ShapeColor.getValue();
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
if (c != ShapeMaterial.getValue().diffuseColor)
ShapeMaterial.setDiffuseColor(c);
}
else if (prop == &Transparency) {
const App::Material &Mat = ShapeMaterial.getValue();
long value = (long)(100 * Mat.transparency);
long value = (long)(100 * ShapeAppearance.getTransparency());
if (value != Transparency.getValue()) {
float trans = Transparency.getValue() / 100.0f;
float trans = (float)Transparency.getValue() / 100.0f;
pcShapeMaterial->transparency = trans;
ShapeMaterial.setTransparency(trans);
ShapeAppearance.setTransparency(trans);
}
}
else if (prop == &ShapeMaterial) {
if (getObject() && getObject()->testStatus(App::ObjectStatus::TouchOnColorChange))
else if (prop == &ShapeAppearance) {
if (getObject() && getObject()->testStatus(App::ObjectStatus::TouchOnColorChange)) {
getObject()->touch(true);
const App::Material &Mat = ShapeMaterial.getValue();
long value = (long)(100 * Mat.transparency);
if (value != Transparency.getValue())
}
const App::Material& Mat = ShapeAppearance[0];
long value = (long)(100.0 * ShapeAppearance.getTransparency() + 0.5);
if (value != Transparency.getValue()) {
Transparency.setValue(value);
const App::Color &color = Mat.diffuseColor;
if (color != ShapeColor.getValue())
ShapeColor.setValue(Mat.diffuseColor);
pcShapeMaterial->ambientColor.setValue(Mat.ambientColor.r, Mat.ambientColor.g, Mat.ambientColor.b);
pcShapeMaterial->diffuseColor.setValue(Mat.diffuseColor.r, Mat.diffuseColor.g, Mat.diffuseColor.b);
pcShapeMaterial->specularColor.setValue(Mat.specularColor.r, Mat.specularColor.g, Mat.specularColor.b);
pcShapeMaterial->emissiveColor.setValue(Mat.emissiveColor.r, Mat.emissiveColor.g, Mat.emissiveColor.b);
pcShapeMaterial->shininess.setValue(Mat.shininess);
pcShapeMaterial->transparency.setValue(Mat.transparency);
}
setSoMaterial(Mat);
}
else if (prop == &BoundingBox) {
showBoundingBox(BoundingBox.getValue());
@@ -161,15 +164,22 @@ void ViewProviderGeometryObject::onChanged(const App::Property* prop)
ViewProviderDragger::onChanged(prop);
}
void ViewProviderGeometryObject::attach(App::DocumentObject *pcObj)
void ViewProviderGeometryObject::attach(App::DocumentObject* pcObj)
{
ViewProviderDragger::attach(pcObj);
}
void ViewProviderGeometryObject::updateData(const App::Property* prop)
{
std::string propName = prop->getName();
if (propName == "Shape") {
// Reapply the appearance
const App::Material& Mat = ShapeAppearance[0];
setSoMaterial(Mat);
}
if (prop->isDerivedFrom(App::PropertyComplexGeoData::getClassTypeId())) {
Base::BoundBox3d box = static_cast<const App::PropertyComplexGeoData*>(prop)->getBoundingBox();
Base::BoundBox3d box =
static_cast<const App::PropertyComplexGeoData*>(prop)->getBoundingBox();
pcBoundingBox->minBounds.setValue(box.MinX, box.MinY, box.MinZ);
pcBoundingBox->maxBounds.setValue(box.MaxX, box.MaxY, box.MaxZ);
}
@@ -184,11 +194,21 @@ void ViewProviderGeometryObject::updateData(const App::Property* prop)
}
}
}
else if (std::string(prop->getName()) == "ShapeMaterial") {
// Set the appearance from the material
auto geometry = dynamic_cast<App::GeoFeature*>(getObject());
if (geometry) {
auto material = geometry->getMaterialAppearance();
ShapeAppearance.setValue(material);
}
}
ViewProviderDragger::updateData(prop);
}
SoPickedPointList ViewProviderGeometryObject::getPickedPoints(const SbVec2s& pos, const View3DInventorViewer& viewer,bool pickAll) const
SoPickedPointList ViewProviderGeometryObject::getPickedPoints(const SbVec2s& pos,
const View3DInventorViewer& viewer,
bool pickAll) const
{
auto root = new SoSeparator;
root->ref();
@@ -207,7 +227,8 @@ SoPickedPointList ViewProviderGeometryObject::getPickedPoints(const SbVec2s& pos
return rp.getPickedPointList();
}
SoPickedPoint* ViewProviderGeometryObject::getPickedPoint(const SbVec2s& pos, const View3DInventorViewer& viewer) const
SoPickedPoint* ViewProviderGeometryObject::getPickedPoint(const SbVec2s& pos,
const View3DInventorViewer& viewer) const
{
auto root = new SoSeparator;
root->ref();
@@ -223,31 +244,55 @@ SoPickedPoint* ViewProviderGeometryObject::getPickedPoint(const SbVec2s& pos, co
// returns a copy of the point
SoPickedPoint* pick = rp.getPickedPoint();
//return (pick ? pick->copy() : 0); // needs the same instance of CRT under MS Windows
// return (pick ? pick->copy() : 0); // needs the same instance of CRT under MS Windows
return (pick ? new SoPickedPoint(*pick) : nullptr);
}
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)
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
unsigned long bbcol =
hGrp->GetUnsigned("BoundingBoxColor", 4294967295UL); // white (255,255,255)
return bbcol;
}
namespace {
void ViewProviderGeometryObject::setSoMaterial(const App::Material& source)
{
pcShapeMaterial->ambientColor.setValue(source.ambientColor.r,
source.ambientColor.g,
source.ambientColor.b);
pcShapeMaterial->diffuseColor.setValue(source.diffuseColor.r,
source.diffuseColor.g,
source.diffuseColor.b);
pcShapeMaterial->specularColor.setValue(source.specularColor.r,
source.specularColor.g,
source.specularColor.b);
pcShapeMaterial->emissiveColor.setValue(source.emissiveColor.r,
source.emissiveColor.g,
source.emissiveColor.b);
pcShapeMaterial->shininess.setValue(source.shininess);
pcShapeMaterial->transparency.setValue(source.transparency);
}
namespace
{
float getBoundBoxFontSize()
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
return hGrp->GetFloat("BoundingBoxFontSize", 10.0);
}
}
} // namespace
void ViewProviderGeometryObject::showBoundingBox(bool show)
{
if (!pcBoundSwitch && show) {
unsigned long bbcol = getBoundColor();
float r,g,b;
r = ((bbcol >> 24) & 0xff) / 255.0; g = ((bbcol >> 16) & 0xff) / 255.0; b = ((bbcol >> 8) & 0xff) / 255.0;
float r, g, b;
r = ((bbcol >> 24) & 0xff) / 255.0;
g = ((bbcol >> 16) & 0xff) / 255.0;
b = ((bbcol >> 8) & 0xff) / 255.0;
pcBoundSwitch = new SoSwitch();
auto pBoundingSep = new SoSeparator();
@@ -284,9 +329,9 @@ void ViewProviderGeometryObject::setSelectable(bool selectable)
sa.setType(Gui::SoFCSelection::getClassTypeId());
sa.apply(pcRoot);
SoPathList & pathList = sa.getPaths();
SoPathList& pathList = sa.getPaths();
for (int i=0;i<pathList.getLength();i++) {
for (int i = 0; i < pathList.getLength(); i++) {
auto selNode = dynamic_cast<SoFCSelection*>(pathList[i]->getTail());
if (selectable) {
if (selNode) {
@@ -303,3 +348,33 @@ void ViewProviderGeometryObject::setSelectable(bool selectable)
}
}
}
PyObject* ViewProviderGeometryObject::getPyObject()
{
if (!pyViewObject) {
pyViewObject = new ViewProviderGeometryObjectPy(this);
}
pyViewObject->IncRef();
return pyViewObject;
}
void ViewProviderGeometryObject::handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName)
{
if (strcmp(PropName, "ShapeColor") == 0
&& strcmp(TypeName, App::PropertyColor::getClassTypeId().getName()) == 0) {
App::PropertyColor prop;
prop.Restore(reader);
ShapeAppearance.setDiffuseColor(prop.getValue());
}
else if (strcmp(PropName, "ShapeMaterial") == 0
&& strcmp(TypeName, App::PropertyMaterial::getClassTypeId().getName()) == 0) {
App::PropertyMaterial prop;
prop.Restore(reader);
ShapeAppearance.setValue(prop.getValue());
}
else {
App::PropertyContainer::handleChangedPropertyName(reader, TypeName, PropName);
}
}
+35 -20
View File
@@ -33,17 +33,19 @@ class SoSensor;
class SbVec2s;
class SoBaseColor;
namespace Gui {
namespace Gui
{
class SoFCSelection;
class SoFCBoundingBox;
class View3DInventorViewer;
/**
* The base class for all view providers that display geometric data, like mesh, point clouds and shapes.
* The base class for all view providers that display geometric data, like mesh, point clouds and
* shapes.
* @author Werner Mayer
*/
class GuiExport ViewProviderGeometryObject : public ViewProviderDragger
class GuiExport ViewProviderGeometryObject: public ViewProviderDragger
{
PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderGeometryObject);
@@ -55,30 +57,35 @@ public:
~ViewProviderGeometryObject() override;
// Display properties
App::PropertyColor ShapeColor;
App::PropertyPercent Transparency;
App::PropertyMaterial ShapeMaterial;
// App::PropertyMaterial ShapeMaterial; // Default appearance and physical properties
App::PropertyMaterialList ShapeAppearance; // May be different from material
App::PropertyBool BoundingBox;
App::PropertyBool Selectable;
/**
* Attaches the document object to this view provider.
*/
void attach(App::DocumentObject *pcObject) override;
void attach(App::DocumentObject* pcObject) override;
void updateData(const App::Property*) override;
bool isSelectable() const override {return Selectable.getValue();}
bool isSelectable() const override
{
return Selectable.getValue();
}
/**
* Returns a list of picked points from the geometry under \a getRoot().
* If \a pickAll is false (the default) only the intersection point closest to the camera will be picked, otherwise
* all intersection points will be picked.
* If \a pickAll is false (the default) only the intersection point closest to the camera will
* be picked, otherwise all intersection points will be picked.
*/
SoPickedPointList getPickedPoints(const SbVec2s& pos, const View3DInventorViewer& viewer,bool pickAll=false) const;
SoPickedPointList getPickedPoints(const SbVec2s& pos,
const View3DInventorViewer& viewer,
bool pickAll = false) const;
/**
* This method is provided for convenience and does basically the same as getPickedPoints() unless that only the closest
* point to the camera will be picked.
* \note It is in the response of the client programmer to delete the returned SoPickedPoint object.
* This method is provided for convenience and does basically the same as getPickedPoints()
* unless that only the closest point to the camera will be picked. \note It is in the response
* of the client programmer to delete the returned SoPickedPoint object.
*/
SoPickedPoint* getPickedPoint(const SbVec2s& pos, const View3DInventorViewer& viewer) const;
@@ -87,21 +94,29 @@ public:
virtual void showBoundingBox(bool);
//@}
/// Get the python wrapper for that ViewProvider
PyObject* getPyObject() override;
protected:
/// get called by the container whenever a property has been changed
void onChanged(const App::Property* prop) override;
void setSelectable(bool Selectable=true);
void setSelectable(bool Selectable = true);
virtual unsigned long getBoundColor() const;
void setSoMaterial(const App::Material& source);
void handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName) override;
protected:
SoMaterial * pcShapeMaterial{nullptr};
SoFCBoundingBox * pcBoundingBox{nullptr};
SoSwitch * pcBoundSwitch{nullptr};
SoBaseColor * pcBoundColor{nullptr};
SoMaterial* pcShapeMaterial {nullptr};
SoFCBoundingBox* pcBoundingBox {nullptr};
SoSwitch* pcBoundSwitch {nullptr};
SoBaseColor* pcBoundColor {nullptr};
};
} // namespace Gui
} // namespace Gui
#endif // GUI_VIEWPROVIDER_GEOMETRYOBJECT_H
#endif // GUI_VIEWPROVIDER_GEOMETRYOBJECT_H
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="ViewProviderDocumentObjectPy"
Name="ViewProviderGeometryObjectPy"
Twin="ViewProviderGeometryObject"
TwinPointer="ViewProviderGeometryObject"
Include="Gui/ViewProviderGeometryObject.h"
Namespace="Gui"
FatherInclude="Gui/ViewProviderDocumentObjectPy.h"
FatherNamespace="Gui">
<Documentation>
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
<UserDocu>This is the ViewProvider geometry class</UserDocu>
</Documentation>
</PythonExport>
</GenerateModel>
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/***************************************************************************
* Copyright (c) 2024 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* 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/>. *
* *
**************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <sstream>
#endif
#include <App/GeoFeature.h>
#include <App/PropertyStandard.h>
#include "ViewProviderGeometryObjectPy.h"
#include "ViewProviderGeometryObjectPy.cpp"
using namespace Gui;
// returns a string which represents the object e.g. when printed in python
std::string ViewProviderGeometryObjectPy::representation() const
{
std::stringstream str;
str << "<View provider geometry object at " << getViewProviderGeometryObjectPtr() << ">";
return str.str();
}
PyObject* ViewProviderGeometryObjectPy::getCustomAttributes(const char* attr) const
{
ViewProviderGeometryObject* vp = getViewProviderGeometryObjectPtr();
if (strcmp(attr, "ShapeColor") == 0) {
// Get material property of ViewProviderGeometryObject
App::PropertyColor prop;
prop.setValue(vp->ShapeAppearance.getDiffuseColor());
return prop.getPyObject();
}
if (strcmp(attr, "ShapeMaterial") == 0) {
// Get material property of ViewProviderGeometryObject
auto geometry = dynamic_cast<App::GeoFeature*>(vp->getObject());
if (geometry) {
auto material = geometry->getMaterialAppearance();
App::PropertyMaterial prop;
prop.setValue(material);
return prop.getPyObject();
}
}
return nullptr;
}
int ViewProviderGeometryObjectPy::setCustomAttributes(const char* attr, PyObject* obj)
{
ViewProviderGeometryObject* vp = getViewProviderGeometryObjectPtr();
if (strcmp(attr, "ShapeColor") == 0) {
// Get material property of ViewProviderGeometryObject
App::PropertyColor prop;
prop.setPyObject(obj);
vp->ShapeAppearance.setDiffuseColor(prop.getValue());
// Assign the value to the new property type
// ...
return 1;
}
if (strcmp(attr, "ShapeMaterial") == 0) {
// Get material property of ViewProviderGeometryObject
auto geometry = dynamic_cast<App::GeoFeature*>(vp->getObject());
if (geometry) {
App::PropertyMaterial prop;
prop.setPyObject(obj);
geometry->setMaterialAppearance(prop.getValue());
}
return 1;
}
return 0;
}
+5 -4
View File
@@ -50,7 +50,8 @@ ViewProviderOriginFeature::ViewProviderOriginFeature () {
ADD_PROPERTY_TYPE ( Size, (ViewProviderOrigin::defaultSize()), 0, App::Prop_ReadOnly,
QT_TRANSLATE_NOOP("App::Property", "Visual size of the feature"));
ShapeColor.setValue ( ViewProviderOrigin::defaultColor ); // Set default color for origin (light-blue)
ShapeAppearance.setDiffuseColor(
ViewProviderOrigin::defaultColor); // Set default color for origin (light-blue)
Transparency.setValue(0);
BoundingBox.setStatus(App::Property::Hidden, true); // Hide Boundingbox from the user due to it doesn't make sense
@@ -108,13 +109,13 @@ void ViewProviderOriginFeature::attach(App::DocumentObject* pcObject)
auto axisRoles = App::Origin::AxisRoles;
if ( strncmp(axisName, axisRoles[0], strlen(axisRoles[0]) ) == 0 ) {
// X-axis: red
ShapeColor.setValue ( 0xFF0000FF );
ShapeAppearance.setDiffuseColor(0xFF0000FF);
} else if ( strncmp(axisName, axisRoles[1], strlen(axisRoles[1]) ) == 0 ) {
// Y-axis: green
ShapeColor.setValue ( 0x00FF00FF );
ShapeAppearance.setDiffuseColor(0x00FF00FF);
} else if ( strncmp(axisName, axisRoles[2], strlen(axisRoles[2]) ) == 0 ) {
// Z-axis: blue
ShapeColor.setValue ( 0x0000FFFF );
ShapeAppearance.setDiffuseColor(0x0000FFFF);
}
}
font->size.setValue ( defaultSz / fontRatio );
+3 -2
View File
@@ -601,7 +601,7 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
<< "Std_ViewDockUndockFullscreen";
if (Gui::Selection().countObjectsOfType(App::DocumentObject::getClassTypeId()) > 0) {
*item << "Separator" << "Std_SetAppearance" << "Std_ToggleVisibility"
*item << "Separator" << "Std_SetMaterial" << "Std_SetAppearance" << "Std_ToggleVisibility"
<< "Std_ToggleSelectability" << "Std_TreeSelection"
<< "Std_RandomColor" << "Std_ToggleTransparency" << "Separator" << "Std_Delete"
<< "Std_SendToPythonConsole" << "Std_TransformManip" << "Std_Placement";
@@ -613,7 +613,7 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
*item << "Std_ToggleFreeze" << "Separator"
<< "Std_Placement" << "Std_ToggleVisibility" << "Std_ShowSelection" << "Std_HideSelection"
<< "Std_ToggleSelectability" << "Std_TreeSelectAllInstances" << "Separator"
<< "Std_SetAppearance" << "Std_RandomColor" << "Std_ToggleTransparency" << "Separator"
<< "Std_SetMaterial" << "Std_SetAppearance" << "Std_RandomColor" << "Std_ToggleTransparency" << "Separator"
<< "Std_Cut" << "Std_Copy" << "Std_Paste" << "Std_Delete"
<< "Std_SendToPythonConsole" << "Separator";
}
@@ -701,6 +701,7 @@ MenuItem* StdWorkbench::setupMenuBar() const
#endif
<< "Separator" << visu
<< "Std_ToggleNavigation"
<< "Std_SetMaterial"
<< "Std_SetAppearance"
<< "Std_RandomColor"
<< "Std_ToggleTransparency"
+1 -1
View File
@@ -607,7 +607,7 @@ class ViewProviderBuildingPart:
vobj.addProperty("App::PropertyColor","ChildrenLineColor","Children",QT_TRANSLATE_NOOP("App::Property","The line color of child objects"))
vobj.ChildrenLineColor = params.get_param_view("DefaultShapeLineColor") & 0xFFFFFF00
if not "ChildrenShapeColor" in pl:
vobj.addProperty("App::PropertyColor","ChildrenShapeColor","Children",QT_TRANSLATE_NOOP("App::Property","The shape color of child objects"))
vobj.addProperty("App::PropertyMaterial","ChildrenShapeColor","Children",QT_TRANSLATE_NOOP("App::Property","The shape appearance of child objects"))
vobj.ChildrenShapeColor = params.get_param_view("DefaultShapeColor") & 0xFFFFFF00
if not "ChildrenTransparency" in pl:
vobj.addProperty("App::PropertyPercent","ChildrenTransparency","Children",QT_TRANSLATE_NOOP("App::Property","The transparency of child objects"))
-2
View File
@@ -1217,7 +1217,6 @@ class ViewProviderComponent:
if len(obj.Base.ViewObject.DiffuseColor) > 1:
obj.ViewObject.DiffuseColor = obj.Base.ViewObject.DiffuseColor
obj.ViewObject.update()
#self.onChanged(obj.ViewObject,"ShapeColor")
elif prop == "CloneOf":
if obj.CloneOf:
mat = None
@@ -1229,7 +1228,6 @@ class ViewProviderComponent:
if len(obj.CloneOf.ViewObject.DiffuseColor) > 1:
obj.ViewObject.DiffuseColor = obj.CloneOf.ViewObject.DiffuseColor
obj.ViewObject.update()
#self.onChanged(obj.ViewObject,"ShapeColor")
return
def getIcon(self):
+1 -1
View File
@@ -302,7 +302,7 @@ class _ViewProviderFence(ArchComponent.ViewProviderComponent):
def applyColors(self, obj):
if not hasattr(obj.ViewObject, "UseOriginalColors") or not obj.ViewObject.UseOriginalColors:
obj.ViewObject.DiffuseColor = [obj.ViewObject.ShapeColor]
obj.ViewObject.DiffuseColor = [obj.ViewObject.ShapeAppeaarance.DiffuseColor]
else:
post = obj.Post
section = obj.Section
+1 -1
View File
@@ -458,7 +458,7 @@ class ViewProviderArchReference:
def onChanged(self,vobj,prop):
if prop == "ShapeColor":
# prevent ShapeColor to override DiffuseColor
# prevent ShapeColor from overriding DiffuseColor
if hasattr(vobj,"DiffuseColor") and hasattr(vobj,"UpdateColors"):
if vobj.DiffuseColor and vobj.UpdateColors:
vobj.DiffuseColor = vobj.DiffuseColor
+1 -1
View File
@@ -727,7 +727,7 @@ class _ViewProviderSpace(ArchComponent.ViewProviderComponent):
elif prop == "ShapeColor":
if hasattr(vobj,"ShapeColor"):
self.fmat.diffuseColor.setValue((vobj.ShapeColor[0],vobj.ShapeColor[1],vobj.ShapeColor[2]))
self.fmat = vobj.ShapeColor.getValue()
elif prop == "Transparency":
if hasattr(vobj,"Transparency"):
+2 -2
View File
@@ -200,7 +200,7 @@ def getGuiData(filename):
"""getGuiData(filename): Extract visual data from a saved FreeCAD file.
Returns a dictionary ["objectName:dict] where dict contains properties
keys like ShapeColor, Transparency, DiffuseColor or Visibility. If found,
keys like ShapeAppearaance, Transparency, DiffuseColor or Visibility. If found,
also contains a GuiCameraSettings key with an iv repr of a coin camera"""
guidata = {}
@@ -310,7 +310,7 @@ def getStepData(objects,colors):
if obj.Name in colors:
color = colors[obj.Name]
if isinstance(color,tuple):
# this is a ShapeColor. We reformat as a list so it works as a DiffuseColor,
# this is a ShapeAppeaaraance. We reformat as a list so it works as a DiffuseColor,
# which is what the exporter expects. DiffuseColor can have either one color,
# or the same number of colors as the number of faces
color = [color]
+1 -1
View File
@@ -242,7 +242,7 @@ def export(exportList,filename,colors=None):
outfile.write("usemtl color_" + mn + "\n")
materials.append(("color_" + mn,color,0))
elif FreeCAD.GuiUp:
if hasattr(obj.ViewObject,"ShapeColor") and hasattr(obj.ViewObject,"Transparency"):
if hasattr(obj.ViewObject,"ShapeAppearnce") and hasattr(obj.ViewObject,"Transparency"):
mn = Draft.getrgb(obj.ViewObject.ShapeColor,testbw=False)[1:]
outfile.write("usemtl color_" + mn + "\n")
materials.append(("color_" + mn,obj.ViewObject.ShapeColor,obj.ViewObject.Transparency))
+2 -2
View File
@@ -59,7 +59,7 @@ def debugMarker(vector, label, color=None, radius=0.5):
vector, FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0)
)
if color:
obj.ViewObject.ShapeColor = color
obj.ViewObject.ShapeAppearance.DiffuseColor = color
def debugCircle(vector, r, label, color=None):
@@ -73,7 +73,7 @@ def debugCircle(vector, r, label, color=None):
)
obj.ViewObject.Transparency = 90
if color:
obj.ViewObject.ShapeColor = color
obj.ViewObject.ShapeAppearance.DiffuseColor = color
def addAngle(a1, a2):
+1 -1
View File
@@ -231,7 +231,7 @@ class TaskPanel:
)
self.interpshape.Shape = obj.interpSurface
self.interpshape.ViewObject.Transparency = 60
self.interpshape.ViewObject.ShapeColor = (1.00000, 1.00000, 0.01961)
self.interpshape.ViewObject.ShapeAppearance.DiffuseColor = (1.00000, 1.00000, 0.01961)
self.interpshape.ViewObject.Selectable = False
stock = PathUtils.findParentJob(obj).Stock
self.interpshape.Placement.Base.z = stock.Shape.BoundBox.ZMax
+3 -3
View File
@@ -83,7 +83,7 @@ def debugMarker(vector, label, color=None, radius=0.5):
vector, FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0)
)
if color:
obj.ViewObject.ShapeColor = color
obj.ViewObject.ShapeAppearance.DiffuseColor = color
def debugCylinder(vector, r, height, label, color=None):
@@ -97,7 +97,7 @@ def debugCylinder(vector, r, height, label, color=None):
)
obj.ViewObject.Transparency = 90
if color:
obj.ViewObject.ShapeColor = color
obj.ViewObject.ShapeAppearance.DiffuseColor = color
def debugCone(vector, r1, r2, height, label, color=None):
@@ -112,7 +112,7 @@ def debugCone(vector, r1, r2, height, label, color=None):
)
obj.ViewObject.Transparency = 90
if color:
obj.ViewObject.ShapeColor = color
obj.ViewObject.ShapeAppearance.DiffuseColor = color
class Tag:
+2 -2
View File
@@ -108,7 +108,7 @@ class _ViewProviderFixture:
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("Selectable", mode)
vobj.setEditorMode("ShapeColor", mode)
vobj.setEditorMode("ShapeAppearance", mode)
vobj.setEditorMode("Transparency", mode)
vobj.setEditorMode("Visibility", mode)
@@ -129,7 +129,7 @@ class _ViewProviderFixture:
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("Selectable", mode)
vobj.setEditorMode("ShapeColor", mode)
vobj.setEditorMode("ShapeAppearance", mode)
vobj.setEditorMode("Transparency", mode)
vobj.setEditorMode("Visibility", mode)
+1 -1
View File
@@ -94,7 +94,7 @@ class ViewProvider:
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("Selectable", mode)
vobj.setEditorMode("ShapeColor", mode)
vobj.setEditorMode("ShapeAppearance", mode)
vobj.setEditorMode("Transparency", mode)
self.deleteOnReject = True
+2 -2
View File
@@ -228,7 +228,7 @@ class PathSimulation:
)
self.cutMaterialIn.ViewObject.Proxy = 0
self.cutMaterialIn.ViewObject.show()
self.cutMaterialIn.ViewObject.ShapeColor = (1.0, 0.85, 0.45, 0.0)
self.cutMaterialIn.ViewObject.ShapeAppearance.DiffuseColor = (1.0, 0.85, 0.45, 0.0)
else:
self.cutMaterial = FreeCAD.ActiveDocument.addObject(
"Part::FeaturePython", "CutMaterial"
@@ -236,7 +236,7 @@ class PathSimulation:
self.cutMaterial.Shape = self.job.Stock.Shape
self.cutMaterial.ViewObject.Proxy = 0
self.cutMaterial.ViewObject.show()
self.cutMaterial.ViewObject.ShapeColor = (0.5, 0.25, 0.25, 0.0)
self.cutMaterial.ViewObject.ShapeAppearance.DiffuseColor = (0.5, 0.25, 0.25, 0.0)
# Add cut path solid for debug
if self.debug:
+2 -2
View File
@@ -70,7 +70,7 @@ class _ViewProviderComment:
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("Selectable", mode)
vobj.setEditorMode("ShapeColor", mode)
vobj.setEditorMode("ShapeAppearance", mode)
vobj.setEditorMode("Transparency", mode)
vobj.setEditorMode("Visibility", mode)
@@ -91,7 +91,7 @@ class _ViewProviderComment:
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("Selectable", mode)
vobj.setEditorMode("ShapeColor", mode)
vobj.setEditorMode("ShapeAppearance", mode)
vobj.setEditorMode("Transparency", mode)
vobj.setEditorMode("Visibility", mode)
+2 -2
View File
@@ -77,7 +77,7 @@ class _ViewProviderStop:
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("Selectable", mode)
vobj.setEditorMode("ShapeColor", mode)
vobj.setEditorMode("ShapeAppearance", mode)
vobj.setEditorMode("Transparency", mode)
vobj.setEditorMode("Visibility", mode)
@@ -98,7 +98,7 @@ class _ViewProviderStop:
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("Selectable", mode)
vobj.setEditorMode("ShapeColor", mode)
vobj.setEditorMode("ShapeAppearance", mode)
vobj.setEditorMode("Transparency", mode)
vobj.setEditorMode("Visibility", mode)
+1 -1
View File
@@ -59,7 +59,7 @@ class ViewProvider:
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("Selectable", mode)
vobj.setEditorMode("ShapeColor", mode)
vobj.setEditorMode("ShapeAppearance", mode)
vobj.setEditorMode("Transparency", mode)
vobj.setEditorMode("Visibility", mode)
self.vobj = vobj
+1 -1
View File
@@ -227,7 +227,7 @@ def upgrade(objects, delete=False, force=None):
# of downgrade, nor do they have the same hashCode().
# Nevertheless, they still keep reference to their original
# colors, capture that in facecolors.
# Also, cannot use ShapeColor here, we need a whole array
# Also, cannot use ShapeAppearance here, we need a whole array
# matching the colors of the array of faces per object,
# only DiffuseColor has that
facecolors[0].extend(obj.ViewObject.DiffuseColor)
+1 -1
View File
@@ -474,7 +474,7 @@ def format_object(target, origin=None):
If construction mode is active target is then placed in the construction
group and the `constr` color is applied to its applicable color properties:
TextColor, PointColor, LineColor, and ShapeColor.
TextColor, PointColor, LineColor, and ShapeAppearance.
Parameters
----------
+8 -8
View File
@@ -88,14 +88,14 @@ def get_default_shape_style():
display_mode_index = params.get_param("DefaultDisplayMode")
draw_style_index = params.get_param("DefaultDrawStyle")
return {
"DisplayMode": ("index", display_mode_index, DISPLAY_MODES[display_mode_index]),
"DrawStyle": ("index", draw_style_index, DRAW_STYLES[draw_style_index]),
"LineColor": ("color", params.get_param_view("DefaultShapeLineColor")),
"LineWidth": ("int", params.get_param_view("DefaultShapeLineWidth")),
"PointColor": ("color", params.get_param_view("DefaultShapeVertexColor")),
"PointSize": ("int", params.get_param_view("DefaultShapePointSize")),
"ShapeColor": ("color", params.get_param_view("DefaultShapeColor")),
"Transparency": ("int", params.get_param_view("DefaultShapeTransparency"))
"DisplayMode": ("index", display_mode_index, DISPLAY_MODES[display_mode_index]),
"DrawStyle": ("index", draw_style_index, DRAW_STYLES[draw_style_index]),
"LineColor": ("color", params.get_param_view("DefaultShapeLineColor")),
"LineWidth": ("int", params.get_param_view("DefaultShapeLineWidth")),
"PointColor": ("color", params.get_param_view("DefaultShapeVertexColor")),
"PointSize": ("int", params.get_param_view("DefaultShapePointSize")),
"ShapeColor": ("color", params.get_param_view("DefaultShapeColor")),
"Transparency": ("int", params.get_param_view("DefaultShapeTransparency"))
}
@@ -70,16 +70,16 @@ class ViewProviderLayer:
_tip)
vobj.OverrideLineColorChildren = True
if "OverrideShapeColorChildren" not in properties:
if "OverrideShapeAppearanceChildren" not in properties:
_tip = QT_TRANSLATE_NOOP("App::Property",
"If it is true, the objects contained "
"within this layer will adopt "
"the shape color of the layer")
vobj.addProperty("App::PropertyBool",
"OverrideShapeColorChildren",
"OverrideShapeAppearanceChildren",
"Layer",
_tip)
vobj.OverrideShapeColorChildren = True
vobj.OverrideShapeAppearanceChildren = True
if "UsePrintColor" not in properties:
_tip = QT_TRANSLATE_NOOP("App::Property",
@@ -59,7 +59,6 @@ ViewProviderFemConstraint::ViewProviderFemConstraint()
{
ADD_PROPERTY(TextColor, (0.0f, 0.0f, 0.0f));
ADD_PROPERTY(FaceColor, (1.0f, 0.0f, 0.2f));
ADD_PROPERTY(ShapeColor, (1.0f, 0.0f, 0.2f));
ADD_PROPERTY(FontSize, (18));
ADD_PROPERTY(DistFactor, (1.0));
ADD_PROPERTY(Mirror, (false));
@@ -56,7 +56,6 @@ public:
// Display properties
App::PropertyColor TextColor;
App::PropertyColor FaceColor;
App::PropertyColor ShapeColor;
App::PropertyInteger FontSize;
App::PropertyFloat DistFactor;
App::PropertyBool Mirror;
@@ -69,10 +69,10 @@ void ViewProviderFemConstraintOnBoundary::highlightReferences(const bool on)
std::vector<App::Color> colors = originalPointColors[base];
// go through the subelements with constraint and recolor them
// TODO: Replace `ShapeColor` with anything more appropriate
PartGui::ReferenceHighlighter highlighter(base->Shape.getValue(),
colors.empty() ? ShapeColor.getValue()
: colors[0]);
// TODO: Replace `ShapeAppearance` with anything more appropriate
PartGui::ReferenceHighlighter highlighter(
base->Shape.getValue(),
colors.empty() ? ShapeAppearance.getDiffuseColor() : colors[0]);
highlighter.getVertexColors(subSet.second, colors);
vp->PointColorArray.setValues(colors);
}
@@ -84,10 +84,10 @@ void ViewProviderFemConstraintOnBoundary::highlightReferences(const bool on)
std::vector<App::Color> colors = originalLineColors[base];
// go through the subelements with constraint and recolor them
// TODO: Replace `ShapeColor` with anything more appropriate
PartGui::ReferenceHighlighter highlighter(base->Shape.getValue(),
colors.empty() ? ShapeColor.getValue()
: colors[0]);
// TODO: Replace `ShapeAppearance` with anything more appropriate
PartGui::ReferenceHighlighter highlighter(
base->Shape.getValue(),
colors.empty() ? ShapeAppearance.getDiffuseColor() : colors[0]);
highlighter.getEdgeColors(subSet.second, colors);
vp->LineColorArray.setValues(colors);
}
+3 -3
View File
@@ -196,7 +196,7 @@ ViewProviderFemMesh::ViewProviderFemMesh()
ADD_PROPERTY(LineWidth, (2.0f));
LineWidth.setConstraints(&floatRange);
ShapeColor.setValue(App::Color(1.0f, 0.7f, 0.0f));
ShapeAppearance.setDiffuseColor(App::Color(1.0f, 0.7f, 0.0f));
Transparency.setValue(0);
ADD_PROPERTY(BackfaceCulling, (true));
ADD_PROPERTY(ShowInner, (false));
@@ -597,7 +597,7 @@ void ViewProviderFemMesh::resetColorByNodeId()
{
pcMatBinding->value = SoMaterialBinding::OVERALL;
pcShapeMaterial->diffuseColor.setNum(0);
const App::Color& c = ShapeColor.getValue();
const App::Color& c = ShapeAppearance.getDiffuseColor();
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
}
@@ -710,7 +710,7 @@ void ViewProviderFemMesh::resetColorByElementId()
{
pcMatBinding->value = SoMaterialBinding::OVERALL;
pcShapeMaterial->diffuseColor.setNum(0);
const App::Color& c = ShapeColor.getValue();
const App::Color& c = ShapeAppearance.getDiffuseColor();
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
}
+2 -2
View File
@@ -562,10 +562,10 @@ void ImportXCAF::createShape(const TopoDS_Shape& shape, bool perface, bool setna
color.r = jt->second.Red();
color.g = jt->second.Green();
color.b = jt->second.Blue();
static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.setValue(color);
static_cast<PartGui::ViewProviderPart*>(vp)->ShapeAppearance.setDiffuseColor(color);
}
partColor = static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.getValue();
partColor = static_cast<PartGui::ViewProviderPart*>(vp)->ShapeAppearance.getDiffuseColor();
}
#endif
+2 -1
View File
@@ -41,7 +41,8 @@ void ExportOCAFGui::findColors(Part::Feature* part, std::vector<App::Color>& col
if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
colors = static_cast<PartGui::ViewProviderPartExt*>(vp)->DiffuseColor.getValues();
if (colors.empty()) {
colors.push_back(static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.getValue());
colors.push_back(
static_cast<PartGui::ViewProviderPart*>(vp)->ShapeAppearance.getDiffuseColor());
}
}
}
+1 -1
View File
@@ -50,7 +50,7 @@ void ImportOCAFGui::applyFaceColors(Part::Feature* part, const std::vector<App::
}
if (colors.size() == 1) {
vp->ShapeColor.setValue(colors.front());
vp->ShapeAppearance.setDiffuseColor(colors.front());
vp->Transparency.setValue(100 * colors.front().a);
}
else {
+1 -1
View File
@@ -72,7 +72,7 @@ void ImpExpDxfReadGui::ApplyGuiStyles(Part::Feature* object) const
App::Color color = ObjectColor(m_entityAttributes.m_Color);
view->LineColor.setValue(color);
view->PointColor.setValue(color);
view->ShapeColor.setValue(color);
view->ShapeAppearance.setDiffuseColor(color);
view->DrawStyle.setValue(GetDrawStyle());
view->Transparency.setValue(0);
}
+12 -9
View File
@@ -36,6 +36,7 @@
#include "ModelPropertyPy.h"
#include "ModelPy.h"
#include "UUIDsPy.h"
#include "PropertyMaterial.h"
namespace Materials
{
@@ -43,9 +44,9 @@ class Module: public Py::ExtensionModule<Module>
{
public:
Module()
: Py::ExtensionModule<Module>("Material")
: Py::ExtensionModule<Module>("Materials")
{
initialize("This module is the Material module."); // register with Python
initialize("This module is the Materials module."); // register with Python
}
~Module() override = default;
@@ -60,18 +61,18 @@ PyObject* initModule()
} // namespace Materials
PyMOD_INIT_FUNC(Material)
PyMOD_INIT_FUNC(Materials)
{
PyObject* module = Materials::initModule();
Base::Console().Log("Loading Material module... done\n");
Base::Interpreter().addType(&Materials::MaterialManagerPy ::Type, module, "MaterialManager");
Base::Interpreter().addType(&Materials::MaterialPy ::Type, module, "Material");
Base::Interpreter().addType(&Materials::ModelManagerPy ::Type, module, "ModelManager");
Base::Interpreter().addType(&Materials::ModelPropertyPy ::Type, module, "ModelProperty");
Base::Interpreter().addType(&Materials::ModelPy ::Type, module, "Model");
Base::Interpreter().addType(&Materials::UUIDsPy ::Type, module, "UUIDs");
Base::Interpreter().addType(&Materials::MaterialManagerPy::Type, module, "MaterialManager");
Base::Interpreter().addType(&Materials::MaterialPy::Type, module, "Material");
Base::Interpreter().addType(&Materials::ModelManagerPy::Type, module, "ModelManager");
Base::Interpreter().addType(&Materials::ModelPropertyPy::Type, module, "ModelProperty");
Base::Interpreter().addType(&Materials::ModelPy::Type, module, "Model");
Base::Interpreter().addType(&Materials::UUIDsPy::Type, module, "UUIDs");
// Initialize types
@@ -95,5 +96,7 @@ PyMOD_INIT_FUNC(Material)
Materials::Material2DArray ::init();
Materials::Material3DArray ::init();
Materials::PropertyMaterial ::init();
PyMOD_Return(module);
}
+17 -12
View File
@@ -20,7 +20,7 @@ include_directories(
)
link_directories(${YAML_CPP_LIBRARY_DIR})
set(Material_LIBS
set(Materials_LIBS
${Boost_LIBRARIES}
FreeCADApp
)
@@ -28,22 +28,23 @@ set(Material_LIBS
include_directories(
${QtConcurrent_INCLUDE_DIRS}
)
list(APPEND Material_LIBS
list(APPEND Materials_LIBS
${QtConcurrent_LIBRARIES}
)
if(yaml-cpp_VERSION VERSION_LESS 0.8.0)
list(APPEND Material_LIBS
list(APPEND Materials_LIBS
${YAML_CPP_LIBRARIES}
)
else()
list(APPEND Material_LIBS
list(APPEND Materials_LIBS
yaml-cpp::yaml-cpp
)
endif()
generate_from_xml(Array2DPy)
generate_from_xml(Array3DPy)
generate_from_xml(MaterialFilterPy)
generate_from_xml(MaterialManagerPy)
generate_from_xml(MaterialPy)
generate_from_xml(ModelManagerPy)
@@ -61,6 +62,8 @@ SET(Python_SRCS
MaterialManagerPyImpl.cpp
MaterialPy.xml
MaterialPyImpl.cpp
MaterialFilterPy.xml
MaterialFilterPyImpl.cpp
ModelManagerPy.xml
ModelManagerPyImpl.cpp
ModelPropertyPy.xml
@@ -72,7 +75,7 @@ SET(Python_SRCS
)
SOURCE_GROUP("Python" FILES ${Python_SRCS})
SET(Material_SRCS
SET(Materials_SRCS
${Python_SRCS}
AppMaterial.cpp
FolderTree.h
@@ -102,19 +105,21 @@ SET(Material_SRCS
ModelUuids.h
PreCompiled.cpp
PreCompiled.h
PropertyMaterial.cpp
PropertyMaterial.h
trim.h
)
if(FREECAD_USE_PCH)
add_definitions(-D_PreComp_)
GET_MSVC_PRECOMPILED_SOURCE("PreCompiled.cpp" PCH_SRCS ${Material_SRCS})
ADD_MSVC_PRECOMPILED_HEADER(Material PreCompiled.h PreCompiled.cpp PCH_SRCS)
GET_MSVC_PRECOMPILED_SOURCE("PreCompiled.cpp" PCH_SRCS ${Materials_SRCS})
ADD_MSVC_PRECOMPILED_HEADER(Materials PreCompiled.h PreCompiled.cpp PCH_SRCS)
endif(FREECAD_USE_PCH)
add_library(Material SHARED ${Material_SRCS})
target_link_libraries(Material ${Material_LIBS})
add_library(Materials SHARED ${Materials_SRCS})
target_link_libraries(Materials ${Materials_LIBS})
SET_BIN_DIR(Material Material /Mod/Material)
SET_PYTHON_PREFIX_SUFFIX(Material)
SET_BIN_DIR(Materials Materials /Mod/Material)
SET_PYTHON_PREFIX_SUFFIX(Materials)
INSTALL(TARGETS Material DESTINATION ${CMAKE_INSTALL_LIBDIR})
INSTALL(TARGETS Materials DESTINATION ${CMAKE_INSTALL_LIBDIR})
+15 -1
View File
@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
* Copyright (c) 2023-2024 David Carter <dcarter@david.carter.ca> *
* *
* This file is part of FreeCAD. *
* *
@@ -25,7 +25,9 @@
#include <App/Application.h>
#include "Exceptions.h"
#include "MaterialFilter.h"
#include "MaterialManager.h"
#include "Materials.h"
@@ -56,6 +58,18 @@ bool MaterialFilter::modelIncluded(const std::shared_ptr<Material>& material) co
return true;
}
bool MaterialFilter::modelIncluded(const QString& uuid) const
{
MaterialManager manager;
try {
auto material = manager.getMaterial(uuid);
return modelIncluded(material);
}
catch (const MaterialNotFound&) {
}
return false;
}
void MaterialFilter::addRequired(const QString& uuid)
{
// Ignore any uuids already present
+19 -3
View File
@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
* Copyright (c) 2023-2024 David Carter <dcarter@david.carter.ca> *
* *
* This file is part of FreeCAD. *
* *
@@ -56,9 +56,9 @@ public:
{
return _includeFolders;
}
void setIncludeEmptyFolders(bool include)
void setIncludeEmptyFolders(bool value)
{
_includeFolders = include;
_includeFolders = value;
}
/* Indicates if we should include materials in the older format
@@ -80,10 +80,26 @@ public:
* Models only need to be included in one set.
*/
bool modelIncluded(const std::shared_ptr<Material>& material) const;
bool modelIncluded(const QString& uuid) const;
/* Add model UUIDs for required models, or models that are both required
* and complete.
*/
void addRequired(const QString& uuid);
void addRequiredComplete(const QString& uuid);
/* These functions shouldn't normally be called directly. They are
* for use by conversion methods, such as MaterialFilterPy
*/
const QSet<QString>* getRequired() const
{
return &_required;
}
const QSet<QString>* getRequiredComplete() const
{
return &_requiredComplete;
}
private:
bool _includeFolders;
bool _includeLegacy;
+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="BaseClassPy"
Name="MaterialFilterPy"
Twin="MaterialFilter"
TwinPointer="MaterialFilter"
Include="Mod/Material/App/MaterialFilter.h"
Namespace="Materials"
FatherInclude="Base/BaseClassPy.h"
FatherNamespace="Base"
Constructor="true"
Delete="true">
<Documentation>
<Author Licence="LGPL" Name="DavidCarter" EMail="dcarter@davidcarter.ca" />
<UserDocu>Material filters.</UserDocu>
</Documentation>
<Attribute Name="IncludeEmptyFolders" ReadOnly="false">
<Documentation>
<UserDocu>Include empty folders in the material list.</UserDocu>
</Documentation>
<Parameter Name="IncludeEmptyFolders" Type="Boolean"/>
</Attribute>
<Attribute Name="IncludeLegacy" ReadOnly="false">
<Documentation>
<UserDocu>Include legacy materials in the material list.</UserDocu>
</Documentation>
<Parameter Name="IncludeLegacy" Type="Boolean"/>
</Attribute>
<Attribute Name="RequiredModels" ReadOnly="false">
<Documentation>
<UserDocu>Materials must include the specified models.</UserDocu>
</Documentation>
<Parameter Name="RequiredModels" Type="List"/>
</Attribute>
<Attribute Name="RequiredCompleteModels" ReadOnly="false">
<Documentation>
<UserDocu>Materials must have complete versions of the specified models.</UserDocu>
</Documentation>
<Parameter Name="RequiredCompleteModels" Type="List"/>
</Attribute>
</PythonExport>
</GenerateModel>
@@ -0,0 +1,132 @@
/***************************************************************************
* Copyright (c) 2023-2024 David Carter <dcarter@david.carter.ca> *
* *
* 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/>. *
* *
**************************************************************************/
#include "PreCompiled.h"
#include <QMetaType>
#include <Base/Quantity.h>
#include <Base/QuantityPy.h>
#include <CXX/Objects.hxx>
#include <Gui/MetaTypes.h>
#include "MaterialFilter.h"
#include "MaterialFilterPy.h"
#include "MaterialFilterPy.cpp"
using namespace Materials;
// Forward declaration
// static PyObject* _pyObjectFromVariant(const QVariant& value);
// static Py::List getList(const QVariant& value);
// returns a string which represents the object e.g. when printed in python
std::string MaterialFilterPy::representation() const
{
std::stringstream str;
str << "<MaterialFilter object at " << getMaterialFilterPtr() << ">";
return str.str();
}
PyObject* MaterialFilterPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
{
// never create such objects with the constructor
return new MaterialFilterPy(new MaterialFilter());
}
// constructor method
int MaterialFilterPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
{
return 0;
}
Py::Boolean MaterialFilterPy::getIncludeEmptyFolders() const
{
return {getMaterialFilterPtr()->includeEmptyFolders()};
}
void MaterialFilterPy::setIncludeEmptyFolders(const Py::Boolean value)
{
getMaterialFilterPtr()->setIncludeEmptyFolders(value.isTrue());
}
Py::Boolean MaterialFilterPy::getIncludeLegacy() const
{
return {getMaterialFilterPtr()->includeLegacy()};
}
void MaterialFilterPy::setIncludeLegacy(const Py::Boolean value)
{
getMaterialFilterPtr()->setIncludeLegacy(value.isTrue());
}
Py::List MaterialFilterPy::getRequiredModels() const
{
auto listValue = getMaterialFilterPtr()->getRequired();
Py::List list;
for (auto& it : *listValue) {
list.append(Py::String(it.toStdString()));
}
return list;
}
void MaterialFilterPy::setRequiredModels(Py::List value)
{
for (const auto& it : value) {
Py::String uuid(it);
getMaterialFilterPtr()->addRequired(QString::fromStdString(uuid));
}
}
Py::List MaterialFilterPy::getRequiredCompleteModels() const
{
auto listValue = getMaterialFilterPtr()->getRequiredComplete();
Py::List list;
for (auto& it : *listValue) {
list.append(Py::String(it.toStdString()));
}
return list;
}
void MaterialFilterPy::setRequiredCompleteModels(Py::List value)
{
for (const auto& it : value) {
Py::String uuid(it);
getMaterialFilterPtr()->addRequiredComplete(QString::fromStdString(uuid));
}
}
PyObject* MaterialFilterPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}
int MaterialFilterPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}
+3 -3
View File
@@ -21,9 +21,9 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QVector>
#include <QDirIterator>
#include <QFileInfo>
#include <QVector>
#endif
@@ -266,7 +266,7 @@ QString MaterialLibrary::getUUIDFromPath(const QString& path) const
}
bool MaterialLibrary::materialInTree(const std::shared_ptr<Material>& material,
const MaterialFilter* filter) const
const std::shared_ptr<Materials::MaterialFilter>& filter) const
{
if (!filter) {
// If there's no filter we always include
@@ -283,7 +283,7 @@ bool MaterialLibrary::materialInTree(const std::shared_ptr<Material>& material,
}
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
MaterialLibrary::getMaterialTree(const MaterialFilter* filter) const
MaterialLibrary::getMaterialTree(const std::shared_ptr<Materials::MaterialFilter>& filter) const
{
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> materialTree =
std::make_shared<std::map<QString, std::shared_ptr<MaterialTreeNode>>>();
+2 -2
View File
@@ -79,7 +79,7 @@ public:
std::shared_ptr<Material> addMaterial(const std::shared_ptr<Material>& material,
const QString& path);
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
getMaterialTree(const MaterialFilter* filter = nullptr) const;
getMaterialTree(const std::shared_ptr<Materials::MaterialFilter>& filter) const;
bool isReadOnly() const
{
@@ -99,7 +99,7 @@ protected:
void updatePaths(const QString& oldPath, const QString& newPath);
QString getUUIDFromPath(const QString& path) const;
bool materialInTree(const std::shared_ptr<Material>& material,
const MaterialFilter* filter) const;
const std::shared_ptr<Materials::MaterialFilter>& filter) const;
bool _readOnly;
std::unique_ptr<std::map<QString, std::shared_ptr<Material>>> _materialPathMap;
+53 -1
View File
@@ -27,12 +27,14 @@
#include <QMutexLocker>
#include <App/Application.h>
#include <App/Material.h>
#include "Exceptions.h"
#include "MaterialConfigLoader.h"
#include "MaterialLoader.h"
#include "MaterialManager.h"
#include "ModelManager.h"
#include "ModelUuids.h"
using namespace Materials;
@@ -108,6 +110,47 @@ bool MaterialManager::isMaterial(const QFileInfo& file) const
return false;
}
std::shared_ptr<Material> MaterialManager::defaultMaterial()
{
MaterialManager manager;
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
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;
}
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;
}
int initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
auto material = manager.getMaterial(defaultMaterialUUID());
if (material->hasAppearanceModel(ModelUUIDs::ModelUUID_Rendering_Basic)) {
material->getAppearanceProperty(QString::fromLatin1("DiffuseColor"))
->setColor(App::Color(r, g, b));
material->getAppearanceProperty(QString::fromLatin1("Transparency"))
->setFloat((float)initialTransparency / 100.0f);
}
return material;
}
QString MaterialManager::defaultMaterialUUID()
{
// Make this a preference
return QString::fromLatin1("7f9fd73b-50c9-41d8-b7b2-575a030c1eeb");
}
std::shared_ptr<Material> MaterialManager::getMaterial(const QString& uuid) const
{
try {
@@ -118,6 +161,13 @@ std::shared_ptr<Material> MaterialManager::getMaterial(const QString& uuid) cons
}
}
std::shared_ptr<Material> MaterialManager::getMaterial(const App::Material& material)
{
MaterialManager manager;
return manager.getMaterial(QString::fromStdString(material.uuid));
}
std::shared_ptr<Material> MaterialManager::getMaterialByPath(const QString& path) const
{
QString cleanPath = QDir::cleanPath(path);
@@ -126,7 +176,9 @@ std::shared_ptr<Material> MaterialManager::getMaterialByPath(const QString& path
if (cleanPath.startsWith(library->getDirectory())) {
try {
return library->getMaterialByPath(cleanPath);
} catch (const MaterialNotFound&) {}
}
catch (const MaterialNotFound&) {
}
// See if it's a new file saved by the old editor
{
+16 -1
View File
@@ -37,6 +37,11 @@
namespace fs = boost::filesystem;
namespace App
{
class Material;
}
namespace Materials
{
@@ -50,11 +55,15 @@ public:
MaterialManager();
~MaterialManager() override = default;
static std::shared_ptr<Material> defaultMaterial();
static QString defaultMaterialUUID();
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> getMaterials() const
{
return _materialMap;
}
std::shared_ptr<Material> getMaterial(const QString& uuid) const;
static std::shared_ptr<Material> getMaterial(const App::Material& material);
std::shared_ptr<Material> getMaterialByPath(const QString& path) const;
std::shared_ptr<Material> getMaterialByPath(const QString& path, const QString& library) const;
std::shared_ptr<Material> getParent(const std::shared_ptr<Material>& material) const;
@@ -66,10 +75,16 @@ public:
std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> getMaterialLibraries() const;
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
getMaterialTree(const std::shared_ptr<MaterialLibrary>& library,
const MaterialFilter* filter = nullptr) const
const std::shared_ptr<Materials::MaterialFilter>& filter) const
{
return library->getMaterialTree(filter);
}
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
getMaterialTree(const std::shared_ptr<MaterialLibrary>& library) const
{
std::shared_ptr<Materials::MaterialFilter> filter;
return library->getMaterialTree(filter);
}
std::shared_ptr<std::list<QString>>
getMaterialFolders(const std::shared_ptr<MaterialLibrary>& library) const;
void createFolder(const std::shared_ptr<MaterialLibrary>& library, const QString& path) const
+32 -32
View File
@@ -103,69 +103,69 @@ int MaterialPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
Py::String MaterialPy::getLibraryName() const
{
auto library = getMaterialPtr()->getLibrary();
return Py::String(library ? library->getName().toStdString() : "");
return {library ? library->getName().toStdString() : ""};
}
Py::String MaterialPy::getLibraryRoot() const
{
auto library = getMaterialPtr()->getLibrary();
return Py::String(library ? library->getDirectoryPath().toStdString() : "");
return {library ? library->getDirectoryPath().toStdString() : ""};
}
Py::String MaterialPy::getLibraryIcon() const
{
auto library = getMaterialPtr()->getLibrary();
return Py::String(library ? library->getIconPath().toStdString() : "");
return {library ? library->getIconPath().toStdString() : ""};
}
Py::String MaterialPy::getName() const
{
return Py::String(getMaterialPtr()->getName().toStdString());
return {getMaterialPtr()->getName().toStdString()};
}
Py::String MaterialPy::getDirectory() const
{
return Py::String(getMaterialPtr()->getDirectory().toStdString());
return {getMaterialPtr()->getDirectory().toStdString()};
}
Py::String MaterialPy::getUUID() const
{
return Py::String(getMaterialPtr()->getUUID().toStdString());
return {getMaterialPtr()->getUUID().toStdString()};
}
Py::String MaterialPy::getDescription() const
{
return Py::String(getMaterialPtr()->getDescription().toStdString());
return {getMaterialPtr()->getDescription().toStdString()};
}
Py::String MaterialPy::getURL() const
{
return Py::String(getMaterialPtr()->getURL().toStdString());
return {getMaterialPtr()->getURL().toStdString()};
}
Py::String MaterialPy::getReference() const
{
return Py::String(getMaterialPtr()->getReference().toStdString());
return {getMaterialPtr()->getReference().toStdString()};
}
Py::String MaterialPy::getParent() const
{
return Py::String(getMaterialPtr()->getParentUUID().toStdString());
return {getMaterialPtr()->getParentUUID().toStdString()};
}
Py::String MaterialPy::getAuthorAndLicense() const
{
return Py::String(getMaterialPtr()->getAuthorAndLicense().toStdString());
return {getMaterialPtr()->getAuthorAndLicense().toStdString()};
}
Py::String MaterialPy::getAuthor() const
{
return Py::String(getMaterialPtr()->getAuthor().toStdString());
return {getMaterialPtr()->getAuthor().toStdString()};
}
Py::String MaterialPy::getLicense() const
{
return Py::String(getMaterialPtr()->getLicense().toStdString());
return {getMaterialPtr()->getLicense().toStdString()};
}
Py::List MaterialPy::getPhysicalModels() const
@@ -173,8 +173,8 @@ Py::List MaterialPy::getPhysicalModels() const
auto models = getMaterialPtr()->getPhysicalModels();
Py::List list;
for (auto it = models->begin(); it != models->end(); it++) {
list.append(Py::String(it->toStdString()));
for (auto it : *models) {
list.append(Py::String(it.toStdString()));
}
return list;
@@ -185,8 +185,8 @@ Py::List MaterialPy::getAppearanceModels() const
auto models = getMaterialPtr()->getAppearanceModels();
Py::List list;
for (auto it = models->begin(); it != models->end(); it++) {
list.append(Py::String(it->toStdString()));
for (auto it : *models) {
list.append(Py::String(it.toStdString()));
}
return list;
@@ -197,8 +197,8 @@ Py::List MaterialPy::getTags() const
auto& tags = getMaterialPtr()->getTags();
Py::List list;
for (auto it = tags.begin(); it != tags.end(); it++) {
list.append(Py::String(it->toStdString()));
for (auto it : tags) {
list.append(Py::String(it.toStdString()));
}
return list;
@@ -298,9 +298,9 @@ Py::Dict MaterialPy::getProperties() const
dict.setItem(Py::String("SourceURL"), Py::String(getMaterialPtr()->getURL().toStdString()));
auto properties = getMaterialPtr()->getPhysicalProperties();
for (auto it = properties.begin(); it != properties.end(); it++) {
QString key = it->first;
auto materialProperty = it->second;
for (auto& it : properties) {
QString key = it.first;
auto materialProperty = it.second;
if (!materialProperty->isNull()) {
auto value = materialProperty->getDictionaryString();
@@ -309,9 +309,9 @@ Py::Dict MaterialPy::getProperties() const
}
properties = getMaterialPtr()->getAppearanceProperties();
for (auto it = properties.begin(); it != properties.end(); it++) {
QString key = it->first;
auto materialProperty = it->second;
for (auto& it : properties) {
QString key = it.first;
auto materialProperty = it.second;
if (!materialProperty->isNull()) {
auto value = materialProperty->getDictionaryString();
@@ -327,9 +327,9 @@ Py::Dict MaterialPy::getPhysicalProperties() const
Py::Dict dict;
auto properties = getMaterialPtr()->getPhysicalProperties();
for (auto it = properties.begin(); it != properties.end(); it++) {
QString key = it->first;
auto materialProperty = it->second;
for (auto& it : properties) {
QString key = it.first;
auto materialProperty = it.second;
if (!materialProperty->isNull()) {
auto value = materialProperty->getDictionaryString();
@@ -345,9 +345,9 @@ Py::Dict MaterialPy::getAppearanceProperties() const
Py::Dict dict;
auto properties = getMaterialPtr()->getAppearanceProperties();
for (auto it = properties.begin(); it != properties.end(); it++) {
QString key = it->first;
auto materialProperty = it->second;
for (auto& it : properties) {
QString key = it.first;
auto materialProperty = it.second;
if (!materialProperty->isNull()) {
auto value = materialProperty->getDictionaryString();
@@ -425,7 +425,7 @@ PyObject* MaterialPy::getPhysicalValue(PyObject* args)
std::static_pointer_cast<Materials::Material2DArray>(property->getMaterialValue());
return new Array2DPy(new Material2DArray(*value));
}
else if (property->getType() == MaterialValue::Array3D) {
if (property->getType() == MaterialValue::Array3D) {
auto value =
std::static_pointer_cast<Materials::Material3DArray>(property->getMaterialValue());
return new Array3DPy(new Material3DArray(*value));
+98
View File
@@ -34,6 +34,7 @@
#include "MaterialLibrary.h"
#include "MaterialManager.h"
#include "ModelManager.h"
#include "ModelUuids.h"
using namespace Materials;
@@ -142,6 +143,32 @@ QString MaterialProperty::getYAMLString() const
return _valuePtr->getYAMLString();
}
App::Color MaterialProperty::getColor() const
{
auto colorString = getValue().toString();
std::stringstream stream(colorString.toStdString());
char c;
stream >> c; // read "("
float red;
stream >> red;
stream >> c; // ","
float green;
stream >> green;
stream >> c; // ","
float blue;
stream >> blue;
stream >> c; // ","
float alpha = 1.0;
if (c == ',') {
stream >> alpha;
}
App::Color color(red, green, blue, alpha);
return color;
}
QString MaterialProperty::getDictionaryString() const
{
// This method produces a non-localized string. For a localized string use
@@ -377,6 +404,13 @@ void MaterialProperty::setURL(const QString& value)
_valuePtr->setValue(QVariant(value));
}
void MaterialProperty::setColor(const App::Color& value)
{
std::stringstream ss;
ss << "(" << value.r << ", " << value.g << ", " << value.b << ", " << value.a << ")";
_valuePtr->setValue(QVariant(QString::fromStdString(ss.str())));
}
MaterialProperty& MaterialProperty::operator=(const MaterialProperty& other)
{
if (this == &other) {
@@ -1434,6 +1468,23 @@ Material& Material::operator=(const Material& other)
return *this;
}
Material& Material::operator=(const App::Material& other)
{
if (!hasAppearanceModel(ModelUUIDs::ModelUUID_Rendering_Basic)) {
addAppearance(ModelUUIDs::ModelUUID_Rendering_Basic);
}
getAppearanceProperty(QString::fromLatin1("AmbientColor"))->setColor(other.ambientColor);
getAppearanceProperty(QString::fromLatin1("DiffuseColor"))->setColor(other.diffuseColor);
getAppearanceProperty(QString::fromLatin1("SpecularColor"))->setColor(other.specularColor);
getAppearanceProperty(QString::fromLatin1("EmissiveColor"))->setColor(other.emissiveColor);
getAppearanceProperty(QString::fromLatin1("Shininess"))->setFloat(other.shininess);
getAppearanceProperty(QString::fromLatin1("Transparency"))->setFloat(other.transparency);
// std::string uuid;
return *this;
}
/*
* Normalize models by removing any inherited models
*/
@@ -1509,3 +1560,50 @@ QStringList Material::inheritedAddedModels(const Material& parent) const
*/
void Material::inheritedPropertyDiff([[maybe_unused]] const QString& parent)
{}
/*
* Return an App::Material object describing the materials appearance, or DEFAULT if
* undefined.
*/
App::Material Material::getMaterialAppearance() const
{
App::Material material(App::Material::DEFAULT);
bool custom = false;
if (hasAppearanceProperty(QString::fromLatin1("AmbientColor"))) {
material.ambientColor =
getAppearanceProperty(QString::fromLatin1("AmbientColor"))->getColor();
custom = true;
}
if (hasAppearanceProperty(QString::fromLatin1("DiffuseColor"))) {
material.diffuseColor =
getAppearanceProperty(QString::fromLatin1("DiffuseColor"))->getColor();
custom = true;
}
if (hasAppearanceProperty(QString::fromLatin1("SpecularColor"))) {
material.specularColor =
getAppearanceProperty(QString::fromLatin1("SpecularColor"))->getColor();
custom = true;
}
if (hasAppearanceProperty(QString::fromLatin1("EmissiveColor"))) {
material.emissiveColor =
getAppearanceProperty(QString::fromLatin1("EmissiveColor"))->getColor();
custom = true;
}
if (hasAppearanceProperty(QString::fromLatin1("Shininess"))) {
material.shininess = getAppearanceProperty(QString::fromLatin1("Shininess"))->getFloat();
custom = true;
}
if (hasAppearanceProperty(QString::fromLatin1("Transparency"))) {
material.transparency =
getAppearanceProperty(QString::fromLatin1("Transparency"))->getFloat();
custom = true;
}
if (custom) {
material.setType(App::Material::USER_DEFINED);
material.uuid = getUUID().toStdString();
}
return material;
}
+38 -4
View File
@@ -31,6 +31,8 @@
#include <QTextStream>
#include <App/Application.h>
#include <App/Color.h>
#include <App/Material.h>
#include <Base/BaseClass.h>
#include <Mod/Material/MaterialGlobal.h>
@@ -79,11 +81,24 @@ public:
QString getString() const;
QString getYAMLString() const;
QString getDictionaryString() const; // Non-localized string
bool getBoolean() const;
int getInt() const;
double getFloat() const;
bool getBoolean() const
{
return getValue().toBool();
}
int getInt() const
{
return getValue().toInt();
}
double getFloat() const
{
return getValue().toFloat();
}
const Base::Quantity& getQuantity() const;
const QString getURL() const;
QString getURL() const
{
return getValue().toString();
}
App::Color getColor() const;
MaterialProperty& getColumn(int column);
const MaterialProperty& getColumn(int column) const;
@@ -109,6 +124,7 @@ public:
void setQuantity(const QString& value);
void setList(const QList<QVariant>& value);
void setURL(const QString& value);
void setColor(const App::Color& value);
MaterialProperty& operator=(const MaterialProperty& other);
friend QTextStream& operator<<(QTextStream& output, const MaterialProperty& property);
@@ -218,6 +234,8 @@ public:
return &_appearanceUuids;
}
App::Material getMaterialAppearance() const;
void setLibrary(const std::shared_ptr<MaterialLibrary>& library)
{
_library = library;
@@ -365,8 +383,24 @@ public:
void save(QTextStream& stream, bool overwrite, bool saveAsCopy, bool saveInherited);
/*
* Assignment operator
*/
Material& operator=(const Material& other);
/*
* Set the appearance properties
*/
Material& operator=(const App::Material& other);
bool operator==(const Material& other) const
{
if (&other == this) {
return true;
}
return getTypeId() == other.getTypeId() && _uuid == other._uuid;
}
protected:
void addModel(const QString& uuid);
static void removeUUID(QSet<QString>& uuidList, const QString& uuid);
-5
View File
@@ -15,11 +15,6 @@
<Author Licence="LGPL" Name="DavidCarter" EMail="dcarter@davidcarter.ca" />
<UserDocu>Material property descriptions.</UserDocu>
</Documentation>
<!-- <Methode Name="mirror">
<Documentation>
<UserDocu>Performs the symmetrical transformation of this geometric object</UserDocu>
</Documentation>
</Methode> -->
<Attribute Name="Name" ReadOnly="true">
<Documentation>
<UserDocu>Property name.</UserDocu>
+119
View File
@@ -0,0 +1,119 @@
/***************************************************************************
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
* *
* 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/>. *
* *
**************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QMetaType>
#include <QUuid>
#endif
#include <App/Application.h>
#include <Base/Writer.h>
#include <Gui/MetaTypes.h>
#include "MaterialPy.h"
#include "PropertyMaterial.h"
using namespace Materials;
/* TRANSLATOR Material::PropertyMaterial */
TYPESYSTEM_SOURCE(Materials::PropertyMaterial, App::Property)
PropertyMaterial::PropertyMaterial() = default;
PropertyMaterial::~PropertyMaterial() = default;
void PropertyMaterial::setValue(const Material& mat)
{
aboutToSetValue();
_material = mat;
hasSetValue();
}
void PropertyMaterial::setValue(const App::Material& mat)
{
aboutToSetValue();
_material = mat;
hasSetValue();
}
const Material& PropertyMaterial::getValue() const
{
return _material;
}
PyObject* PropertyMaterial::getPyObject()
{
return new MaterialPy(new Material(_material));
}
void PropertyMaterial::setPyObject(PyObject* value)
{
if (PyObject_TypeCheck(value, &(MaterialPy::Type))) {
setValue(*static_cast<MaterialPy*>(value)->getMaterialPtr());
}
else {
std::string error = std::string("type must be 'Material' not ");
error += value->ob_type->tp_name;
throw Base::TypeError(error);
}
}
void PropertyMaterial::Save(Base::Writer& writer) const
{
writer.Stream() << writer.ind() << "<PropertyMaterial uuid=\""
<< _material.getUUID().toStdString() << "\"/>" << std::endl;
}
void PropertyMaterial::Restore(Base::XMLReader& reader)
{
// read my Element
reader.readElement("PropertyMaterial");
// get the value of my Attribute
aboutToSetValue();
auto uuid = reader.getAttribute("uuid");
_material.setUUID(QString::fromLatin1(uuid));
hasSetValue();
}
const char* PropertyMaterial::getEditorName() const
{
if (testStatus(MaterialEdit)) {
return ""; //"Gui::PropertyEditor::PropertyMaterialItem";
}
return "";
}
App::Property* PropertyMaterial::Copy() const
{
PropertyMaterial* p = new PropertyMaterial();
p->_material = _material;
return p;
}
void PropertyMaterial::Paste(const App::Property& from)
{
aboutToSetValue();
_material = dynamic_cast<const PropertyMaterial&>(from)._material;
hasSetValue();
}
+101
View File
@@ -0,0 +1,101 @@
/***************************************************************************
* Copyright (c) 2023-2024 David Carter <dcarter@david.carter.ca> *
* *
* 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/>. *
* *
**************************************************************************/
#ifndef MATERIAL_PROPERTYMATERIAL_H
#define MATERIAL_PROPERTYMATERIAL_H
#include <App/Property.h>
#include <Base/Reader.h>
#include "Materials.h"
namespace App
{
class Material;
}
namespace Materials
{
/** Material properties
* This is the father of all properties handling colors.
*/
class MaterialsExport PropertyMaterial: public App::Property
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
/**
* A constructor.
* A more elaborate description of the constructor.
*/
PropertyMaterial();
/**
* A destructor.
* A more elaborate description of the destructor.
*/
~PropertyMaterial() override;
/** Sets the property
*/
void setValue(const Material& mat);
/** Sets the appearance properties
*/
void setValue(const App::Material& mat);
/** This method returns a string representation of the property
*/
const Material& getValue() const;
PyObject* getPyObject() override;
void setPyObject(PyObject*) override;
void Save(Base::Writer& writer) const override;
void Restore(Base::XMLReader& reader) override;
const char* getEditorName() const override;
Property* Copy() const override;
void Paste(const Property& from) override;
unsigned int getMemSize() const override
{
return sizeof(_material);
}
bool isSame(const Property& other) const override
{
if (&other == this) {
return true;
}
return getTypeId() == other.getTypeId()
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
}
private:
Material _material;
};
} // namespace Materials
#endif // MATERIAL_PROPERTYMATERIAL_H
+1
View File
@@ -34,6 +34,7 @@ SET(Material_Icon_Files
# collect all the material cards:
SET(MaterialLib_Files
Resources/Materials/Standard/Default.FCMat
Resources/Materials/Standard/Aggregate/Concrete-EN-C35_45.FCMat
Resources/Materials/Standard/Aggregate/Concrete-Generic.FCMat
Resources/Materials/Standard/Aggregate/Reinforcement-FIB-B500.FCMat
+15 -1
View File
@@ -19,8 +19,9 @@ include_directories(
link_directories(${OCC_LIBRARY_DIR})
set(MatGui_LIBS
Material
Materials
FreeCADGui
Part
)
include_directories(
@@ -39,6 +40,8 @@ qt_add_resources(MatGui_QRC_SRCS Resources/Material.qrc ${Material_TR_QRC})
set(MatGui_UIC_SRCS
Array2D.ui
Array3D.ui
DlgDisplayProperties.ui
DlgMaterial.ui
DlgSettingsMaterial.ui
ImageEdit.ui
ListEdit.ui
@@ -67,6 +70,15 @@ SET(MatGui_SRCS
BaseDelegate.cpp
BaseDelegate.h
Command.cpp
DlgDisplayPropertiesImp.cpp
DlgDisplayPropertiesImp.h
DlgDisplayProperties.ui
DlgMaterialImp.cpp
DlgMaterialImp.h
DlgDisplayProperties.ui
DlgMaterialImp.cpp
DlgMaterialImp.h
DlgMaterial.ui
DlgSettingsMaterial.cpp
DlgSettingsMaterial.h
DlgSettingsMaterial.ui
@@ -88,6 +100,8 @@ SET(MatGui_SRCS
MaterialsEditor.cpp
MaterialsEditor.h
MaterialsEditor.ui
MaterialTreeWidget.cpp
MaterialTreeWidget.h
ModelSelect.cpp
ModelSelect.h
ModelSelect.ui
+64
View File
@@ -25,8 +25,12 @@
#endif
#include <Gui/Command.h>
#include <Gui/Control.h>
#include <Gui/MainWindow.h>
#include <Gui/Selection.h>
#include "DlgDisplayPropertiesImp.h"
#include "DlgMaterialImp.h"
#include "MaterialSave.h"
#include "MaterialsEditor.h"
#include "ModelSelect.h"
@@ -71,6 +75,64 @@ bool CmdMaterialsEdit::isActive()
return true;
}
//===========================================================================
// Std_SetAppearance
//===========================================================================
DEF_STD_CMD_A(StdCmdSetAppearance)
StdCmdSetAppearance::StdCmdSetAppearance()
: Command("Std_SetAppearance")
{
sGroup = "Standard-View";
sMenuText = QT_TR_NOOP("Appearance...");
sToolTipText = QT_TR_NOOP("Sets the display properties of the selected object");
sWhatsThis = "Std_SetAppearance";
sStatusTip = QT_TR_NOOP("Sets the display properties of the selected object");
sPixmap = "Std_SetAppearance";
sAccel = "Ctrl+D";
eType = Alter3DView;
}
void StdCmdSetAppearance::activated(int iMsg)
{
Q_UNUSED(iMsg);
Gui::Control().showDialog(new MatGui::TaskDisplayProperties());
}
bool StdCmdSetAppearance::isActive()
{
return (Gui::Control().activeDialog() == nullptr) && (Gui::Selection().size() != 0);
}
//===========================================================================
// Std_SetMaterial
//===========================================================================
DEF_STD_CMD_A(StdCmdSetMaterial)
StdCmdSetMaterial::StdCmdSetMaterial()
: Command("Std_SetMaterial")
{
sGroup = "Standard-View";
sMenuText = QT_TR_NOOP("Material...");
sToolTipText = QT_TR_NOOP("Sets the material of the selected object");
sWhatsThis = "Std_SetMaterial";
sStatusTip = QT_TR_NOOP("Sets the material of the selected object");
sPixmap = "Materials_Edit";
// sAccel = "Ctrl+D";
// eType = Alter3DView;
}
void StdCmdSetMaterial::activated(int iMsg)
{
Q_UNUSED(iMsg);
Gui::Control().showDialog(new MatGui::TaskMaterial());
}
bool StdCmdSetMaterial::isActive()
{
return (Gui::Control().activeDialog() == nullptr) && (Gui::Selection().size() != 0);
}
//---------------------------------------------------------------
void CreateMaterialCommands()
@@ -78,4 +140,6 @@ void CreateMaterialCommands()
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommand(new CmdMaterialsEdit());
rcCmdMgr.addCommand(new StdCmdSetAppearance());
rcCmdMgr.addCommand(new StdCmdSetMaterial());
}
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Gui::Dialog::DlgDisplayProperties</class>
<widget class="QDialog" name="Gui::Dialog::DlgDisplayProperties">
<class>MatGui::DlgDisplayProperties</class>
<widget class="QDialog" name="MatGui::DlgDisplayProperties">
<property name="geometry">
<rect>
<x>0</x>
@@ -100,108 +100,6 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox3">
<property name="title">
<string>Material</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="changeMaterial"/>
</item>
<item>
<widget class="QPushButton" name="buttonUserDefinedMaterial">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>32767</height>
</size>
</property>
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Color plot:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="buttonColorPlot">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Shape color:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::ColorButton" name="buttonColor">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Line color:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::ColorButton" name="buttonLineColor"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Point color:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::ColorButton" name="buttonPointColor"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox2">
<property name="title">
@@ -434,6 +332,101 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox3">
<property name="title">
<string>Material</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</item>
<item row="2" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Color plot:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Shape Appearance:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::ColorButton" name="buttonPointColor"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Point color:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Line color:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="buttonColorPlot">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::ColorButton" name="buttonLineColor"/>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="buttonUserDefinedMaterial">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>32767</height>
</size>
</property>
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="MatGui::MaterialTreeWidget" name="widgetMaterial" native="true"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
@@ -443,13 +436,16 @@
<extends>QPushButton</extends>
<header>Gui/Widgets.h</header>
</customwidget>
<customwidget>
<class>MatGui::MaterialTreeWidget</class>
<extends>QWidget</extends>
<header>Mod/Material/Gui/MaterialTreeWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>changeMode</tabstop>
<tabstop>changePlot</tabstop>
<tabstop>changeMaterial</tabstop>
<tabstop>buttonUserDefinedMaterial</tabstop>
<tabstop>buttonColor</tabstop>
<tabstop>buttonLineColor</tabstop>
<tabstop>spinPointSize</tabstop>
<tabstop>spinLineWidth</tabstop>
@@ -1,131 +1,136 @@
/***************************************************************************
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_DIALOG_DLGDISPLAYPROPERTIES_IMP_H
#define GUI_DIALOG_DLGDISPLAYPROPERTIES_IMP_H
#include <memory>
#include <vector>
#include <QDialog>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/TaskView/TaskView.h>
#include <App/Material.h>
namespace App
{
class Property;
}
namespace Gui {
class ViewProvider;
class Command;
namespace Dialog {
/**
* The DlgDisplayPropertiesImp class implements a dialog containing all available document
* templates to create a new document.
* \author Jürgen Riegel
*/
class DlgDisplayPropertiesImp : public QDialog,
public Gui::SelectionSingleton::ObserverType
{
Q_OBJECT
public:
explicit DlgDisplayPropertiesImp(bool floating, QWidget* parent = nullptr, Qt::WindowFlags fl = Qt::WindowFlags());
~DlgDisplayPropertiesImp() override;
/// Observer message from the Selection
void OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
Gui::SelectionSingleton::MessageType Reason) override;
void showDefaultButtons(bool);
void reject() override;
private Q_SLOTS:
void onChangeMaterialActivated(int);
void onChangeModeActivated(const QString&);
void onChangePlotActivated(const QString&);
void onButtonColorChanged();
void onSpinTransparencyValueChanged(int);
void onSpinPointSizeValueChanged(int);
void onButtonLineColorChanged();
void onButtonPointColorChanged();
void onSpinLineWidthValueChanged(int);
void onSpinLineTransparencyValueChanged(int);
void onButtonUserDefinedMaterialClicked();
void onButtonColorPlotClicked();
protected:
void changeEvent(QEvent *e) override;
private:
void setupConnections();
void slotChangedObject(const Gui::ViewProvider&, const App::Property& Prop);
void setDisplayModes(const std::vector<ViewProvider*>&);
void setMaterial(const std::vector<ViewProvider*>&);
void setColorPlot(const std::vector<ViewProvider*>&);
void fillupMaterials();
void setShapeColor(const std::vector<ViewProvider*>&);
void setLineColor(const std::vector<ViewProvider*>&);
void setPointColor(const std::vector<ViewProvider*>&);
void setPointSize(const std::vector<ViewProvider*>&);
void setLineWidth(const std::vector<ViewProvider*>&);
void setTransparency(const std::vector<ViewProvider*>&);
void setLineTransparency(const std::vector<ViewProvider*>&);
std::vector<ViewProvider*> getSelection() const;
private:
class Private;
std::unique_ptr<Private> d;
};
class TaskDisplayProperties : public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskDisplayProperties();
~TaskDisplayProperties() override;
public:
bool reject() override;
bool isAllowedAlterDocument() const override
{ return true; }
bool isAllowedAlterView() const override
{ return true; }
bool isAllowedAlterSelection() const override
{ return true; }
QDialogButtonBox::StandardButtons getStandardButtons() const override;
private:
DlgDisplayPropertiesImp* widget;
};
} // namespace Dialog
} // namespace Gui
#endif // GUI_DIALOG_DLGDISPLAYPROPERTIES_IMP_H
/***************************************************************************
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef MATGUI_DIALOG_DLGDISPLAYPROPERTIES_IMP_H
#define MATGUI_DIALOG_DLGDISPLAYPROPERTIES_IMP_H
#include <QDialog>
#include <memory>
#include <vector>
#include <App/Material.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/TaskView/TaskView.h>
#include <Mod/Material/App/Materials.h>
namespace App
{
class Property;
}
namespace MatGui
{
class ViewProvider;
class Command;
/**
* The DlgDisplayPropertiesImp class implements a dialog containing all available document
* templates to create a new document.
* \author Jürgen Riegel
*/
class DlgDisplayPropertiesImp: public QDialog, public Gui::SelectionSingleton::ObserverType
{
Q_OBJECT
public:
explicit DlgDisplayPropertiesImp(bool floating,
QWidget* parent = nullptr,
Qt::WindowFlags fl = Qt::WindowFlags());
~DlgDisplayPropertiesImp() override;
/// Observer message from the Selection
void OnChange(Gui::SelectionSingleton::SubjectType& rCaller,
Gui::SelectionSingleton::MessageType Reason) override;
void showDefaultButtons(bool);
void reject() override;
private Q_SLOTS:
void onChangeModeActivated(const QString&);
void onChangePlotActivated(const QString&);
void onSpinTransparencyValueChanged(int);
void onSpinPointSizeValueChanged(int);
void onButtonLineColorChanged();
void onButtonPointColorChanged();
void onSpinLineWidthValueChanged(int);
void onSpinLineTransparencyValueChanged(int);
void onButtonUserDefinedMaterialClicked();
void onButtonColorPlotClicked();
void onMaterialSelected(const std::shared_ptr<Materials::Material>& material);
protected:
void changeEvent(QEvent* e) override;
private:
void setupConnections();
void slotChangedObject(const Gui::ViewProvider&, const App::Property& Prop);
void setDisplayModes(const std::vector<Gui::ViewProvider*>&);
void setMaterial(const std::vector<Gui::ViewProvider*>&);
void setColorPlot(const std::vector<Gui::ViewProvider*>&);
void setShapeAppearance(const std::vector<Gui::ViewProvider*>&);
void setLineColor(const std::vector<Gui::ViewProvider*>&);
void setPointColor(const std::vector<Gui::ViewProvider*>&);
void setPointSize(const std::vector<Gui::ViewProvider*>&);
void setLineWidth(const std::vector<Gui::ViewProvider*>&);
void setTransparency(const std::vector<Gui::ViewProvider*>&);
void setLineTransparency(const std::vector<Gui::ViewProvider*>&);
std::vector<Gui::ViewProvider*> getSelection() const;
private:
class Private;
std::unique_ptr<Private> d;
};
class TaskDisplayProperties: public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskDisplayProperties();
~TaskDisplayProperties() override;
public:
bool reject() override;
bool isAllowedAlterDocument() const override
{
return true;
}
bool isAllowedAlterView() const override
{
return true;
}
bool isAllowedAlterSelection() const override
{
return true;
}
QDialogButtonBox::StandardButtons getStandardButtons() const override;
private:
DlgDisplayPropertiesImp* widget;
};
} // namespace MatGui
#endif // MATGUI_DIALOG_DLGDISPLAYPROPERTIES_IMP_H
+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MatGui::DlgMaterial</class>
<widget class="QDialog" name="MatGui::DlgMaterial">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>290</width>
<height>503</height>
</rect>
</property>
<property name="windowTitle">
<string>Material</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="MatGui::MaterialTreeWidget" name="widgetMaterial" native="true"/>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>MatGui::MaterialTreeWidget</class>
<extends>QWidget</extends>
<header>Mod/Material/Gui/MaterialTreeWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+282
View File
@@ -0,0 +1,282 @@
/***************************************************************************
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QDockWidget>
#include <QSignalBlocker>
#include <QString>
#include <algorithm>
#include <boost_signals2.hpp>
#endif
#include <Base/Console.h>
#include <Gui/Application.h>
#include <Gui/DlgMaterialPropertiesImp.h>
#include <Gui/DockWindowManager.h>
#include <Gui/Document.h>
#include <Gui/Selection.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Mod/Material/App/Exceptions.h>
#include <Mod/Material/App/MaterialManager.h>
#include <Mod/Material/App/ModelUuids.h>
#include <Mod/Part/App/PartFeature.h>
#include "DlgMaterialImp.h"
#include "ui_DlgMaterial.h"
using namespace MatGui;
using namespace std;
namespace sp = std::placeholders;
/* TRANSLATOR Gui::Dialog::DlgMaterialImp */
#if 0 // needed for Qt's lupdate utility
qApp->translate("QDockWidget", "Material");
#endif
class DlgMaterialImp::Private
{
using DlgMaterialImp_Connection = boost::signals2::connection;
public:
Ui::DlgMaterial ui;
bool floating;
DlgMaterialImp_Connection connectChangedObject;
};
/**
* Constructs a DlgMaterialImp which is a child of 'parent', with the
* name 'name' and widget flags set to 'f'
*
* The dialog will by default be modeless, unless you set 'modal' to
* true to construct a modal dialog.
*/
DlgMaterialImp::DlgMaterialImp(bool floating, QWidget* parent, Qt::WindowFlags fl)
: QDialog(parent, fl)
, d(new Private)
{
d->ui.setupUi(this);
setupConnections();
d->floating = floating;
// // Create a filter to only include current format materials
// // that contain the basic render model.
// auto filter = std::make_shared<Materials::MaterialFilter>();
// filter->setIncludeEmptyFolders(false);
// filter->setIncludeLegacy(false);
// filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Rendering_Basic);
// d->ui.widgetMaterial->setFilter(filter);
std::vector<App::DocumentObject*> objects = getSelectionObjects();
setMaterial(objects);
// embed this dialog into a dockable widget container
if (floating) {
Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
QDockWidget* dw =
pDockMgr->addDockWindow("Display properties", this, Qt::AllDockWidgetAreas);
dw->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
dw->setFloating(true);
dw->show();
}
Gui::Selection().Attach(this);
// NOLINTBEGIN
d->connectChangedObject = Gui::Application::Instance->signalChangedObject.connect(
std::bind(&DlgMaterialImp::slotChangedObject, this, sp::_1, sp::_2));
// NOLINTEND
}
/**
* Destroys the object and frees any allocated resources
*/
DlgMaterialImp::~DlgMaterialImp()
{
// no need to delete child widgets, Qt does it all for us
d->connectChangedObject.disconnect();
Gui::Selection().Detach(this);
}
void DlgMaterialImp::setupConnections()
{
connect(d->ui.widgetMaterial,
&MaterialTreeWidget::materialSelected,
this,
&DlgMaterialImp::onMaterialSelected);
}
void DlgMaterialImp::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
d->ui.retranslateUi(this);
}
QDialog::changeEvent(e);
}
/// @cond DOXERR
void DlgMaterialImp::OnChange(Gui::SelectionSingleton::SubjectType& rCaller,
Gui::SelectionSingleton::MessageType Reason)
{
Q_UNUSED(rCaller);
if (Reason.Type == Gui::SelectionChanges::AddSelection
|| Reason.Type == Gui::SelectionChanges::RmvSelection
|| Reason.Type == Gui::SelectionChanges::SetSelection
|| Reason.Type == Gui::SelectionChanges::ClrSelection) {
std::vector<App::DocumentObject*> objects = getSelectionObjects();
setMaterial(objects);
}
}
/// @endcond
void DlgMaterialImp::slotChangedObject(const Gui::ViewProvider& obj, const App::Property& prop)
{
// This method gets called if a property of any view provider is changed.
// We pick out all the properties for which we need to update this dialog.
std::vector<Gui::ViewProvider*> Provider = getSelection();
auto vp = std::find_if(Provider.begin(), Provider.end(), [&obj](Gui::ViewProvider* v) {
return v == &obj;
});
if (vp != Provider.end()) {
const char* name = obj.getPropertyName(&prop);
// this is not a property of the view provider but of the document object
if (!name) {
return;
}
std::string prop_name = name;
if (prop.isDerivedFrom<App::PropertyMaterial>()) {
auto& value = static_cast<const App::PropertyMaterial&>(prop).getValue();
if (prop_name == "ShapeMaterial") {
// bool blocked = d->ui.buttonColor->blockSignals(true);
// auto color = value.diffuseColor;
// d->ui.buttonColor->setColor(QColor((int)(255.0f * color.r),
// (int)(255.0f * color.g),
// (int)(255.0f * color.b)));
// d->ui.buttonColor->blockSignals(blocked);
}
}
}
}
/**
* Destroys the dock window this object is embedded into without destroying itself.
*/
void DlgMaterialImp::reject()
{
if (d->floating) {
// closes the dock window
Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
pDockMgr->removeDockWindow(this);
}
QDialog::reject();
}
void DlgMaterialImp::setMaterial(const std::vector<App::DocumentObject*>& objects)
{
for (auto it : objects) {
if (auto* obj = dynamic_cast<Part::Feature*>(it)) {
auto material = obj->ShapeMaterial.getValue();
try {
std::string mat = material.getUUID().toStdString();
d->ui.widgetMaterial->setMaterial(material.getUUID());
return;
}
catch (const Materials::MaterialNotFound&) {
}
}
}
d->ui.widgetMaterial->setMaterial(Materials::MaterialManager::defaultMaterialUUID());
}
std::vector<Gui::ViewProvider*> DlgMaterialImp::getSelection() const
{
std::vector<Gui::ViewProvider*> views;
// get the complete selection
std::vector<Gui::SelectionSingleton::SelObj> sel = Gui::Selection().getCompleteSelection();
for (const auto& it : sel) {
Gui::ViewProvider* view =
Gui::Application::Instance->getDocument(it.pDoc)->getViewProvider(it.pObject);
views.push_back(view);
}
return views;
}
std::vector<App::DocumentObject*> DlgMaterialImp::getSelectionObjects() const
{
std::vector<App::DocumentObject*> objects;
// get the complete selection
std::vector<Gui::SelectionSingleton::SelObj> sel = Gui::Selection().getCompleteSelection();
for (const auto& it : sel) {
objects.push_back(it.pObject);
}
return objects;
}
void DlgMaterialImp::onMaterialSelected(const std::shared_ptr<Materials::Material>& material)
{
std::string mat = material->getUUID().toStdString();
std::vector<App::DocumentObject*> objects = getSelectionObjects();
for (auto it : objects) {
if (auto* obj = dynamic_cast<Part::Feature*>(it)) {
obj->ShapeMaterial.setValue(*material);
}
}
}
// ----------------------------------------------------------------------------
/* TRANSLATOR Gui::Dialog::TaskMaterial */
TaskMaterial::TaskMaterial()
{
this->setButtonPosition(TaskMaterial::North);
widget = new DlgMaterialImp(false);
taskbox = new Gui::TaskView::TaskBox(QPixmap(), widget->windowTitle(), true, nullptr);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
}
TaskMaterial::~TaskMaterial() = default;
QDialogButtonBox::StandardButtons TaskMaterial::getStandardButtons() const
{
return QDialogButtonBox::Close;
}
bool TaskMaterial::reject()
{
widget->reject();
return (widget->result() == QDialog::Rejected);
}
#include "moc_DlgMaterialImp.cpp"
+119
View File
@@ -0,0 +1,119 @@
/***************************************************************************
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef MATGUI_DIALOGMATERIALIMP_H
#define MATGUI_DIALOGMATERIALIMP_H
#include <QDialog>
#include <memory>
#include <vector>
#include <App/Material.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/TaskView/TaskView.h>
#include <Mod/Material/App/Materials.h>
namespace App
{
class Property;
}
namespace MatGui
{
class ViewProvider;
class Command;
/**
* The DlgMaterialImp class implements a dialog containing all available document
* templates to create a new document.
* \author Jürgen Riegel
*/
class DlgMaterialImp: public QDialog, public Gui::SelectionSingleton::ObserverType
{
Q_OBJECT
public:
explicit DlgMaterialImp(bool floating,
QWidget* parent = nullptr,
Qt::WindowFlags fl = Qt::WindowFlags());
~DlgMaterialImp() override;
/// Observer message from the Selection
void OnChange(Gui::SelectionSingleton::SubjectType& rCaller,
Gui::SelectionSingleton::MessageType Reason) override;
void showDefaultButtons(bool);
void reject() override;
private Q_SLOTS:
void onMaterialSelected(const std::shared_ptr<Materials::Material>& material);
protected:
void changeEvent(QEvent* e) override;
private:
void setupConnections();
void slotChangedObject(const Gui::ViewProvider&, const App::Property& Prop);
void setMaterial(const std::vector<App::DocumentObject*>&);
std::vector<Gui::ViewProvider*> getSelection() const;
std::vector<App::DocumentObject*> getSelectionObjects() const;
private:
class Private;
std::unique_ptr<Private> d;
};
class TaskMaterial: public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskMaterial();
~TaskMaterial() override;
public:
bool reject() override;
bool isAllowedAlterDocument() const override
{
return true;
}
bool isAllowedAlterView() const override
{
return true;
}
bool isAllowedAlterSelection() const override
{
return true;
}
QDialogButtonBox::StandardButtons getStandardButtons() const override;
private:
DlgMaterialImp* widget;
Gui::TaskView::TaskBox* taskbox;
};
} // namespace MatGui
#endif // MATGUI_DIALOGMATERIALIMP_H
+461
View File
@@ -0,0 +1,461 @@
/***************************************************************************
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
* *
* 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/>. *
* *
**************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QContextMenuEvent>
#include <QMenu>
#endif
#include <cstring>
#include <QHBoxLayout>
#include <QSpacerItem>
#include <QVBoxLayout>
#include <App/Color.h>
#include <Base/Console.h>
#include <Base/Tools.h>
#include <Gui/Command.h>
#include <Mod/Material/App/Exceptions.h>
#include <Mod/Material/App/MaterialFilter.h>
#include <Mod/Material/App/ModelUuids.h>
#include "MaterialTreeWidget.h"
#include "MaterialsEditor.h"
#include "ui_MaterialsEditor.h"
using Base::Console;
using namespace MatGui;
/** Constructs a Material tree widget.
*/
MaterialTreeWidget::MaterialTreeWidget(std::shared_ptr<Materials::MaterialFilter> filter,
QWidget* parent)
: QWidget(parent)
, m_expanded(false)
, _filter(filter)
{
setup();
}
MaterialTreeWidget::MaterialTreeWidget(QWidget* parent)
: QWidget(parent)
, m_expanded(false)
, _filter(nullptr)
{
setup();
}
void MaterialTreeWidget::setup()
{
getFavorites();
getRecents();
createLayout();
createMaterialTree();
}
/**
* Destroys the widget and detaches it from its parameter group.
*/
MaterialTreeWidget::~MaterialTreeWidget() = default;
void MaterialTreeWidget::createLayout()
{
m_material = new QLineEdit(this);
m_expand = new QPushButton(this);
m_expand->setIcon(style()->standardIcon(QStyle::SP_TitleBarUnshadeButton));
m_materialTree = new QTreeView(this);
m_editor = new QPushButton(tr("Launch editor"), this);
// m_materialTree->setSelectionModel(QAbstractItemView::SingleSelection);
m_materialTree->setSelectionMode(QAbstractItemView::SingleSelection);
m_materialTree->setSelectionBehavior(QAbstractItemView::SelectItems);
auto materialLayout = new QHBoxLayout();
materialLayout->addWidget(m_material);
materialLayout->addWidget(m_expand);
auto treeLayout = new QHBoxLayout();
treeLayout->addWidget(m_materialTree);
auto buttonLayout = new QHBoxLayout();
buttonLayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Preferred));
buttonLayout->addWidget(m_editor);
auto layout = new QVBoxLayout();
layout->setContentsMargins(0, 9, 0, 9);
layout->addItem(materialLayout);
layout->addItem(treeLayout);
layout->addItem(buttonLayout);
setLayout(layout);
// Start in an unexpanded state. Store the state?
openWidgetState(false);
connect(m_expand, &QPushButton::clicked, this, &MaterialTreeWidget::expandClicked);
connect(m_editor, &QPushButton::clicked, this, &MaterialTreeWidget::editorClicked);
}
void MaterialTreeWidget::openWidgetState(bool open)
{
m_materialTree->setVisible(open);
m_editor->setVisible(open);
m_expanded = open;
if (open) {
m_expand->setIcon(style()->standardIcon(QStyle::SP_TitleBarShadeButton));
}
else {
m_expand->setIcon(style()->standardIcon(QStyle::SP_TitleBarUnshadeButton));
}
}
void MaterialTreeWidget::expandClicked(bool checked)
{
Q_UNUSED(checked)
// Toggle the open state
openWidgetState(!m_expanded);
}
void MaterialTreeWidget::editorClicked(bool checked)
{
Q_UNUSED(checked)
MaterialsEditor dialog(_filter, this);
dialog.setModal(true);
if (dialog.exec() == QDialog::Accepted) {
// updateMaterialGeneral();
// _material->resetEditState();
// refreshMaterialTree();
// _materialSelected = true;
auto material = dialog.getMaterial();
updateMaterialTree();
setMaterial(material->getUUID());
}
// Gui::Application::Instance->commandManager().runCommandByName("Materials_Edit");
// Toggle the open state
// openWidgetState(!m_expanded);
}
void MaterialTreeWidget::updateMaterial(const QString& uuid)
{
if (uuid.isEmpty() || uuid == m_uuid) {
return;
}
m_uuid = uuid;
// Fetch the material from the manager
auto material = std::make_shared<Materials::Material>();
try {
material = std::make_shared<Materials::Material>(*getMaterialManager().getMaterial(uuid));
}
catch (Materials::ModelNotFound const&) {
Base::Console().Log("*** Unable to load material '%s'\n", uuid.toStdString().c_str());
}
m_materialDisplay = material->getName();
m_material->setText(m_materialDisplay);
}
bool MaterialTreeWidget::findInTree(const QStandardItem& node,
QModelIndex* index,
const QString& uuid)
{
auto vv = node.data(Qt::UserRole);
if (vv.isValid() && vv == uuid) {
*index = node.index();
return true;
}
if (node.hasChildren()) {
int rows = node.rowCount();
for (int i = 0; i < node.rowCount(); i++) {
auto child = node.child(i);
if (findInTree(*child, index, uuid)) {
return true;
}
}
}
return false;
}
QModelIndex MaterialTreeWidget::findInTree(const QString& uuid)
{
auto model = dynamic_cast<QStandardItemModel*>(m_materialTree->model());
auto root = model->invisibleRootItem();
QModelIndex index;
if (findInTree(*root, &index, uuid)) {
return index;
}
return {};
}
void MaterialTreeWidget::setMaterial(const QString& uuid)
{
if (uuid.isEmpty() || uuid == m_uuid) {
return;
}
updateMaterial(uuid);
// Now select the material in the tree
auto index = findInTree(uuid);
if (index.isValid()) {
QItemSelectionModel* selectionModel = m_materialTree->selectionModel();
selectionModel->select(index, QItemSelectionModel::SelectCurrent);
}
}
QString MaterialTreeWidget::getMaterialUUID() const
{
return m_uuid;
}
void MaterialTreeWidget::setFilter(std::shared_ptr<Materials::MaterialFilter> filter)
{
_filter.reset();
_filter = filter;
updateMaterialTree();
}
void MaterialTreeWidget::updateMaterialTree()
{
_favorites.clear();
_recents.clear();
auto model = dynamic_cast<QStandardItemModel*>(m_materialTree->model());
model->clear();
getFavorites();
getRecents();
fillMaterialTree();
}
void MaterialTreeWidget::getFavorites()
{
_favorites.clear();
auto param = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Material/Favorites");
auto count = param->GetInt("Favorites", 0);
for (int i = 0; static_cast<long>(i) < count; i++) {
QString key = QString::fromLatin1("FAV%1").arg(i);
QString uuid = QString::fromStdString(param->GetASCII(key.toStdString().c_str(), ""));
if (!_filter || _filter->modelIncluded(uuid)) {
_favorites.push_back(uuid);
}
}
}
void MaterialTreeWidget::getRecents()
{
_recents.clear();
auto param = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Material/Recent");
_recentMax = static_cast<int>(param->GetInt("RecentMax", 5));
auto count = param->GetInt("Recent", 0);
for (int i = 0; static_cast<long>(i) < count; i++) {
QString key = QString::fromLatin1("MRU%1").arg(i);
QString uuid = QString::fromStdString(param->GetASCII(key.toStdString().c_str(), ""));
if (!_filter || _filter->modelIncluded(uuid)) {
_recents.push_back(uuid);
}
}
}
void MaterialTreeWidget::createMaterialTree()
{
auto model = new QStandardItemModel(this);
m_materialTree->setModel(model);
m_materialTree->setHeaderHidden(true);
// This needs to be done after the model is set
QItemSelectionModel* selectionModel = m_materialTree->selectionModel();
connect(selectionModel,
&QItemSelectionModel::selectionChanged,
this,
&MaterialTreeWidget::onSelectMaterial);
connect(m_materialTree, &QTreeView::doubleClicked, this, &MaterialTreeWidget::onDoubleClick);
fillMaterialTree();
}
void MaterialTreeWidget::fillMaterialTree()
{
auto model = dynamic_cast<QStandardItemModel*>(m_materialTree->model());
auto lib = new QStandardItem(tr("Favorites"));
lib->setFlags(Qt::ItemIsEnabled);
addExpanded(model, lib);
addFavorites(lib);
lib = new QStandardItem(tr("Recent"));
lib->setFlags(Qt::ItemIsEnabled);
addExpanded(model, lib);
addRecents(lib);
// // Create a filter to only include current format materials
// // that contain the basic render model.
// Materials::MaterialFilter filter;
// filter.setIncludeEmptyFolders(false);
// filter.setIncludeLegacy(false);
// filter.addRequired(Materials::ModelUUIDs::ModelUUID_Rendering_Basic);
auto libraries = _materialManager.getMaterialLibraries();
for (const auto& library : *libraries) {
lib = new QStandardItem(library->getName());
lib->setFlags(Qt::ItemIsEnabled);
addExpanded(model, lib);
QIcon icon(library->getIconPath());
QIcon folderIcon(QString::fromStdString(":/icons/folder.svg"));
auto modelTree = _materialManager.getMaterialTree(library, _filter);
addMaterials(*lib, modelTree, folderIcon, icon);
}
}
void MaterialTreeWidget::addExpanded(QStandardItem* parent, QStandardItem* child)
{
parent->appendRow(child);
m_materialTree->setExpanded(child->index(), true);
}
void MaterialTreeWidget::addExpanded(QStandardItemModel* model, QStandardItem* child)
{
model->appendRow(child);
m_materialTree->setExpanded(child->index(), true);
}
void MaterialTreeWidget::addRecents(QStandardItem* parent)
{
for (auto& uuid : _recents) {
try {
auto material = getMaterialManager().getMaterial(uuid);
QIcon icon = QIcon(material->getLibrary()->getIconPath());
auto card = new QStandardItem(icon, material->getName());
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
card->setData(QVariant(uuid), Qt::UserRole);
addExpanded(parent, card);
}
catch (const Materials::MaterialNotFound&) {
}
}
}
void MaterialTreeWidget::addFavorites(QStandardItem* parent)
{
for (auto& uuid : _favorites) {
try {
auto material = getMaterialManager().getMaterial(uuid);
QIcon icon = QIcon(material->getLibrary()->getIconPath());
auto card = new QStandardItem(icon, material->getName());
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
card->setData(QVariant(uuid), Qt::UserRole);
addExpanded(parent, card);
}
catch (const Materials::MaterialNotFound&) {
}
}
}
void MaterialTreeWidget::addMaterials(
QStandardItem& parent,
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::MaterialTreeNode>>>&
modelTree,
const QIcon& folderIcon,
const QIcon& icon)
{
for (auto& mat : *modelTree) {
auto nodePtr = mat.second;
if (nodePtr->getType() == Materials::MaterialTreeNode::DataNode) {
auto material = nodePtr->getData();
QString uuid = material->getUUID();
// Base::Console().Log("Material path '%s'\n",
// material->getDirectory().toStdString().c_str());
// auto card = new QStandardItem(icon, material->getName());
auto card = new QStandardItem(icon, mat.first);
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
card->setData(QVariant(uuid), Qt::UserRole);
addExpanded(&parent, card);
}
else {
auto node = new QStandardItem(folderIcon, mat.first);
addExpanded(&parent, node);
node->setFlags(Qt::ItemIsEnabled);
auto treeMap = nodePtr->getFolder();
addMaterials(*node, treeMap, folderIcon, icon);
}
}
}
void MaterialTreeWidget::onSelectMaterial(const QItemSelection& selected,
const QItemSelection& deselected)
{
Q_UNUSED(deselected);
// Get the UUID before changing the underlying data model
QString uuid;
auto model = dynamic_cast<QStandardItemModel*>(m_materialTree->model());
QModelIndexList indexes = selected.indexes();
for (auto it = indexes.begin(); it != indexes.end(); it++) {
QStandardItem* item = model->itemFromIndex(*it);
if (item) {
uuid = item->data(Qt::UserRole).toString();
break;
}
}
updateMaterial(uuid);
std::string _uuid = uuid.toStdString();
Q_EMIT materialSelected(getMaterialManager().getMaterial(uuid));
}
void MaterialTreeWidget::onDoubleClick(const QModelIndex& index)
{
auto model = dynamic_cast<QStandardItemModel*>(m_materialTree->model());
auto item = model->itemFromIndex(index);
if (item) {
auto uuid = item->data(Qt::UserRole).toString();
updateMaterial(uuid);
}
}
+177
View File
@@ -0,0 +1,177 @@
/***************************************************************************
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
* *
* 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/>. *
* *
**************************************************************************/
#ifndef MATGUI_MATERIALTREEWIDGET_H
#define MATGUI_MATERIALTREEWIDGET_H
#include <memory>
#include <QCheckBox>
#include <QComboBox>
#include <QFontComboBox>
#include <QLineEdit>
#include <QPushButton>
#include <QRadioButton>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QTreeView>
#include <FCGlobal.h>
#include <Base/Parameter.h>
#include <Gui/WidgetFactory.h>
#include <Mod/Material/App/MaterialFilter.h>
#include <Mod/Material/App/MaterialManager.h>
#include <Mod/Material/App/Materials.h>
namespace MatGui
{
class CommandManager;
class WidgetFactoryInst;
/** The Material Tree widget class
* This widget is intended for use wherever materials are used. It is a light weight
* alternative to the full Materials editor.
*
* The widget itself is the combination of a number of smaller widgets. A simple text
* field shows any currently selected material. An arrow will expand a tree to show
* the widget library, allowing the user to select the material they require.
*
* When expanded, the user will be presented the option to launch the full material
* editor. This will allow them to create/copy/modify as required.
*
* Additionally, they will be given the option to create a material card based on the
* current settings.
*
* \author David Carter
*/
class MatGuiExport MaterialTreeWidget: public QWidget
{
Q_OBJECT
public:
explicit MaterialTreeWidget(std::shared_ptr<Materials::MaterialFilter> filter,
QWidget* parent = nullptr);
explicit MaterialTreeWidget(QWidget* parent = nullptr);
~MaterialTreeWidget() override;
// void setEntryName( const QByteArray& name );
// QByteArray entryName() const;
// /** Does the same as setEntryName().
// * This function is added for convenience because the ui compiler
// * will use this function if the attribute stdset isn't set to 0 in a .ui file.
// */
// void setPrefEntry(const QByteArray& name);
// void setParamGrpPath( const QByteArray& path );
// QByteArray paramGrpPath() const;
// /** Does the same as setParamGrpPath().
// * This function is added for convenience because the ui compiler
// * will use this function if the attribute stdset isn't set to 0 in a .ui file.
// */
// void setPrefPath(const QByteArray& name);
// void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;
// void onSave();
// void onRestore();
/** Set the material by specifying its UUID
*/
void setMaterial(const QString& uuid);
/** get the material UUID
*/
QString getMaterialUUID() const;
/** Set the material filter
*/
void setFilter(std::shared_ptr<Materials::MaterialFilter> filter);
Q_SIGNALS:
/** Emits this signal when a material has been selected */
void materialSelected(const std::shared_ptr<Materials::Material>& material);
private Q_SLOTS:
void expandClicked(bool checked);
void editorClicked(bool checked);
void onSelectMaterial(const QItemSelection& selected, const QItemSelection& deselected);
void onDoubleClick(const QModelIndex& index);
private:
void setup();
QLineEdit* m_material;
QPushButton* m_expand;
QTreeView* m_materialTree;
QPushButton* m_editor;
bool m_expanded;
QString m_materialDisplay;
QString m_uuid;
std::list<QString> _favorites;
std::list<QString> _recents;
std::shared_ptr<Materials::MaterialFilter> _filter;
int _recentMax;
Materials::MaterialManager _materialManager;
// friends
friend class Gui::WidgetFactoryInst;
protected:
// bool m_Restored = false;
Materials::MaterialManager& getMaterialManager()
{
return _materialManager;
}
void getFavorites();
void getRecents();
/** Create the widgets UI objects
*/
void createLayout();
bool findInTree(const QStandardItem& node, QModelIndex* index, const QString& uuid);
QModelIndex findInTree(const QString& uuid);
void updateMaterial(const QString& uuid);
void createMaterialTree();
void fillMaterialTree();
void updateMaterialTree();
void addExpanded(QStandardItem* parent, QStandardItem* child);
void addExpanded(QStandardItemModel* model, QStandardItem* child);
void addRecents(QStandardItem* parent);
void addFavorites(QStandardItem* parent);
void addMaterials(
QStandardItem& parent,
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::MaterialTreeNode>>>&
modelTree,
const QIcon& folderIcon,
const QIcon& icon);
void openWidgetState(bool open);
};
} // namespace MatGui
#endif // MATGUI_MATERIALTREEWIDGET_H
+30 -4
View File
@@ -59,14 +59,33 @@ using namespace MatGui;
/* TRANSLATOR MatGui::MaterialsEditor */
MaterialsEditor::MaterialsEditor(std::shared_ptr<Materials::MaterialFilter> filter, QWidget* parent)
: QDialog(parent)
, ui(new Ui_MaterialsEditor)
, _material(std::make_shared<Materials::Material>())
, _materialSelected(false)
, _rendered(nullptr)
, _recentMax(0)
, _filter(filter)
{
setup();
}
MaterialsEditor::MaterialsEditor(QWidget* parent)
: QDialog(parent)
, ui(new Ui_MaterialsEditor)
, _material(std::make_shared<Materials::Material>())
, _materialSelected(false)
, _rendered(nullptr)
, _edited(false)
, _recentMax(0)
, _filter(nullptr)
{
setup();
}
void MaterialsEditor::setup()
{
Gui::WaitCursor wc;
ui->setupUi(this);
_warningIcon = QIcon(QString::fromStdString(":/icons/Warning.svg"));
@@ -158,7 +177,9 @@ void MaterialsEditor::getFavorites()
for (int i = 0; static_cast<long>(i) < count; i++) {
QString key = QString::fromLatin1("FAV%1").arg(i);
QString uuid = QString::fromStdString(param->GetASCII(key.toStdString().c_str(), ""));
_favorites.push_back(uuid);
if (!_filter || _filter->modelIncluded(uuid)) {
_favorites.push_back(uuid);
}
}
}
@@ -234,7 +255,9 @@ void MaterialsEditor::getRecents()
for (int i = 0; static_cast<long>(i) < count; i++) {
QString key = QString::fromLatin1("MRU%1").arg(i);
QString uuid = QString::fromStdString(param->GetASCII(key.toStdString().c_str(), ""));
_recents.push_back(uuid);
if (!_filter || _filter->modelIncluded(uuid)) {
_recents.push_back(uuid);
}
}
}
@@ -342,7 +365,6 @@ void MaterialsEditor::propertyChange(const QString& property, const QString valu
updatePreview();
}
update();
_edited = true;
}
void MaterialsEditor::onURL(bool checked)
@@ -486,6 +508,7 @@ void MaterialsEditor::onNewMaterial(bool checked)
// Create a new material
_material = std::make_shared<Materials::Material>();
setMaterialDefaults();
_materialSelected = false;
}
void MaterialsEditor::onInheritNewMaterial(bool checked)
@@ -548,6 +571,7 @@ void MaterialsEditor::saveMaterial()
updateMaterialGeneral();
_material->resetEditState();
refreshMaterialTree();
_materialSelected = true;
}
}
@@ -1147,6 +1171,7 @@ void MaterialsEditor::onSelectMaterial(const QItemSelection& selected,
updateMaterial();
_material->resetEditState();
_materialSelected = true;
}
void MaterialsEditor::onDoubleClick(const QModelIndex& index)
@@ -1162,6 +1187,7 @@ void MaterialsEditor::onDoubleClick(const QModelIndex& index)
}
}
_materialSelected = true;
accept();
}
+16 -1
View File
@@ -36,6 +36,7 @@
#include <Base/Handle.h>
#include <Base/Parameter.h>
#include <Mod/Material/App/MaterialFilter.h>
#include <Mod/Material/App/MaterialManager.h>
#include <Mod/Material/App/Materials.h>
#include <Mod/Material/App/ModelManager.h>
@@ -52,6 +53,8 @@ class MaterialsEditor: public QDialog
Q_OBJECT
public:
explicit MaterialsEditor(std::shared_ptr<Materials::MaterialFilter> filter,
QWidget* parent = nullptr);
explicit MaterialsEditor(QWidget* parent = nullptr);
~MaterialsEditor() override = default;
@@ -96,6 +99,15 @@ public:
void onDoubleClick(const QModelIndex& index);
void onContextMenu(const QPoint& pos);
bool isMaterialSelected() const
{
return _materialSelected;
}
std::shared_ptr<Materials::Material> getMaterial()
{
return _material;
}
protected:
int confirmSave(QWidget* parent);
void saveMaterial();
@@ -106,11 +118,14 @@ private:
Materials::ModelManager _modelManager;
std::shared_ptr<Materials::Material> _material;
AppearancePreview* _rendered;
bool _edited;
bool _materialSelected;
std::list<QString> _favorites;
std::list<QString> _recents;
int _recentMax;
QIcon _warningIcon;
std::shared_ptr<Materials::MaterialFilter> _filter;
void setup();
void saveWindow();
void saveMaterialTreeChildren(const Base::Reference<ParameterGrp>& param,
+2 -2
View File
@@ -685,9 +685,9 @@ class MaterialEditor:
from importFCMat import write
write(filename, d)
import Material
import Materials
# Load the material
manager = Material.MaterialManager()
manager = Materials.MaterialManager()
manager.getMaterialByPath(filename)
self.edited = False
self.updateCardsInCombo()
+1 -1
View File
@@ -26,7 +26,7 @@
// Material
#ifndef MaterialsExport
#ifdef Material_EXPORTS
#ifdef Materials_EXPORTS
#define MaterialsExport FREECAD_DECL_EXPORT
#else
#define MaterialsExport FREECAD_DECL_IMPORT
@@ -0,0 +1,15 @@
---
# File created by ConvertFCMat.py
General:
UUID: "7f9fd73b-50c9-41d8-b7b2-575a030c1eeb"
Author: "David Carter"
License: "GPL-2.0-or-later"
Name: "Default"
Description: "Generic material with density of 1"
Inherits:
Default:
UUID: "5dbb7be6-8b63-479b-ab4c-87be02ead973"
Models:
Density:
UUID: '454661e5-265b-4320-8e6f-fcf6223ac3af'
Density: "1 kg/m^3"
@@ -35,7 +35,12 @@ AppearanceModel:
Type: 'File'
Units: ''
URL: ''
Description: " "
Description: "Path to file containing a texture image. Only used if TextureImage is unpopulated"
TextureImage:
Type: 'Image'
Units: ''
URL: ''
Description: "Embedded texture image"
TextureScaling:
DisplayName: "Texture Scaling"
Type: 'Float'
+1 -1
View File
@@ -24,7 +24,7 @@
from os import walk
import unittest
import FreeCAD
import Material
import Materials
from materialtests.TestModels import ModelTestCases
from materialtests.TestMaterials import MaterialTestCases
+2 -2
View File
@@ -30,7 +30,7 @@ import os
import FreeCAD
from materialtools.cardutils import get_material_template
import Material
import Materials
if FreeCAD.GuiUp:
from PySide import QtGui
@@ -99,7 +99,7 @@ def decode(name):
# https://github.com/berndhahnebach/FreeCAD_bhb/commits/materialdev
def read(filename):
materialManager = Material.MaterialManager()
materialManager = Materials.MaterialManager()
material = materialManager.getMaterialByPath(filename)
return material.Properties
@@ -26,7 +26,7 @@ Test module for FreeCAD material cards and APIs
import unittest
import FreeCAD
import Material
import Materials
parseQuantity = FreeCAD.Units.parseQuantity
@@ -37,9 +37,9 @@ class MaterialTestCases(unittest.TestCase):
def setUp(self):
""" Setup function to initialize test data """
self.ModelManager = Material.ModelManager()
self.MaterialManager = Material.MaterialManager()
self.uuids = Material.UUIDs()
self.ModelManager = Materials.ModelManager()
self.MaterialManager = Materials.MaterialManager()
self.uuids = Materials.UUIDs()
def testMaterialManager(self):
""" Ensure the MaterialManager has been initialized correctly """
+3 -3
View File
@@ -26,7 +26,7 @@ Test module for FreeCAD material models
import unittest
import FreeCAD
import Material
import Materials
parseQuantity = FreeCAD.Units.parseQuantity
@@ -36,8 +36,8 @@ class ModelTestCases(unittest.TestCase):
"""
def setUp(self):
""" Setup function to initialize test data """
self.ModelManager = Material.ModelManager()
self.uuids = Material.UUIDs()
self.ModelManager = Materials.ModelManager()
self.uuids = Materials.UUIDs()
def testModelManager(self):
""" Ensure we can access ModelManager member functions """
+2 -2
View File
@@ -28,7 +28,7 @@ from os.path import join
from pathlib import Path
import FreeCAD
import Material
import Materials
unicode = str
@@ -260,7 +260,7 @@ def output_resources(resources):
# used in material editor and FEM material task panels
def import_materials(category='Solid', template=False):
materialManager = Material.MaterialManager()
materialManager = Materials.MaterialManager()
mats = materialManager.Materials
materials = {}
cards = {}
+4 -4
View File
@@ -23,10 +23,10 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <algorithm>
#include <functional>
#include <QMenu>
#include <QTimer>
#include <algorithm>
#include <functional>
#include <Inventor/SbLine.h>
#include <Inventor/SoPickedPoint.h>
@@ -51,8 +51,8 @@
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Gui/WaitCursor.h>
#include <Mod/Mesh/App/MeshFeature.h>
#include <Mod/Mesh/App/Core/Algorithm.h>
#include <Mod/Mesh/App/MeshFeature.h>
#include "MeshEditor.h"
#include "SoFCMeshObject.h"
@@ -117,7 +117,7 @@ void ViewProviderFace::attach(App::DocumentObject* obj)
SoBaseColor* basecol = new SoBaseColor;
if (mesh) {
App::Color col = mesh->ShapeColor.getValue();
App::Color col = mesh->ShapeAppearance.getDiffuseColor();
basecol->rgb.setValue(col.r, col.g, col.b);
}
else {
+21 -20
View File
@@ -22,32 +22,32 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <cstdlib>
#include <QAction>
#include <QMenu>
#include <cstdlib>
#include <Inventor/SbBox2s.h>
#include <Inventor/SbLine.h>
#include <Inventor/SbPlane.h>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/VRMLnodes/SoVRMLGroup.h>
#include <Inventor/actions/SoToVRML2Action.h>
#include <Inventor/details/SoFaceDetail.h>
#include <Inventor/events/SoMouseButtonEvent.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoLightModel.h>
#include <Inventor/nodes/SoIndexedFaceSet.h>
#include <Inventor/nodes/SoIndexedLineSet.h>
#include <Inventor/nodes/SoLightModel.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoMaterialBinding.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoPolygonOffset.h>
#include <Inventor/nodes/SoShapeHints.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoShapeHints.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/VRMLnodes/SoVRMLGroup.h>
#endif
#include <QFuture>
@@ -267,7 +267,7 @@ ViewProviderMesh::ViewProviderMesh()
pcHighlight->addChild(pcShapeGroup);
pOpenColor = new SoBaseColor();
setOpenEdgeColorFrom(ShapeColor.getValue());
setOpenEdgeColorFrom(ShapeAppearance.getDiffuseColor());
pOpenColor->ref();
pcLineStyle = new SoDrawStyle();
@@ -297,12 +297,12 @@ ViewProviderMesh::ViewProviderMesh()
Gui::WindowParameter::getDefaultParameter()->GetGroup("Mod/Mesh");
// Mesh color
App::Color color = ShapeColor.getValue();
App::Color color = ShapeAppearance.getDiffuseColor();
unsigned long current = color.getPackedValue();
unsigned long setting = hGrp->GetUnsigned("MeshColor", current);
if (current != setting) {
color.setPackedValue((uint32_t)setting);
ShapeColor.setValue(color);
ShapeAppearance.setDiffuseColor(color);
}
Transparency.setValue(hGrp->GetInt("MeshTransparency", 0));
@@ -353,7 +353,8 @@ ViewProviderMesh::~ViewProviderMesh()
void ViewProviderMesh::onChanged(const App::Property* prop)
{
// we're going to change the number of colors to one
if (prop == &ShapeColor || prop == &ShapeMaterial) {
// if (prop == &ShapeAppearance || prop == &ShapeMaterial) {
if (prop == &ShapeAppearance) {
pcMatBinding->value = SoMaterialBinding::OVERALL;
}
if (prop == &LineTransparency) {
@@ -393,12 +394,12 @@ void ViewProviderMesh::onChanged(const App::Property* prop)
}
else {
// Set the inverse color for open edges
if (prop == &ShapeColor) {
setOpenEdgeColorFrom(ShapeColor.getValue());
}
else if (prop == &ShapeMaterial) {
setOpenEdgeColorFrom(ShapeMaterial.getValue().diffuseColor);
if (prop == &ShapeAppearance) {
setOpenEdgeColorFrom(ShapeAppearance.getDiffuseColor());
}
// else if (prop == &ShapeMaterial) {
// setOpenEdgeColorFrom(ShapeMaterial.getValue().diffuseColor);
// }
}
ViewProviderGeometryObject::onChanged(prop);
@@ -597,7 +598,7 @@ void ViewProviderMesh::tryColorPerVertexOrFace(bool on)
}
else {
pcMatBinding->value = SoMaterialBinding::OVERALL;
const App::Color& c = ShapeColor.getValue();
const App::Color& c = ShapeAppearance.getDiffuseColor();
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
pcShapeMaterial->transparency.setValue(Transparency.getValue() / 100.0f);
}
@@ -1987,7 +1988,7 @@ void ViewProviderMesh::fillHole(Mesh::FacetIndex uFacet)
void ViewProviderMesh::setFacetTransparency(const std::vector<float>& facetTransparency)
{
if (pcShapeMaterial->diffuseColor.getNum() != int(facetTransparency.size())) {
App::Color c = ShapeColor.getValue();
App::Color c = ShapeAppearance.getDiffuseColor();
pcShapeMaterial->diffuseColor.setNum(facetTransparency.size());
SbColor* cols = pcShapeMaterial->diffuseColor.startEditing();
for (std::size_t index = 0; index < facetTransparency.size(); ++index) {
@@ -2009,7 +2010,7 @@ void ViewProviderMesh::setFacetTransparency(const std::vector<float>& facetTrans
void ViewProviderMesh::resetFacetTransparency()
{
pcMatBinding->value = SoMaterialBinding::OVERALL;
App::Color c = ShapeColor.getValue();
App::Color c = ShapeAppearance.getDiffuseColor();
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
pcShapeMaterial->transparency.setValue(0);
}
@@ -2115,7 +2116,7 @@ void ViewProviderMesh::deselectFacet(Mesh::FacetIndex facet)
highlightSelection();
}
else {
App::Color c = ShapeColor.getValue();
App::Color c = ShapeAppearance.getDiffuseColor();
pcShapeMaterial->diffuseColor.set1Value(facet, c.r, c.g, c.b);
}
}
@@ -2285,7 +2286,7 @@ void ViewProviderMesh::highlightSelection()
// Colorize the selection
pcMatBinding->value = SoMaterialBinding::PER_FACE;
App::Color c = ShapeColor.getValue();
App::Color c = ShapeAppearance.getDiffuseColor();
int uCtFacets = (int)rMesh.countFacets();
pcShapeMaterial->diffuseColor.setNum(uCtFacets);
@@ -2301,7 +2302,7 @@ void ViewProviderMesh::highlightSelection()
void ViewProviderMesh::unhighlightSelection()
{
App::Color c = ShapeColor.getValue();
App::Color c = ShapeAppearance.getDiffuseColor();
pcMatBinding->value = SoMaterialBinding::OVERALL;
pcShapeMaterial->diffuseColor.setNum(1);
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
@@ -2359,7 +2360,7 @@ void ViewProviderMesh::highlightSegments()
std::vector<App::Color> colors;
const Mesh::MeshObject& rMesh = static_cast<Mesh::Feature*>(pcObject)->Mesh.getValue();
unsigned long numSegm = rMesh.countSegments();
colors.resize(numSegm, this->ShapeColor.getValue());
colors.resize(numSegm, this->ShapeAppearance.getDiffuseColor());
for (unsigned long i = 0; i < numSegm; i++) {
App::Color col;
+3 -3
View File
@@ -21,6 +21,7 @@ set(Part_LIBS
${OCC_LIBRARIES}
${OCC_DEBUG_LIBRARIES}
FreeCADApp
Materials
)
if(FREETYPE_FOUND)
@@ -567,17 +568,16 @@ if(FREECAD_USE_PCH)
endif(FREECAD_USE_PCH)
# Suppress some very long Eigen3 warnings of older versions
if (EIGEN3_NO_DEPRECATED_COPY)
if(EIGEN3_NO_DEPRECATED_COPY)
set_source_files_properties(
GeometryCurvePyImp.cpp
GeometrySurfacePyImp.cpp
PROPERTIES COMPILE_FLAGS ${EIGEN3_NO_DEPRECATED_COPY})
endif ()
endif()
add_library(Part SHARED ${Part_SRCS})
target_link_libraries(Part ${Part_LIBS})
SET_BIN_DIR(Part Part /Mod/Part)
SET_PYTHON_PREFIX_SUFFIX(Part)
+1 -1
View File
@@ -147,7 +147,7 @@ int Part::ImportStepParts(App::Document *pcDoc, const char* Name)
col.setItem(0, Py::Float(it->second.Red()));
col.setItem(1, Py::Float(it->second.Green()));
col.setItem(2, Py::Float(it->second.Blue()));
vp.setAttr("ShapeColor", col);
vp.setAttr("ShapeAppearance", col);
//Base::Console().Message("Set color to shape\n");
}
catch (Py::Exception& e) {
+13
View File
@@ -66,6 +66,7 @@
#include <Base/Placement.h>
#include <Base/Rotation.h>
#include <Base/Stream.h>
#include <Mod/Material/App/MaterialManager.h>
#include "PartFeature.h"
#include "PartFeaturePy.h"
@@ -83,6 +84,9 @@ PROPERTY_SOURCE(Part::Feature, App::GeoFeature)
Feature::Feature()
{
ADD_PROPERTY(Shape, (TopoDS_Shape()));
auto mat = Materials::MaterialManager::defaultMaterial();
// ADD_PROPERTY_TYPE(ShapeMaterial, (mat), osgroup, App::Prop_None, "Shape material");
ADD_PROPERTY(ShapeMaterial, (*mat));
}
Feature::~Feature() = default;
@@ -589,6 +593,15 @@ TopoDS_Shape Feature::getShape(const App::DocumentObject *obj, const char *subna
return getTopoShape(obj,subname,needSubElement,pmat,powner,resolveLink,transform,true).getShape();
}
App::Material Feature::getMaterialAppearance() const
{
return ShapeMaterial.getValue().getMaterialAppearance();
}
void Feature::setMaterialAppearance(const App::Material& material)
{
ShapeMaterial.setValue(material);
}
// Toponaming project March 2024: This method should be going away when we get to the python layer.
void Feature::clearShapeCache() {
+5
View File
@@ -25,6 +25,7 @@
#include <App/FeaturePython.h>
#include <App/GeoFeature.h>
#include <Mod/Material/App/PropertyMaterial.h>
#include <Mod/Part/PartGlobal.h>
#include <TopoDS_Face.hxx>
@@ -57,6 +58,7 @@ public:
~Feature() override;
PropertyPartShape Shape;
Materials::PropertyMaterial ShapeMaterial;
/** @name methods override feature */
//@{
@@ -105,6 +107,9 @@ public:
DocumentObject *getSubObject(const char *subname, PyObject **pyObj,
Base::Matrix4D *mat, bool transform, int depth) const override;
App::Material getMaterialAppearance() const override;
void setMaterialAppearance(const App::Material& material) override;
/** Convenience function to extract shape from fully qualified subname
*
* @param obj: the parent object
+1 -1
View File
@@ -103,7 +103,7 @@ class BOPFeatures:
def copy_visual_attributes(self, target, source):
if target.ViewObject:
target.ViewObject.ShapeColor = source.ViewObject.ShapeColor
target.ViewObject.ShapeAppearance = source.ViewObject.ShapeAppearance
displayMode = source.ViewObject.DisplayMode
src = source
while displayMode == "Link":
+1
View File
@@ -15,6 +15,7 @@ link_directories(${OCC_LIBRARY_DIR})
set(PartGui_LIBS
Part
FreeCADGui
MatGui
)
if(MSVC)
+5 -5
View File
@@ -925,7 +925,7 @@ void CmdPartSection::activated(int iMsg)
doCommand(Doc,"App.activeDocument().%s.Tool = App.activeDocument().%s",FeatName.c_str(),ToolName.c_str());
doCommand(Gui,"Gui.activeDocument().hide('%s')",BaseName.c_str());
doCommand(Gui,"Gui.activeDocument().hide('%s')",ToolName.c_str());
doCommand(Gui,"Gui.activeDocument().%s.LineColor = Gui.activeDocument().%s.ShapeColor", FeatName.c_str(),BaseName.c_str());
doCommand(Gui,"Gui.activeDocument().%s.LineColor = Gui.activeDocument().%s.ShapeAppearance.DiffuseColor",FeatName.c_str(),BaseName.c_str());
updateActive();
commitCommand();
}
@@ -1215,7 +1215,7 @@ void CmdPartReverseShape::activated(int iMsg)
try {
runCommand(Doc, str.toLatin1());
copyVisual(name.c_str(), "ShapeColor", it->getNameInDocument());
copyVisual(name.c_str(), "ShapeAppearance", it->getNameInDocument());
copyVisual(name.c_str(), "LineColor" , it->getNameInDocument());
copyVisual(name.c_str(), "PointColor", it->getNameInDocument());
}
@@ -1656,7 +1656,7 @@ void CmdPartOffset::activated(int iMsg)
adjustCameraPosition();
copyVisual(offset.c_str(), "ShapeColor", shape->getNameInDocument());
copyVisual(offset.c_str(), "ShapeAppearance", shape->getNameInDocument());
copyVisual(offset.c_str(), "LineColor" , shape->getNameInDocument());
copyVisual(offset.c_str(), "PointColor", shape->getNameInDocument());
}
@@ -1712,7 +1712,7 @@ void CmdPartOffset2D::activated(int iMsg)
doCommand(Gui,"Gui.ActiveDocument.setEdit('%s')",offset.c_str());
adjustCameraPosition();
copyVisual(offset.c_str(), "ShapeColor", shape->getNameInDocument());
copyVisual(offset.c_str(), "ShapeAppearance", shape->getNameInDocument());
copyVisual(offset.c_str(), "LineColor" , shape->getNameInDocument());
copyVisual(offset.c_str(), "PointColor", shape->getNameInDocument());
}
@@ -1896,7 +1896,7 @@ void CmdPartThickness::activated(int iMsg)
doCommand(Gui,"Gui.ActiveDocument.setEdit('%s')",thick.c_str());
adjustCameraPosition();
copyVisual(thick.c_str(), "ShapeColor", obj->getNameInDocument());
copyVisual(thick.c_str(), "ShapeAppearance", obj->getNameInDocument());
copyVisual(thick.c_str(), "LineColor" , obj->getNameInDocument());
copyVisual(thick.c_str(), "PointColor", obj->getNameInDocument());
}
+2 -2
View File
@@ -263,7 +263,7 @@ static void _copyShape(const char *cmdName, bool resolve,bool needElement=false,
v.second->getNameInDocument(),
Gui::Command::getObjectCmd(v.second).c_str());
auto newObj = App::GetApplication().getActiveDocument()->getActiveObject();
Gui::Command::copyVisual(newObj, "ShapeColor", v.second);
Gui::Command::copyVisual(newObj, "ShapeAppearance", v.second);
Gui::Command::copyVisual(newObj, "LineColor", v.second);
Gui::Command::copyVisual(newObj, "PointColor", v.second);
}
@@ -378,7 +378,7 @@ void CmdPartRefineShape::activated(int iMsg)
obj->getNameInDocument(),
obj->getNameInDocument());
copyVisual("ActiveObject", "ShapeColor", obj->getNameInDocument());
copyVisual("ActiveObject", "ShapeAppearance", obj->getNameInDocument());
copyVisual("ActiveObject", "LineColor", obj->getNameInDocument());
copyVisual("ActiveObject", "PointColor", obj->getNameInDocument());
}
+1 -1
View File
@@ -481,7 +481,7 @@ void DlgExtrusion::apply()
this->writeParametersToFeature(*newObj, sourceObj);
Gui::Command::copyVisual(newObj, "ShapeColor", sourceObj);
Gui::Command::copyVisual(newObj, "ShapeAppearance", sourceObj);
Gui::Command::copyVisual(newObj, "LineColor", sourceObj);
Gui::Command::copyVisual(newObj, "PointColor", sourceObj);
+17 -15
View File
@@ -655,7 +655,7 @@ void PartGui::DlgProjectionOnSurface::show_projected_shapes(
if (vp) {
const unsigned int color = 0x8ae23400;
vp->LineColor.setValue(color);
vp->ShapeColor.setValue(color);
vp->ShapeAppearance.setDiffuseColor(App::Color(color));
vp->PointColor.setValue(color);
vp->Transparency.setValue(0);
}
@@ -716,20 +716,22 @@ void PartGui::DlgProjectionOnSurface::higlight_object(Part::Feature* iCurrentObj
}
auto index = anIndices.FindIndex(currentShape);
// set color
auto vp = dynamic_cast<PartGui::ViewProviderPartExt*>(
Gui::Application::Instance->getViewProvider(iCurrentObject));
if (vp) {
std::vector<App::Color> colors;
App::Color defaultColor;
if (currentShapeType == TopAbs_FACE) {
colors = vp->DiffuseColor.getValues();
defaultColor = vp->ShapeColor.getValue();
}
else if (currentShapeType == TopAbs_EDGE) {
colors = vp->LineColorArray.getValues();
defaultColor = vp->LineColor.getValue();
}
//set color
PartGui::ViewProviderPartExt* vp = dynamic_cast<PartGui::ViewProviderPartExt*>(Gui::Application::Instance->getViewProvider(iCurrentObject));
if (vp)
{
std::vector<App::Color> colors;
App::Color defaultColor;
if (currentShapeType == TopAbs_FACE)
{
colors = vp->DiffuseColor.getValues();
defaultColor = vp->ShapeAppearance.getDiffuseColor();
}
else if ( currentShapeType == TopAbs_EDGE )
{
colors = vp->LineColorArray.getValues();
defaultColor = vp->LineColor.getValue();
}
if (static_cast<Standard_Integer>(colors.size()) != anIndices.Extent()) {
colors.resize(anIndices.Extent(), defaultColor);
+1 -1
View File
@@ -431,7 +431,7 @@ void DlgRevolution::accept()
Gui::Command::runCommand(Gui::Command::App, code.toLatin1());
QByteArray to = name.toLatin1();
QByteArray from = shape.toLatin1();
Gui::Command::copyVisual(to, "ShapeColor", from);
Gui::Command::copyVisual(to, "ShapeAppearance", from);
Gui::Command::copyVisual(to, "LineColor", from);
Gui::Command::copyVisual(to, "PointColor", from);
}

Some files were not shown because too many files have changed in this diff Show More