Material: Material appearance
Uses new material system for appearance Each feature object now has a property called ShapeMaterial that describes its physical properties. If it has a shape, it has a material. The ShapeColor attribute is replaced by a ShapeAppearance attribute. This is a material list that describes all appearance properties, not just diffuse color. As a list in can be used for all elements of a shape, such as edges and faces. A new widget is provided to allow the user to select materials in a consistent fashion. It can also launch the material editor with its more advanced capabilities.
This commit is contained in:
committed by
Chris Hennes
parent
37c38acd19
commit
ba20441935
@@ -36,6 +36,7 @@
|
||||
#include "ModelPropertyPy.h"
|
||||
#include "ModelPy.h"
|
||||
#include "UUIDsPy.h"
|
||||
#include "PropertyMaterial.h"
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
@@ -43,9 +44,9 @@ class Module: public Py::ExtensionModule<Module>
|
||||
{
|
||||
public:
|
||||
Module()
|
||||
: Py::ExtensionModule<Module>("Material")
|
||||
: Py::ExtensionModule<Module>("Materials")
|
||||
{
|
||||
initialize("This module is the Material module."); // register with Python
|
||||
initialize("This module is the Materials module."); // register with Python
|
||||
}
|
||||
|
||||
~Module() override = default;
|
||||
@@ -60,18 +61,18 @@ PyObject* initModule()
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
PyMOD_INIT_FUNC(Material)
|
||||
PyMOD_INIT_FUNC(Materials)
|
||||
{
|
||||
PyObject* module = Materials::initModule();
|
||||
|
||||
Base::Console().Log("Loading Material module... done\n");
|
||||
|
||||
Base::Interpreter().addType(&Materials::MaterialManagerPy ::Type, module, "MaterialManager");
|
||||
Base::Interpreter().addType(&Materials::MaterialPy ::Type, module, "Material");
|
||||
Base::Interpreter().addType(&Materials::ModelManagerPy ::Type, module, "ModelManager");
|
||||
Base::Interpreter().addType(&Materials::ModelPropertyPy ::Type, module, "ModelProperty");
|
||||
Base::Interpreter().addType(&Materials::ModelPy ::Type, module, "Model");
|
||||
Base::Interpreter().addType(&Materials::UUIDsPy ::Type, module, "UUIDs");
|
||||
Base::Interpreter().addType(&Materials::MaterialManagerPy::Type, module, "MaterialManager");
|
||||
Base::Interpreter().addType(&Materials::MaterialPy::Type, module, "Material");
|
||||
Base::Interpreter().addType(&Materials::ModelManagerPy::Type, module, "ModelManager");
|
||||
Base::Interpreter().addType(&Materials::ModelPropertyPy::Type, module, "ModelProperty");
|
||||
Base::Interpreter().addType(&Materials::ModelPy::Type, module, "Model");
|
||||
Base::Interpreter().addType(&Materials::UUIDsPy::Type, module, "UUIDs");
|
||||
|
||||
|
||||
// Initialize types
|
||||
@@ -95,5 +96,7 @@ PyMOD_INIT_FUNC(Material)
|
||||
Materials::Material2DArray ::init();
|
||||
Materials::Material3DArray ::init();
|
||||
|
||||
Materials::PropertyMaterial ::init();
|
||||
|
||||
PyMOD_Return(module);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ include_directories(
|
||||
)
|
||||
link_directories(${YAML_CPP_LIBRARY_DIR})
|
||||
|
||||
set(Material_LIBS
|
||||
set(Materials_LIBS
|
||||
${Boost_LIBRARIES}
|
||||
FreeCADApp
|
||||
)
|
||||
@@ -28,22 +28,23 @@ set(Material_LIBS
|
||||
include_directories(
|
||||
${QtConcurrent_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND Material_LIBS
|
||||
list(APPEND Materials_LIBS
|
||||
${QtConcurrent_LIBRARIES}
|
||||
)
|
||||
|
||||
if(yaml-cpp_VERSION VERSION_LESS 0.8.0)
|
||||
list(APPEND Material_LIBS
|
||||
list(APPEND Materials_LIBS
|
||||
${YAML_CPP_LIBRARIES}
|
||||
)
|
||||
else()
|
||||
list(APPEND Material_LIBS
|
||||
list(APPEND Materials_LIBS
|
||||
yaml-cpp::yaml-cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
generate_from_xml(Array2DPy)
|
||||
generate_from_xml(Array3DPy)
|
||||
generate_from_xml(MaterialFilterPy)
|
||||
generate_from_xml(MaterialManagerPy)
|
||||
generate_from_xml(MaterialPy)
|
||||
generate_from_xml(ModelManagerPy)
|
||||
@@ -61,6 +62,8 @@ SET(Python_SRCS
|
||||
MaterialManagerPyImpl.cpp
|
||||
MaterialPy.xml
|
||||
MaterialPyImpl.cpp
|
||||
MaterialFilterPy.xml
|
||||
MaterialFilterPyImpl.cpp
|
||||
ModelManagerPy.xml
|
||||
ModelManagerPyImpl.cpp
|
||||
ModelPropertyPy.xml
|
||||
@@ -72,7 +75,7 @@ SET(Python_SRCS
|
||||
)
|
||||
SOURCE_GROUP("Python" FILES ${Python_SRCS})
|
||||
|
||||
SET(Material_SRCS
|
||||
SET(Materials_SRCS
|
||||
${Python_SRCS}
|
||||
AppMaterial.cpp
|
||||
FolderTree.h
|
||||
@@ -102,19 +105,21 @@ SET(Material_SRCS
|
||||
ModelUuids.h
|
||||
PreCompiled.cpp
|
||||
PreCompiled.h
|
||||
PropertyMaterial.cpp
|
||||
PropertyMaterial.h
|
||||
trim.h
|
||||
)
|
||||
|
||||
if(FREECAD_USE_PCH)
|
||||
add_definitions(-D_PreComp_)
|
||||
GET_MSVC_PRECOMPILED_SOURCE("PreCompiled.cpp" PCH_SRCS ${Material_SRCS})
|
||||
ADD_MSVC_PRECOMPILED_HEADER(Material PreCompiled.h PreCompiled.cpp PCH_SRCS)
|
||||
GET_MSVC_PRECOMPILED_SOURCE("PreCompiled.cpp" PCH_SRCS ${Materials_SRCS})
|
||||
ADD_MSVC_PRECOMPILED_HEADER(Materials PreCompiled.h PreCompiled.cpp PCH_SRCS)
|
||||
endif(FREECAD_USE_PCH)
|
||||
|
||||
add_library(Material SHARED ${Material_SRCS})
|
||||
target_link_libraries(Material ${Material_LIBS})
|
||||
add_library(Materials SHARED ${Materials_SRCS})
|
||||
target_link_libraries(Materials ${Materials_LIBS})
|
||||
|
||||
SET_BIN_DIR(Material Material /Mod/Material)
|
||||
SET_PYTHON_PREFIX_SUFFIX(Material)
|
||||
SET_BIN_DIR(Materials Materials /Mod/Material)
|
||||
SET_PYTHON_PREFIX_SUFFIX(Materials)
|
||||
|
||||
INSTALL(TARGETS Material DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
INSTALL(TARGETS Materials DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
|
||||
* Copyright (c) 2023-2024 David Carter <dcarter@david.carter.ca> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
@@ -25,7 +25,9 @@
|
||||
|
||||
#include <App/Application.h>
|
||||
|
||||
#include "Exceptions.h"
|
||||
#include "MaterialFilter.h"
|
||||
#include "MaterialManager.h"
|
||||
#include "Materials.h"
|
||||
|
||||
|
||||
@@ -56,6 +58,18 @@ bool MaterialFilter::modelIncluded(const std::shared_ptr<Material>& material) co
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MaterialFilter::modelIncluded(const QString& uuid) const
|
||||
{
|
||||
MaterialManager manager;
|
||||
try {
|
||||
auto material = manager.getMaterial(uuid);
|
||||
return modelIncluded(material);
|
||||
}
|
||||
catch (const MaterialNotFound&) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MaterialFilter::addRequired(const QString& uuid)
|
||||
{
|
||||
// Ignore any uuids already present
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
|
||||
* Copyright (c) 2023-2024 David Carter <dcarter@david.carter.ca> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
@@ -56,9 +56,9 @@ public:
|
||||
{
|
||||
return _includeFolders;
|
||||
}
|
||||
void setIncludeEmptyFolders(bool include)
|
||||
void setIncludeEmptyFolders(bool value)
|
||||
{
|
||||
_includeFolders = include;
|
||||
_includeFolders = value;
|
||||
}
|
||||
|
||||
/* Indicates if we should include materials in the older format
|
||||
@@ -80,10 +80,26 @@ public:
|
||||
* Models only need to be included in one set.
|
||||
*/
|
||||
bool modelIncluded(const std::shared_ptr<Material>& material) const;
|
||||
bool modelIncluded(const QString& uuid) const;
|
||||
|
||||
/* Add model UUIDs for required models, or models that are both required
|
||||
* and complete.
|
||||
*/
|
||||
void addRequired(const QString& uuid);
|
||||
void addRequiredComplete(const QString& uuid);
|
||||
|
||||
/* These functions shouldn't normally be called directly. They are
|
||||
* for use by conversion methods, such as MaterialFilterPy
|
||||
*/
|
||||
const QSet<QString>* getRequired() const
|
||||
{
|
||||
return &_required;
|
||||
}
|
||||
const QSet<QString>* getRequiredComplete() const
|
||||
{
|
||||
return &_requiredComplete;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _includeFolders;
|
||||
bool _includeLegacy;
|
||||
|
||||
43
src/Mod/Material/App/MaterialFilterPy.xml
Normal file
43
src/Mod/Material/App/MaterialFilterPy.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="BaseClassPy"
|
||||
Name="MaterialFilterPy"
|
||||
Twin="MaterialFilter"
|
||||
TwinPointer="MaterialFilter"
|
||||
Include="Mod/Material/App/MaterialFilter.h"
|
||||
Namespace="Materials"
|
||||
FatherInclude="Base/BaseClassPy.h"
|
||||
FatherNamespace="Base"
|
||||
Constructor="true"
|
||||
Delete="true">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="DavidCarter" EMail="dcarter@davidcarter.ca" />
|
||||
<UserDocu>Material filters.</UserDocu>
|
||||
</Documentation>
|
||||
<Attribute Name="IncludeEmptyFolders" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Include empty folders in the material list.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IncludeEmptyFolders" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="IncludeLegacy" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Include legacy materials in the material list.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IncludeLegacy" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="RequiredModels" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Materials must include the specified models.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="RequiredModels" Type="List"/>
|
||||
</Attribute>
|
||||
<Attribute Name="RequiredCompleteModels" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Materials must have complete versions of the specified models.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="RequiredCompleteModels" Type="List"/>
|
||||
</Attribute>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
132
src/Mod/Material/App/MaterialFilterPyImpl.cpp
Normal file
132
src/Mod/Material/App/MaterialFilterPyImpl.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023-2024 David Carter <dcarter@david.carter.ca> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
#include <Base/Quantity.h>
|
||||
#include <Base/QuantityPy.h>
|
||||
#include <CXX/Objects.hxx>
|
||||
#include <Gui/MetaTypes.h>
|
||||
|
||||
#include "MaterialFilter.h"
|
||||
|
||||
#include "MaterialFilterPy.h"
|
||||
|
||||
#include "MaterialFilterPy.cpp"
|
||||
|
||||
using namespace Materials;
|
||||
|
||||
// Forward declaration
|
||||
// static PyObject* _pyObjectFromVariant(const QVariant& value);
|
||||
// static Py::List getList(const QVariant& value);
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string MaterialFilterPy::representation() const
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "<MaterialFilter object at " << getMaterialFilterPtr() << ">";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject* MaterialFilterPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// never create such objects with the constructor
|
||||
return new MaterialFilterPy(new MaterialFilter());
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int MaterialFilterPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py::Boolean MaterialFilterPy::getIncludeEmptyFolders() const
|
||||
{
|
||||
return {getMaterialFilterPtr()->includeEmptyFolders()};
|
||||
}
|
||||
|
||||
void MaterialFilterPy::setIncludeEmptyFolders(const Py::Boolean value)
|
||||
{
|
||||
getMaterialFilterPtr()->setIncludeEmptyFolders(value.isTrue());
|
||||
}
|
||||
|
||||
Py::Boolean MaterialFilterPy::getIncludeLegacy() const
|
||||
{
|
||||
return {getMaterialFilterPtr()->includeLegacy()};
|
||||
}
|
||||
|
||||
void MaterialFilterPy::setIncludeLegacy(const Py::Boolean value)
|
||||
{
|
||||
getMaterialFilterPtr()->setIncludeLegacy(value.isTrue());
|
||||
}
|
||||
|
||||
Py::List MaterialFilterPy::getRequiredModels() const
|
||||
{
|
||||
auto listValue = getMaterialFilterPtr()->getRequired();
|
||||
Py::List list;
|
||||
|
||||
for (auto& it : *listValue) {
|
||||
list.append(Py::String(it.toStdString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void MaterialFilterPy::setRequiredModels(Py::List value)
|
||||
{
|
||||
for (const auto& it : value) {
|
||||
Py::String uuid(it);
|
||||
getMaterialFilterPtr()->addRequired(QString::fromStdString(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
Py::List MaterialFilterPy::getRequiredCompleteModels() const
|
||||
{
|
||||
auto listValue = getMaterialFilterPtr()->getRequiredComplete();
|
||||
Py::List list;
|
||||
|
||||
for (auto& it : *listValue) {
|
||||
list.append(Py::String(it.toStdString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void MaterialFilterPy::setRequiredCompleteModels(Py::List value)
|
||||
{
|
||||
for (const auto& it : value) {
|
||||
Py::String uuid(it);
|
||||
getMaterialFilterPtr()->addRequiredComplete(QString::fromStdString(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* MaterialFilterPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int MaterialFilterPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <QVector>
|
||||
#include <QDirIterator>
|
||||
#include <QFileInfo>
|
||||
#include <QVector>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ QString MaterialLibrary::getUUIDFromPath(const QString& path) const
|
||||
}
|
||||
|
||||
bool MaterialLibrary::materialInTree(const std::shared_ptr<Material>& material,
|
||||
const MaterialFilter* filter) const
|
||||
const std::shared_ptr<Materials::MaterialFilter>& filter) const
|
||||
{
|
||||
if (!filter) {
|
||||
// If there's no filter we always include
|
||||
@@ -283,7 +283,7 @@ bool MaterialLibrary::materialInTree(const std::shared_ptr<Material>& material,
|
||||
}
|
||||
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
MaterialLibrary::getMaterialTree(const MaterialFilter* filter) const
|
||||
MaterialLibrary::getMaterialTree(const std::shared_ptr<Materials::MaterialFilter>& filter) const
|
||||
{
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> materialTree =
|
||||
std::make_shared<std::map<QString, std::shared_ptr<MaterialTreeNode>>>();
|
||||
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
std::shared_ptr<Material> addMaterial(const std::shared_ptr<Material>& material,
|
||||
const QString& path);
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
getMaterialTree(const MaterialFilter* filter = nullptr) const;
|
||||
getMaterialTree(const std::shared_ptr<Materials::MaterialFilter>& filter) const;
|
||||
|
||||
bool isReadOnly() const
|
||||
{
|
||||
@@ -99,7 +99,7 @@ protected:
|
||||
void updatePaths(const QString& oldPath, const QString& newPath);
|
||||
QString getUUIDFromPath(const QString& path) const;
|
||||
bool materialInTree(const std::shared_ptr<Material>& material,
|
||||
const MaterialFilter* filter) const;
|
||||
const std::shared_ptr<Materials::MaterialFilter>& filter) const;
|
||||
|
||||
bool _readOnly;
|
||||
std::unique_ptr<std::map<QString, std::shared_ptr<Material>>> _materialPathMap;
|
||||
|
||||
@@ -27,12 +27,14 @@
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Material.h>
|
||||
|
||||
#include "Exceptions.h"
|
||||
#include "MaterialConfigLoader.h"
|
||||
#include "MaterialLoader.h"
|
||||
#include "MaterialManager.h"
|
||||
#include "ModelManager.h"
|
||||
#include "ModelUuids.h"
|
||||
|
||||
|
||||
using namespace Materials;
|
||||
@@ -108,6 +110,47 @@ bool MaterialManager::isMaterial(const QFileInfo& file) const
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<Material> MaterialManager::defaultMaterial()
|
||||
{
|
||||
MaterialManager manager;
|
||||
|
||||
ParameterGrp::handle hGrp =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
bool randomColor = hGrp->GetBool("RandomColor", false);
|
||||
float r, g, b;
|
||||
|
||||
if (randomColor) {
|
||||
auto fMax = (float)RAND_MAX;
|
||||
r = (float)rand() / fMax;
|
||||
g = (float)rand() / fMax;
|
||||
b = (float)rand() / fMax;
|
||||
}
|
||||
else {
|
||||
unsigned long shcol = hGrp->GetUnsigned("DefaultShapeColor", 3435980543UL);
|
||||
r = ((shcol >> 24) & 0xff) / 255.0;
|
||||
g = ((shcol >> 16) & 0xff) / 255.0;
|
||||
b = ((shcol >> 8) & 0xff) / 255.0;
|
||||
}
|
||||
|
||||
int initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
|
||||
|
||||
auto material = manager.getMaterial(defaultMaterialUUID());
|
||||
if (material->hasAppearanceModel(ModelUUIDs::ModelUUID_Rendering_Basic)) {
|
||||
material->getAppearanceProperty(QString::fromLatin1("DiffuseColor"))
|
||||
->setColor(App::Color(r, g, b));
|
||||
material->getAppearanceProperty(QString::fromLatin1("Transparency"))
|
||||
->setFloat((float)initialTransparency / 100.0f);
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
QString MaterialManager::defaultMaterialUUID()
|
||||
{
|
||||
// Make this a preference
|
||||
return QString::fromLatin1("7f9fd73b-50c9-41d8-b7b2-575a030c1eeb");
|
||||
}
|
||||
|
||||
std::shared_ptr<Material> MaterialManager::getMaterial(const QString& uuid) const
|
||||
{
|
||||
try {
|
||||
@@ -118,6 +161,13 @@ std::shared_ptr<Material> MaterialManager::getMaterial(const QString& uuid) cons
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Material> MaterialManager::getMaterial(const App::Material& material)
|
||||
{
|
||||
MaterialManager manager;
|
||||
|
||||
return manager.getMaterial(QString::fromStdString(material.uuid));
|
||||
}
|
||||
|
||||
std::shared_ptr<Material> MaterialManager::getMaterialByPath(const QString& path) const
|
||||
{
|
||||
QString cleanPath = QDir::cleanPath(path);
|
||||
@@ -126,7 +176,9 @@ std::shared_ptr<Material> MaterialManager::getMaterialByPath(const QString& path
|
||||
if (cleanPath.startsWith(library->getDirectory())) {
|
||||
try {
|
||||
return library->getMaterialByPath(cleanPath);
|
||||
} catch (const MaterialNotFound&) {}
|
||||
}
|
||||
catch (const MaterialNotFound&) {
|
||||
}
|
||||
|
||||
// See if it's a new file saved by the old editor
|
||||
{
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace App
|
||||
{
|
||||
class Material;
|
||||
}
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
@@ -50,11 +55,15 @@ public:
|
||||
MaterialManager();
|
||||
~MaterialManager() override = default;
|
||||
|
||||
static std::shared_ptr<Material> defaultMaterial();
|
||||
static QString defaultMaterialUUID();
|
||||
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> getMaterials() const
|
||||
{
|
||||
return _materialMap;
|
||||
}
|
||||
std::shared_ptr<Material> getMaterial(const QString& uuid) const;
|
||||
static std::shared_ptr<Material> getMaterial(const App::Material& material);
|
||||
std::shared_ptr<Material> getMaterialByPath(const QString& path) const;
|
||||
std::shared_ptr<Material> getMaterialByPath(const QString& path, const QString& library) const;
|
||||
std::shared_ptr<Material> getParent(const std::shared_ptr<Material>& material) const;
|
||||
@@ -66,10 +75,16 @@ public:
|
||||
std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> getMaterialLibraries() const;
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
getMaterialTree(const std::shared_ptr<MaterialLibrary>& library,
|
||||
const MaterialFilter* filter = nullptr) const
|
||||
const std::shared_ptr<Materials::MaterialFilter>& filter) const
|
||||
{
|
||||
return library->getMaterialTree(filter);
|
||||
}
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
getMaterialTree(const std::shared_ptr<MaterialLibrary>& library) const
|
||||
{
|
||||
std::shared_ptr<Materials::MaterialFilter> filter;
|
||||
return library->getMaterialTree(filter);
|
||||
}
|
||||
std::shared_ptr<std::list<QString>>
|
||||
getMaterialFolders(const std::shared_ptr<MaterialLibrary>& library) const;
|
||||
void createFolder(const std::shared_ptr<MaterialLibrary>& library, const QString& path) const
|
||||
|
||||
@@ -103,69 +103,69 @@ int MaterialPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
Py::String MaterialPy::getLibraryName() const
|
||||
{
|
||||
auto library = getMaterialPtr()->getLibrary();
|
||||
return Py::String(library ? library->getName().toStdString() : "");
|
||||
return {library ? library->getName().toStdString() : ""};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getLibraryRoot() const
|
||||
{
|
||||
auto library = getMaterialPtr()->getLibrary();
|
||||
return Py::String(library ? library->getDirectoryPath().toStdString() : "");
|
||||
return {library ? library->getDirectoryPath().toStdString() : ""};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getLibraryIcon() const
|
||||
{
|
||||
auto library = getMaterialPtr()->getLibrary();
|
||||
return Py::String(library ? library->getIconPath().toStdString() : "");
|
||||
return {library ? library->getIconPath().toStdString() : ""};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getName() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getName().toStdString());
|
||||
return {getMaterialPtr()->getName().toStdString()};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getDirectory() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getDirectory().toStdString());
|
||||
return {getMaterialPtr()->getDirectory().toStdString()};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getUUID() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getUUID().toStdString());
|
||||
return {getMaterialPtr()->getUUID().toStdString()};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getDescription() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getDescription().toStdString());
|
||||
return {getMaterialPtr()->getDescription().toStdString()};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getURL() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getURL().toStdString());
|
||||
return {getMaterialPtr()->getURL().toStdString()};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getReference() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getReference().toStdString());
|
||||
return {getMaterialPtr()->getReference().toStdString()};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getParent() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getParentUUID().toStdString());
|
||||
return {getMaterialPtr()->getParentUUID().toStdString()};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getAuthorAndLicense() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getAuthorAndLicense().toStdString());
|
||||
return {getMaterialPtr()->getAuthorAndLicense().toStdString()};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getAuthor() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getAuthor().toStdString());
|
||||
return {getMaterialPtr()->getAuthor().toStdString()};
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getLicense() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getLicense().toStdString());
|
||||
return {getMaterialPtr()->getLicense().toStdString()};
|
||||
}
|
||||
|
||||
Py::List MaterialPy::getPhysicalModels() const
|
||||
@@ -173,8 +173,8 @@ Py::List MaterialPy::getPhysicalModels() const
|
||||
auto models = getMaterialPtr()->getPhysicalModels();
|
||||
Py::List list;
|
||||
|
||||
for (auto it = models->begin(); it != models->end(); it++) {
|
||||
list.append(Py::String(it->toStdString()));
|
||||
for (auto it : *models) {
|
||||
list.append(Py::String(it.toStdString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -185,8 +185,8 @@ Py::List MaterialPy::getAppearanceModels() const
|
||||
auto models = getMaterialPtr()->getAppearanceModels();
|
||||
Py::List list;
|
||||
|
||||
for (auto it = models->begin(); it != models->end(); it++) {
|
||||
list.append(Py::String(it->toStdString()));
|
||||
for (auto it : *models) {
|
||||
list.append(Py::String(it.toStdString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -197,8 +197,8 @@ Py::List MaterialPy::getTags() const
|
||||
auto& tags = getMaterialPtr()->getTags();
|
||||
Py::List list;
|
||||
|
||||
for (auto it = tags.begin(); it != tags.end(); it++) {
|
||||
list.append(Py::String(it->toStdString()));
|
||||
for (auto it : tags) {
|
||||
list.append(Py::String(it.toStdString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -298,9 +298,9 @@ Py::Dict MaterialPy::getProperties() const
|
||||
dict.setItem(Py::String("SourceURL"), Py::String(getMaterialPtr()->getURL().toStdString()));
|
||||
|
||||
auto properties = getMaterialPtr()->getPhysicalProperties();
|
||||
for (auto it = properties.begin(); it != properties.end(); it++) {
|
||||
QString key = it->first;
|
||||
auto materialProperty = it->second;
|
||||
for (auto& it : properties) {
|
||||
QString key = it.first;
|
||||
auto materialProperty = it.second;
|
||||
|
||||
if (!materialProperty->isNull()) {
|
||||
auto value = materialProperty->getDictionaryString();
|
||||
@@ -309,9 +309,9 @@ Py::Dict MaterialPy::getProperties() const
|
||||
}
|
||||
|
||||
properties = getMaterialPtr()->getAppearanceProperties();
|
||||
for (auto it = properties.begin(); it != properties.end(); it++) {
|
||||
QString key = it->first;
|
||||
auto materialProperty = it->second;
|
||||
for (auto& it : properties) {
|
||||
QString key = it.first;
|
||||
auto materialProperty = it.second;
|
||||
|
||||
if (!materialProperty->isNull()) {
|
||||
auto value = materialProperty->getDictionaryString();
|
||||
@@ -327,9 +327,9 @@ Py::Dict MaterialPy::getPhysicalProperties() const
|
||||
Py::Dict dict;
|
||||
|
||||
auto properties = getMaterialPtr()->getPhysicalProperties();
|
||||
for (auto it = properties.begin(); it != properties.end(); it++) {
|
||||
QString key = it->first;
|
||||
auto materialProperty = it->second;
|
||||
for (auto& it : properties) {
|
||||
QString key = it.first;
|
||||
auto materialProperty = it.second;
|
||||
|
||||
if (!materialProperty->isNull()) {
|
||||
auto value = materialProperty->getDictionaryString();
|
||||
@@ -345,9 +345,9 @@ Py::Dict MaterialPy::getAppearanceProperties() const
|
||||
Py::Dict dict;
|
||||
|
||||
auto properties = getMaterialPtr()->getAppearanceProperties();
|
||||
for (auto it = properties.begin(); it != properties.end(); it++) {
|
||||
QString key = it->first;
|
||||
auto materialProperty = it->second;
|
||||
for (auto& it : properties) {
|
||||
QString key = it.first;
|
||||
auto materialProperty = it.second;
|
||||
|
||||
if (!materialProperty->isNull()) {
|
||||
auto value = materialProperty->getDictionaryString();
|
||||
@@ -425,7 +425,7 @@ PyObject* MaterialPy::getPhysicalValue(PyObject* args)
|
||||
std::static_pointer_cast<Materials::Material2DArray>(property->getMaterialValue());
|
||||
return new Array2DPy(new Material2DArray(*value));
|
||||
}
|
||||
else if (property->getType() == MaterialValue::Array3D) {
|
||||
if (property->getType() == MaterialValue::Array3D) {
|
||||
auto value =
|
||||
std::static_pointer_cast<Materials::Material3DArray>(property->getMaterialValue());
|
||||
return new Array3DPy(new Material3DArray(*value));
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "MaterialLibrary.h"
|
||||
#include "MaterialManager.h"
|
||||
#include "ModelManager.h"
|
||||
#include "ModelUuids.h"
|
||||
|
||||
|
||||
using namespace Materials;
|
||||
@@ -142,6 +143,32 @@ QString MaterialProperty::getYAMLString() const
|
||||
return _valuePtr->getYAMLString();
|
||||
}
|
||||
|
||||
App::Color MaterialProperty::getColor() const
|
||||
{
|
||||
auto colorString = getValue().toString();
|
||||
std::stringstream stream(colorString.toStdString());
|
||||
|
||||
char c;
|
||||
stream >> c; // read "("
|
||||
float red;
|
||||
stream >> red;
|
||||
stream >> c; // ","
|
||||
float green;
|
||||
stream >> green;
|
||||
stream >> c; // ","
|
||||
float blue;
|
||||
stream >> blue;
|
||||
stream >> c; // ","
|
||||
float alpha = 1.0;
|
||||
if (c == ',') {
|
||||
stream >> alpha;
|
||||
}
|
||||
|
||||
App::Color color(red, green, blue, alpha);
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
QString MaterialProperty::getDictionaryString() const
|
||||
{
|
||||
// This method produces a non-localized string. For a localized string use
|
||||
@@ -377,6 +404,13 @@ void MaterialProperty::setURL(const QString& value)
|
||||
_valuePtr->setValue(QVariant(value));
|
||||
}
|
||||
|
||||
void MaterialProperty::setColor(const App::Color& value)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "(" << value.r << ", " << value.g << ", " << value.b << ", " << value.a << ")";
|
||||
_valuePtr->setValue(QVariant(QString::fromStdString(ss.str())));
|
||||
}
|
||||
|
||||
MaterialProperty& MaterialProperty::operator=(const MaterialProperty& other)
|
||||
{
|
||||
if (this == &other) {
|
||||
@@ -1434,6 +1468,23 @@ Material& Material::operator=(const Material& other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Material& Material::operator=(const App::Material& other)
|
||||
{
|
||||
if (!hasAppearanceModel(ModelUUIDs::ModelUUID_Rendering_Basic)) {
|
||||
addAppearance(ModelUUIDs::ModelUUID_Rendering_Basic);
|
||||
}
|
||||
|
||||
getAppearanceProperty(QString::fromLatin1("AmbientColor"))->setColor(other.ambientColor);
|
||||
getAppearanceProperty(QString::fromLatin1("DiffuseColor"))->setColor(other.diffuseColor);
|
||||
getAppearanceProperty(QString::fromLatin1("SpecularColor"))->setColor(other.specularColor);
|
||||
getAppearanceProperty(QString::fromLatin1("EmissiveColor"))->setColor(other.emissiveColor);
|
||||
getAppearanceProperty(QString::fromLatin1("Shininess"))->setFloat(other.shininess);
|
||||
getAppearanceProperty(QString::fromLatin1("Transparency"))->setFloat(other.transparency);
|
||||
// std::string uuid;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normalize models by removing any inherited models
|
||||
*/
|
||||
@@ -1509,3 +1560,50 @@ QStringList Material::inheritedAddedModels(const Material& parent) const
|
||||
*/
|
||||
void Material::inheritedPropertyDiff([[maybe_unused]] const QString& parent)
|
||||
{}
|
||||
|
||||
/*
|
||||
* Return an App::Material object describing the materials appearance, or DEFAULT if
|
||||
* undefined.
|
||||
*/
|
||||
App::Material Material::getMaterialAppearance() const
|
||||
{
|
||||
App::Material material(App::Material::DEFAULT);
|
||||
|
||||
bool custom = false;
|
||||
if (hasAppearanceProperty(QString::fromLatin1("AmbientColor"))) {
|
||||
material.ambientColor =
|
||||
getAppearanceProperty(QString::fromLatin1("AmbientColor"))->getColor();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("DiffuseColor"))) {
|
||||
material.diffuseColor =
|
||||
getAppearanceProperty(QString::fromLatin1("DiffuseColor"))->getColor();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("SpecularColor"))) {
|
||||
material.specularColor =
|
||||
getAppearanceProperty(QString::fromLatin1("SpecularColor"))->getColor();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("EmissiveColor"))) {
|
||||
material.emissiveColor =
|
||||
getAppearanceProperty(QString::fromLatin1("EmissiveColor"))->getColor();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("Shininess"))) {
|
||||
material.shininess = getAppearanceProperty(QString::fromLatin1("Shininess"))->getFloat();
|
||||
custom = true;
|
||||
}
|
||||
if (hasAppearanceProperty(QString::fromLatin1("Transparency"))) {
|
||||
material.transparency =
|
||||
getAppearanceProperty(QString::fromLatin1("Transparency"))->getFloat();
|
||||
custom = true;
|
||||
}
|
||||
|
||||
if (custom) {
|
||||
material.setType(App::Material::USER_DEFINED);
|
||||
material.uuid = getUUID().toStdString();
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <QTextStream>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Color.h>
|
||||
#include <App/Material.h>
|
||||
#include <Base/BaseClass.h>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
@@ -79,11 +81,24 @@ public:
|
||||
QString getString() const;
|
||||
QString getYAMLString() const;
|
||||
QString getDictionaryString() const; // Non-localized string
|
||||
bool getBoolean() const;
|
||||
int getInt() const;
|
||||
double getFloat() const;
|
||||
bool getBoolean() const
|
||||
{
|
||||
return getValue().toBool();
|
||||
}
|
||||
int getInt() const
|
||||
{
|
||||
return getValue().toInt();
|
||||
}
|
||||
double getFloat() const
|
||||
{
|
||||
return getValue().toFloat();
|
||||
}
|
||||
const Base::Quantity& getQuantity() const;
|
||||
const QString getURL() const;
|
||||
QString getURL() const
|
||||
{
|
||||
return getValue().toString();
|
||||
}
|
||||
App::Color getColor() const;
|
||||
|
||||
MaterialProperty& getColumn(int column);
|
||||
const MaterialProperty& getColumn(int column) const;
|
||||
@@ -109,6 +124,7 @@ public:
|
||||
void setQuantity(const QString& value);
|
||||
void setList(const QList<QVariant>& value);
|
||||
void setURL(const QString& value);
|
||||
void setColor(const App::Color& value);
|
||||
|
||||
MaterialProperty& operator=(const MaterialProperty& other);
|
||||
friend QTextStream& operator<<(QTextStream& output, const MaterialProperty& property);
|
||||
@@ -218,6 +234,8 @@ public:
|
||||
return &_appearanceUuids;
|
||||
}
|
||||
|
||||
App::Material getMaterialAppearance() const;
|
||||
|
||||
void setLibrary(const std::shared_ptr<MaterialLibrary>& library)
|
||||
{
|
||||
_library = library;
|
||||
@@ -365,8 +383,24 @@ public:
|
||||
|
||||
void save(QTextStream& stream, bool overwrite, bool saveAsCopy, bool saveInherited);
|
||||
|
||||
/*
|
||||
* Assignment operator
|
||||
*/
|
||||
Material& operator=(const Material& other);
|
||||
|
||||
/*
|
||||
* Set the appearance properties
|
||||
*/
|
||||
Material& operator=(const App::Material& other);
|
||||
|
||||
bool operator==(const Material& other) const
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
return getTypeId() == other.getTypeId() && _uuid == other._uuid;
|
||||
}
|
||||
|
||||
protected:
|
||||
void addModel(const QString& uuid);
|
||||
static void removeUUID(QSet<QString>& uuidList, const QString& uuid);
|
||||
|
||||
@@ -15,11 +15,6 @@
|
||||
<Author Licence="LGPL" Name="DavidCarter" EMail="dcarter@davidcarter.ca" />
|
||||
<UserDocu>Material property descriptions.</UserDocu>
|
||||
</Documentation>
|
||||
<!-- <Methode Name="mirror">
|
||||
<Documentation>
|
||||
<UserDocu>Performs the symmetrical transformation of this geometric object</UserDocu>
|
||||
</Documentation>
|
||||
</Methode> -->
|
||||
<Attribute Name="Name" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Property name.</UserDocu>
|
||||
|
||||
119
src/Mod/Material/App/PropertyMaterial.cpp
Normal file
119
src/Mod/Material/App/PropertyMaterial.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <QMetaType>
|
||||
#include <QUuid>
|
||||
#endif
|
||||
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/Writer.h>
|
||||
#include <Gui/MetaTypes.h>
|
||||
|
||||
#include "MaterialPy.h"
|
||||
#include "PropertyMaterial.h"
|
||||
|
||||
using namespace Materials;
|
||||
|
||||
/* TRANSLATOR Material::PropertyMaterial */
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::PropertyMaterial, App::Property)
|
||||
|
||||
PropertyMaterial::PropertyMaterial() = default;
|
||||
|
||||
PropertyMaterial::~PropertyMaterial() = default;
|
||||
|
||||
void PropertyMaterial::setValue(const Material& mat)
|
||||
{
|
||||
aboutToSetValue();
|
||||
_material = mat;
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
void PropertyMaterial::setValue(const App::Material& mat)
|
||||
{
|
||||
aboutToSetValue();
|
||||
_material = mat;
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
const Material& PropertyMaterial::getValue() const
|
||||
{
|
||||
return _material;
|
||||
}
|
||||
|
||||
PyObject* PropertyMaterial::getPyObject()
|
||||
{
|
||||
return new MaterialPy(new Material(_material));
|
||||
}
|
||||
|
||||
void PropertyMaterial::setPyObject(PyObject* value)
|
||||
{
|
||||
if (PyObject_TypeCheck(value, &(MaterialPy::Type))) {
|
||||
setValue(*static_cast<MaterialPy*>(value)->getMaterialPtr());
|
||||
}
|
||||
else {
|
||||
std::string error = std::string("type must be 'Material' not ");
|
||||
error += value->ob_type->tp_name;
|
||||
throw Base::TypeError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyMaterial::Save(Base::Writer& writer) const
|
||||
{
|
||||
writer.Stream() << writer.ind() << "<PropertyMaterial uuid=\""
|
||||
<< _material.getUUID().toStdString() << "\"/>" << std::endl;
|
||||
}
|
||||
|
||||
void PropertyMaterial::Restore(Base::XMLReader& reader)
|
||||
{
|
||||
// read my Element
|
||||
reader.readElement("PropertyMaterial");
|
||||
// get the value of my Attribute
|
||||
aboutToSetValue();
|
||||
auto uuid = reader.getAttribute("uuid");
|
||||
_material.setUUID(QString::fromLatin1(uuid));
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
const char* PropertyMaterial::getEditorName() const
|
||||
{
|
||||
if (testStatus(MaterialEdit)) {
|
||||
return ""; //"Gui::PropertyEditor::PropertyMaterialItem";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
App::Property* PropertyMaterial::Copy() const
|
||||
{
|
||||
PropertyMaterial* p = new PropertyMaterial();
|
||||
p->_material = _material;
|
||||
return p;
|
||||
}
|
||||
|
||||
void PropertyMaterial::Paste(const App::Property& from)
|
||||
{
|
||||
aboutToSetValue();
|
||||
_material = dynamic_cast<const PropertyMaterial&>(from)._material;
|
||||
hasSetValue();
|
||||
}
|
||||
101
src/Mod/Material/App/PropertyMaterial.h
Normal file
101
src/Mod/Material/App/PropertyMaterial.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023-2024 David Carter <dcarter@david.carter.ca> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef MATERIAL_PROPERTYMATERIAL_H
|
||||
#define MATERIAL_PROPERTYMATERIAL_H
|
||||
|
||||
#include <App/Property.h>
|
||||
#include <Base/Reader.h>
|
||||
|
||||
#include "Materials.h"
|
||||
|
||||
namespace App
|
||||
{
|
||||
class Material;
|
||||
}
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
/** Material properties
|
||||
* This is the father of all properties handling colors.
|
||||
*/
|
||||
class MaterialsExport PropertyMaterial: public App::Property
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
*/
|
||||
PropertyMaterial();
|
||||
|
||||
/**
|
||||
* A destructor.
|
||||
* A more elaborate description of the destructor.
|
||||
*/
|
||||
~PropertyMaterial() override;
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(const Material& mat);
|
||||
|
||||
/** Sets the appearance properties
|
||||
*/
|
||||
void setValue(const App::Material& mat);
|
||||
|
||||
/** This method returns a string representation of the property
|
||||
*/
|
||||
const Material& getValue() const;
|
||||
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
const char* getEditorName() const override;
|
||||
|
||||
Property* Copy() const override;
|
||||
void Paste(const Property& from) override;
|
||||
|
||||
unsigned int getMemSize() const override
|
||||
{
|
||||
return sizeof(_material);
|
||||
}
|
||||
|
||||
bool isSame(const Property& other) const override
|
||||
{
|
||||
if (&other == this) {
|
||||
return true;
|
||||
}
|
||||
return getTypeId() == other.getTypeId()
|
||||
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
|
||||
}
|
||||
|
||||
private:
|
||||
Material _material;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
#endif // MATERIAL_PROPERTYMATERIAL_H
|
||||
Reference in New Issue
Block a user