Material: Appearance Updates 2
Improves the use of the ShapeAppearance property for the Part workbench.
removes DiffuseColor property
adds Python compatibility using custom attributes
transitions DiffuseColor to ShapeAppearance on open
Improved UI elements for setting object appearance, and appearance per face
Lays the foundation for future texture support
This commit is contained in:
committed by
Chris Hennes
parent
c4d0f3ed97
commit
5feb963f9d
@@ -25,10 +25,26 @@
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <cstring>
|
||||
#include <random>
|
||||
#endif
|
||||
|
||||
#include "Application.h"
|
||||
#include "Material.h"
|
||||
|
||||
// Helper functions to consistently convert between float and long
|
||||
namespace
|
||||
{
|
||||
float fromPercent(long value)
|
||||
{
|
||||
return std::roundf(value) / 100.0F;
|
||||
}
|
||||
|
||||
long toPercent(float value)
|
||||
{
|
||||
return std::lround(100.0 * value);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
using namespace App;
|
||||
|
||||
|
||||
@@ -317,4 +333,47 @@ void Material::setType(MaterialType MatType)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
App::Material Material::getDefaultAppearance()
|
||||
{
|
||||
ParameterGrp::handle hGrp =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
|
||||
auto getColor = [hGrp](const char* parameter, App::Color& color) {
|
||||
uint32_t packed = color.getPackedRGB();
|
||||
packed = hGrp->GetUnsigned(parameter, packed);
|
||||
color.setPackedRGB(packed);
|
||||
};
|
||||
auto intRandom = [](int min, int max) -> int {
|
||||
static std::mt19937 generator;
|
||||
std::uniform_int_distribution<int> distribution(min, max);
|
||||
return distribution(generator);
|
||||
};
|
||||
|
||||
App::Material mat(App::Material::DEFAULT);
|
||||
mat.transparency = fromPercent(hGrp->GetInt("DefaultShapeTransparency", 0));
|
||||
long shininess = toPercent(mat.shininess);
|
||||
mat.shininess = fromPercent(hGrp->GetInt("DefaultShapeShininess", shininess));
|
||||
|
||||
// This is handled in the material code when using the object appearance
|
||||
bool randomColor = hGrp->GetBool("RandomColor", false);
|
||||
|
||||
// diffuse color
|
||||
if (randomColor) {
|
||||
float red = static_cast<float>(intRandom(0, 255)) / 255.0F;
|
||||
float green = static_cast<float>(intRandom(0, 255)) / 255.0F;
|
||||
float blue = static_cast<float>(intRandom(0, 255)) / 255.0F;
|
||||
mat.diffuseColor = App::Color(red, green, blue);
|
||||
}
|
||||
else {
|
||||
// Color = (204, 204, 230) = 3435980543UL
|
||||
getColor("DefaultShapeColor", mat.diffuseColor);
|
||||
}
|
||||
|
||||
getColor("DefaultAmbientColor", mat.ambientColor);
|
||||
getColor("DefaultEmissiveColor", mat.emissiveColor);
|
||||
getColor("DefaultSpecularColor", mat.specularColor);
|
||||
|
||||
return mat;
|
||||
}
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
|
||||
|
||||
@@ -131,6 +131,8 @@ public:
|
||||
Color emissiveColor; /**< Defines the emissive color. */
|
||||
float shininess;
|
||||
float transparency;
|
||||
std::string image;
|
||||
std::string imagePath;
|
||||
std::string uuid;
|
||||
// NOLINTEND
|
||||
//@}
|
||||
@@ -145,6 +147,8 @@ public:
|
||||
&& diffuseColor == m.diffuseColor
|
||||
&& specularColor == m.specularColor
|
||||
&& emissiveColor == m.emissiveColor
|
||||
&& image == m.image
|
||||
&& image == m.imagePath
|
||||
&& uuid == m.uuid;
|
||||
// clang-format on
|
||||
}
|
||||
@@ -155,6 +159,8 @@ public:
|
||||
Material& operator=(const Material& other) = default;
|
||||
Material& operator=(Material&& other) = default;
|
||||
|
||||
static Material getDefaultAppearance();
|
||||
|
||||
private:
|
||||
MaterialType _matType;
|
||||
};
|
||||
|
||||
@@ -2579,6 +2579,8 @@ void PropertyMaterial::Save(Base::Writer& writer) const
|
||||
<< "\" emissiveColor=\"" << _cMat.emissiveColor.getPackedValue()
|
||||
<< "\" shininess=\"" << _cMat.shininess
|
||||
<< "\" transparency=\"" << _cMat.transparency
|
||||
<< "\" image=\"" << _cMat.image
|
||||
<< "\" imagePath=\"" << _cMat.imagePath
|
||||
<< "\" uuid=\"" << _cMat.uuid
|
||||
<< "\"/>" << std::endl;
|
||||
// clang-format on
|
||||
@@ -2596,6 +2598,12 @@ 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("image")) {
|
||||
_cMat.image = reader.getAttribute("image");
|
||||
}
|
||||
if (reader.hasAttribute("imagePath")) {
|
||||
_cMat.imagePath = reader.getAttribute("imagePath");
|
||||
}
|
||||
if (reader.hasAttribute("uuid")) {
|
||||
_cMat.uuid = reader.getAttribute("uuid");
|
||||
}
|
||||
@@ -2635,7 +2643,7 @@ TYPESYSTEM_SOURCE(App::PropertyMaterialList, App::PropertyLists)
|
||||
|
||||
PropertyMaterialList::PropertyMaterialList()
|
||||
{
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
}
|
||||
|
||||
PropertyMaterialList::~PropertyMaterialList() = default;
|
||||
@@ -2662,7 +2670,7 @@ void PropertyMaterialList::verifyIndex(int index) const
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyMaterialList::setSizeOne()
|
||||
void PropertyMaterialList::setMinimumSizeOne()
|
||||
{
|
||||
int size = getSize();
|
||||
if (size < 1) {
|
||||
@@ -2690,7 +2698,7 @@ void PropertyMaterialList::setValue()
|
||||
void PropertyMaterialList::setValue(const Material& mat)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setSize(1);
|
||||
for (auto& material : _lValueList) {
|
||||
material = mat;
|
||||
}
|
||||
@@ -2710,7 +2718,7 @@ void PropertyMaterialList::setValue(int index, const Material& mat)
|
||||
void PropertyMaterialList::setAmbientColor(const Color& col)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.ambientColor = col;
|
||||
}
|
||||
@@ -2720,7 +2728,7 @@ void PropertyMaterialList::setAmbientColor(const Color& col)
|
||||
void PropertyMaterialList::setAmbientColor(float r, float g, float b, float a)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.ambientColor.set(r, g, b, a);
|
||||
}
|
||||
@@ -2730,7 +2738,7 @@ void PropertyMaterialList::setAmbientColor(float r, float g, float b, float a)
|
||||
void PropertyMaterialList::setAmbientColor(uint32_t rgba)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.ambientColor.setPackedValue(rgba);
|
||||
}
|
||||
@@ -2770,7 +2778,7 @@ void PropertyMaterialList::setAmbientColor(int index, uint32_t rgba)
|
||||
void PropertyMaterialList::setDiffuseColor(const Color& col)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.diffuseColor = col;
|
||||
}
|
||||
@@ -2780,7 +2788,7 @@ void PropertyMaterialList::setDiffuseColor(const Color& col)
|
||||
void PropertyMaterialList::setDiffuseColor(float r, float g, float b, float a)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.diffuseColor.set(r, g, b, a);
|
||||
}
|
||||
@@ -2790,7 +2798,7 @@ void PropertyMaterialList::setDiffuseColor(float r, float g, float b, float a)
|
||||
void PropertyMaterialList::setDiffuseColor(uint32_t rgba)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.diffuseColor.setPackedValue(rgba);
|
||||
}
|
||||
@@ -2827,10 +2835,21 @@ void PropertyMaterialList::setDiffuseColor(int index, uint32_t rgba)
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
void PropertyMaterialList::setDiffuseColors(const std::vector<App::Color>& colors)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSize(colors.size(), _lValueList[0]);
|
||||
|
||||
for (int i = 0; i < colors.size(); i++) {
|
||||
_lValueList[i].diffuseColor = colors[i];
|
||||
}
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
void PropertyMaterialList::setSpecularColor(const Color& col)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.specularColor = col;
|
||||
}
|
||||
@@ -2840,7 +2859,7 @@ void PropertyMaterialList::setSpecularColor(const Color& col)
|
||||
void PropertyMaterialList::setSpecularColor(float r, float g, float b, float a)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.specularColor.set(r, g, b, a);
|
||||
}
|
||||
@@ -2850,7 +2869,7 @@ void PropertyMaterialList::setSpecularColor(float r, float g, float b, float a)
|
||||
void PropertyMaterialList::setSpecularColor(uint32_t rgba)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.specularColor.setPackedValue(rgba);
|
||||
}
|
||||
@@ -2890,7 +2909,7 @@ void PropertyMaterialList::setSpecularColor(int index, uint32_t rgba)
|
||||
void PropertyMaterialList::setEmissiveColor(const Color& col)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.emissiveColor = col;
|
||||
}
|
||||
@@ -2900,7 +2919,7 @@ void PropertyMaterialList::setEmissiveColor(const Color& col)
|
||||
void PropertyMaterialList::setEmissiveColor(float r, float g, float b, float a)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.emissiveColor.set(r, g, b, a);
|
||||
}
|
||||
@@ -2910,7 +2929,7 @@ void PropertyMaterialList::setEmissiveColor(float r, float g, float b, float a)
|
||||
void PropertyMaterialList::setEmissiveColor(uint32_t rgba)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.emissiveColor.setPackedValue(rgba);
|
||||
}
|
||||
@@ -2950,7 +2969,7 @@ void PropertyMaterialList::setEmissiveColor(int index, uint32_t rgba)
|
||||
void PropertyMaterialList::setShininess(float val)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.shininess = val;
|
||||
}
|
||||
@@ -2970,7 +2989,7 @@ void PropertyMaterialList::setShininess(int index, float val)
|
||||
void PropertyMaterialList::setTransparency(float val)
|
||||
{
|
||||
aboutToSetValue();
|
||||
setSizeOne();
|
||||
setMinimumSizeOne();
|
||||
for (auto& material : _lValueList) {
|
||||
material.transparency = val;
|
||||
}
|
||||
@@ -3039,12 +3058,12 @@ const Color& PropertyMaterialList::getEmissiveColor(int index) const
|
||||
|
||||
float PropertyMaterialList::getShininess() const
|
||||
{
|
||||
return _lValueList[0].transparency;
|
||||
return _lValueList[0].shininess;
|
||||
}
|
||||
|
||||
float PropertyMaterialList::getShininess(int index) const
|
||||
{
|
||||
return _lValueList[index].transparency;
|
||||
return _lValueList[index].shininess;
|
||||
}
|
||||
|
||||
float PropertyMaterialList::getTransparency() const
|
||||
@@ -3074,7 +3093,7 @@ void PropertyMaterialList::Save(Base::Writer& writer) const
|
||||
if (!writer.isForceXML()) {
|
||||
writer.Stream() << writer.ind() << "<MaterialList file=\""
|
||||
<< (getSize() ? writer.addFile(getName(), this) : "") << "\""
|
||||
<< " version=\"2\"/>"
|
||||
<< " version=\"3\"/>"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
@@ -3107,8 +3126,21 @@ void PropertyMaterialList::SaveDocFile(Base::Writer& writer) const
|
||||
str << it.emissiveColor.getPackedValue();
|
||||
str << it.shininess;
|
||||
str << it.transparency;
|
||||
// str << it.uuid.c_str();
|
||||
}
|
||||
|
||||
// Apply the latest changes last for backwards compatibility
|
||||
for (const auto& it : _lValueList) {
|
||||
writeString(str, it.image);
|
||||
writeString(str, it.imagePath);
|
||||
writeString(str, it.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyMaterialList::writeString(Base::OutputStream& str, const std::string &value) const
|
||||
{
|
||||
uint32_t uCt = (uint32_t)value.size();
|
||||
str << uCt;
|
||||
str.write(value.c_str(), uCt);
|
||||
}
|
||||
|
||||
void PropertyMaterialList::RestoreDocFile(Base::Reader& reader)
|
||||
@@ -3120,11 +3152,20 @@ void PropertyMaterialList::RestoreDocFile(Base::Reader& reader)
|
||||
str >> count;
|
||||
RestoreDocFileV0(count, reader);
|
||||
}
|
||||
else if (formatVersion == Version_3) {
|
||||
// Default to the latest
|
||||
RestoreDocFileV3(reader);
|
||||
}
|
||||
else {
|
||||
int32_t version;
|
||||
str >> version;
|
||||
if (version < 0) {
|
||||
RestoreDocFileV1(reader);
|
||||
// This was a failed attempt at versioning, but is included
|
||||
// to support files created during development. In can be removed
|
||||
// in a future release once dev files are migrated.
|
||||
uint32_t count = 0;
|
||||
str >> count;
|
||||
RestoreDocFileV0(count, reader);
|
||||
}
|
||||
else {
|
||||
uint32_t uCt = static_cast<uint32_t>(version);
|
||||
@@ -3156,14 +3197,14 @@ void PropertyMaterialList::RestoreDocFileV0(uint32_t count, Base::Reader& reader
|
||||
setValues(values);
|
||||
}
|
||||
|
||||
void PropertyMaterialList::RestoreDocFileV1(Base::Reader& reader)
|
||||
void PropertyMaterialList::RestoreDocFileV3(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 {};
|
||||
uint32_t value; // must be 32 bit long
|
||||
float valueF;
|
||||
for (auto& it : values) {
|
||||
str >> value;
|
||||
it.ambientColor.setPackedValue(value);
|
||||
@@ -3177,12 +3218,29 @@ void PropertyMaterialList::RestoreDocFileV1(Base::Reader& reader)
|
||||
it.shininess = valueF;
|
||||
str >> valueF;
|
||||
it.transparency = valueF;
|
||||
// str >> valueS;
|
||||
// it.uuid = valueS;
|
||||
}
|
||||
for (auto& it : values) {
|
||||
readString(str, it.image);
|
||||
readString(str, it.imagePath);
|
||||
readString(str, it.uuid);
|
||||
}
|
||||
setValues(values);
|
||||
}
|
||||
|
||||
void PropertyMaterialList::readString(Base::InputStream& str,
|
||||
std::string& value)
|
||||
{
|
||||
uint32_t uCt;
|
||||
str >> uCt;
|
||||
|
||||
char *temp = new char[uCt];
|
||||
|
||||
str.read(temp, uCt);
|
||||
value.assign(temp, static_cast<std::size_t>(uCt));
|
||||
|
||||
delete [] temp;
|
||||
}
|
||||
|
||||
const char* PropertyMaterialList::getEditorName() const
|
||||
{
|
||||
if (testStatus(NoMaterialListEdit)) {
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
|
||||
|
||||
namespace Base {
|
||||
class InputStream;
|
||||
class OutputStream;
|
||||
class Writer;
|
||||
}
|
||||
|
||||
@@ -1132,6 +1134,7 @@ public:
|
||||
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 setDiffuseColors(const std::vector<App::Color>& colors);
|
||||
|
||||
void setSpecularColor(const Color& col);
|
||||
void setSpecularColor(float r, float g, float b, float a = 0.0F);
|
||||
@@ -1193,14 +1196,18 @@ private:
|
||||
enum Format {
|
||||
Version_0,
|
||||
Version_1,
|
||||
Version_2
|
||||
Version_2,
|
||||
Version_3
|
||||
};
|
||||
|
||||
void RestoreDocFileV0(uint32_t count, Base::Reader& reader);
|
||||
void RestoreDocFileV1(Base::Reader& reader);
|
||||
void RestoreDocFileV3(Base::Reader& reader);
|
||||
|
||||
void writeString(Base::OutputStream& str, const std::string &value) const;
|
||||
void readString(Base::InputStream& str, std::string& value);
|
||||
|
||||
void verifyIndex(int index) const;
|
||||
void setSizeOne();
|
||||
void setMinimumSizeOne();
|
||||
int resizeByOneIfNeeded(int index);
|
||||
|
||||
Format formatVersion {Version_0};
|
||||
|
||||
@@ -150,6 +150,12 @@ OutputStream& OutputStream::operator<<(double d)
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::write(const char* s, int n)
|
||||
{
|
||||
_out.write(s, n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream::InputStream(std::istream& rin)
|
||||
: _in(rin)
|
||||
{}
|
||||
@@ -246,6 +252,12 @@ InputStream& InputStream::operator>>(double& d)
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::read(char* s, int n)
|
||||
{
|
||||
_in.read(s, n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ByteArrayOStreambuf::ByteArrayOStreambuf(QByteArray& ba)
|
||||
|
||||
@@ -95,6 +95,8 @@ public:
|
||||
OutputStream& operator<<(float f);
|
||||
OutputStream& operator<<(double d);
|
||||
|
||||
OutputStream& write(const char* s, int n);
|
||||
|
||||
OutputStream(const OutputStream&) = delete;
|
||||
OutputStream(OutputStream&&) = delete;
|
||||
void operator=(const OutputStream&) = delete;
|
||||
@@ -126,6 +128,8 @@ public:
|
||||
InputStream& operator>>(float& f);
|
||||
InputStream& operator>>(double& d);
|
||||
|
||||
InputStream& read(char* s, int n);
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
// test if _Ipfx succeeded
|
||||
|
||||
@@ -271,7 +271,7 @@ protected:
|
||||
std::make_pair(QT_TRANSLATE_NOOP("EditMode", "Color"),
|
||||
QT_TRANSLATE_NOOP("EditMode",
|
||||
"The object will have the color of its individual faces "
|
||||
"editable with the Part FaceColors command"))},
|
||||
"editable with the Part FaceAppearances command"))},
|
||||
};
|
||||
int userEditMode = userEditModes.begin()->first;
|
||||
|
||||
|
||||
@@ -41,62 +41,6 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="textLabel2">
|
||||
<property name="text">
|
||||
<string>Ambient color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::ColorButton" name="ambientColor">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="textLabel1">
|
||||
<property name="text">
|
||||
<string>Diffuse color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::ColorButton" name="diffuseColor">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Emissive color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::ColorButton" name="emissiveColor">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="textLabel3">
|
||||
<property name="text">
|
||||
<string>Specular color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="Gui::ColorButton" name="specularColor">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
@@ -149,6 +93,76 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="textLabel1">
|
||||
<property name="text">
|
||||
<string>Diffuse color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::ColorButton" name="ambientColor">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::ColorButton" name="emissiveColor">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="textLabel3">
|
||||
<property name="text">
|
||||
<string>Specular color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::ColorButton" name="diffuseColor">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="textLabel2">
|
||||
<property name="text">
|
||||
<string>Ambient color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="Gui::ColorButton" name="specularColor">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Emissive color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QPushButton" name="buttonReset">
|
||||
<property name="text">
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QPushButton" name="buttonDefault">
|
||||
<property name="text">
|
||||
<string>Default</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -22,8 +22,11 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <App/Color.h>
|
||||
#include <App/Material.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "DlgMaterialPropertiesImp.h"
|
||||
#include "ui_DlgMaterialProperties.h"
|
||||
#include "ViewProvider.h"
|
||||
@@ -46,11 +49,12 @@ DlgMaterialPropertiesImp::DlgMaterialPropertiesImp(const std::string& mat, QWidg
|
||||
: QDialog(parent, fl)
|
||||
, ui(new Ui_DlgMaterialProperties)
|
||||
, material(mat)
|
||||
, updateColors(true)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setupConnections();
|
||||
|
||||
if (material != "ShapeMaterial") {
|
||||
if (material != "ShapeAppearance") {
|
||||
ui->textLabel1->hide();
|
||||
ui->diffuseColor->hide();
|
||||
}
|
||||
@@ -68,6 +72,8 @@ DlgMaterialPropertiesImp::~DlgMaterialPropertiesImp() = default;
|
||||
|
||||
void DlgMaterialPropertiesImp::setupConnections()
|
||||
{
|
||||
Base::Console().Log("DlgMaterialPropertiesImp::setupConnections()\n");
|
||||
|
||||
connect(ui->ambientColor, &ColorButton::changed,
|
||||
this, &DlgMaterialPropertiesImp::onAmbientColorChanged);
|
||||
connect(ui->diffuseColor, &ColorButton::changed,
|
||||
@@ -78,6 +84,10 @@ void DlgMaterialPropertiesImp::setupConnections()
|
||||
this, &DlgMaterialPropertiesImp::onSpecularColorChanged);
|
||||
connect(ui->shininess, qOverload<int>(&QSpinBox::valueChanged),
|
||||
this, &DlgMaterialPropertiesImp::onShininessValueChanged);
|
||||
connect(ui->buttonReset, &QPushButton::clicked,
|
||||
this, &DlgMaterialPropertiesImp::onButtonReset);
|
||||
connect(ui->buttonDefault, &QPushButton::clicked,
|
||||
this, &DlgMaterialPropertiesImp::onButtonDefault);
|
||||
}
|
||||
|
||||
QColor DlgMaterialPropertiesImp::diffuseColor() const
|
||||
@@ -85,24 +95,54 @@ QColor DlgMaterialPropertiesImp::diffuseColor() const
|
||||
return ui->diffuseColor->color();
|
||||
}
|
||||
|
||||
App::Material DlgMaterialPropertiesImp::getMaterial()
|
||||
{
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
|
||||
auto& materials = ShapeAppearance->getValues();
|
||||
auto mat = materials[0];
|
||||
|
||||
mat.setType(App::Material::USER_DEFINED);
|
||||
|
||||
// Reset any texture data
|
||||
mat.image = "";
|
||||
mat.imagePath = "";
|
||||
mat.uuid = "";
|
||||
|
||||
return mat;
|
||||
}
|
||||
}
|
||||
|
||||
return App::Material::getDefaultAppearance();
|
||||
}
|
||||
|
||||
App::Color DlgMaterialPropertiesImp::getColor(const QColor& color) const
|
||||
{
|
||||
float r = (float)color.red() / 255.0F;
|
||||
float g = (float)color.green() / 255.0F;
|
||||
float b = (float)color.blue() / 255.0F;
|
||||
|
||||
return App::Color(r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ambient color.
|
||||
*/
|
||||
void DlgMaterialPropertiesImp::onAmbientColorChanged()
|
||||
{
|
||||
QColor col = ui->ambientColor->color();
|
||||
float r = (float)col.red() / 255.0f;
|
||||
float g = (float)col.green() / 255.0f;
|
||||
float b = (float)col.blue() / 255.0f;
|
||||
App::Color ambient(r, g, b);
|
||||
if (updateColors) {
|
||||
App::Color ambient = getColor(ui->ambientColor->color());
|
||||
|
||||
for (std::vector<ViewProvider*>::iterator it= Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterial>()) {
|
||||
auto ShapeMaterial = static_cast<App::PropertyMaterial*>(prop);
|
||||
App::Material mat = ShapeMaterial->getValue();
|
||||
mat.ambientColor = ambient;
|
||||
ShapeMaterial->setValue(mat);
|
||||
for (std::vector<ViewProvider*>::iterator it= Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
|
||||
auto mat = getMaterial();
|
||||
mat.ambientColor = ambient;
|
||||
ShapeAppearance->setValue(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,19 +152,17 @@ void DlgMaterialPropertiesImp::onAmbientColorChanged()
|
||||
*/
|
||||
void DlgMaterialPropertiesImp::onDiffuseColorChanged()
|
||||
{
|
||||
QColor col = ui->diffuseColor->color();
|
||||
float r = (float)col.red() / 255.0f;
|
||||
float g = (float)col.green() / 255.0f;
|
||||
float b = (float)col.blue() / 255.0f;
|
||||
App::Color diffuse(r, g, b);
|
||||
if (updateColors) {
|
||||
App::Color diffuse = getColor(ui->diffuseColor->color());
|
||||
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterial>()) {
|
||||
auto ShapeMaterial = static_cast<App::PropertyMaterial*>(prop);
|
||||
App::Material mat = ShapeMaterial->getValue();
|
||||
mat.diffuseColor = diffuse;
|
||||
ShapeMaterial->setValue(mat);
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
|
||||
auto mat = getMaterial();
|
||||
mat.diffuseColor = diffuse;
|
||||
ShapeAppearance->setValue(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,19 +172,17 @@ void DlgMaterialPropertiesImp::onDiffuseColorChanged()
|
||||
*/
|
||||
void DlgMaterialPropertiesImp::onEmissiveColorChanged()
|
||||
{
|
||||
QColor col = ui->emissiveColor->color();
|
||||
float r = (float)col.red() / 255.0f;
|
||||
float g = (float)col.green() / 255.0f;
|
||||
float b = (float)col.blue() / 255.0f;
|
||||
App::Color emissive(r, g, b);
|
||||
if (updateColors) {
|
||||
App::Color emissive = getColor(ui->emissiveColor->color());
|
||||
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterial>()) {
|
||||
auto ShapeMaterial = static_cast<App::PropertyMaterial*>(prop);
|
||||
App::Material mat = ShapeMaterial->getValue();
|
||||
mat.emissiveColor = emissive;
|
||||
ShapeMaterial->setValue(mat);
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
|
||||
auto mat = getMaterial();
|
||||
mat.emissiveColor = emissive;
|
||||
ShapeAppearance->setValue(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,19 +192,17 @@ void DlgMaterialPropertiesImp::onEmissiveColorChanged()
|
||||
*/
|
||||
void DlgMaterialPropertiesImp::onSpecularColorChanged()
|
||||
{
|
||||
QColor col = ui->specularColor->color();
|
||||
float r = (float)col.red() / 255.0f;
|
||||
float g = (float)col.green() / 255.0f;
|
||||
float b = (float)col.blue() / 255.0f;
|
||||
App::Color specular(r, g, b);
|
||||
if (updateColors) {
|
||||
App::Color specular = getColor(ui->specularColor->color());
|
||||
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterial>()) {
|
||||
auto ShapeMaterial = static_cast<App::PropertyMaterial*>(prop);
|
||||
App::Material mat = ShapeMaterial->getValue();
|
||||
mat.specularColor = specular;
|
||||
ShapeMaterial->setValue(mat);
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
|
||||
auto mat = getMaterial();
|
||||
mat.specularColor = specular;
|
||||
ShapeAppearance->setValue(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,14 +212,63 @@ void DlgMaterialPropertiesImp::onSpecularColorChanged()
|
||||
*/
|
||||
void DlgMaterialPropertiesImp::onShininessValueChanged(int sh)
|
||||
{
|
||||
float shininess = (float)sh / 100.0f;
|
||||
if (updateColors) {
|
||||
float shininess = (float)sh / 100.0F;
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
|
||||
auto mat = getMaterial();
|
||||
mat.shininess = shininess;
|
||||
ShapeAppearance->setValue(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the colors to the Coin3D defaults
|
||||
*/
|
||||
void DlgMaterialPropertiesImp::onButtonReset(bool checked)
|
||||
{
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterial>()) {
|
||||
auto ShapeMaterial = static_cast<App::PropertyMaterial*>(prop);
|
||||
App::Material mat = ShapeMaterial->getValue();
|
||||
mat.shininess = shininess;
|
||||
ShapeMaterial->setValue(mat);
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
|
||||
auto mat = getMaterial();
|
||||
|
||||
App::Color defaultAmbient(0.2, 0.2, 0.2);
|
||||
App::Color defaultDiffuse(0.8, 0.8, 0.8);
|
||||
App::Color black(0, 0, 0);
|
||||
|
||||
mat.ambientColor = defaultAmbient;
|
||||
mat.diffuseColor = defaultDiffuse;
|
||||
mat.emissiveColor = black;
|
||||
mat.specularColor = black;
|
||||
mat.shininess = 0.2;
|
||||
ShapeAppearance->setValue(mat);
|
||||
|
||||
setButtonColors();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the colors to the current default
|
||||
*/
|
||||
void DlgMaterialPropertiesImp::onButtonDefault(bool checked)
|
||||
{
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
|
||||
auto mat = App::Material::getDefaultAppearance();
|
||||
|
||||
ShapeAppearance->setValue(mat);
|
||||
|
||||
setButtonColors();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -197,33 +280,82 @@ void DlgMaterialPropertiesImp::setViewProviders(const std::vector<Gui::ViewProvi
|
||||
{
|
||||
Objects = Obj;
|
||||
|
||||
setButtonColors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the button colors to match the current material settings.
|
||||
*/
|
||||
void DlgMaterialPropertiesImp::setButtonColors()
|
||||
{
|
||||
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
|
||||
App::Property* prop = (*it)->getPropertyByName(material.c_str());
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterial>()) {
|
||||
auto ShapeMaterial = static_cast<App::PropertyMaterial*>(prop);
|
||||
App::Material mat = ShapeMaterial->getValue();
|
||||
int r = int(mat.ambientColor.r * 255.0f);
|
||||
int g = int(mat.ambientColor.g * 255.0f);
|
||||
int b = int(mat.ambientColor.b * 255.0f);
|
||||
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
|
||||
auto& materials = ShapeAppearance->getValues();
|
||||
auto& mat = materials[0];
|
||||
int r = int(mat.ambientColor.r * 255.0F);
|
||||
int g = int(mat.ambientColor.g * 255.0F);
|
||||
int b = int(mat.ambientColor.b * 255.0F);
|
||||
ui->ambientColor->setColor(QColor(r, g, b));
|
||||
r = int(mat.diffuseColor.r * 255.0f);
|
||||
g = int(mat.diffuseColor.g * 255.0f);
|
||||
b = int(mat.diffuseColor.b * 255.0f);
|
||||
r = int(mat.diffuseColor.r * 255.0F);
|
||||
g = int(mat.diffuseColor.g * 255.0F);
|
||||
b = int(mat.diffuseColor.b * 255.0F);
|
||||
ui->diffuseColor->setColor(QColor(r, g, b));
|
||||
r = int(mat.emissiveColor.r * 255.0f);
|
||||
g = int(mat.emissiveColor.g * 255.0f);
|
||||
b = int(mat.emissiveColor.b * 255.0f);
|
||||
r = int(mat.emissiveColor.r * 255.0F);
|
||||
g = int(mat.emissiveColor.g * 255.0F);
|
||||
b = int(mat.emissiveColor.b * 255.0F);
|
||||
ui->emissiveColor->setColor(QColor(r, g, b));
|
||||
r = int(mat.specularColor.r * 255.0f);
|
||||
g = int(mat.specularColor.g * 255.0f);
|
||||
b = int(mat.specularColor.b * 255.0f);
|
||||
r = int(mat.specularColor.r * 255.0F);
|
||||
g = int(mat.specularColor.g * 255.0F);
|
||||
b = int(mat.specularColor.b * 255.0F);
|
||||
ui->specularColor->setColor(QColor(r, g, b));
|
||||
ui->shininess->blockSignals(true);
|
||||
ui->shininess->setValue((int)(100.0f * (mat.shininess + 0.001f)));
|
||||
ui->shininess->setValue((int)(100.0f * (mat.shininess + 0.001F)));
|
||||
ui->shininess->blockSignals(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Gui::Dialog::DlgFaceMaterialPropertiesImp as 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.
|
||||
*
|
||||
* This differs from Gui::Dialog::DlgMaterialPropertiesImp in that it does not update
|
||||
* the underlying object. This is undesirable when we're updating only a single face.
|
||||
*/
|
||||
DlgFaceMaterialPropertiesImp::DlgFaceMaterialPropertiesImp(const std::string& mat,
|
||||
QWidget* parent,
|
||||
Qt::WindowFlags fl)
|
||||
: DlgMaterialPropertiesImp(mat, parent, fl)
|
||||
{
|
||||
Base::Console().Log("DlgFaceMaterialPropertiesImp::DlgFaceMaterialPropertiesImp()\n");
|
||||
|
||||
// Override the base class on this. Otherwise the whole object changes
|
||||
updateColors = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the object and frees any allocated resources
|
||||
*/
|
||||
DlgFaceMaterialPropertiesImp::~DlgFaceMaterialPropertiesImp() = default;
|
||||
|
||||
App::Material DlgFaceMaterialPropertiesImp::getCustomAppearance() const
|
||||
{
|
||||
App::Material material;
|
||||
material.setType(App::Material::USER_DEFINED);
|
||||
|
||||
material.ambientColor = getColor(ui->ambientColor->color());
|
||||
material.diffuseColor = getColor(ui->diffuseColor->color());
|
||||
material.emissiveColor = getColor(ui->emissiveColor->color());
|
||||
material.specularColor = getColor(ui->specularColor->color());
|
||||
material.shininess = (float)ui->shininess->value() / 100.0F;
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
#include "moc_DlgMaterialPropertiesImp.cpp"
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace App
|
||||
{
|
||||
class Color;
|
||||
class Material;
|
||||
}
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
class ViewProvider;
|
||||
@@ -48,18 +54,36 @@ public:
|
||||
void setViewProviders(const std::vector<Gui::ViewProvider*>&);
|
||||
QColor diffuseColor() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
void setupConnections();
|
||||
App::Material getMaterial();
|
||||
App::Color getColor(const QColor& color) const;
|
||||
void onAmbientColorChanged();
|
||||
void onDiffuseColorChanged();
|
||||
void onEmissiveColorChanged();
|
||||
void onSpecularColorChanged();
|
||||
void onShininessValueChanged(int);
|
||||
void onButtonReset(bool checked);
|
||||
void onButtonDefault(bool checked);
|
||||
void setButtonColors();
|
||||
|
||||
private:
|
||||
protected:
|
||||
std::unique_ptr<Ui_DlgMaterialProperties> ui;
|
||||
std::string material;
|
||||
std::vector<Gui::ViewProvider*> Objects;
|
||||
bool updateColors;
|
||||
};
|
||||
|
||||
class GuiExport DlgFaceMaterialPropertiesImp: public DlgMaterialPropertiesImp
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DlgFaceMaterialPropertiesImp(const std::string& mat,
|
||||
QWidget* parent = nullptr,
|
||||
Qt::WindowFlags fl = Qt::WindowFlags());
|
||||
~DlgFaceMaterialPropertiesImp() override;
|
||||
App::Material getCustomAppearance() const;
|
||||
};
|
||||
|
||||
} // namespace Dialog
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <random>
|
||||
#include <Inventor/SoPickedPoint.h>
|
||||
#include <Inventor/actions/SoRayPickAction.h>
|
||||
#include <Inventor/actions/SoSearchAction.h>
|
||||
@@ -35,12 +34,14 @@
|
||||
#include <Inventor/nodes/SoMaterial.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/nodes/SoSwitch.h>
|
||||
#include <Inventor/nodes/SoTexture2.h>
|
||||
#endif
|
||||
|
||||
#include <Inventor/nodes/SoResetTransform.h>
|
||||
|
||||
#include <App/GeoFeature.h>
|
||||
#include <App/PropertyGeo.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Document.h"
|
||||
@@ -56,12 +57,12 @@ using namespace Gui;
|
||||
namespace {
|
||||
float fromPercent(long value)
|
||||
{
|
||||
return static_cast<float>(value) / 100.0F;
|
||||
return std::roundf(value) / 100.0F;
|
||||
}
|
||||
|
||||
long toPercent(float value)
|
||||
{
|
||||
return static_cast<long>(100.0 * value + 0.5);
|
||||
return std::lround(100.0 * value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +72,7 @@ const App::PropertyIntegerConstraint::Constraints intPercent = {0, 100, 5};
|
||||
|
||||
ViewProviderGeometryObject::ViewProviderGeometryObject()
|
||||
{
|
||||
App::Material mat = getUserDefinedMaterial();
|
||||
App::Material mat = App::Material::getDefaultAppearance();
|
||||
long initialTransparency = toPercent(mat.transparency);
|
||||
|
||||
static const char* dogroup = "Display Options";
|
||||
@@ -95,10 +96,29 @@ ViewProviderGeometryObject::ViewProviderGeometryObject()
|
||||
|
||||
Selectable.setValue(isSelectionEnabled());
|
||||
|
||||
pcSwitchAppearance = new SoSwitch;
|
||||
pcSwitchAppearance->ref();
|
||||
pcSwitchTexture = new SoSwitch;
|
||||
pcSwitchTexture->ref();
|
||||
|
||||
pcShapeMaterial = new SoMaterial;
|
||||
setSoMaterial(mat);
|
||||
setCoinAppearance(mat);
|
||||
pcShapeMaterial->ref();
|
||||
|
||||
pcShapeTexture2D = new SoTexture2;
|
||||
pcShapeTexture2D->ref();
|
||||
|
||||
pcTextureGroup3D = new SoGroup;
|
||||
pcTextureGroup3D->ref();
|
||||
|
||||
// Materials go first, with textured faces drawing over them
|
||||
pcSwitchAppearance->addChild(pcShapeMaterial);
|
||||
pcSwitchAppearance->addChild(pcSwitchTexture);
|
||||
pcSwitchTexture->addChild(pcShapeTexture2D);
|
||||
pcSwitchTexture->addChild(pcTextureGroup3D);
|
||||
pcSwitchAppearance->whichChild.setValue(0);
|
||||
pcSwitchTexture->whichChild.setValue(SO_SWITCH_NONE);
|
||||
|
||||
pcBoundingBox = new Gui::SoFCBoundingBox;
|
||||
pcBoundingBox->ref();
|
||||
|
||||
@@ -110,54 +130,15 @@ ViewProviderGeometryObject::ViewProviderGeometryObject()
|
||||
|
||||
ViewProviderGeometryObject::~ViewProviderGeometryObject()
|
||||
{
|
||||
pcSwitchAppearance->unref();
|
||||
pcSwitchTexture->unref();
|
||||
pcShapeMaterial->unref();
|
||||
pcShapeTexture2D->unref();
|
||||
pcTextureGroup3D->unref();
|
||||
pcBoundingBox->unref();
|
||||
pcBoundColor->unref();
|
||||
}
|
||||
|
||||
App::Material ViewProviderGeometryObject::getUserDefinedMaterial()
|
||||
{
|
||||
ParameterGrp::handle hGrp =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
|
||||
auto getColor = [hGrp](const char* parameter, App::Color& color) {
|
||||
uint32_t packed = color.getPackedRGB();
|
||||
packed = hGrp->GetUnsigned(parameter, packed);
|
||||
color.setPackedRGB(packed);
|
||||
};
|
||||
auto intRandom = [] (int min, int max) -> int {
|
||||
static std::mt19937 generator;
|
||||
std::uniform_int_distribution<int> distribution(min, max);
|
||||
return distribution(generator);
|
||||
};
|
||||
|
||||
App::Material mat(App::Material::DEFAULT);
|
||||
mat.transparency = fromPercent(hGrp->GetInt("DefaultShapeTransparency", 0));
|
||||
long shininess = toPercent(mat.shininess);
|
||||
mat.shininess = fromPercent(hGrp->GetInt("DefaultShapeShininess", shininess));
|
||||
|
||||
// This is handled in the material code when using the object appearance
|
||||
bool randomColor = hGrp->GetBool("RandomColor", false);
|
||||
|
||||
// diffuse color
|
||||
if (randomColor) {
|
||||
float red = static_cast<float>(intRandom(0, 255)) / 255.0F;
|
||||
float green = static_cast<float>(intRandom(0, 255)) / 255.0F;
|
||||
float blue = static_cast<float>(intRandom(0, 255)) / 255.0F;
|
||||
mat.diffuseColor = App::Color(red, green, blue);
|
||||
}
|
||||
else {
|
||||
// Color = (204, 204, 230) = 3435980543UL
|
||||
getColor("DefaultShapeColor", mat.diffuseColor);
|
||||
}
|
||||
|
||||
getColor("DefaultAmbientColor", mat.ambientColor);
|
||||
getColor("DefaultEmissiveColor", mat.emissiveColor);
|
||||
getColor("DefaultSpecularColor", mat.specularColor);
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
bool ViewProviderGeometryObject::isSelectionEnabled() const
|
||||
{
|
||||
ParameterGrp::handle hGrp =
|
||||
@@ -187,12 +168,14 @@ void ViewProviderGeometryObject::onChanged(const App::Property* prop)
|
||||
if (getObject() && getObject()->testStatus(App::ObjectStatus::TouchOnColorChange)) {
|
||||
getObject()->touch(true);
|
||||
}
|
||||
const App::Material& Mat = ShapeAppearance[0];
|
||||
long value = toPercent(ShapeAppearance.getTransparency());
|
||||
if (value != Transparency.getValue()) {
|
||||
Transparency.setValue(value);
|
||||
}
|
||||
setSoMaterial(Mat);
|
||||
if (ShapeAppearance.getSize() == 1) {
|
||||
const App::Material& Mat = ShapeAppearance[0];
|
||||
setCoinAppearance(Mat);
|
||||
}
|
||||
}
|
||||
else if (prop == &BoundingBox) {
|
||||
showBoundingBox(BoundingBox.getValue());
|
||||
@@ -288,14 +271,33 @@ unsigned long ViewProviderGeometryObject::getBoundColor() const
|
||||
return bbcol;
|
||||
}
|
||||
|
||||
void ViewProviderGeometryObject::setSoMaterial(const App::Material& source)
|
||||
void ViewProviderGeometryObject::setCoinAppearance(const App::Material& source)
|
||||
{
|
||||
#if 0
|
||||
if (!source.image.empty()) {
|
||||
Base::Console().Log("setCoinAppearance(Texture)\n");
|
||||
activateTexture2D();
|
||||
|
||||
QByteArray by = QByteArray::fromBase64(QString::fromStdString(source.image).toUtf8());
|
||||
auto image = QImage::fromData(by, "PNG"); //.scaled(64, 64, Qt::KeepAspectRatio);
|
||||
|
||||
SoSFImage texture;
|
||||
Gui::BitmapFactory().convert(image, texture);
|
||||
pcShapeTexture2D->image = texture;
|
||||
} else {
|
||||
Base::Console().Log("setCoinAppearance(Material)\n");
|
||||
activateMaterial();
|
||||
}
|
||||
#endif
|
||||
activateMaterial();
|
||||
|
||||
// Always set the material for items such as lines that don't support textures
|
||||
pcShapeMaterial->ambientColor.setValue(source.ambientColor.r,
|
||||
source.ambientColor.g,
|
||||
source.ambientColor.b);
|
||||
source.ambientColor.g,
|
||||
source.ambientColor.b);
|
||||
pcShapeMaterial->diffuseColor.setValue(source.diffuseColor.r,
|
||||
source.diffuseColor.g,
|
||||
source.diffuseColor.b);
|
||||
source.diffuseColor.g,
|
||||
source.diffuseColor.b);
|
||||
pcShapeMaterial->specularColor.setValue(source.specularColor.r,
|
||||
source.specularColor.g,
|
||||
source.specularColor.b);
|
||||
@@ -306,6 +308,31 @@ void ViewProviderGeometryObject::setSoMaterial(const App::Material& source)
|
||||
pcShapeMaterial->transparency.setValue(source.transparency);
|
||||
}
|
||||
|
||||
void ViewProviderGeometryObject::activateMaterial()
|
||||
{
|
||||
pcSwitchAppearance->whichChild.setValue(0);
|
||||
pcSwitchTexture->whichChild.setValue(SO_SWITCH_NONE);
|
||||
}
|
||||
|
||||
void ViewProviderGeometryObject::activateTexture2D()
|
||||
{
|
||||
pcSwitchAppearance->whichChild.setValue(1);
|
||||
pcSwitchTexture->whichChild.setValue(0);
|
||||
}
|
||||
|
||||
void ViewProviderGeometryObject::activateTexture3D()
|
||||
{
|
||||
pcSwitchAppearance->whichChild.setValue(1);
|
||||
pcSwitchTexture->whichChild.setValue(1);
|
||||
}
|
||||
|
||||
void ViewProviderGeometryObject::activateMixed3D()
|
||||
{
|
||||
pcSwitchAppearance->whichChild.setValue(SO_SWITCH_ALL);
|
||||
pcSwitchTexture->whichChild.setValue(1);
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
float getBoundBoxFontSize()
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
class SoPickedPointList;
|
||||
class SoSwitch;
|
||||
class SoSensor;
|
||||
class SoTexture2;
|
||||
class SbVec2s;
|
||||
class SoBaseColor;
|
||||
|
||||
@@ -58,7 +59,6 @@ public:
|
||||
|
||||
// Display properties
|
||||
App::PropertyPercent Transparency;
|
||||
// App::PropertyMaterial ShapeMaterial; // Default appearance and physical properties
|
||||
App::PropertyMaterialList ShapeAppearance; // May be different from material
|
||||
App::PropertyBool BoundingBox;
|
||||
App::PropertyBool Selectable;
|
||||
@@ -108,13 +108,30 @@ protected:
|
||||
void handleChangedPropertyName(Base::XMLReader& reader,
|
||||
const char* TypeName,
|
||||
const char* PropName) override;
|
||||
void setCoinAppearance(const App::Material& source);
|
||||
|
||||
/**
|
||||
* Select which appearance type is active
|
||||
*
|
||||
*/
|
||||
/** Material only */
|
||||
void activateMaterial();
|
||||
/** 2D Texture */
|
||||
void activateTexture2D();
|
||||
/** 3D texture only */
|
||||
void activateTexture3D();
|
||||
/** Mix of material and 3D textures */
|
||||
void activateMixed3D();
|
||||
|
||||
private:
|
||||
void setSoMaterial(const App::Material& source);
|
||||
bool isSelectionEnabled() const;
|
||||
|
||||
protected:
|
||||
SoSwitch* pcSwitchAppearance {nullptr};
|
||||
SoSwitch* pcSwitchTexture {nullptr};
|
||||
SoMaterial* pcShapeMaterial {nullptr};
|
||||
SoTexture2* pcShapeTexture2D {nullptr};
|
||||
SoGroup* pcTextureGroup3D {nullptr};
|
||||
SoFCBoundingBox* pcBoundingBox {nullptr};
|
||||
SoSwitch* pcBoundSwitch {nullptr};
|
||||
SoBaseColor* pcBoundColor {nullptr};
|
||||
|
||||
@@ -71,7 +71,7 @@ PyObject* ViewProviderGeometryObjectPy::getCustomAttributes(const char* attr) co
|
||||
|
||||
PyObject* ViewProviderGeometryObjectPy::getUserDefinedMaterial()
|
||||
{
|
||||
App::Material mat = ViewProviderGeometryObject::getUserDefinedMaterial();
|
||||
App::Material mat = App::Material::getDefaultAppearance();
|
||||
return new App::MaterialPy(new App::Material(mat));
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ void ViewProviderFemConstraintOnBoundary::highlightReferences(const bool on)
|
||||
else if (subSet.second[0].find("Face") != std::string::npos) {
|
||||
// make sure original colors are remembered
|
||||
if (originalFaceColors[base].empty()) {
|
||||
originalFaceColors[base] = vp->DiffuseColor.getValues();
|
||||
originalFaceColors[base] = vp->ShapeAppearance.getDiffuseColors();
|
||||
}
|
||||
std::vector<App::Color> colors = originalFaceColors[base];
|
||||
|
||||
@@ -104,7 +104,7 @@ void ViewProviderFemConstraintOnBoundary::highlightReferences(const bool on)
|
||||
base->Shape.getValue(),
|
||||
colors.empty() ? ShapeAppearance.getDiffuseColor() : colors[0]);
|
||||
highlighter.getFaceColors(subSet.second, colors);
|
||||
vp->DiffuseColor.setValues(colors);
|
||||
vp->ShapeAppearance.setDiffuseColors(colors);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -117,7 +117,7 @@ void ViewProviderFemConstraintOnBoundary::highlightReferences(const bool on)
|
||||
originalLineColors[base].clear();
|
||||
}
|
||||
else if (!originalFaceColors[base].empty()) {
|
||||
vp->DiffuseColor.setValues(originalFaceColors[base]);
|
||||
vp->ShapeAppearance.setDiffuseColors(originalFaceColors[base]);
|
||||
originalFaceColors[base].clear();
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ void ViewProviderFemConstraintOnBoundary::highlightReferences(const bool on)
|
||||
continue;
|
||||
}
|
||||
|
||||
vp->DiffuseColor.setValues(ogPair.second);
|
||||
vp->ShapeAppearance.setDiffuseColors(ogPair.second);
|
||||
ogPair.second.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,6 @@ void ExportOCAFGui::findColors(Part::Feature* part, std::vector<App::Color>& col
|
||||
{
|
||||
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
|
||||
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)->ShapeAppearance.getDiffuseColor());
|
||||
}
|
||||
colors = static_cast<PartGui::ViewProviderPartExt*>(vp)->ShapeAppearance.getDiffuseColors();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ void ImportOCAFGui::applyFaceColors(Part::Feature* part, const std::vector<App::
|
||||
vp->Transparency.setValue(100 * colors.front().a);
|
||||
}
|
||||
else {
|
||||
vp->DiffuseColor.setValues(colors);
|
||||
vp->ShapeAppearance.setDiffuseColors(colors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -333,6 +333,11 @@ void MaterialProperty::setString(const QString& value)
|
||||
_valuePtr->setValue(QVariant(value));
|
||||
}
|
||||
|
||||
void MaterialProperty::setString(const std::string& value)
|
||||
{
|
||||
_valuePtr->setValue(QVariant(QString::fromStdString(value)));
|
||||
}
|
||||
|
||||
void MaterialProperty::setBoolean(bool value)
|
||||
{
|
||||
_valuePtr->setValue(QVariant(value));
|
||||
@@ -1545,13 +1550,21 @@ Material& Material::operator=(const App::Material& other)
|
||||
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;
|
||||
getAppearanceProperty(QLatin1String("AmbientColor"))->setColor(other.ambientColor);
|
||||
getAppearanceProperty(QLatin1String("DiffuseColor"))->setColor(other.diffuseColor);
|
||||
getAppearanceProperty(QLatin1String("SpecularColor"))->setColor(other.specularColor);
|
||||
getAppearanceProperty(QLatin1String("EmissiveColor"))->setColor(other.emissiveColor);
|
||||
getAppearanceProperty(QLatin1String("Shininess"))->setFloat(other.shininess);
|
||||
getAppearanceProperty(QLatin1String("Transparency"))->setFloat(other.transparency);
|
||||
|
||||
if (!other.image.empty() || !other.imagePath.empty()) {
|
||||
if (!hasAppearanceModel(ModelUUIDs::ModelUUID_Rendering_Texture)) {
|
||||
addAppearance(ModelUUIDs::ModelUUID_Rendering_Texture);
|
||||
}
|
||||
|
||||
getAppearanceProperty(QLatin1String("TextureImage"))->setString(other.image);
|
||||
getAppearanceProperty(QLatin1String("TexturePath"))->setString(other.imagePath);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -1641,33 +1654,46 @@ 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();
|
||||
if (hasAppearanceProperty(QLatin1String("AmbientColor"))) {
|
||||
material.ambientColor = getAppearanceProperty(QLatin1String("AmbientColor"))->getColor();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("DiffuseColor"))) {
|
||||
material.diffuseColor =
|
||||
getAppearanceProperty(QString::fromLatin1("DiffuseColor"))->getColor();
|
||||
if (hasAppearanceProperty(QLatin1String("DiffuseColor"))) {
|
||||
material.diffuseColor = getAppearanceProperty(QLatin1String("DiffuseColor"))->getColor();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("SpecularColor"))) {
|
||||
material.specularColor =
|
||||
getAppearanceProperty(QString::fromLatin1("SpecularColor"))->getColor();
|
||||
if (hasAppearanceProperty(QLatin1String("SpecularColor"))) {
|
||||
material.specularColor = getAppearanceProperty(QLatin1String("SpecularColor"))->getColor();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("EmissiveColor"))) {
|
||||
material.emissiveColor =
|
||||
getAppearanceProperty(QString::fromLatin1("EmissiveColor"))->getColor();
|
||||
if (hasAppearanceProperty(QLatin1String("EmissiveColor"))) {
|
||||
material.emissiveColor = getAppearanceProperty(QLatin1String("EmissiveColor"))->getColor();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("Shininess"))) {
|
||||
material.shininess = getAppearanceProperty(QString::fromLatin1("Shininess"))->getFloat();
|
||||
if (hasAppearanceProperty(QLatin1String("Shininess"))) {
|
||||
material.shininess = getAppearanceProperty(QLatin1String("Shininess"))->getFloat();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("Transparency"))) {
|
||||
material.transparency =
|
||||
getAppearanceProperty(QString::fromLatin1("Transparency"))->getFloat();
|
||||
if (hasAppearanceProperty(QLatin1String("Transparency"))) {
|
||||
material.transparency = getAppearanceProperty(QLatin1String("Transparency"))->getFloat();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QLatin1String("TextureImage"))) {
|
||||
auto property = getAppearanceProperty(QLatin1String("TextureImage"));
|
||||
if (!property->isNull()) {
|
||||
Base::Console().Log("Has 'TextureImage'\n");
|
||||
material.image = property->getString().toStdString();
|
||||
}
|
||||
|
||||
custom = true;
|
||||
}
|
||||
else if (hasAppearanceProperty(QLatin1String("TexturePath"))) {
|
||||
auto property = getAppearanceProperty(QLatin1String("TexturePath"));
|
||||
if (!property->isNull()) {
|
||||
Base::Console().Log("Has 'TexturePath'\n");
|
||||
material.imagePath = property->getString().toStdString();
|
||||
}
|
||||
|
||||
custom = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ public:
|
||||
void setValue(const QString& value);
|
||||
void setValue(const std::shared_ptr<MaterialValue>& value);
|
||||
void setString(const QString& value);
|
||||
void setString(const std::string& value);
|
||||
void setBoolean(bool value);
|
||||
void setBoolean(int value);
|
||||
void setBoolean(const QString& value);
|
||||
|
||||
@@ -21,15 +21,23 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
#include <QImage>
|
||||
#include <QImageReader>
|
||||
|
||||
#include <Inventor/nodes/SoGroup.h>
|
||||
#include <Inventor/nodes/SoMaterial.h>
|
||||
#include <Inventor/nodes/SoOrthographicCamera.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/nodes/SoSphere.h>
|
||||
#include <Inventor/nodes/SoSwitch.h>
|
||||
#include <Inventor/nodes/SoTexture2.h>
|
||||
#endif
|
||||
|
||||
#include <Inventor/nodes/SoTextureCoordinateEnvironment.h>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/Parameter.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
|
||||
#include "AppearancePreview.h"
|
||||
|
||||
@@ -123,11 +131,24 @@ AppearancePreview::AppearancePreview(QWidget* parent)
|
||||
// setBackground();
|
||||
setEnabledNaviCube(false);
|
||||
|
||||
auto root = dynamic_cast<SoSeparator*>(getSceneGraph());
|
||||
_group = dynamic_cast<SoSeparator*>(getSceneGraph());
|
||||
_group->ref();
|
||||
|
||||
_switch = new SoSwitch();
|
||||
_switch->ref();
|
||||
_material = new SoMaterial();
|
||||
_material->ref();
|
||||
root->addChild(_material);
|
||||
root->addChild(new SoSphere());
|
||||
_texture = new SoTexture2();
|
||||
_texture->ref();
|
||||
_environment = new SoTextureCoordinateEnvironment();
|
||||
_environment->ref();
|
||||
|
||||
_switch->addChild(_material);
|
||||
_switch->addChild(_texture);
|
||||
_switch->whichChild.setValue(0);
|
||||
|
||||
_group->addChild(_switch);
|
||||
_group->addChild(new SoSphere());
|
||||
|
||||
setCameraType(SoOrthographicCamera::getClassTypeId());
|
||||
setViewDirection(SbVec3f(1, 1, -5));
|
||||
@@ -136,8 +157,30 @@ AppearancePreview::AppearancePreview(QWidget* parent)
|
||||
|
||||
AppearancePreview::~AppearancePreview()
|
||||
{
|
||||
if (_switch) {
|
||||
if (_switch->findChild(_material) > -1) {
|
||||
_switch->removeChild(_material);
|
||||
}
|
||||
if (_switch->findChild(_texture) > -1) {
|
||||
_switch->removeChild(_texture);
|
||||
}
|
||||
}
|
||||
if (_group) {
|
||||
if (_group->findChild(_switch) > -1) {
|
||||
_group->removeChild(_switch);
|
||||
}
|
||||
}
|
||||
|
||||
_group->unref();
|
||||
_group = nullptr;
|
||||
_switch->unref();
|
||||
_switch = nullptr;
|
||||
_material->unref();
|
||||
_material = nullptr;
|
||||
_texture->unref();
|
||||
_texture = nullptr;
|
||||
_environment->unref();
|
||||
_environment = nullptr;
|
||||
}
|
||||
|
||||
void AppearancePreview::applySettings()
|
||||
@@ -148,8 +191,19 @@ void AppearancePreview::applySettings()
|
||||
viewSettings->applySettings();
|
||||
}
|
||||
|
||||
void AppearancePreview::setCoinTexture()
|
||||
{
|
||||
_switch->whichChild.setValue(1);
|
||||
}
|
||||
|
||||
void AppearancePreview::setCoinMaterial()
|
||||
{
|
||||
_switch->whichChild.setValue(0);
|
||||
}
|
||||
|
||||
void AppearancePreview::setAmbientColor(const QColor& color)
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->ambientColor.setValue(
|
||||
SbColor(color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0));
|
||||
_material->ambientColor.setDefault(false);
|
||||
@@ -157,6 +211,7 @@ void AppearancePreview::setAmbientColor(const QColor& color)
|
||||
|
||||
void AppearancePreview::setDiffuseColor(const QColor& color)
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->diffuseColor.setValue(
|
||||
SbColor(color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0));
|
||||
_material->diffuseColor.setDefault(false);
|
||||
@@ -164,6 +219,7 @@ void AppearancePreview::setDiffuseColor(const QColor& color)
|
||||
|
||||
void AppearancePreview::setSpecularColor(const QColor& color)
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->specularColor.setValue(
|
||||
SbColor(color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0));
|
||||
_material->specularColor.setDefault(false);
|
||||
@@ -171,6 +227,7 @@ void AppearancePreview::setSpecularColor(const QColor& color)
|
||||
|
||||
void AppearancePreview::setEmissiveColor(const QColor& color)
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->emissiveColor.setValue(
|
||||
SbColor(color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0));
|
||||
_material->emissiveColor.setDefault(false);
|
||||
@@ -178,48 +235,74 @@ void AppearancePreview::setEmissiveColor(const QColor& color)
|
||||
|
||||
void AppearancePreview::setShininess(double value)
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->shininess.setValue(value);
|
||||
_material->shininess.setDefault(false);
|
||||
}
|
||||
|
||||
void AppearancePreview::setTransparency(double value)
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->transparency.setValue(value);
|
||||
_material->transparency.setDefault(false);
|
||||
}
|
||||
|
||||
void AppearancePreview::setTexture(const QImage& image)
|
||||
{
|
||||
setCoinTexture();
|
||||
|
||||
SoSFImage texture;
|
||||
Gui::BitmapFactory().convert(image, texture);
|
||||
_texture->image = texture;
|
||||
}
|
||||
|
||||
void AppearancePreview::setTextureScaling(double scale)
|
||||
{}
|
||||
|
||||
void AppearancePreview::resetAmbientColor()
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->ambientColor.deleteValues(0);
|
||||
_material->ambientColor.setDefault(true);
|
||||
}
|
||||
|
||||
void AppearancePreview::resetDiffuseColor()
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->diffuseColor.deleteValues(0);
|
||||
_material->diffuseColor.setDefault(true);
|
||||
}
|
||||
|
||||
void AppearancePreview::resetSpecularColor()
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->specularColor.deleteValues(0);
|
||||
_material->specularColor.setDefault(true);
|
||||
}
|
||||
|
||||
void AppearancePreview::resetEmissiveColor()
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->emissiveColor.deleteValues(0);
|
||||
_material->emissiveColor.setDefault(true);
|
||||
}
|
||||
|
||||
void AppearancePreview::resetShininess()
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->shininess.deleteValues(0);
|
||||
_material->shininess.setDefault(true);
|
||||
}
|
||||
|
||||
void AppearancePreview::resetTransparency()
|
||||
{
|
||||
setCoinMaterial();
|
||||
_material->transparency.deleteValues(0);
|
||||
_material->transparency.setDefault(true);
|
||||
}
|
||||
|
||||
void AppearancePreview::resetTexture()
|
||||
{}
|
||||
|
||||
void AppearancePreview::resetTextureScaling()
|
||||
{}
|
||||
|
||||
@@ -26,7 +26,11 @@
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
#include <Gui/View3DSettings.h>
|
||||
|
||||
class SoGroup;
|
||||
class SoMaterial;
|
||||
class SoSwitch;
|
||||
class SoTexture2;
|
||||
class SoTextureCoordinateEnvironment;
|
||||
|
||||
namespace MatGui
|
||||
{
|
||||
@@ -57,6 +61,8 @@ public:
|
||||
void setEmissiveColor(const QColor& color);
|
||||
void setShininess(double value);
|
||||
void setTransparency(double value);
|
||||
void setTexture(const QImage& image);
|
||||
void setTextureScaling(double scale);
|
||||
|
||||
void resetAmbientColor();
|
||||
void resetDiffuseColor();
|
||||
@@ -64,12 +70,20 @@ public:
|
||||
void resetEmissiveColor();
|
||||
void resetShininess();
|
||||
void resetTransparency();
|
||||
void resetTexture();
|
||||
void resetTextureScaling();
|
||||
|
||||
private:
|
||||
SoSeparator* _group;
|
||||
SoSwitch* _switch;
|
||||
SoMaterial* _material;
|
||||
SoTexture2* _texture;
|
||||
SoTextureCoordinateEnvironment* _environment;
|
||||
std::unique_ptr<AppearanceSettings> viewSettings;
|
||||
|
||||
void applySettings();
|
||||
void setCoinTexture();
|
||||
void setCoinMaterial();
|
||||
};
|
||||
|
||||
} // namespace MatGui
|
||||
|
||||
@@ -369,7 +369,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Shape Appearance:</string>
|
||||
<string>Custom Appearance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -401,7 +401,7 @@
|
||||
<widget class="Gui::ColorButton" name="buttonLineColor"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="buttonUserDefinedMaterial">
|
||||
<widget class="QPushButton" name="buttonCustomAppearance">
|
||||
<property name="text">
|
||||
<string notr="true">...</string>
|
||||
</property>
|
||||
|
||||
@@ -167,7 +167,6 @@ DlgDisplayPropertiesImp::DlgDisplayPropertiesImp(bool floating, QWidget* parent,
|
||||
|
||||
std::vector<Gui::ViewProvider*> views = getSelection();
|
||||
setDisplayModes(views);
|
||||
setMaterial(views);
|
||||
setColorPlot(views);
|
||||
setShapeAppearance(views);
|
||||
setLineColor(views);
|
||||
@@ -276,10 +275,10 @@ void DlgDisplayPropertiesImp::setupConnections()
|
||||
qOverload<int>(&QSpinBox::valueChanged),
|
||||
this,
|
||||
&DlgDisplayPropertiesImp::onSpinLineTransparencyValueChanged);
|
||||
connect(d->ui.buttonUserDefinedMaterial,
|
||||
connect(d->ui.buttonCustomAppearance,
|
||||
&Gui::ColorButton::clicked,
|
||||
this,
|
||||
&DlgDisplayPropertiesImp::onButtonUserDefinedMaterialClicked);
|
||||
&DlgDisplayPropertiesImp::onbuttonCustomAppearanceClicked);
|
||||
connect(d->ui.buttonColorPlot,
|
||||
&Gui::ColorButton::clicked,
|
||||
this,
|
||||
@@ -309,7 +308,6 @@ void DlgDisplayPropertiesImp::OnChange(Gui::SelectionSingleton::SubjectType& rCa
|
||||
|| Reason.Type == Gui::SelectionChanges::ClrSelection) {
|
||||
std::vector<Gui::ViewProvider*> views = getSelection();
|
||||
setDisplayModes(views);
|
||||
setMaterial(views);
|
||||
setColorPlot(views);
|
||||
setShapeAppearance(views);
|
||||
setLineColor(views);
|
||||
@@ -357,15 +355,10 @@ void DlgDisplayPropertiesImp::slotChangedObject(const Gui::ViewProvider& obj,
|
||||
}
|
||||
}
|
||||
else if (prop.isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
//auto& value = static_cast<const App::PropertyMaterialList&>(prop).getValue();
|
||||
if (prop_name == "ShapeAppearance") {
|
||||
// Base::Console().Log("slotChangeObject(ShapeAppearance)\n");
|
||||
// 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);
|
||||
auto& values = static_cast<const App::PropertyMaterialList&>(prop).getValues();
|
||||
auto& material = values[0];
|
||||
d->ui.widgetMaterial->setMaterial(QString::fromStdString(material.uuid));
|
||||
}
|
||||
}
|
||||
else if (prop.isDerivedFrom<App::PropertyInteger>()) {
|
||||
@@ -419,10 +412,10 @@ void DlgDisplayPropertiesImp::reject()
|
||||
/**
|
||||
* Opens a dialog that allows to modify the 'ShapeMaterial' property of all selected view providers.
|
||||
*/
|
||||
void DlgDisplayPropertiesImp::onButtonUserDefinedMaterialClicked()
|
||||
void DlgDisplayPropertiesImp::onbuttonCustomAppearanceClicked()
|
||||
{
|
||||
std::vector<Gui::ViewProvider*> Provider = getSelection();
|
||||
Gui::Dialog::DlgMaterialPropertiesImp dlg("ShapeMaterial", this);
|
||||
Gui::Dialog::DlgMaterialPropertiesImp dlg("ShapeAppearance", this);
|
||||
dlg.setViewProviders(Provider);
|
||||
dlg.exec();
|
||||
|
||||
@@ -586,25 +579,6 @@ void DlgDisplayPropertiesImp::setDisplayModes(const std::vector<Gui::ViewProvide
|
||||
}
|
||||
}
|
||||
|
||||
void DlgDisplayPropertiesImp::setMaterial(const std::vector<Gui::ViewProvider*>& views)
|
||||
{
|
||||
Q_UNUSED(views);
|
||||
// bool material = false;
|
||||
// App::Material mat = App::Material(App::Material::DEFAULT);
|
||||
// for (auto view : views) {
|
||||
// if (auto* prop =
|
||||
// dynamic_cast<App::PropertyMaterial*>(view->getPropertyByName("ShapeMaterial"))) {
|
||||
// mat = prop->getValue();
|
||||
// material = mat.uuid.empty();
|
||||
// if (!material) {
|
||||
// d->ui.widgetMaterial->setMaterial(QString::fromStdString(mat.uuid));
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// d->ui.buttonUserDefinedMaterial->setEnabled(material);
|
||||
}
|
||||
|
||||
void DlgDisplayPropertiesImp::setColorPlot(const std::vector<Gui::ViewProvider*>& views)
|
||||
{
|
||||
bool material = false;
|
||||
@@ -627,16 +601,13 @@ void DlgDisplayPropertiesImp::setShapeAppearance(const std::vector<Gui::ViewProv
|
||||
for (auto view : views) {
|
||||
if (auto* prop =
|
||||
dynamic_cast<App::PropertyMaterialList*>(view->getPropertyByName("ShapeAppearance"))) {
|
||||
material = true;
|
||||
mat = prop->getValues()[0];
|
||||
material = mat.uuid.empty();
|
||||
if (!material) {
|
||||
d->ui.widgetMaterial->setMaterial(QString::fromStdString(mat.uuid));
|
||||
}
|
||||
d->ui.widgetMaterial->setMaterial(QString::fromStdString(mat.uuid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// d->ui.buttonUserDefinedMaterial->setEnabled(material);
|
||||
d->ui.buttonUserDefinedMaterial->setEnabled(true);
|
||||
d->ui.buttonCustomAppearance->setEnabled(material);
|
||||
}
|
||||
|
||||
void DlgDisplayPropertiesImp::setLineColor(const std::vector<Gui::ViewProvider*>& views)
|
||||
@@ -694,21 +665,7 @@ void DlgDisplayPropertiesImp::onMaterialSelected(
|
||||
for (auto it : Provider) {
|
||||
if (auto* prop = dynamic_cast<App::PropertyMaterialList*>(
|
||||
it->getPropertyByName("ShapeAppearance"))) {
|
||||
App::Material mat;
|
||||
mat.ambientColor =
|
||||
material->getAppearanceProperty(QString::fromLatin1("AmbientColor"))->getColor();
|
||||
mat.diffuseColor =
|
||||
material->getAppearanceProperty(QString::fromLatin1("DiffuseColor"))->getColor();
|
||||
mat.emissiveColor =
|
||||
material->getAppearanceProperty(QString::fromLatin1("EmissiveColor"))->getColor();
|
||||
mat.specularColor =
|
||||
material->getAppearanceProperty(QString::fromLatin1("SpecularColor"))->getColor();
|
||||
mat.shininess =
|
||||
material->getAppearanceProperty(QString::fromLatin1("Shininess"))->getFloat();
|
||||
mat.transparency =
|
||||
material->getAppearanceProperty(QString::fromLatin1("Transparency"))->getFloat();
|
||||
mat.uuid = material->getUUID().toStdString();
|
||||
prop->setValue(mat);
|
||||
prop->setValue(material->getMaterialAppearance());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ private Q_SLOTS:
|
||||
void onButtonPointColorChanged();
|
||||
void onSpinLineWidthValueChanged(int);
|
||||
void onSpinLineTransparencyValueChanged(int);
|
||||
void onButtonUserDefinedMaterialClicked();
|
||||
void onbuttonCustomAppearanceClicked();
|
||||
void onButtonColorPlotClicked();
|
||||
void onMaterialSelected(const std::shared_ptr<Materials::Material>& material);
|
||||
|
||||
@@ -87,7 +87,6 @@ private:
|
||||
void setupFilters();
|
||||
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*>&);
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/DlgMaterialPropertiesImp.h>
|
||||
#include <Gui/DockWindowManager.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/Selection.h>
|
||||
|
||||
@@ -285,9 +285,19 @@ QModelIndex MaterialTreeWidget::findInTree(const QString& uuid)
|
||||
|
||||
void MaterialTreeWidget::setMaterial(const QString& uuid)
|
||||
{
|
||||
if (uuid.isEmpty() || uuid == m_uuid) {
|
||||
if (uuid == m_uuid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (uuid.isEmpty()) {
|
||||
// Nothing is selected
|
||||
QItemSelectionModel* selectionModel = m_materialTree->selectionModel();
|
||||
selectionModel->clear();
|
||||
m_material->clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
updateMaterial(uuid);
|
||||
|
||||
// Now select the material in the tree
|
||||
@@ -634,6 +644,11 @@ void MaterialTreeWidget::onSelectMaterial(const QItemSelection& selected,
|
||||
{
|
||||
Q_UNUSED(deselected);
|
||||
|
||||
if (selected.isEmpty()) {
|
||||
m_uuid.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the UUID before changing the underlying data model
|
||||
QString uuid;
|
||||
auto model = dynamic_cast<QStandardItemModel*>(m_materialTree->model());
|
||||
|
||||
@@ -89,7 +89,7 @@ void MaterialsEditor::setup()
|
||||
Gui::WaitCursor wc;
|
||||
ui->setupUi(this);
|
||||
|
||||
_warningIcon = QIcon(QString::fromStdString(":/icons/Warning.svg"));
|
||||
_warningIcon = QIcon(QLatin1String(":/icons/Warning.svg"));
|
||||
|
||||
getFavorites();
|
||||
getRecents();
|
||||
@@ -108,7 +108,7 @@ void MaterialsEditor::setup()
|
||||
|
||||
resize(width, height);
|
||||
|
||||
ui->buttonURL->setIcon(QIcon(QString::fromStdString(":/icons/internet-web-browser.svg")));
|
||||
ui->buttonURL->setIcon(QIcon(QLatin1String(":/icons/internet-web-browser.svg")));
|
||||
|
||||
connect(ui->standardButtons->button(QDialogButtonBox::Ok),
|
||||
&QPushButton::clicked,
|
||||
@@ -491,7 +491,7 @@ void MaterialsEditor::setMaterialDefaults()
|
||||
const char* name = App::licenseItems.at(index).at(App::posnOfFullName);
|
||||
// const char* url = App::licenseItems.at(index).at(App::posnOfUrl);
|
||||
// std::string licenseUrl = (paramGrp->GetASCII("prefLicenseUrl", url));
|
||||
_material->setLicense(QString::fromStdString(name));
|
||||
_material->setLicense(QLatin1String(name));
|
||||
|
||||
// Empty materials will have no parent
|
||||
_materialManager.dereference(_material);
|
||||
@@ -894,54 +894,120 @@ void MaterialsEditor::refreshMaterialTree()
|
||||
fillMaterialTree();
|
||||
}
|
||||
|
||||
void MaterialsEditor::updatePreview() const
|
||||
bool MaterialsEditor::updateTexturePreview() const
|
||||
{
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("AmbientColor"))) {
|
||||
QString color = _material->getAppearanceValueString(QString::fromStdString("AmbientColor"));
|
||||
bool hasImage = false;
|
||||
QImage image;
|
||||
double scaling = 99.0;
|
||||
if (_material->hasModel(Materials::ModelUUIDs::ModelUUID_Rendering_Texture)) {
|
||||
// First try loading an embedded image
|
||||
try {
|
||||
auto property = _material->getAppearanceProperty(QLatin1String("TextureImage"));
|
||||
if (!property->isNull()) {
|
||||
// Base::Console().Log("Has 'TextureImage'\n");
|
||||
auto propertyValue = property->getString();
|
||||
if (!propertyValue.isEmpty()) {
|
||||
QByteArray by = QByteArray::fromBase64(propertyValue.toUtf8());
|
||||
image = QImage::fromData(by, "PNG"); //.scaled(64, 64, Qt::KeepAspectRatio);
|
||||
hasImage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const Materials::PropertyNotFound&) {
|
||||
}
|
||||
|
||||
// If no embedded image, load from a path
|
||||
if (!hasImage) {
|
||||
try {
|
||||
auto property = _material->getAppearanceProperty(QLatin1String("TexturePath"));
|
||||
if (!property->isNull()) {
|
||||
// Base::Console().Log("Has 'TexturePath'\n");
|
||||
auto filePath = property->getString();
|
||||
if (!image.load(filePath)) {
|
||||
Base::Console().Log("Unable to load image '%s'\n",
|
||||
filePath.toStdString().c_str());
|
||||
// return; // ???
|
||||
}
|
||||
hasImage = true;
|
||||
}
|
||||
}
|
||||
catch (const Materials::PropertyNotFound&) {
|
||||
}
|
||||
}
|
||||
|
||||
// Apply any scaling
|
||||
try {
|
||||
auto property = _material->getAppearanceProperty(QLatin1String("TextureScaling"));
|
||||
if (!property->isNull()) {
|
||||
scaling = property->getFloat();
|
||||
// Base::Console().Log("Has 'TextureScaling' = %g\n", scaling);
|
||||
}
|
||||
}
|
||||
catch (const Materials::PropertyNotFound&) {
|
||||
}
|
||||
|
||||
if (hasImage) {
|
||||
_rendered->setTexture(image);
|
||||
}
|
||||
}
|
||||
|
||||
return hasImage;
|
||||
}
|
||||
|
||||
bool MaterialsEditor::updateMaterialPreview() const
|
||||
{
|
||||
if (_material->hasAppearanceProperty(QLatin1String("AmbientColor"))) {
|
||||
QString color = _material->getAppearanceValueString(QLatin1String("AmbientColor"));
|
||||
_rendered->setAmbientColor(getColorHash(color, 255));
|
||||
}
|
||||
else {
|
||||
_rendered->resetAmbientColor();
|
||||
}
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("DiffuseColor"))) {
|
||||
QString color = _material->getAppearanceValueString(QString::fromStdString("DiffuseColor"));
|
||||
if (_material->hasAppearanceProperty(QLatin1String("DiffuseColor"))) {
|
||||
QString color = _material->getAppearanceValueString(QLatin1String("DiffuseColor"));
|
||||
_rendered->setDiffuseColor(getColorHash(color, 255));
|
||||
}
|
||||
else {
|
||||
_rendered->resetDiffuseColor();
|
||||
}
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("SpecularColor"))) {
|
||||
QString color =
|
||||
_material->getAppearanceValueString(QString::fromStdString("SpecularColor"));
|
||||
if (_material->hasAppearanceProperty(QLatin1String("SpecularColor"))) {
|
||||
QString color = _material->getAppearanceValueString(QLatin1String("SpecularColor"));
|
||||
_rendered->setSpecularColor(getColorHash(color, 255));
|
||||
}
|
||||
else {
|
||||
_rendered->resetSpecularColor();
|
||||
}
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("EmissiveColor"))) {
|
||||
QString color =
|
||||
_material->getAppearanceValueString(QString::fromStdString("EmissiveColor"));
|
||||
if (_material->hasAppearanceProperty(QLatin1String("EmissiveColor"))) {
|
||||
QString color = _material->getAppearanceValueString(QLatin1String("EmissiveColor"));
|
||||
_rendered->setEmissiveColor(getColorHash(color, 255));
|
||||
}
|
||||
else {
|
||||
_rendered->resetEmissiveColor();
|
||||
}
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("Shininess"))) {
|
||||
double value =
|
||||
_material->getAppearanceValue(QString::fromStdString("Shininess")).toDouble();
|
||||
if (_material->hasAppearanceProperty(QLatin1String("Shininess"))) {
|
||||
double value = _material->getAppearanceValue(QLatin1String("Shininess")).toDouble();
|
||||
_rendered->setShininess(value);
|
||||
}
|
||||
else {
|
||||
_rendered->resetShininess();
|
||||
}
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("Transparency"))) {
|
||||
double value =
|
||||
_material->getAppearanceValue(QString::fromStdString("Transparency")).toDouble();
|
||||
if (_material->hasAppearanceProperty(QLatin1String("Transparency"))) {
|
||||
double value = _material->getAppearanceValue(QLatin1String("Transparency")).toDouble();
|
||||
_rendered->setTransparency(value);
|
||||
}
|
||||
else {
|
||||
_rendered->resetTransparency();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MaterialsEditor::updatePreview() const
|
||||
{
|
||||
if (updateTexturePreview()) {
|
||||
return;
|
||||
}
|
||||
updateMaterialPreview();
|
||||
}
|
||||
|
||||
QString MaterialsEditor::getColorHash(const QString& colorString, int colorRange)
|
||||
@@ -1108,12 +1174,12 @@ QString MaterialsEditor::libraryPath(const std::shared_ptr<Materials::Material>&
|
||||
QString path;
|
||||
auto library = material->getLibrary();
|
||||
if (library) {
|
||||
path = QString::fromStdString("/%1/%2")
|
||||
path = QString::fromLatin1("/%1/%2")
|
||||
.arg(material->getLibrary()->getName())
|
||||
.arg(material->getDirectory());
|
||||
}
|
||||
else {
|
||||
path = QString::fromStdString("%1").arg(material->getDirectory());
|
||||
path = QString::fromLatin1("%1").arg(material->getDirectory());
|
||||
}
|
||||
|
||||
return path;
|
||||
|
||||
@@ -152,6 +152,8 @@ private:
|
||||
void onInheritNew(bool checked);
|
||||
|
||||
void setMaterialDefaults();
|
||||
bool updateTexturePreview() const;
|
||||
bool updateMaterialPreview() const;
|
||||
void updatePreview() const;
|
||||
static QString getColorHash(const QString& colorString, int colorRange = 255);
|
||||
|
||||
|
||||
@@ -61,10 +61,10 @@
|
||||
#include <Gui/QtAll.h>
|
||||
#endif
|
||||
|
||||
// // Inventor includes OpenGL
|
||||
// #ifndef __InventorAll__
|
||||
// # include <Gui/InventorAll.h>
|
||||
// #endif
|
||||
// Inventor includes OpenGL
|
||||
#ifndef __InventorAll__
|
||||
# include <Gui/InventorAll.h>
|
||||
#endif
|
||||
|
||||
#endif //_PreComp_
|
||||
|
||||
|
||||
@@ -35,8 +35,9 @@ AppearanceModel:
|
||||
Type: 'File'
|
||||
Units: ''
|
||||
URL: ''
|
||||
Description: "Path to file containing a texture image. Only used if TextureImage is unpopulated"
|
||||
Description: "Path to file containing a texture image. Only used if Texture Image is unpopulated"
|
||||
TextureImage:
|
||||
DisplayName: "Texture Image"
|
||||
Type: 'Image'
|
||||
Units: ''
|
||||
URL: ''
|
||||
|
||||
@@ -378,7 +378,7 @@ void Tessellation::setFaceColors(int method, App::Document* doc, App::DocumentOb
|
||||
auto svp = Base::freecad_dynamic_cast<PartGui::ViewProviderPartExt>(
|
||||
Gui::Application::Instance->getViewProvider(obj));
|
||||
if (vpmesh && svp) {
|
||||
std::vector<App::Color> diff_col = svp->DiffuseColor.getValues();
|
||||
std::vector<App::Color> diff_col = svp->ShapeAppearance.getDiffuseColors();
|
||||
if (ui->groupsFaceColors->isChecked()) {
|
||||
diff_col = getUniqueColors(diff_col);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
* as published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* for detail see the LICENCE text file. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with FreeCAD; if not, write to the Free Software *
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
* Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
* as published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* for detail see the LICENCE text file. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with FreeCAD; if not, write to the Free Software *
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
@@ -92,13 +92,15 @@ void loadPartResource()
|
||||
Gui::Translator::instance()->refresh();
|
||||
}
|
||||
|
||||
namespace PartGui {
|
||||
class Module : public Py::ExtensionModule<Module>
|
||||
namespace PartGui
|
||||
{
|
||||
class Module: public Py::ExtensionModule<Module>
|
||||
{
|
||||
public:
|
||||
Module() : Py::ExtensionModule<Module>("PartGui")
|
||||
Module()
|
||||
: Py::ExtensionModule<Module>("PartGui")
|
||||
{
|
||||
initialize("This module is the PartGui module."); // register with Python
|
||||
initialize("This module is the PartGui module."); // register with Python
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -106,10 +108,11 @@ private:
|
||||
|
||||
PyObject* initModule()
|
||||
{
|
||||
return Base::Interpreter().addModule(new Module);;
|
||||
return Base::Interpreter().addModule(new Module);
|
||||
;
|
||||
}
|
||||
|
||||
} // namespace PartGui
|
||||
} // namespace PartGui
|
||||
|
||||
PyMOD_INIT_FUNC(PartGui)
|
||||
{
|
||||
@@ -123,7 +126,7 @@ PyMOD_INIT_FUNC(PartGui)
|
||||
Base::Interpreter().runString("import Part");
|
||||
Base::Interpreter().runString("import MatGui");
|
||||
}
|
||||
catch(const Base::Exception& e) {
|
||||
catch (const Base::Exception& e) {
|
||||
PyErr_SetString(PyExc_ImportError, e.what());
|
||||
PyMOD_Return(nullptr);
|
||||
}
|
||||
@@ -137,13 +140,15 @@ PyMOD_INIT_FUNC(PartGui)
|
||||
Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/parametric"));
|
||||
Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/tools"));
|
||||
|
||||
static struct PyModuleDef pAttachEngineTextsModuleDef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"AttachEngineResources",
|
||||
"AttachEngineResources", -1,
|
||||
AttacherGui::AttacherGuiPy::Methods,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
static struct PyModuleDef pAttachEngineTextsModuleDef = {PyModuleDef_HEAD_INIT,
|
||||
"AttachEngineResources",
|
||||
"AttachEngineResources",
|
||||
-1,
|
||||
AttacherGui::AttacherGuiPy::Methods,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr};
|
||||
PyObject* pAttachEngineTextsModule = PyModule_Create(&pAttachEngineTextsModuleDef);
|
||||
|
||||
Py_INCREF(pAttachEngineTextsModule);
|
||||
@@ -220,23 +225,31 @@ PyMOD_INIT_FUNC(PartGui)
|
||||
CreateSimplePartCommands();
|
||||
CreateParamPartCommands();
|
||||
CreatePartSelectCommands();
|
||||
try{
|
||||
Py::Object ae = Base::Interpreter().runStringObject("__import__('AttachmentEditor.Commands').Commands");
|
||||
Py::Module(partGuiModule).setAttr(std::string("AttachmentEditor"),ae);
|
||||
} catch (Base::PyException &err){
|
||||
try {
|
||||
Py::Object ae =
|
||||
Base::Interpreter().runStringObject("__import__('AttachmentEditor.Commands').Commands");
|
||||
Py::Module(partGuiModule).setAttr(std::string("AttachmentEditor"), ae);
|
||||
}
|
||||
catch (Base::PyException& err) {
|
||||
err.ReportException();
|
||||
}
|
||||
|
||||
// register preferences pages
|
||||
Gui::Dialog::DlgPreferencesImp::setGroupData("Part/Part Design", "Part design", QObject::tr("Part and Part Design workbench"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgSettingsGeneral>(QT_TRANSLATE_NOOP("QObject", "Part/Part Design"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgSettings3DViewPart>(QT_TRANSLATE_NOOP("QObject", "Part/Part Design"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgSettingsObjectColor>(QT_TRANSLATE_NOOP("QObject", "Part/Part Design"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgImportExportIges>(QT_TRANSLATE_NOOP("QObject", "Import-Export"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgImportExportStep>(QT_TRANSLATE_NOOP("QObject", "Import-Export"));
|
||||
Gui::ViewProviderBuilder::add(
|
||||
Part::PropertyPartShape::getClassTypeId(),
|
||||
PartGui::ViewProviderPart::getClassTypeId());
|
||||
Gui::Dialog::DlgPreferencesImp::setGroupData("Part/Part Design",
|
||||
"Part design",
|
||||
QObject::tr("Part and Part Design workbench"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgSettingsGeneral>(
|
||||
QT_TRANSLATE_NOOP("QObject", "Part/Part Design"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgSettings3DViewPart>(
|
||||
QT_TRANSLATE_NOOP("QObject", "Part/Part Design"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgSettingsObjectColor>(
|
||||
QT_TRANSLATE_NOOP("QObject", "Part/Part Design"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgImportExportIges>(
|
||||
QT_TRANSLATE_NOOP("QObject", "Import-Export"));
|
||||
(void)new Gui::PrefPageProducer<PartGui::DlgImportExportStep>(
|
||||
QT_TRANSLATE_NOOP("QObject", "Import-Export"));
|
||||
Gui::ViewProviderBuilder::add(Part::PropertyPartShape::getClassTypeId(),
|
||||
PartGui::ViewProviderPart::getClassTypeId());
|
||||
|
||||
// add resources and reloads the translators
|
||||
loadPartResource();
|
||||
|
||||
@@ -31,6 +31,8 @@ list(APPEND PartGui_LIBS
|
||||
${QtConcurrent_LIBRARIES}
|
||||
)
|
||||
|
||||
generate_from_xml(ViewProviderExtPy)
|
||||
|
||||
set (Part_TR_QRC ${CMAKE_CURRENT_BINARY_DIR}/Resources/Part_translation.qrc)
|
||||
qt_find_and_add_translation(QM_SRCS "Resources/translations/*_*.ts"
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Resources/translations)
|
||||
@@ -61,7 +63,7 @@ set(PartGui_UIC_SRCS
|
||||
DlgProjectionOnSurface.ui
|
||||
SectionCutting.ui
|
||||
ShapeFromMesh.ui
|
||||
TaskFaceColors.ui
|
||||
TaskFaceAppearances.ui
|
||||
TaskShapeBuilder.ui
|
||||
TaskLoft.ui
|
||||
TaskOffset.ui
|
||||
@@ -69,9 +71,16 @@ set(PartGui_UIC_SRCS
|
||||
TaskAttacher.ui
|
||||
)
|
||||
|
||||
SET(Python_SRCS
|
||||
ViewProviderExtPy.xml
|
||||
ViewProviderExtPyImp.cpp
|
||||
)
|
||||
SOURCE_GROUP("Python" FILES ${Python_SRCS})
|
||||
|
||||
SET(PartGui_SRCS
|
||||
${PartGui_QRC_SRCS}
|
||||
${PartGui_UIC_HDRS}
|
||||
${Python_SRCS}
|
||||
AppPartGui.cpp
|
||||
AttacherTexts.h
|
||||
AttacherTexts.cpp
|
||||
@@ -224,9 +233,9 @@ SET(PartGui_SRCS
|
||||
SectionCutting.ui
|
||||
ShapeFromMesh.cpp
|
||||
ShapeFromMesh.h
|
||||
TaskFaceColors.cpp
|
||||
TaskFaceColors.h
|
||||
TaskFaceColors.ui
|
||||
TaskFaceAppearances.cpp
|
||||
TaskFaceAppearances.h
|
||||
TaskFaceAppearances.ui
|
||||
TaskShapeBuilder.cpp
|
||||
TaskShapeBuilder.h
|
||||
TaskShapeBuilder.ui
|
||||
|
||||
@@ -2112,7 +2112,7 @@ void CmdColorPerFace::activated(int iMsg)
|
||||
return;
|
||||
PartGui::ViewProviderPartExt* vp = dynamic_cast<PartGui::ViewProviderPartExt*>(Gui::Application::Instance->getViewProvider(sel.front()));
|
||||
if (vp)
|
||||
vp->changeFaceColors();
|
||||
vp->changeFaceAppearances();
|
||||
}
|
||||
|
||||
bool CmdColorPerFace::isActive()
|
||||
|
||||
@@ -720,34 +720,38 @@ void PartGui::DlgProjectionOnSurface::higlight_object(Part::Feature* iCurrentObj
|
||||
auto vp = dynamic_cast<PartGui::ViewProviderPartExt*>(
|
||||
Gui::Application::Instance->getViewProvider(iCurrentObject));
|
||||
if (vp) {
|
||||
std::vector<App::Color> colors;
|
||||
App::Color defaultColor;
|
||||
App::Color aColor;
|
||||
aColor.setPackedValue(iColor);
|
||||
if (currentShapeType == TopAbs_FACE) {
|
||||
colors = vp->DiffuseColor.getValues();
|
||||
defaultColor = vp->ShapeAppearance.getDiffuseColor();
|
||||
std::vector<App::Material> colors = vp->ShapeAppearance.getValues();
|
||||
App::Color defaultColor = vp->ShapeAppearance.getDiffuseColor();
|
||||
|
||||
if (static_cast<Standard_Integer>(colors.size()) != anIndices.Extent()) {
|
||||
colors.resize(anIndices.Extent(), vp->ShapeAppearance[0]);
|
||||
}
|
||||
|
||||
if (iHighlight) {
|
||||
colors.at(index - 1).diffuseColor = aColor;
|
||||
}
|
||||
else {
|
||||
colors.at(index - 1).diffuseColor = defaultColor;
|
||||
}
|
||||
vp->ShapeAppearance.setValues(colors);
|
||||
}
|
||||
else if (currentShapeType == TopAbs_EDGE) {
|
||||
colors = vp->LineColorArray.getValues();
|
||||
defaultColor = vp->LineColor.getValue();
|
||||
}
|
||||
std::vector<App::Color> colors = vp->LineColorArray.getValues();
|
||||
App::Color defaultColor = vp->LineColor.getValue();
|
||||
|
||||
if (static_cast<Standard_Integer>(colors.size()) != anIndices.Extent()) {
|
||||
colors.resize(anIndices.Extent(), defaultColor);
|
||||
}
|
||||
if (static_cast<Standard_Integer>(colors.size()) != anIndices.Extent()) {
|
||||
colors.resize(anIndices.Extent(), defaultColor);
|
||||
}
|
||||
|
||||
if (iHighlight) {
|
||||
App::Color aColor;
|
||||
aColor.setPackedValue(iColor);
|
||||
colors.at(index - 1) = aColor;
|
||||
}
|
||||
else {
|
||||
colors.at(index - 1) = defaultColor;
|
||||
}
|
||||
if (currentShapeType == TopAbs_FACE) {
|
||||
vp->DiffuseColor.setValues(colors);
|
||||
}
|
||||
else if (currentShapeType == TopAbs_EDGE) {
|
||||
vp->LineColorArray.setValues(colors);
|
||||
if (iHighlight) {
|
||||
colors.at(index - 1) = aColor;
|
||||
}
|
||||
else {
|
||||
colors.at(index - 1) = defaultColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,6 +210,17 @@ void ReferenceHighlighter::getFaceColor(const std::string& element, std::vector<
|
||||
colors[pos] = elementColor;
|
||||
}
|
||||
|
||||
void ReferenceHighlighter::getFaceColor(const std::string& element,
|
||||
std::vector<App::Material>& materials) const
|
||||
{
|
||||
int idx = std::stoi(element.substr(4)) - 1;
|
||||
assert(idx >= 0);
|
||||
std::size_t pos = std::size_t(idx);
|
||||
if (pos < materials.size()) {
|
||||
materials[pos].diffuseColor = elementColor;
|
||||
}
|
||||
}
|
||||
|
||||
void ReferenceHighlighter::getFaceColors(const std::vector<std::string>& elements,
|
||||
std::vector<App::Color>& colors) const
|
||||
{
|
||||
@@ -226,3 +237,24 @@ void ReferenceHighlighter::getFaceColors(const std::vector<std::string>& element
|
||||
std::fill(colors.begin(), colors.end(), objectColor);
|
||||
}
|
||||
}
|
||||
|
||||
void ReferenceHighlighter::getFaceMaterials(const std::vector<std::string>& elements,
|
||||
std::vector<App::Material>& materials) const
|
||||
{
|
||||
App::Material defaultMaterial;
|
||||
materials.resize(fMap.Extent(), defaultMaterial);
|
||||
|
||||
if (!elements.empty()) {
|
||||
for (const std::string& e : elements) {
|
||||
if (boost::starts_with(e, "Face")) {
|
||||
getFaceColor(e, materials);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (auto& material : materials) {
|
||||
material.diffuseColor = objectColor;
|
||||
}
|
||||
// std::fill(materials.begin(), materials.end(), objectColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,14 @@ public:
|
||||
*/
|
||||
void getFaceColors(const std::vector<std::string>& elements,
|
||||
std::vector<App::Color>& colors) const;
|
||||
/*!
|
||||
* \brief getFaceMaterials
|
||||
* \param elements The sub-element names. If this list is empty \a materials will be filled with
|
||||
* the default color. \param materials The size of the \a materials array is equal to the number
|
||||
* of faces of the shape
|
||||
*/
|
||||
void getFaceMaterials(const std::vector<std::string>& elements,
|
||||
std::vector<App::Material>& materials) const;
|
||||
|
||||
private:
|
||||
void getVertexColor(const std::string& element, std::vector<App::Color>& colors) const;
|
||||
@@ -89,6 +97,7 @@ private:
|
||||
void getEdgeColorsOfWire(const std::string& element, std::vector<App::Color>& colors) const;
|
||||
void getEdgeColorsOfFace(const std::string& element, std::vector<App::Color>& colors) const;
|
||||
void getFaceColor(const std::string& element, std::vector<App::Color>& colors) const;
|
||||
void getFaceColor(const std::string& element, std::vector<App::Material>& materials) const;
|
||||
|
||||
private:
|
||||
App::Color defaultColor;
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <App/Document.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Control.h>
|
||||
#include <Gui/DlgMaterialPropertiesImp.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Selection.h>
|
||||
@@ -54,8 +55,10 @@
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
|
||||
#include "TaskFaceColors.h"
|
||||
#include "ui_TaskFaceColors.h"
|
||||
#include <Mod/Material/Gui/MaterialTreeWidget.h>
|
||||
|
||||
#include "TaskFaceAppearances.h"
|
||||
#include "ui_TaskFaceAppearances.h"
|
||||
#include "SoBrepFaceSet.h"
|
||||
#include "ViewProviderExt.h"
|
||||
|
||||
@@ -84,23 +87,23 @@ namespace PartGui {
|
||||
};
|
||||
}
|
||||
|
||||
class FaceColors::Private
|
||||
class FaceAppearances::Private
|
||||
{
|
||||
public:
|
||||
using Connection = boost::signals2::connection;
|
||||
Ui_TaskFaceColors* ui;
|
||||
Ui_TaskFaceAppearances* ui;
|
||||
QPointer<Gui::View3DInventorViewer> view;
|
||||
ViewProviderPartExt* vp;
|
||||
App::DocumentObject* obj;
|
||||
Gui::Document* doc;
|
||||
std::vector<App::Color> perface;
|
||||
std::vector<App::Material> perface;
|
||||
QSet<int> index;
|
||||
bool boxSelection;
|
||||
Connection connectDelDoc;
|
||||
Connection connectDelObj;
|
||||
Connection connectUndoDoc;
|
||||
|
||||
explicit Private(ViewProviderPartExt* vp) : ui(new Ui_TaskFaceColors()), view(nullptr), vp(vp)
|
||||
explicit Private(ViewProviderPartExt* vp) : ui(new Ui_TaskFaceAppearances()), view(nullptr), vp(vp)
|
||||
{
|
||||
obj = vp->getObject();
|
||||
doc = Gui::Application::Instance->getDocument(obj->getDocument());
|
||||
@@ -113,9 +116,7 @@ public:
|
||||
xp.Next();
|
||||
}
|
||||
|
||||
std::vector<App::Color> current = vp->DiffuseColor.getValues();
|
||||
if (current.empty())
|
||||
current.push_back(vp->ShapeAppearance.getDiffuseColor());
|
||||
std::vector<App::Material> current = vp->ShapeAppearance.getValues();
|
||||
perface = current;
|
||||
perface.resize(mapOfShape.Extent(), perface.front());
|
||||
|
||||
@@ -220,7 +221,7 @@ public:
|
||||
polygon.Add(Base::Vector2d(it[0], it[1]));
|
||||
}
|
||||
|
||||
FaceColors* self = static_cast<FaceColors*>(ud);
|
||||
FaceAppearances* self = static_cast<FaceAppearances*>(ud);
|
||||
self->d->view = nullptr;
|
||||
if (self->d->obj && self->d->obj->isDerivedFrom<Part::Feature>()) {
|
||||
cb->setHandled();
|
||||
@@ -235,9 +236,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/* TRANSLATOR PartGui::TaskFaceColors */
|
||||
/* TRANSLATOR PartGui::TaskFaceAppearances */
|
||||
|
||||
FaceColors::FaceColors(ViewProviderPartExt* vp, QWidget* parent)
|
||||
FaceAppearances::FaceAppearances(ViewProviderPartExt* vp, QWidget* parent)
|
||||
: d(new Private(vp))
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
@@ -245,23 +246,22 @@ FaceColors::FaceColors(ViewProviderPartExt* vp, QWidget* parent)
|
||||
setupConnections();
|
||||
|
||||
d->ui->groupBox->setTitle(QString::fromUtf8(vp->getObject()->Label.getValue()));
|
||||
d->ui->colorButton->setDisabled(true);
|
||||
d->ui->colorButton->setAllowTransparency(true);
|
||||
d->ui->buttonCustomAppearance->setDisabled(true);
|
||||
|
||||
FaceSelection* gate = new FaceSelection(d->vp->getObject());
|
||||
Gui::Selection().addSelectionGate(gate);
|
||||
|
||||
//NOLINTBEGIN
|
||||
d->connectDelDoc = Gui::Application::Instance->signalDeleteDocument.connect(std::bind
|
||||
(&FaceColors::slotDeleteDocument, this, sp::_1));
|
||||
(&FaceAppearances::slotDeleteDocument, this, sp::_1));
|
||||
d->connectDelObj = Gui::Application::Instance->signalDeletedObject.connect(std::bind
|
||||
(&FaceColors::slotDeleteObject, this, sp::_1));
|
||||
(&FaceAppearances::slotDeleteObject, this, sp::_1));
|
||||
d->connectUndoDoc = d->doc->signalUndoDocument.connect(std::bind
|
||||
(&FaceColors::slotUndoDocument, this, sp::_1));
|
||||
(&FaceAppearances::slotUndoDocument, this, sp::_1));
|
||||
//NOLINTEND
|
||||
}
|
||||
|
||||
FaceColors::~FaceColors()
|
||||
FaceAppearances::~FaceAppearances()
|
||||
{
|
||||
if (d->view) {
|
||||
d->view->stopSelection();
|
||||
@@ -276,17 +276,23 @@ FaceColors::~FaceColors()
|
||||
delete d;
|
||||
}
|
||||
|
||||
void FaceColors::setupConnections()
|
||||
void FaceAppearances::setupConnections()
|
||||
{
|
||||
connect(d->ui->colorButton, &Gui::ColorButton::changed,
|
||||
this, &FaceColors::onColorButtonChanged);
|
||||
connect(d->ui->defaultButton, &QPushButton::clicked,
|
||||
this, &FaceColors::onDefaultButtonClicked);
|
||||
this, &FaceAppearances::onDefaultButtonClicked);
|
||||
connect(d->ui->boxSelection, &QPushButton::toggled,
|
||||
this, &FaceColors::onBoxSelectionToggled);
|
||||
this, &FaceAppearances::onBoxSelectionToggled);
|
||||
connect(d->ui->widgetMaterial,
|
||||
&MatGui::MaterialTreeWidget::materialSelected,
|
||||
this,
|
||||
&FaceAppearances::onMaterialSelected);
|
||||
connect(d->ui->buttonCustomAppearance,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&FaceAppearances::onButtonCustomAppearanceClicked);
|
||||
}
|
||||
|
||||
void FaceColors::slotUndoDocument(const Gui::Document& Doc)
|
||||
void FaceAppearances::slotUndoDocument(const Gui::Document& Doc)
|
||||
{
|
||||
if (d->doc == &Doc) {
|
||||
d->doc->resetEdit();
|
||||
@@ -294,19 +300,19 @@ void FaceColors::slotUndoDocument(const Gui::Document& Doc)
|
||||
}
|
||||
}
|
||||
|
||||
void FaceColors::slotDeleteDocument(const Gui::Document& Doc)
|
||||
void FaceAppearances::slotDeleteDocument(const Gui::Document& Doc)
|
||||
{
|
||||
if (d->doc == &Doc)
|
||||
Gui::Control().closeDialog();
|
||||
}
|
||||
|
||||
void FaceColors::slotDeleteObject(const Gui::ViewProvider& obj)
|
||||
void FaceAppearances::slotDeleteObject(const Gui::ViewProvider& obj)
|
||||
{
|
||||
if (d->vp == &obj)
|
||||
Gui::Control().closeDialog();
|
||||
}
|
||||
|
||||
void FaceColors::onBoxSelectionToggled(bool checked)
|
||||
void FaceAppearances::onBoxSelectionToggled(bool checked)
|
||||
{
|
||||
Gui::View3DInventor* view = qobject_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow());
|
||||
// toggle the button state and feature
|
||||
@@ -330,28 +336,26 @@ void FaceColors::onBoxSelectionToggled(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void FaceColors::onDefaultButtonClicked()
|
||||
void FaceAppearances::onDefaultButtonClicked()
|
||||
{
|
||||
std::fill(d->perface.begin(), d->perface.end(), d->vp->ShapeAppearance.getDiffuseColor());
|
||||
d->vp->DiffuseColor.setValues(d->perface);
|
||||
std::fill(d->perface.begin(), d->perface.end(), d->vp->ShapeAppearance[0]);
|
||||
d->vp->ShapeAppearance.setValues(d->perface);
|
||||
}
|
||||
|
||||
void FaceColors::onColorButtonChanged()
|
||||
void FaceAppearances::onMaterialSelected(const std::shared_ptr<Materials::Material>& material)
|
||||
{
|
||||
if (!d->index.isEmpty()) {
|
||||
QColor color = d->ui->colorButton->color();
|
||||
for (int it : d->index) {
|
||||
// alpha of App::Color is contrary to the one of QColor
|
||||
d->perface[it].set(color.redF(), color.greenF(), color.blueF(), (1.0 - color.alphaF()));
|
||||
d->perface[it] = material->getMaterialAppearance();
|
||||
}
|
||||
d->vp->DiffuseColor.setValues(d->perface);
|
||||
d->vp->ShapeAppearance.setValues(d->perface);
|
||||
// new color has been applied, unselect so that users can see this
|
||||
onSelectionChanged(Gui::SelectionChanges::ClrSelection);
|
||||
Gui::Selection().clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void FaceColors::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
void FaceAppearances::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
{
|
||||
// no object selected in the combobox or no sub-element was selected
|
||||
if (!msg.pSubName)
|
||||
@@ -366,11 +370,10 @@ void FaceColors::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
if (docname == msg.pDocName && objname == msg.pObjectName) {
|
||||
int index = std::atoi(msg.pSubName + 4) - 1;
|
||||
d->index.insert(index);
|
||||
const App::Color& faceColor = d->perface[index];
|
||||
const App::Color& faceColor = d->perface[index].diffuseColor;
|
||||
QColor color;
|
||||
// alpha of App::Color is contrary to the one of QColor
|
||||
color.setRgbF(faceColor.r, faceColor.g, faceColor.b, (1.0 - faceColor.a));
|
||||
d->ui->colorButton->setColor(color);
|
||||
selection_changed = true;
|
||||
}
|
||||
}
|
||||
@@ -394,7 +397,7 @@ void FaceColors::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
}
|
||||
}
|
||||
|
||||
void FaceColors::updatePanel()
|
||||
void FaceAppearances::updatePanel()
|
||||
{
|
||||
QString faces = QString::fromLatin1("[");
|
||||
int size = d->index.size();
|
||||
@@ -412,16 +415,39 @@ void FaceColors::updatePanel()
|
||||
}
|
||||
|
||||
d->ui->labelElement->setText(faces);
|
||||
d->ui->colorButton->setDisabled(d->index.isEmpty());
|
||||
d->ui->buttonCustomAppearance->setDisabled(d->index.isEmpty());
|
||||
}
|
||||
|
||||
void FaceColors::open()
|
||||
/**
|
||||
* Opens a dialog that allows to modify the 'ShapeMaterial' property of all selected view providers.
|
||||
*/
|
||||
void FaceAppearances::onButtonCustomAppearanceClicked()
|
||||
{
|
||||
std::vector<Gui::ViewProvider*> Provider;
|
||||
Provider.push_back(d->vp);
|
||||
Gui::Dialog::DlgFaceMaterialPropertiesImp dlg("ShapeAppearance", this);
|
||||
dlg.setViewProviders(Provider);
|
||||
dlg.exec();
|
||||
|
||||
// Set the face appearance
|
||||
if (!d->index.isEmpty()) {
|
||||
for (int it : d->index) {
|
||||
d->perface[it] = dlg.getCustomAppearance();
|
||||
}
|
||||
d->vp->ShapeAppearance.setValues(d->perface);
|
||||
// new color has been applied, unselect so that users can see this
|
||||
onSelectionChanged(Gui::SelectionChanges::ClrSelection);
|
||||
Gui::Selection().clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void FaceAppearances::open()
|
||||
{
|
||||
Gui::Document* doc = Gui::Application::Instance->getDocument(d->vp->getObject()->getDocument());
|
||||
doc->openCommand(QT_TRANSLATE_NOOP("Command", "Change face colors"));
|
||||
}
|
||||
|
||||
bool FaceColors::accept()
|
||||
bool FaceAppearances::accept()
|
||||
{
|
||||
Gui::Document* doc = Gui::Application::Instance->getDocument(d->vp->getObject()->getDocument());
|
||||
doc->commitCommand();
|
||||
@@ -429,7 +455,7 @@ bool FaceColors::accept()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FaceColors::reject()
|
||||
bool FaceAppearances::reject()
|
||||
{
|
||||
Gui::Document* doc = Gui::Application::Instance->getDocument(d->vp->getObject()->getDocument());
|
||||
doc->abortCommand();
|
||||
@@ -437,7 +463,7 @@ bool FaceColors::reject()
|
||||
return true;
|
||||
}
|
||||
|
||||
void FaceColors::changeEvent(QEvent* e)
|
||||
void FaceAppearances::changeEvent(QEvent* e)
|
||||
{
|
||||
QWidget::changeEvent(e);
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
@@ -446,33 +472,33 @@ void FaceColors::changeEvent(QEvent* e)
|
||||
}
|
||||
|
||||
|
||||
/* TRANSLATOR PartGui::TaskFaceColors */
|
||||
/* TRANSLATOR PartGui::TaskFaceAppearances */
|
||||
|
||||
TaskFaceColors::TaskFaceColors(ViewProviderPartExt* vp)
|
||||
TaskFaceAppearances::TaskFaceAppearances(ViewProviderPartExt* vp)
|
||||
{
|
||||
widget = new FaceColors(vp);
|
||||
widget = new FaceAppearances(vp);
|
||||
addTaskBox(widget);
|
||||
}
|
||||
|
||||
TaskFaceColors::~TaskFaceColors() = default;
|
||||
TaskFaceAppearances::~TaskFaceAppearances() = default;
|
||||
|
||||
void TaskFaceColors::open()
|
||||
void TaskFaceAppearances::open()
|
||||
{
|
||||
widget->open();
|
||||
}
|
||||
|
||||
void TaskFaceColors::clicked(int)
|
||||
void TaskFaceAppearances::clicked(int)
|
||||
{
|
||||
}
|
||||
|
||||
bool TaskFaceColors::accept()
|
||||
bool TaskFaceAppearances::accept()
|
||||
{
|
||||
return widget->accept();
|
||||
}
|
||||
|
||||
bool TaskFaceColors::reject()
|
||||
bool TaskFaceAppearances::reject()
|
||||
{
|
||||
return widget->reject();
|
||||
}
|
||||
|
||||
#include "moc_TaskFaceColors.cpp"
|
||||
#include "moc_TaskFaceAppearances.cpp"
|
||||
@@ -31,17 +31,21 @@ namespace Gui {
|
||||
class ViewProvider;
|
||||
}
|
||||
|
||||
namespace Materials {
|
||||
class Material;
|
||||
}
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
class ViewProviderPartExt;
|
||||
|
||||
class FaceColors : public QWidget, public Gui::SelectionObserver
|
||||
class FaceAppearances : public QWidget, public Gui::SelectionObserver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FaceColors(ViewProviderPartExt* vp, QWidget* parent = nullptr);
|
||||
~FaceColors() override;
|
||||
explicit FaceAppearances(ViewProviderPartExt* vp, QWidget* parent = nullptr);
|
||||
~FaceAppearances() override;
|
||||
|
||||
void open();
|
||||
bool accept();
|
||||
@@ -49,9 +53,10 @@ public:
|
||||
|
||||
private:
|
||||
void setupConnections();
|
||||
void onColorButtonChanged();
|
||||
void onMaterialSelected(const std::shared_ptr<Materials::Material>& material);
|
||||
void onDefaultButtonClicked();
|
||||
void onBoxSelectionToggled(bool checked);
|
||||
void onButtonCustomAppearanceClicked();
|
||||
|
||||
protected:
|
||||
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
|
||||
@@ -66,13 +71,13 @@ private:
|
||||
Private* d;
|
||||
};
|
||||
|
||||
class TaskFaceColors : public Gui::TaskView::TaskDialog
|
||||
class TaskFaceAppearances : public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TaskFaceColors(ViewProviderPartExt* vp);
|
||||
~TaskFaceColors() override;
|
||||
explicit TaskFaceAppearances(ViewProviderPartExt* vp);
|
||||
~TaskFaceAppearances() override;
|
||||
|
||||
public:
|
||||
void open() override;
|
||||
@@ -84,7 +89,7 @@ public:
|
||||
{ return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; }
|
||||
|
||||
private:
|
||||
FaceColors* widget;
|
||||
FaceAppearances* widget;
|
||||
};
|
||||
|
||||
} //namespace PartGui
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PartGui::TaskFaceColors</class>
|
||||
<widget class="QWidget" name="PartGui::TaskFaceColors">
|
||||
<class>PartGui::TaskFaceAppearances</class>
|
||||
<widget class="QWidget" name="PartGui::TaskFaceAppearances">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>247</width>
|
||||
<height>143</height>
|
||||
<height>219</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Set color per face</string>
|
||||
<string>Set appearance per face</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
@@ -26,57 +26,57 @@
|
||||
<property name="title">
|
||||
<string notr="true">Group box</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="faceLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Faces:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="faceLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Faces:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelElement">
|
||||
<property name="text">
|
||||
<string notr="true">[]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLabel" name="labelElement">
|
||||
<property name="text">
|
||||
<string notr="true">[]</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="MatGui::MaterialTreeWidget" name="widgetMaterial" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="Gui::ColorButton" name="colorButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>146</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>160</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="buttonCustomAppearance">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelCustomAppearance">
|
||||
<property name="text">
|
||||
<string>Custom Appearance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -136,9 +136,10 @@ by dragging a selection rectangle in the 3D view</string>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::ColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>Gui/Widgets.h</header>
|
||||
<class>MatGui::MaterialTreeWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>Mod/Material/Gui/MaterialTreeWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
@@ -71,6 +71,20 @@ void ViewProviderPart::applyColor(const Part::ShapeHistory& hist,
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderPart::applyMaterial(const Part::ShapeHistory& hist,
|
||||
const App::PropertyMaterialList& colBase,
|
||||
std::vector<App::Material>& colBool)
|
||||
{
|
||||
std::map<int, std::vector<int>>::const_iterator jt;
|
||||
// apply color from modified faces
|
||||
for (jt = hist.shapeMap.begin(); jt != hist.shapeMap.end(); ++jt) {
|
||||
std::vector<int>::const_iterator kt;
|
||||
for (kt = jt->second.begin(); kt != jt->second.end(); ++kt) {
|
||||
colBool[*kt] = colBase[jt->first];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderPart::applyTransparency(const float& transparency,
|
||||
std::vector<App::Color>& colors)
|
||||
{
|
||||
@@ -85,6 +99,20 @@ void ViewProviderPart::applyTransparency(const float& transparency,
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderPart::applyTransparency(const float& transparency, std::vector<App::Material>& colors)
|
||||
{
|
||||
if (transparency != 0.0) {
|
||||
// transparency has been set object-wide
|
||||
std::vector<App::Material>::iterator j;
|
||||
for (j = colors.begin(); j != colors.end(); ++j) {
|
||||
// transparency hasn't been set for this face
|
||||
if (j->transparency == 0.0) {
|
||||
j->transparency = transparency / 100.0; // transparency comes in percent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ViewProviderShapeBuilder::buildNodes(const App::Property* , std::vector<SoNode*>& ) const
|
||||
|
||||
@@ -57,8 +57,13 @@ protected:
|
||||
void applyColor(const Part::ShapeHistory& hist,
|
||||
const std::vector<App::Color>& colBase,
|
||||
std::vector<App::Color>& colBool);
|
||||
void applyMaterial(const Part::ShapeHistory& hist,
|
||||
const App::PropertyMaterialList& colBase,
|
||||
std::vector<App::Material>& colBool);
|
||||
void applyTransparency(const float& transparency,
|
||||
std::vector<App::Color>& colors);
|
||||
void applyTransparency(const float& transparency,
|
||||
std::vector<App::Material>& colors);
|
||||
};
|
||||
|
||||
} // namespace PartGui
|
||||
|
||||
@@ -100,27 +100,27 @@ void ViewProviderBoolean::updateData(const App::Property* prop)
|
||||
auto vpTool = dynamic_cast<PartGui::ViewProviderPart*>(
|
||||
Gui::Application::Instance->getViewProvider(objTool));
|
||||
if (vpBase && vpTool) {
|
||||
std::vector<App::Color> colBase = vpBase->DiffuseColor.getValues();
|
||||
std::vector<App::Color> colTool = vpTool->DiffuseColor.getValues();
|
||||
std::vector<App::Color> colBool;
|
||||
colBool.resize(boolMap.Extent(), this->ShapeAppearance.getDiffuseColor());
|
||||
applyTransparency(vpBase->Transparency.getValue(),colBase);
|
||||
applyTransparency(vpTool->Transparency.getValue(),colTool);
|
||||
std::vector<App::Material> colBool;
|
||||
colBool.resize(boolMap.Extent(), this->ShapeAppearance[0]);
|
||||
vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue());
|
||||
vpTool->ShapeAppearance.setTransparency(vpTool->Transparency.getValue());
|
||||
|
||||
if (static_cast<int>(colBase.size()) == baseMap.Extent()) {
|
||||
applyColor(hist[0], colBase, colBool);
|
||||
if (static_cast<int>(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) {
|
||||
applyMaterial(hist[0], vpBase->ShapeAppearance, colBool);
|
||||
}
|
||||
else if (!colBase.empty() && colBase[0] != this->ShapeAppearance.getDiffuseColor()) {
|
||||
colBase.resize(baseMap.Extent(), colBase[0]);
|
||||
applyColor(hist[0], colBase, colBool);
|
||||
else if (vpBase->ShapeAppearance.getSize() > 0
|
||||
&& vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) {
|
||||
vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]);
|
||||
applyMaterial(hist[0], vpBase->ShapeAppearance, colBool);
|
||||
}
|
||||
|
||||
if (static_cast<int>(colTool.size()) == toolMap.Extent()) {
|
||||
applyColor(hist[1], colTool, colBool);
|
||||
if (static_cast<int>(vpTool->ShapeAppearance.getSize()) == toolMap.Extent()) {
|
||||
applyMaterial(hist[1], vpTool->ShapeAppearance, colBool);
|
||||
}
|
||||
else if (!colTool.empty() && colTool[0] != this->ShapeAppearance.getDiffuseColor()) {
|
||||
colTool.resize(toolMap.Extent(), colTool[0]);
|
||||
applyColor(hist[1], colTool, colBool);
|
||||
else if (vpTool->ShapeAppearance.getSize() > 0
|
||||
&& vpTool->ShapeAppearance[0] != this->ShapeAppearance[0]) {
|
||||
vpTool->ShapeAppearance.setSize(toolMap.Extent(), vpTool->ShapeAppearance[0]);
|
||||
applyMaterial(hist[1], vpTool->ShapeAppearance, colBool);
|
||||
}
|
||||
|
||||
// If the view provider has set a transparency then override the values
|
||||
@@ -129,7 +129,7 @@ void ViewProviderBoolean::updateData(const App::Property* prop)
|
||||
applyTransparency(Transparency.getValue(), colBool);
|
||||
}
|
||||
|
||||
this->DiffuseColor.setValues(colBool);
|
||||
this->ShapeAppearance.setValues(colBool);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,8 +186,8 @@ void ViewProviderMultiFuse::updateData(const App::Property* prop)
|
||||
TopTools_IndexedMapOfShape boolMap;
|
||||
TopExp::MapShapes(boolShape, TopAbs_FACE, boolMap);
|
||||
|
||||
std::vector<App::Color> colBool;
|
||||
colBool.resize(boolMap.Extent(), this->ShapeAppearance.getDiffuseColor());
|
||||
std::vector<App::Material> colBool;
|
||||
colBool.resize(boolMap.Extent(), this->ShapeAppearance[0]);
|
||||
|
||||
int index=0;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = sources.begin(); it != sources.end(); ++it, ++index) {
|
||||
@@ -201,14 +201,14 @@ void ViewProviderMultiFuse::updateData(const App::Property* prop)
|
||||
|
||||
auto vpBase = dynamic_cast<PartGui::ViewProviderPart*>(Gui::Application::Instance->getViewProvider(objBase));
|
||||
if (vpBase) {
|
||||
std::vector<App::Color> colBase = vpBase->DiffuseColor.getValues();
|
||||
applyTransparency(vpBase->Transparency.getValue(),colBase);
|
||||
if (static_cast<int>(colBase.size()) == baseMap.Extent()) {
|
||||
applyColor(hist[index], colBase, colBool);
|
||||
vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue());
|
||||
if (static_cast<int>(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) {
|
||||
applyMaterial(hist[index], vpBase->ShapeAppearance, colBool);
|
||||
}
|
||||
else if (!colBase.empty() && colBase[0] != this->ShapeAppearance.getDiffuseColor()) {
|
||||
colBase.resize(baseMap.Extent(), colBase[0]);
|
||||
applyColor(hist[index], colBase, colBool);
|
||||
else if (vpBase->ShapeAppearance.getSize() > 0
|
||||
&& vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) {
|
||||
vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]);
|
||||
applyMaterial(hist[index], vpBase->ShapeAppearance, colBool);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +219,7 @@ void ViewProviderMultiFuse::updateData(const App::Property* prop)
|
||||
applyTransparency(Transparency.getValue(), colBool);
|
||||
}
|
||||
|
||||
this->DiffuseColor.setValues(colBool);
|
||||
this->ShapeAppearance.setValues(colBool);
|
||||
}
|
||||
else if (prop->isDerivedFrom<App::PropertyLinkList>()) {
|
||||
std::vector<App::DocumentObject*> pShapes = static_cast<const App::PropertyLinkList*>(prop)->getValues();
|
||||
@@ -321,8 +321,8 @@ void ViewProviderMultiCommon::updateData(const App::Property* prop)
|
||||
TopTools_IndexedMapOfShape boolMap;
|
||||
TopExp::MapShapes(boolShape, TopAbs_FACE, boolMap);
|
||||
|
||||
std::vector<App::Color> colBool;
|
||||
colBool.resize(boolMap.Extent(), this->ShapeAppearance.getDiffuseColor());
|
||||
std::vector<App::Material> colBool;
|
||||
colBool.resize(boolMap.Extent(), this->ShapeAppearance[0]);
|
||||
|
||||
int index=0;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = sources.begin(); it != sources.end(); ++it, ++index) {
|
||||
@@ -336,14 +336,14 @@ void ViewProviderMultiCommon::updateData(const App::Property* prop)
|
||||
|
||||
auto vpBase = dynamic_cast<PartGui::ViewProviderPart*>(Gui::Application::Instance->getViewProvider(objBase));
|
||||
if (vpBase) {
|
||||
std::vector<App::Color> colBase = vpBase->DiffuseColor.getValues();
|
||||
applyTransparency(vpBase->Transparency.getValue(),colBase);
|
||||
if (static_cast<int>(colBase.size()) == baseMap.Extent()) {
|
||||
applyColor(hist[index], colBase, colBool);
|
||||
vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue());
|
||||
if (static_cast<int>(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) {
|
||||
applyMaterial(hist[index], vpBase->ShapeAppearance, colBool);
|
||||
}
|
||||
else if (!colBase.empty() && colBase[0] != this->ShapeAppearance.getDiffuseColor()) {
|
||||
colBase.resize(baseMap.Extent(), colBase[0]);
|
||||
applyColor(hist[index], colBase, colBool);
|
||||
else if (vpBase->ShapeAppearance.getSize() > 0
|
||||
&& vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) {
|
||||
vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]);
|
||||
applyMaterial(hist[index], vpBase->ShapeAppearance, colBool);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,7 +354,7 @@ void ViewProviderMultiCommon::updateData(const App::Property* prop)
|
||||
applyTransparency(Transparency.getValue(), colBool);
|
||||
}
|
||||
|
||||
this->DiffuseColor.setValues(colBool);
|
||||
this->ShapeAppearance.setValues(colBool);
|
||||
}
|
||||
else if (prop->isDerivedFrom<App::PropertyLinkList>()) {
|
||||
std::vector<App::DocumentObject*> pShapes = static_cast<const App::PropertyLinkList*>(prop)->getValues();
|
||||
|
||||
@@ -95,8 +95,8 @@ void ViewProviderCompound::updateData(const App::Property* prop)
|
||||
TopTools_IndexedMapOfShape compMap;
|
||||
TopExp::MapShapes(compShape, TopAbs_FACE, compMap);
|
||||
|
||||
std::vector<App::Color> compCol;
|
||||
compCol.resize(compMap.Extent(), this->ShapeAppearance.getDiffuseColor());
|
||||
std::vector<App::Material> compCol;
|
||||
compCol.resize(compMap.Extent(), this->ShapeAppearance[0]);
|
||||
|
||||
int index=0;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = sources.begin(); it != sources.end(); ++it, ++index) {
|
||||
@@ -111,14 +111,14 @@ void ViewProviderCompound::updateData(const App::Property* prop)
|
||||
|
||||
auto vpBase = dynamic_cast<PartGui::ViewProviderPart*>(Gui::Application::Instance->getViewProvider(objBase));
|
||||
if (vpBase) {
|
||||
std::vector<App::Color> baseCol = vpBase->DiffuseColor.getValues();
|
||||
applyTransparency(vpBase->Transparency.getValue(),baseCol);
|
||||
if (static_cast<int>(baseCol.size()) == baseMap.Extent()) {
|
||||
applyColor(hist[index], baseCol, compCol);
|
||||
vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue());
|
||||
if (static_cast<int>(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) {
|
||||
applyMaterial(hist[index], vpBase->ShapeAppearance, compCol);
|
||||
}
|
||||
else if (!baseCol.empty() && baseCol[0] != this->ShapeAppearance.getDiffuseColor()) {
|
||||
baseCol.resize(baseMap.Extent(), baseCol[0]);
|
||||
applyColor(hist[index], baseCol, compCol);
|
||||
else if (vpBase->ShapeAppearance.getSize() > 0
|
||||
&& vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) {
|
||||
vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]);
|
||||
applyMaterial(hist[index], vpBase->ShapeAppearance, compCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,7 +129,7 @@ void ViewProviderCompound::updateData(const App::Property* prop)
|
||||
applyTransparency(Transparency.getValue(), compCol);
|
||||
}
|
||||
|
||||
this->DiffuseColor.setValues(compCol);
|
||||
this->ShapeAppearance.setValues(compCol);
|
||||
}
|
||||
else if (prop->isDerivedFrom<App::PropertyLinkList>()) {
|
||||
const std::vector<App::DocumentObject *>& pBases = static_cast<const App::PropertyLinkList*>(prop)->getValues();
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
# include <Inventor/nodes/SoPolygonOffset.h>
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoShapeHints.h>
|
||||
# include <Inventor/nodes/SoTexture3.h>
|
||||
|
||||
# include <boost/algorithm/string/predicate.hpp>
|
||||
#endif
|
||||
@@ -86,10 +87,11 @@
|
||||
#include <Mod/Part/App/Tools.h>
|
||||
|
||||
#include "ViewProviderExt.h"
|
||||
#include "ViewProviderPartExtPy.h"
|
||||
#include "SoBrepEdgeSet.h"
|
||||
#include "SoBrepFaceSet.h"
|
||||
#include "SoBrepPointSet.h"
|
||||
#include "TaskFaceColors.h"
|
||||
#include "TaskFaceAppearances.h"
|
||||
|
||||
|
||||
FC_LOG_LEVEL_INIT("Part", true, true)
|
||||
@@ -100,12 +102,12 @@ using namespace PartGui;
|
||||
namespace {
|
||||
float fromPercent(long value)
|
||||
{
|
||||
return static_cast<float>(value) / 100.0F;
|
||||
return std::roundf(value) / 100.0F;
|
||||
}
|
||||
|
||||
long toPercent(float value)
|
||||
{
|
||||
return static_cast<long>(100.0 * value + 0.5);
|
||||
return std::lround(100.0 * value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +177,6 @@ ViewProviderPartExt::ViewProviderPartExt()
|
||||
ADD_PROPERTY_TYPE(LineColor, (lmat.diffuseColor), osgroup, App::Prop_None, "Set object line color.");
|
||||
ADD_PROPERTY_TYPE(PointColor, (vmat.diffuseColor), osgroup, App::Prop_None, "Set object point color");
|
||||
ADD_PROPERTY_TYPE(PointColorArray, (PointColor.getValue()), osgroup, App::Prop_None, "Object point color array.");
|
||||
ADD_PROPERTY_TYPE(DiffuseColor,(ShapeAppearance.getDiffuseColors()), osgroup, App::Prop_None, "Object diffuse color.");
|
||||
ADD_PROPERTY_TYPE(LineColorArray,(LineColor.getValue()), osgroup, App::Prop_None, "Object line color array.");
|
||||
ADD_PROPERTY_TYPE(LineWidth,(lwidth), osgroup, App::Prop_None, "Set object line width.");
|
||||
LineWidth.setConstraints(&sizeRange);
|
||||
@@ -196,6 +197,16 @@ ViewProviderPartExt::ViewProviderPartExt()
|
||||
ADD_PROPERTY_TYPE(DrawStyle,((long int)0), osgroup, App::Prop_None, "Defines the style of the edges in the 3D view.");
|
||||
DrawStyle.setEnums(DrawStyleEnums);
|
||||
|
||||
// This is needed to restore old DiffuseColor values since the restore
|
||||
// function is asynchronous
|
||||
App::PropertyColor noColor;
|
||||
ADD_PROPERTY_TYPE(_diffuseColor,
|
||||
(noColor.getValue()),
|
||||
osgroup,
|
||||
App::Prop_NoPersist,
|
||||
"Object diffuse color.");
|
||||
_diffuseColor.setStatus(App::Property::PropHidden, true);
|
||||
|
||||
coords = new SoCoordinate3();
|
||||
coords->ref();
|
||||
faceset = new SoBrepFaceSet();
|
||||
@@ -210,6 +221,14 @@ ViewProviderPartExt::ViewProviderPartExt()
|
||||
nodeset = new SoBrepPointSet();
|
||||
nodeset->ref();
|
||||
|
||||
// Support for textured faces
|
||||
pcShapeTexture3D = new SoTexture3;
|
||||
pcShapeTexture3D->ref();
|
||||
pcShapeCoordinates = new SoCoordinate3;
|
||||
pcShapeCoordinates->ref();
|
||||
pcShapeFaceset = new SoIndexedFaceSet;
|
||||
pcShapeFaceset->ref();
|
||||
|
||||
pcFaceBind = new SoMaterialBinding();
|
||||
pcFaceBind->ref();
|
||||
|
||||
@@ -261,6 +280,19 @@ ViewProviderPartExt::~ViewProviderPartExt()
|
||||
normb->unref();
|
||||
lineset->unref();
|
||||
nodeset->unref();
|
||||
|
||||
pcShapeTexture3D->unref();
|
||||
pcShapeCoordinates->unref();
|
||||
pcShapeFaceset->unref();
|
||||
}
|
||||
|
||||
PyObject* ViewProviderPartExt::getPyObject()
|
||||
{
|
||||
if (!pyViewObject) {
|
||||
pyViewObject = new ViewProviderPartExtPy(this);
|
||||
}
|
||||
pyViewObject->IncRef();
|
||||
return pyViewObject;
|
||||
}
|
||||
|
||||
void ViewProviderPartExt::onChanged(const App::Property* prop)
|
||||
@@ -328,29 +360,20 @@ void ViewProviderPartExt::onChanged(const App::Property* prop)
|
||||
else if (prop == &LineColorArray) {
|
||||
setHighlightedEdges(LineColorArray.getValues());
|
||||
}
|
||||
else if (prop == &DiffuseColor) {
|
||||
setHighlightedFaces(DiffuseColor.getValues());
|
||||
else if (prop == &_diffuseColor) {
|
||||
// Used to load the old DiffuseColor values asynchronously
|
||||
ShapeAppearance.setDiffuseColors(_diffuseColor.getValues());
|
||||
ShapeAppearance.setTransparency(Transparency.getValue() / 100.0f);
|
||||
}
|
||||
else if (prop == &ShapeAppearance) {
|
||||
pcFaceBind->value = SoMaterialBinding::OVERALL;
|
||||
setHighlightedFaces(ShapeAppearance);
|
||||
ViewProviderGeometryObject::onChanged(prop);
|
||||
// While restoring a document do not override the
|
||||
// DiffuseColor that has already been restored
|
||||
if (!isRestoring()) {
|
||||
App::Color c = ShapeAppearance.getDiffuseColor();
|
||||
c.a = fromPercent(Transparency.getValue());
|
||||
DiffuseColor.setValue(c);
|
||||
}
|
||||
}
|
||||
else if (prop == &Transparency) {
|
||||
const App::Material& Mat = ShapeAppearance[0];
|
||||
long value = toPercent(Mat.transparency);
|
||||
if (value != Transparency.getValue()) {
|
||||
float trans = fromPercent(Transparency.getValue());
|
||||
auto colors = DiffuseColor.getValues();
|
||||
for (auto &c : colors)
|
||||
c.a = trans;
|
||||
DiffuseColor.setValues(colors);
|
||||
|
||||
App::PropertyContainer* parent = ShapeAppearance.getContainer();
|
||||
ShapeAppearance.setContainer(nullptr);
|
||||
@@ -380,12 +403,12 @@ void ViewProviderPartExt::onChanged(const App::Property* prop)
|
||||
updateVisual();
|
||||
// updateVisual() may not be triggered by any change (e.g.
|
||||
// triggered by an external object through forceUpdate()). And
|
||||
// since DiffuseColor is not changed here either, do not falsely set
|
||||
// since ShapeAppearance is not changed here either, do not falsely set
|
||||
// the document modified status
|
||||
Base::ObjectStatusLocker<App::Property::Status,App::Property> guard(
|
||||
App::Property::NoModify, &DiffuseColor);
|
||||
App::Property::NoModify, &ShapeAppearance);
|
||||
// The material has to be checked again (#0001736)
|
||||
onChanged(&DiffuseColor);
|
||||
onChanged(&ShapeAppearance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,7 +467,10 @@ void ViewProviderPartExt::attach(App::DocumentObject *pcFeat)
|
||||
// just faces with no edges or points
|
||||
pcFlatRoot->addChild(pShapeHints);
|
||||
pcFlatRoot->addChild(pcFaceBind);
|
||||
pcFlatRoot->addChild(pcShapeMaterial);
|
||||
pcFlatRoot->addChild(pcSwitchAppearance);
|
||||
pcTextureGroup3D->addChild(pcShapeTexture3D);
|
||||
pcTextureGroup3D->addChild(pcShapeCoordinates);
|
||||
pcTextureGroup3D->addChild(pcShapeFaceset);
|
||||
SoDrawStyle* pcFaceStyle = new SoDrawStyle();
|
||||
pcFaceStyle->style = SoDrawStyle::FILLED;
|
||||
pcFlatRoot->addChild(pcFaceStyle);
|
||||
@@ -599,69 +625,89 @@ std::vector<Base::Vector3d> ViewProviderPartExt::getSelectionShape(const char* /
|
||||
return {};
|
||||
}
|
||||
|
||||
void ViewProviderPartExt::setHighlightedFaces(const std::vector<App::Color>& colors)
|
||||
void ViewProviderPartExt::setHighlightedFaces(const std::vector<App::Material>& materials)
|
||||
{
|
||||
if (getObject() && getObject()->testStatus(App::ObjectStatus::TouchOnColorChange))
|
||||
getObject()->touch(true);
|
||||
|
||||
Gui::SoUpdateVBOAction action;
|
||||
action.apply(this->faceset);
|
||||
|
||||
int size = static_cast<int>(colors.size());
|
||||
if (size > 1 && size == this->faceset->partIndex.getNum()) {
|
||||
pcFaceBind->value = SoMaterialBinding::PER_PART;
|
||||
pcShapeMaterial->diffuseColor.setNum(size);
|
||||
pcShapeMaterial->transparency.setNum(size);
|
||||
SbColor* ca = pcShapeMaterial->diffuseColor.startEditing();
|
||||
float *t = pcShapeMaterial->transparency.startEditing();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ca[i].setValue(colors[i].r, colors[i].g, colors[i].b);
|
||||
t[i] = colors[i].a;
|
||||
}
|
||||
pcShapeMaterial->diffuseColor.finishEditing();
|
||||
pcShapeMaterial->transparency.finishEditing();
|
||||
}
|
||||
else if (colors.size() == 1) {
|
||||
pcFaceBind->value = SoMaterialBinding::OVERALL;
|
||||
pcShapeMaterial->diffuseColor.setValue(colors[0].r, colors[0].g, colors[0].b);
|
||||
pcShapeMaterial->transparency = Transparency.getValue()/100.f;
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderPartExt::setHighlightedFaces(const std::vector<App::Material>& colors)
|
||||
{
|
||||
int size = static_cast<int>(colors.size());
|
||||
int size = static_cast<int>(materials.size());
|
||||
if (size > 1 && size == this->faceset->partIndex.getNum()) {
|
||||
pcFaceBind->value = SoMaterialBinding::PER_PART;
|
||||
activateMaterial();
|
||||
|
||||
pcShapeMaterial->diffuseColor.setNum(size);
|
||||
pcShapeMaterial->ambientColor.setNum(size);
|
||||
pcShapeMaterial->specularColor.setNum(size);
|
||||
pcShapeMaterial->emissiveColor.setNum(size);
|
||||
pcShapeMaterial->shininess.setNum(size);
|
||||
|
||||
SbColor* dc = pcShapeMaterial->diffuseColor.startEditing();
|
||||
SbColor* ac = pcShapeMaterial->ambientColor.startEditing();
|
||||
SbColor* sc = pcShapeMaterial->specularColor.startEditing();
|
||||
SbColor* ec = pcShapeMaterial->emissiveColor.startEditing();
|
||||
float* sh = pcShapeMaterial->shininess.startEditing();
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
dc[i].setValue(colors[i].diffuseColor.r, colors[i].diffuseColor.g, colors[i].diffuseColor.b);
|
||||
ac[i].setValue(colors[i].ambientColor.r, colors[i].ambientColor.g, colors[i].ambientColor.b);
|
||||
sc[i].setValue(colors[i].specularColor.r, colors[i].specularColor.g, colors[i].specularColor.b);
|
||||
ec[i].setValue(colors[i].emissiveColor.r, colors[i].emissiveColor.g, colors[i].emissiveColor.b);
|
||||
dc[i].setValue(materials[i].diffuseColor.r, materials[i].diffuseColor.g, materials[i].diffuseColor.b);
|
||||
ac[i].setValue(materials[i].ambientColor.r, materials[i].ambientColor.g, materials[i].ambientColor.b);
|
||||
sc[i].setValue(materials[i].specularColor.r, materials[i].specularColor.g, materials[i].specularColor.b);
|
||||
ec[i].setValue(materials[i].emissiveColor.r, materials[i].emissiveColor.g, materials[i].emissiveColor.b);
|
||||
sh[i] = materials[i].shininess;
|
||||
}
|
||||
|
||||
pcShapeMaterial->diffuseColor.finishEditing();
|
||||
pcShapeMaterial->ambientColor.finishEditing();
|
||||
pcShapeMaterial->specularColor.finishEditing();
|
||||
pcShapeMaterial->emissiveColor.finishEditing();
|
||||
pcShapeMaterial->shininess.finishEditing();
|
||||
}
|
||||
else if (colors.size() == 1) {
|
||||
else if (size == 1) {
|
||||
pcFaceBind->value = SoMaterialBinding::OVERALL;
|
||||
pcShapeMaterial->diffuseColor.setValue(colors[0].diffuseColor.r, colors[0].diffuseColor.g, colors[0].diffuseColor.b);
|
||||
pcShapeMaterial->ambientColor.setValue(colors[0].ambientColor.r, colors[0].ambientColor.g, colors[0].ambientColor.b);
|
||||
pcShapeMaterial->specularColor.setValue(colors[0].specularColor.r, colors[0].specularColor.g, colors[0].specularColor.b);
|
||||
pcShapeMaterial->emissiveColor.setValue(colors[0].emissiveColor.r, colors[0].emissiveColor.g, colors[0].emissiveColor.b);
|
||||
setCoinAppearance(materials[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderPartExt::setHighlightedFaces(const App::PropertyMaterialList& appearance)
|
||||
{
|
||||
int size = static_cast<int>(appearance.getSize());
|
||||
if (size > 1 && size == this->faceset->partIndex.getNum()) {
|
||||
pcFaceBind->value = SoMaterialBinding::PER_PART;
|
||||
activateMaterial();
|
||||
|
||||
pcShapeMaterial->diffuseColor.setNum(size);
|
||||
pcShapeMaterial->ambientColor.setNum(size);
|
||||
pcShapeMaterial->specularColor.setNum(size);
|
||||
pcShapeMaterial->emissiveColor.setNum(size);
|
||||
pcShapeMaterial->shininess.setNum(size);
|
||||
|
||||
SbColor* dc = pcShapeMaterial->diffuseColor.startEditing();
|
||||
SbColor* ac = pcShapeMaterial->ambientColor.startEditing();
|
||||
SbColor* sc = pcShapeMaterial->specularColor.startEditing();
|
||||
SbColor* ec = pcShapeMaterial->emissiveColor.startEditing();
|
||||
float* sh = pcShapeMaterial->shininess.startEditing();
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
dc[i].setValue(appearance.getDiffuseColor(i).r,
|
||||
appearance.getDiffuseColor(i).g,
|
||||
appearance.getDiffuseColor(i).b);
|
||||
ac[i].setValue(appearance.getAmbientColor(i).r,
|
||||
appearance.getAmbientColor(i).g,
|
||||
appearance.getAmbientColor(i).b);
|
||||
sc[i].setValue(appearance.getSpecularColor(i).r,
|
||||
appearance.getSpecularColor(i).g,
|
||||
appearance.getSpecularColor(i).b);
|
||||
ec[i].setValue(appearance.getEmissiveColor(i).r,
|
||||
appearance.getEmissiveColor(i).g,
|
||||
appearance.getEmissiveColor(i).b);
|
||||
sh[i] = appearance.getShininess(i);
|
||||
}
|
||||
|
||||
pcShapeMaterial->diffuseColor.finishEditing();
|
||||
pcShapeMaterial->ambientColor.finishEditing();
|
||||
pcShapeMaterial->specularColor.finishEditing();
|
||||
pcShapeMaterial->emissiveColor.finishEditing();
|
||||
pcShapeMaterial->shininess.finishEditing();
|
||||
}
|
||||
else if (size == 1) {
|
||||
pcFaceBind->value = SoMaterialBinding::OVERALL;
|
||||
setCoinAppearance(appearance[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,18 +724,21 @@ std::map<std::string,App::Color> ViewProviderPartExt::getElementColors(const cha
|
||||
}
|
||||
|
||||
if(boost::starts_with(element,"Face")) {
|
||||
auto size = DiffuseColor.getSize();
|
||||
auto size = ShapeAppearance.getSize();
|
||||
if(element[4]=='*') {
|
||||
auto color = ShapeAppearance.getDiffuseColor();
|
||||
color.a = Transparency.getValue()/100.0f;
|
||||
bool singleColor = true;
|
||||
for(int i=0;i<size;++i) {
|
||||
if(DiffuseColor[i]!=color)
|
||||
ret[std::string(element,4)+std::to_string(i+1)] = DiffuseColor[i];
|
||||
singleColor = singleColor && DiffuseColor[0]==DiffuseColor[i];
|
||||
if (ShapeAppearance.getDiffuseColor(i) != color) {
|
||||
ret[std::string(element, 4) + std::to_string(i + 1)] =
|
||||
ShapeAppearance.getDiffuseColor(i);
|
||||
}
|
||||
singleColor = singleColor
|
||||
&& ShapeAppearance.getDiffuseColor(0) == ShapeAppearance.getDiffuseColor(i);
|
||||
}
|
||||
if(size && singleColor) {
|
||||
color = DiffuseColor[0];
|
||||
color = ShapeAppearance.getDiffuseColor(0);
|
||||
color.a = Transparency.getValue()/100.0f;
|
||||
ret.clear();
|
||||
}
|
||||
@@ -697,7 +746,7 @@ std::map<std::string,App::Color> ViewProviderPartExt::getElementColors(const cha
|
||||
}else{
|
||||
int idx = atoi(element+4);
|
||||
if(idx>0 && idx<=size)
|
||||
ret[element] = DiffuseColor[idx-1];
|
||||
ret[element] = ShapeAppearance.getDiffuseColor(idx - 1);
|
||||
else
|
||||
ret[element] = ShapeAppearance.getDiffuseColor();
|
||||
if(size==1)
|
||||
@@ -753,7 +802,8 @@ std::map<std::string,App::Color> ViewProviderPartExt::getElementColors(const cha
|
||||
|
||||
void ViewProviderPartExt::unsetHighlightedFaces()
|
||||
{
|
||||
DiffuseColor.touch();
|
||||
// DiffuseColor.touch();
|
||||
ShapeAppearance.touch();
|
||||
Transparency.touch();
|
||||
}
|
||||
|
||||
@@ -875,7 +925,7 @@ void ViewProviderPartExt::finishRestoring()
|
||||
// and currently sets a single color.
|
||||
// In case DiffuseColor has defined multiple colors they will
|
||||
// be passed to the scene graph now.
|
||||
DiffuseColor.touch();
|
||||
ShapeAppearance.touch();
|
||||
Gui::ViewProviderGeometryObject::finishRestoring();
|
||||
}
|
||||
|
||||
@@ -883,11 +933,11 @@ void ViewProviderPartExt::setupContextMenu(QMenu* menu, QObject* receiver, const
|
||||
{
|
||||
QIcon iconObject = mergeGreyableOverlayIcons(Gui::BitmapFactory().pixmap("Part_ColorFace.svg"));
|
||||
Gui::ViewProviderGeometryObject::setupContextMenu(menu, receiver, member);
|
||||
QAction* act = menu->addAction(iconObject, QObject::tr("Set colors..."), receiver, member);
|
||||
QAction* act = menu->addAction(iconObject, QObject::tr("Set appearance per face..."), receiver, member);
|
||||
act->setData(QVariant((int)ViewProvider::Color));
|
||||
}
|
||||
|
||||
bool ViewProviderPartExt::changeFaceColors()
|
||||
bool ViewProviderPartExt::changeFaceAppearances()
|
||||
{
|
||||
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
|
||||
if (dlg) {
|
||||
@@ -896,7 +946,7 @@ bool ViewProviderPartExt::changeFaceColors()
|
||||
}
|
||||
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Control().showDialog(new TaskFaceColors(this));
|
||||
Gui::Control().showDialog(new TaskFaceAppearances(this));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -906,7 +956,7 @@ bool ViewProviderPartExt::setEdit(int ModNum)
|
||||
// When double-clicking on the item for this pad the
|
||||
// object unsets and sets its edit mode without closing
|
||||
// the task panel
|
||||
return changeFaceColors();
|
||||
return changeFaceAppearances();
|
||||
}
|
||||
else {
|
||||
return Gui::ViewProviderGeometryObject::setEdit(ModNum);
|
||||
@@ -1321,7 +1371,8 @@ void ViewProviderPartExt::updateVisual()
|
||||
VisualTouched = false;
|
||||
|
||||
// The material has to be checked again
|
||||
setHighlightedFaces(DiffuseColor.getValues());
|
||||
// setHighlightedFaces(DiffuseColor.getValues());
|
||||
setHighlightedFaces(ShapeAppearance);
|
||||
setHighlightedEdges(LineColorArray.getValues());
|
||||
setHighlightedPoints(PointColorArray.getValue());
|
||||
}
|
||||
@@ -1336,3 +1387,18 @@ void ViewProviderPartExt::forceUpdate(bool enable) {
|
||||
--forceUpdateCount;
|
||||
}
|
||||
|
||||
|
||||
void ViewProviderPartExt::handleChangedPropertyName(Base::XMLReader& reader,
|
||||
const char* TypeName,
|
||||
const char* PropName)
|
||||
{
|
||||
if (strcmp(PropName, "DiffuseColor") == 0
|
||||
&& strcmp(TypeName, App::PropertyColorList::getClassTypeId().getName()) == 0) {
|
||||
|
||||
// PropertyColorLists are loaded asynchronously as they're stored in separate files
|
||||
_diffuseColor.Restore(reader);
|
||||
}
|
||||
else {
|
||||
Gui::ViewProviderGeometryObject::handleChangedPropertyName(reader, TypeName, PropName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ class SoNormal;
|
||||
class SoNormalBinding;
|
||||
class SoMaterialBinding;
|
||||
class SoIndexedLineSet;
|
||||
class SoTexture3;
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
@@ -85,8 +86,8 @@ public:
|
||||
App::PropertyColor LineColor;
|
||||
App::PropertyMaterial LineMaterial;
|
||||
App::PropertyColorList LineColorArray;
|
||||
// Faces (Gui::ViewProviderGeometryObject::ShapeColor and Gui::ViewProviderGeometryObject::ShapeMaterial apply)
|
||||
App::PropertyColorList DiffuseColor;
|
||||
// Faces (Gui::ViewProviderGeometryObject::ShapeAppearance and Gui::ViewProviderGeometryObject::ShapeMaterial apply)
|
||||
// App::PropertyColorList DiffuseColor;
|
||||
|
||||
void attach(App::DocumentObject *) override;
|
||||
void setDisplayMode(const char* ModeName) override;
|
||||
@@ -95,7 +96,7 @@ public:
|
||||
/// Update the view representation
|
||||
void reload();
|
||||
/// If no other task is pending it opens a dialog to allow to change face colors
|
||||
bool changeFaceColors();
|
||||
bool changeFaceAppearances();
|
||||
|
||||
void updateData(const App::Property*) override;
|
||||
|
||||
@@ -125,8 +126,8 @@ public:
|
||||
* This group of methods do the highlighting of elements.
|
||||
*/
|
||||
//@{
|
||||
void setHighlightedFaces(const std::vector<App::Color>& colors);
|
||||
void setHighlightedFaces(const std::vector<App::Material>& colors);
|
||||
void setHighlightedFaces(const std::vector<App::Material>& materials);
|
||||
void setHighlightedFaces(const App::PropertyMaterialList& appearance);
|
||||
void unsetHighlightedFaces();
|
||||
void setHighlightedEdges(const std::vector<App::Color>& colors);
|
||||
void unsetHighlightedEdges();
|
||||
@@ -151,6 +152,9 @@ public:
|
||||
//@{
|
||||
void setupContextMenu(QMenu*, QObject*, const char*) override;
|
||||
|
||||
/// Get the python wrapper for that ViewProvider
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
protected:
|
||||
bool setEdit(int ModNum) override;
|
||||
void unsetEdit(int ModNum) override;
|
||||
@@ -161,6 +165,9 @@ protected:
|
||||
void onChanged(const App::Property* prop) override;
|
||||
bool loadParameter();
|
||||
void updateVisual();
|
||||
void handleChangedPropertyName(Base::XMLReader& reader,
|
||||
const char* TypeName,
|
||||
const char* PropName) override;
|
||||
|
||||
// nodes for the data representation
|
||||
SoMaterialBinding * pcFaceBind;
|
||||
@@ -179,6 +186,11 @@ protected:
|
||||
SoBrepEdgeSet * lineset;
|
||||
SoBrepPointSet * nodeset;
|
||||
|
||||
// Used to support per face textures
|
||||
SoTexture3 * pcShapeTexture3D;
|
||||
SoCoordinate3 * pcShapeCoordinates;
|
||||
SoIndexedFaceSet * pcShapeFaceset;
|
||||
|
||||
bool VisualTouched;
|
||||
bool NormalsFromUV;
|
||||
|
||||
@@ -190,6 +202,10 @@ private:
|
||||
static App::PropertyQuantityConstraint::Constraints angDeflectionRange;
|
||||
static const char* LightingEnums[];
|
||||
static const char* DrawStyleEnums[];
|
||||
|
||||
// This is needed to restore old DiffuseColor values since the restore
|
||||
// function is asynchronous
|
||||
App::PropertyColorList _diffuseColor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
17
src/Mod/Part/Gui/ViewProviderExtPy.xml
Normal file
17
src/Mod/Part/Gui/ViewProviderExtPy.xml
Normal 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="ViewProviderGeometryObjectPy"
|
||||
Name="ViewProviderPartExtPy"
|
||||
Twin="ViewProviderPartExt"
|
||||
TwinPointer="ViewProviderPartExt"
|
||||
Include="Mod/Part/Gui/ViewProviderExt.h"
|
||||
Namespace="PartGui"
|
||||
FatherInclude="Gui/ViewProviderGeometryObjectPy.h"
|
||||
FatherNamespace="Gui">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="David Carter" EMail="dcarter@davidcarter.ca" />
|
||||
<UserDocu>This is the ViewProvider geometry class</UserDocu>
|
||||
</Documentation>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
73
src/Mod/Part/Gui/ViewProviderExtPyImp.cpp
Normal file
73
src/Mod/Part/Gui/ViewProviderExtPyImp.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 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"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#include <App/GeoFeature.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
|
||||
#include "ViewProviderExt.h"
|
||||
#include "ViewProviderPartExtPy.h"
|
||||
|
||||
#include "ViewProviderPartExtPy.cpp"
|
||||
|
||||
|
||||
using namespace PartGui;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string ViewProviderPartExtPy::representation() const
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "<View provider geometry object at " << getViewProviderPartExtPtr() << ">";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject* ViewProviderPartExtPy::getCustomAttributes(const char* attr) const
|
||||
{
|
||||
ViewProviderPartExt* vp = getViewProviderPartExtPtr();
|
||||
if (strcmp(attr, "DiffuseColor") == 0) {
|
||||
// Get the color properties
|
||||
App::PropertyColorList prop;
|
||||
prop.setValues(vp->ShapeAppearance.getDiffuseColors());
|
||||
return prop.getPyObject();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ViewProviderPartExtPy::setCustomAttributes(const char* attr, PyObject* obj)
|
||||
{
|
||||
ViewProviderPartExt* vp = getViewProviderPartExtPtr();
|
||||
if (strcmp(attr, "DiffuseColor") == 0) {
|
||||
// Set the color properties
|
||||
App::PropertyColorList prop;
|
||||
prop.setPyObject(obj);
|
||||
vp->ShapeAppearance.setDiffuseColors(prop.getValues());
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -263,17 +263,18 @@ void ViewProviderFillet::updateData(const App::Property* prop)
|
||||
|
||||
auto vpBase = dynamic_cast<PartGui::ViewProviderPart*>(Gui::Application::Instance->getViewProvider(objBase));
|
||||
if (vpBase) {
|
||||
std::vector<App::Color> colBase = vpBase->DiffuseColor.getValues();
|
||||
std::vector<App::Color> colFill;
|
||||
colFill.resize(fillMap.Extent(), vpBase->ShapeAppearance.getDiffuseColor());
|
||||
applyTransparency(vpBase->Transparency.getValue(),colBase);
|
||||
// std::vector<App::Color> colBase = vpBase->DiffuseColor.getValues();
|
||||
std::vector<App::Material> colFill;
|
||||
colFill.resize(fillMap.Extent(), vpBase->ShapeAppearance[0]);
|
||||
vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue());
|
||||
|
||||
if (static_cast<int>(colBase.size()) == baseMap.Extent()) {
|
||||
applyColor(hist[0], colBase, colFill);
|
||||
if (static_cast<int>(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) {
|
||||
applyMaterial(hist[0], vpBase->ShapeAppearance, colFill);
|
||||
}
|
||||
else if (!colBase.empty() && colBase[0] != this->ShapeAppearance.getDiffuseColor()) {
|
||||
colBase.resize(baseMap.Extent(), colBase[0]);
|
||||
applyColor(hist[0], colBase, colFill);
|
||||
else if (vpBase->ShapeAppearance.getSize() > 0
|
||||
&& vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) {
|
||||
vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]);
|
||||
applyMaterial(hist[0], vpBase->ShapeAppearance, colFill);
|
||||
}
|
||||
|
||||
// If the view provider has set a transparency then override the values
|
||||
@@ -282,7 +283,7 @@ void ViewProviderFillet::updateData(const App::Property* prop)
|
||||
applyTransparency(Transparency.getValue(), colFill);
|
||||
}
|
||||
|
||||
this->DiffuseColor.setValues(colFill);
|
||||
this->ShapeAppearance.setValues(colFill);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,17 +374,18 @@ void ViewProviderChamfer::updateData(const App::Property* prop)
|
||||
|
||||
auto vpBase = dynamic_cast<PartGui::ViewProviderPart*>(Gui::Application::Instance->getViewProvider(objBase));
|
||||
if (vpBase) {
|
||||
std::vector<App::Color> colBase = static_cast<PartGui::ViewProviderPart*>(vpBase)->DiffuseColor.getValues();
|
||||
std::vector<App::Color> colCham;
|
||||
colCham.resize(chamMap.Extent(), static_cast<PartGui::ViewProviderPart*>(vpBase)->ShapeAppearance.getDiffuseColor());
|
||||
applyTransparency(static_cast<PartGui::ViewProviderPart*>(vpBase)->Transparency.getValue(),colBase);
|
||||
// std::vector<App::Color> colBase = static_cast<PartGui::ViewProviderPart*>(vpBase)->DiffuseColor.getValues();
|
||||
auto& colBase = static_cast<PartGui::ViewProviderPart*>(vpBase)->ShapeAppearance;
|
||||
std::vector<App::Material> colCham;
|
||||
colCham.resize(chamMap.Extent(), colBase[0]);
|
||||
colBase.setTransparency(static_cast<PartGui::ViewProviderPart*>(vpBase)->Transparency.getValue());
|
||||
|
||||
if (static_cast<int>(colBase.size()) == baseMap.Extent()) {
|
||||
applyColor(hist[0], colBase, colCham);
|
||||
if (static_cast<int>(colBase.getSize()) == baseMap.Extent()) {
|
||||
applyMaterial(hist[0], colBase, colCham);
|
||||
}
|
||||
else if (!colBase.empty() && colBase[0] != this->ShapeAppearance.getDiffuseColor()) {
|
||||
colBase.resize(baseMap.Extent(), colBase[0]);
|
||||
applyColor(hist[0], colBase, colCham);
|
||||
else if (colBase.getSize() > 0 && colBase[0] != this->ShapeAppearance[0]) {
|
||||
colBase.setSize(baseMap.Extent(), colBase[0]);
|
||||
applyMaterial(hist[0], colBase, colCham);
|
||||
}
|
||||
|
||||
// If the view provider has set a transparency then override the values
|
||||
@@ -392,7 +394,7 @@ void ViewProviderChamfer::updateData(const App::Property* prop)
|
||||
applyTransparency(Transparency.getValue(), colCham);
|
||||
}
|
||||
|
||||
this->DiffuseColor.setValues(colCham);
|
||||
this->ShapeAppearance.setValues(colCham);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,11 +255,11 @@ void ViewProviderBody::updateData(const App::Property* prop)
|
||||
}
|
||||
|
||||
void ViewProviderBody::copyColorsfromTip(App::DocumentObject* tip) {
|
||||
// update DiffuseColor
|
||||
// update ShapeAppearance
|
||||
Gui::ViewProvider* vptip = Gui::Application::Instance->getViewProvider(tip);
|
||||
if (vptip && vptip->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
|
||||
auto colors = static_cast<PartGui::ViewProviderPartExt*>(vptip)->DiffuseColor.getValues();
|
||||
this->DiffuseColor.setValues(colors);
|
||||
auto materials = static_cast<PartGui::ViewProviderPartExt*>(vptip)->ShapeAppearance.getValues();
|
||||
this->ShapeAppearance.setValues(materials);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,7 +426,6 @@ void ViewProviderBody::unifyVisualProperty(const App::Property* prop) {
|
||||
if (prop == &Visibility ||
|
||||
prop == &Selectable ||
|
||||
prop == &DisplayModeBody ||
|
||||
prop == &DiffuseColor ||
|
||||
prop == &PointColorArray ||
|
||||
prop == &LineColorArray) {
|
||||
return;
|
||||
|
||||
@@ -100,13 +100,13 @@ void ViewProviderDressUp::highlightReferences(const bool on)
|
||||
std::vector<std::string> edges = pcDressUp->Base.getSubValuesStartsWith("Edge");
|
||||
|
||||
if (on) {
|
||||
if (!faces.empty() && originalFaceColors.empty()) {
|
||||
originalFaceColors = vp->DiffuseColor.getValues();
|
||||
std::vector<App::Color> colors = originalFaceColors;
|
||||
if (!faces.empty() && originalFaceMaterials.empty()) {
|
||||
originalFaceMaterials = vp->ShapeAppearance.getValues();
|
||||
std::vector<App::Material> materials = originalFaceMaterials;
|
||||
|
||||
PartGui::ReferenceHighlighter highlighter(base->Shape.getValue(), ShapeAppearance.getDiffuseColor());
|
||||
highlighter.getFaceColors(faces, colors);
|
||||
vp->DiffuseColor.setValues(colors);
|
||||
highlighter.getFaceMaterials(faces, materials);
|
||||
vp->ShapeAppearance.setValues(materials);
|
||||
}
|
||||
if (!edges.empty() && originalLineColors.empty()) {
|
||||
originalLineColors = vp->LineColorArray.getValues();
|
||||
@@ -117,9 +117,9 @@ void ViewProviderDressUp::highlightReferences(const bool on)
|
||||
vp->LineColorArray.setValues(colors);
|
||||
}
|
||||
} else {
|
||||
if (!faces.empty() && !originalFaceColors.empty()) {
|
||||
vp->DiffuseColor.setValues(originalFaceColors);
|
||||
originalFaceColors.clear();
|
||||
if (!faces.empty() && !originalFaceMaterials.empty()) {
|
||||
vp->ShapeAppearance.setValues(originalFaceMaterials);
|
||||
originalFaceMaterials.clear();
|
||||
}
|
||||
if (!edges.empty() && !originalLineColors.empty()) {
|
||||
vp->LineColorArray.setValues(originalLineColors);
|
||||
|
||||
@@ -60,7 +60,7 @@ protected:
|
||||
bool setEdit(int ModNum) override;
|
||||
|
||||
private:
|
||||
std::vector<App::Color> originalFaceColors;
|
||||
std::vector<App::Material> originalFaceMaterials;
|
||||
std::vector<App::Color> originalLineColors;
|
||||
|
||||
};
|
||||
|
||||
@@ -161,9 +161,9 @@ void ViewProviderShapeBinder::highlightReferences(bool on)
|
||||
lcolors.resize(eMap.Extent(), svp->LineColor.getValue());
|
||||
|
||||
TopExp::MapShapes(static_cast<Part::Feature*>(obj)->Shape.getValue(), TopAbs_FACE, eMap);
|
||||
originalFaceColors = svp->DiffuseColor.getValues();
|
||||
std::vector<App::Color> fcolors = originalFaceColors;
|
||||
fcolors.resize(eMap.Extent(), svp->ShapeAppearance.getDiffuseColor());
|
||||
originalFaceAppearance = svp->ShapeAppearance.getValues();
|
||||
std::vector<App::Material> fcolors = originalFaceAppearance;
|
||||
fcolors.resize(eMap.Extent(), svp->ShapeAppearance[0]);
|
||||
|
||||
for (const std::string& e : subs) {
|
||||
// Note: stoi may throw, but it strictly shouldn't happen
|
||||
@@ -177,11 +177,11 @@ void ViewProviderShapeBinder::highlightReferences(bool on)
|
||||
int idx = std::stoi(e.substr(4)) - 1;
|
||||
assert(idx >= 0);
|
||||
if (idx < static_cast<int>(fcolors.size()))
|
||||
fcolors[idx] = App::Color(1.0, 0.0, 1.0); // magenta
|
||||
fcolors[idx].diffuseColor = App::Color(1.0, 0.0, 1.0); // magenta
|
||||
}
|
||||
}
|
||||
svp->LineColorArray.setValues(lcolors);
|
||||
svp->DiffuseColor.setValues(fcolors);
|
||||
svp->ShapeAppearance.setValues(fcolors);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -189,8 +189,8 @@ void ViewProviderShapeBinder::highlightReferences(bool on)
|
||||
svp->LineColorArray.setValues(originalLineColors);
|
||||
originalLineColors.clear();
|
||||
|
||||
svp->DiffuseColor.setValues(originalFaceColors);
|
||||
originalFaceColors.clear();
|
||||
svp->ShapeAppearance.setValues(originalFaceAppearance);
|
||||
originalFaceAppearance.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ protected:
|
||||
|
||||
private:
|
||||
std::vector<App::Color> originalLineColors;
|
||||
std::vector<App::Color> originalFaceColors;
|
||||
std::vector<App::Material> originalFaceAppearance;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -161,22 +161,23 @@ void ViewProviderFilling::highlightReferences(ShapeType type, const References&
|
||||
break;
|
||||
case ViewProviderFilling::Face:
|
||||
if (on) {
|
||||
std::vector<App::Color> colors;
|
||||
std::vector<App::Material> materials;
|
||||
TopTools_IndexedMapOfShape fMap;
|
||||
TopExp::MapShapes(base->Shape.getValue(), TopAbs_FACE, fMap);
|
||||
colors.resize(fMap.Extent(), svp->ShapeAppearance.getDiffuseColor());
|
||||
materials.resize(fMap.Extent(), svp->ShapeAppearance[0]);
|
||||
|
||||
for (const auto& jt : it.second) {
|
||||
std::size_t idx =
|
||||
static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
|
||||
// check again that the index is in range because it's possible that
|
||||
// the sub-names are invalid
|
||||
if (idx < colors.size()) {
|
||||
colors[idx] = App::Color(1.0, 0.0, 1.0); // magenta
|
||||
if (idx < materials.size()) {
|
||||
materials[idx].diffuseColor =
|
||||
App::Color(1.0, 0.0, 1.0); // magenta
|
||||
}
|
||||
}
|
||||
|
||||
svp->setHighlightedFaces(colors);
|
||||
svp->setHighlightedFaces(materials);
|
||||
}
|
||||
else {
|
||||
svp->unsetHighlightedFaces();
|
||||
|
||||
@@ -161,22 +161,23 @@ void ViewProviderSections::highlightReferences(ShapeType type, const References&
|
||||
break;
|
||||
case ViewProviderSections::Face:
|
||||
if (on) {
|
||||
std::vector<App::Color> colors;
|
||||
std::vector<App::Material> materials;
|
||||
TopTools_IndexedMapOfShape fMap;
|
||||
TopExp::MapShapes(base->Shape.getValue(), TopAbs_FACE, fMap);
|
||||
colors.resize(fMap.Extent(), svp->ShapeAppearance.getDiffuseColor());
|
||||
materials.resize(fMap.Extent(), svp->ShapeAppearance[0]);
|
||||
|
||||
for (const auto& jt : it.second) {
|
||||
std::size_t idx =
|
||||
static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
|
||||
// check again that the index is in range because it's possible that
|
||||
// the sub-names are invalid
|
||||
if (idx < colors.size()) {
|
||||
colors[idx] = App::Color(1.0, 0.0, 1.0); // magenta
|
||||
if (idx < materials.size()) {
|
||||
materials[idx].diffuseColor =
|
||||
App::Color(1.0, 0.0, 1.0); // magenta
|
||||
}
|
||||
}
|
||||
|
||||
svp->setHighlightedFaces(colors);
|
||||
svp->setHighlightedFaces(materials);
|
||||
}
|
||||
else {
|
||||
svp->unsetHighlightedFaces();
|
||||
|
||||
Reference in New Issue
Block a user