diff --git a/src/Gui/View3DSettings.h b/src/Gui/View3DSettings.h
index eddea34ea3e1..4c3798f07754 100644
--- a/src/Gui/View3DSettings.h
+++ b/src/Gui/View3DSettings.h
@@ -26,18 +26,19 @@
#include
#include
-namespace Gui {
+namespace Gui
+{
class View3DInventorViewer;
-class View3DSettings : public ParameterGrp::ObserverType
+class GuiExport View3DSettings: public ParameterGrp::ObserverType
{
public:
- View3DSettings(ParameterGrp::handle hGrp, View3DInventorViewer *);
- View3DSettings(ParameterGrp::handle hGrp, const std::vector&);
+ View3DSettings(ParameterGrp::handle hGrp, View3DInventorViewer*);
+ View3DSettings(ParameterGrp::handle hGrp, const std::vector&);
~View3DSettings() override;
/// Observer message from the ParameterGrp
- void OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason) override;
+ void OnChange(ParameterGrp::SubjectType& rCaller, ParameterGrp::MessageType Reason) override;
void applySettings();
int stopAnimatingIfDeactivated() const;
@@ -56,17 +57,18 @@ class NaviCubeSettings
{
Q_DECLARE_TR_FUNCTIONS(NaviCubeSettings)
public:
- NaviCubeSettings(ParameterGrp::handle hGrp, View3DInventorViewer *);
+ NaviCubeSettings(ParameterGrp::handle hGrp, View3DInventorViewer*);
~NaviCubeSettings();
void applySettings();
+
private:
void parameterChanged(ParameterGrp::MessageType pName);
ParameterGrp::handle hGrp;
- View3DInventorViewer * _viewer;
+ View3DInventorViewer* _viewer;
boost::signals2::connection connectParameterChanged;
};
-} // namespace Gui
+} // namespace Gui
#endif // GUI_VIEW3DSETTINGS_H
diff --git a/src/Mod/Material/App/Array2DPy.xml b/src/Mod/Material/App/Array2DPy.xml
index ba6f5f965ff3..c4d066b17bfc 100644
--- a/src/Mod/Material/App/Array2DPy.xml
+++ b/src/Mod/Material/App/Array2DPy.xml
@@ -15,6 +15,12 @@
2D Array of material properties.
+
+
+ The 2 dimensional array.
+
+
+
The number of rows in the array.
@@ -27,9 +33,14 @@
-
+
+
+ Get the row given the first column value
+
+
+
- Get the default value for the first column of the array
+ Get the value at the given row and column
diff --git a/src/Mod/Material/App/Array2DPyImpl.cpp b/src/Mod/Material/App/Array2DPyImpl.cpp
index 02ef6e5465eb..706f62dddecf 100644
--- a/src/Mod/Material/App/Array2DPyImpl.cpp
+++ b/src/Mod/Material/App/Array2DPyImpl.cpp
@@ -21,7 +21,16 @@
#include "PreCompiled.h"
+#include
+#include
+
+#include
+#include
+#include
+#include
+
#include "Array2DPy.h"
+#include "Exceptions.h"
#include "Model.h"
#include "ModelLibrary.h"
#include "ModelPropertyPy.h"
@@ -52,6 +61,25 @@ int Array2DPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
return 0;
}
+Py::List Array2DPy::getArray() const
+{
+ Py::List list;
+ auto array = getMaterial2DArrayPtr()->getArray();
+
+ for (auto& row : array) {
+ Py::List* rowList = new Py::List();
+ for (auto& column : *row) {
+ auto quantity =
+ new Base::QuantityPy(new Base::Quantity(column.value()));
+ rowList->append(Py::Object(quantity));
+ }
+
+ list.append(*rowList);
+ }
+
+ return list;
+}
+
Py::Int Array2DPy::getRows() const
{
return Py::Int(getMaterial2DArrayPtr()->rows());
@@ -62,15 +90,48 @@ Py::Int Array2DPy::getColumns() const
return Py::Int(getMaterial2DArrayPtr()->columns());
}
-PyObject* Array2DPy::getDefaultValue(PyObject* args)
+PyObject* Array2DPy::getRow(PyObject* args)
+{
+ int row;
+ if (!PyArg_ParseTuple(args, "i", &row)) {
+ return nullptr;
+ }
+
+ try {
+ Py::List list;
+
+ auto arrayRow = getMaterial2DArrayPtr()->getRow(row);
+ for (auto& column : *arrayRow) {
+ auto quantity =
+ new Base::QuantityPy(new Base::Quantity(column.value()));
+ list.append(Py::Object(quantity));
+ }
+
+ return Py::new_reference_to(list);
+ }
+ catch (const InvalidIndex&) {
+ }
+
+ PyErr_SetString(PyExc_IndexError, "Invalid array index");
+ return nullptr;
+}
+
+PyObject* Array2DPy::getValue(PyObject* args)
{
- char* name;
- if (!PyArg_ParseTuple(args, "s", &name)) {
+ int row;
+ int column;
+ if (!PyArg_ParseTuple(args, "ii", &row, &column)) {
return nullptr;
}
- // QVariant value = getMaterial2DArrayPtr()->getPhysicalValue(QString::fromStdString(name));
- // return _pyObjectFromVariant(value);
+ try {
+ auto value = getMaterial2DArrayPtr()->getValue(row, column);
+ return new Base::QuantityPy(new Base::Quantity(value.value()));
+ }
+ catch (const InvalidIndex&) {
+ }
+
+ PyErr_SetString(PyExc_IndexError, "Invalid array index");
return nullptr;
}
diff --git a/src/Mod/Material/App/Array3DPy.xml b/src/Mod/Material/App/Array3DPy.xml
new file mode 100644
index 000000000000..b6d55f42edf5
--- /dev/null
+++ b/src/Mod/Material/App/Array3DPy.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+ 3D Array of material properties.
+
+
+
+ The 3 dimensional array.
+
+
+
+
+
+ The number of columns in the array.
+
+
+
+
+
+ The depth of the array (3rd dimension).
+
+
+
+
+
+ Get the number of rows in the array at the specified depth.
+
+
+
+
+ Get the value at the given row and column
+
+
+
+
+ Get the column value at the given depth
+
+
+
+
diff --git a/src/Mod/Material/App/Array3DPyImpl.cpp b/src/Mod/Material/App/Array3DPyImpl.cpp
new file mode 100644
index 000000000000..e4650c59306b
--- /dev/null
+++ b/src/Mod/Material/App/Array3DPyImpl.cpp
@@ -0,0 +1,152 @@
+/***************************************************************************
+ * Copyright (c) 2023 David Carter *
+ * *
+ * 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 *
+ * . *
+ * *
+ **************************************************************************/
+
+#include "PreCompiled.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include "Array3DPy.h"
+#include "Exceptions.h"
+#include "Model.h"
+#include "ModelLibrary.h"
+#include "ModelPropertyPy.h"
+#include "ModelUuids.h"
+
+#include "Array3DPy.cpp"
+
+using namespace Materials;
+
+// returns a string which represents the object e.g. when printed in python
+std::string Array3DPy::representation() const
+{
+ std::stringstream str;
+ str << "";
+
+ return str.str();
+}
+
+PyObject* Array3DPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
+{
+ // never create such objects with the constructor
+ return new Array3DPy(new Material3DArray());
+}
+
+// constructor method
+int Array3DPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
+{
+ return 0;
+}
+
+Py::List Array3DPy::getArray() const
+{
+ Py::List list;
+ auto array = getMaterial3DArrayPtr()->getArray();
+
+ for (auto& depth : array) {
+ Py::List* depthList = new Py::List();
+ for (auto& row : *std::get<1>(depth)) {
+ Py::List* rowList = new Py::List();
+ for (auto& column : *row) {
+ auto quantity = new Base::QuantityPy(new Base::Quantity(column));
+ rowList->append(Py::Object(quantity));
+ }
+
+ depthList->append(*rowList);
+ }
+ list.append(*depthList);
+ }
+
+ return list;
+}
+
+Py::Int Array3DPy::getColumns() const
+{
+ return Py::Int(getMaterial3DArrayPtr()->columns());
+}
+
+Py::Int Array3DPy::getDepth() const
+{
+ return Py::Int(getMaterial3DArrayPtr()->depth());
+}
+
+PyObject* Array3DPy::getRows(PyObject* args)
+{
+ int depth = getMaterial3DArrayPtr()->currentDepth();
+ if (!PyArg_ParseTuple(args, "|i", &depth)) {
+ return nullptr;
+ }
+
+ return PyLong_FromLong(getMaterial3DArrayPtr()->rows(depth));
+}
+
+PyObject* Array3DPy::getValue(PyObject* args)
+{
+ int depth;
+ int row;
+ int column;
+ if (!PyArg_ParseTuple(args, "iii", &depth, &row, &column)) {
+ return nullptr;
+ }
+
+ try {
+ auto value = getMaterial3DArrayPtr()->getValue(depth, row, column);
+ return new Base::QuantityPy(new Base::Quantity(value));
+ }
+ catch (const InvalidIndex&) {
+ }
+
+ PyErr_SetString(PyExc_IndexError, "Invalid array index");
+ return nullptr;
+}
+
+PyObject* Array3DPy::getDepthValue(PyObject* args)
+{
+ int depth;
+ if (!PyArg_ParseTuple(args, "i", &depth)) {
+ return nullptr;
+ }
+
+ try {
+ auto value = getMaterial3DArrayPtr()->getDepthValue(depth);
+ return new Base::QuantityPy(new Base::Quantity(value));
+ }
+ catch (const InvalidIndex&) {
+ }
+
+ PyErr_SetString(PyExc_IndexError, "Invalid array index");
+ return nullptr;
+}
+
+PyObject* Array3DPy::getCustomAttributes(const char* /*attr*/) const
+{
+ return nullptr;
+}
+
+int Array3DPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
+{
+ return 0;
+}
diff --git a/src/Mod/Material/App/CMakeLists.txt b/src/Mod/Material/App/CMakeLists.txt
index ab2bc85745db..4f04e494a6fe 100644
--- a/src/Mod/Material/App/CMakeLists.txt
+++ b/src/Mod/Material/App/CMakeLists.txt
@@ -34,6 +34,7 @@ list(APPEND Material_LIBS
)
generate_from_xml(Array2DPy)
+generate_from_xml(Array3DPy)
generate_from_xml(MaterialManagerPy)
generate_from_xml(MaterialPy)
generate_from_xml(ModelManagerPy)
@@ -45,6 +46,8 @@ SET(Python_SRCS
Exceptions.h
Array2DPy.xml
Array2DPyImpl.cpp
+ Array3DPy.xml
+ Array3DPyImpl.cpp
MaterialManagerPy.xml
MaterialManagerPyImpl.cpp
MaterialPy.xml
diff --git a/src/Mod/Material/App/Exceptions.h b/src/Mod/Material/App/Exceptions.h
index 49152cd263fd..c27adbdf24db 100644
--- a/src/Mod/Material/App/Exceptions.h
+++ b/src/Mod/Material/App/Exceptions.h
@@ -110,6 +110,22 @@ class MaterialExists: public Base::Exception
~MaterialExists() noexcept override = default;
};
+class MaterialReadError: public Base::Exception
+{
+public:
+ MaterialReadError()
+ {}
+ explicit MaterialReadError(const char* msg)
+ {
+ this->setMessage(msg);
+ }
+ explicit MaterialReadError(const QString& msg)
+ {
+ this->setMessage(msg.toStdString().c_str());
+ }
+ ~MaterialReadError() noexcept override = default;
+};
+
class PropertyNotFound: public Base::Exception
{
public:
@@ -158,54 +174,6 @@ class InvalidModel: public Base::Exception
~InvalidModel() noexcept override = default;
};
-class InvalidRow: public Base::Exception
-{
-public:
- InvalidRow()
- {}
- explicit InvalidRow(char* msg)
- {
- this->setMessage(msg);
- }
- explicit InvalidRow(const QString& msg)
- {
- this->setMessage(msg.toStdString().c_str());
- }
- ~InvalidRow() noexcept override = default;
-};
-
-class InvalidColumn: public Base::Exception
-{
-public:
- InvalidColumn()
- {}
- explicit InvalidColumn(char* msg)
- {
- this->setMessage(msg);
- }
- explicit InvalidColumn(const QString& msg)
- {
- this->setMessage(msg.toStdString().c_str());
- }
- ~InvalidColumn() noexcept override = default;
-};
-
-class InvalidDepth: public Base::Exception
-{
-public:
- InvalidDepth()
- {}
- explicit InvalidDepth(char* msg)
- {
- this->setMessage(msg);
- }
- explicit InvalidDepth(const QString& msg)
- {
- this->setMessage(msg.toStdString().c_str());
- }
- ~InvalidDepth() noexcept override = default;
-};
-
class InvalidIndex: public Base::Exception
{
public:
diff --git a/src/Mod/Material/App/MaterialConfigLoader.cpp b/src/Mod/Material/App/MaterialConfigLoader.cpp
index 492730f2ec17..449c00e571c0 100644
--- a/src/Mod/Material/App/MaterialConfigLoader.cpp
+++ b/src/Mod/Material/App/MaterialConfigLoader.cpp
@@ -26,6 +26,11 @@
#include
#endif
+#include
+
+#include
+#include
+#include
#include
#include
@@ -33,6 +38,7 @@
#include
+#include "Exceptions.h"
#include "MaterialConfigLoader.h"
#include "MaterialLoader.h"
#include "Model.h"
@@ -41,27 +47,117 @@
using namespace Materials;
-MaterialConfigLoader::MaterialConfigLoader()
-{}
-
bool MaterialConfigLoader::isConfigStyle(const QString& path)
{
- std::ifstream infile(path.toStdString());
+ QSettings fcmat(path, QSettings::IniFormat);
- // Check the first 2 lines for a ";"
- for (int i = 0; i < 2; i++) {
- std::string line;
- if (!std::getline(infile, line)) {
- return false;
- }
- if (line.at(0) != ';') {
- return false;
+ // No [sections] means not .ini
+ if (fcmat.childGroups().empty()) {
+ return false;
+ }
+
+ // Sometimes arrays can create a false positive
+ QFile infile(path);
+ if (infile.open(QIODevice::ReadOnly)) {
+ QTextStream in(&infile);
+
+ if (!in.atEnd()) {
+ auto line = in.readLine();
+ if (line.trimmed().startsWith(QLatin1Char('-'))
+ || line.trimmed().startsWith(QLatin1Char('#'))) {
+ // Definitely a YAML file
+ return false;
+ }
}
}
+ infile.close();
+ // No false positive
return true;
}
+bool MaterialConfigLoader::readFile(const QString& path, QMap& map)
+{
+ // This function is necessary as the built in routines don't always return the full value string
+ QFile infile(path);
+ if (infile.open(QIODevice::ReadOnly)) {
+ QTextStream in(&infile);
+ in.setCodec("UTF-8");
+
+ QString line;
+ QString prefix;
+ while (!in.atEnd()) {
+ line = in.readLine();
+ if (line.trimmed().startsWith(QLatin1Char(';'))) {
+ continue;
+ }
+
+ if (line.startsWith(QLatin1Char('['))) {
+ // read prefix
+ auto end = line.indexOf(QLatin1Char(']'));
+ if (end > 1) {
+ prefix = line.mid(1, end - 1) + QString::fromStdString("/");
+
+ // Render WB uses both Render and Rendering
+ if (prefix == QString::fromStdString("Rendering/")) {
+ prefix = QString::fromStdString("Render/");
+ }
+ }
+ }
+ else {
+ auto separator = line.indexOf(QLatin1Char('='));
+ if (separator > 2) {
+ auto left = line.mid(0, separator - 1);
+ auto right = line.mid(separator + 2);
+ map[prefix + left] = right;
+ }
+ }
+ }
+ infile.close();
+ return true;
+ }
+
+ return false;
+}
+
+void MaterialConfigLoader::splitTexture(const QString& value, QString* texture, QString* remain)
+{
+ // Split Texture(...);(...) into its two pieces
+ if (value.contains(QLatin1Char(';'))) {
+ auto separator = value.indexOf(QLatin1Char(';'));
+ auto left = value.mid(0, separator);
+ auto right = value.mid(separator + 1);
+ if (isTexture(left)) {
+ *texture = left;
+ *remain = right;
+ }
+ else {
+ *texture = right;
+ *remain = left;
+ }
+ }
+ else {
+ if (isTexture(value)) {
+ *texture = value;
+ }
+ else {
+ *remain = value;
+ }
+ }
+}
+
+void MaterialConfigLoader::splitTextureObject(const QString& value,
+ QString* texture,
+ QString* remain,
+ QString* object)
+{
+ splitTexture(value, texture, remain);
+ if (*remain == QString::fromStdString("Object")) {
+ *remain = QString(); // Empty string
+ *object = QString::fromStdString("true");
+ }
+}
+
QString MaterialConfigLoader::getAuthorAndLicense(const QString& path)
{
std::ifstream infile(path.toStdString());
@@ -77,7 +173,7 @@ QString MaterialConfigLoader::getAuthorAndLicense(const QString& path)
if (!std::getline(infile, line)) {
return noAuthor;
}
- std::size_t found = line.find(";");
+ std::size_t found = line.find(';');
if (found != std::string::npos) {
return QString::fromStdString(trim_copy(line.substr(found + 1)));
}
@@ -85,8 +181,8 @@ QString MaterialConfigLoader::getAuthorAndLicense(const QString& path)
return noAuthor;
}
-void MaterialConfigLoader::addVectorRendering(const QSettings& fcmat,
- std::shared_ptr finalModel)
+void MaterialConfigLoader::addVectorRendering(const QMap& fcmat,
+ const std::shared_ptr& finalModel)
{
QString sectionFillPattern = value(fcmat, "VectorRendering/SectionFillPattern", "");
QString sectionLinewidth = value(fcmat, "VectorRendering/SectionLinewidth", "");
@@ -95,23 +191,30 @@ void MaterialConfigLoader::addVectorRendering(const QSettings& fcmat,
QString viewFillPattern = value(fcmat, "VectorRendering/ViewFillPattern", "");
QString viewLinewidth = value(fcmat, "VectorRendering/ViewLinewidth", "");
+ // Defined by the Render WB
+ QString aSection = value(fcmat, "Architectural/SectionColor", "");
+
+ if (!aSection.isEmpty()) {
+ sectionColor = aSection;
+ }
+
if (sectionFillPattern.length() + sectionLinewidth.length() + sectionColor.length()
+ viewColor.length() + viewFillPattern.length() + viewLinewidth.length()
> 0) {
finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Vector);
- }
- // Now add the data
- setAppearanceValue(finalModel, "SectionFillPattern", sectionFillPattern);
- setAppearanceValue(finalModel, "SectionLinewidth", sectionLinewidth);
- setAppearanceValue(finalModel, "SectionColor", sectionColor);
- setAppearanceValue(finalModel, "ViewColor", viewColor);
- setAppearanceValue(finalModel, "ViewFillPattern", viewFillPattern);
- setAppearanceValue(finalModel, "ViewLinewidth", viewLinewidth);
+ // Now add the data
+ setAppearanceValue(finalModel, "SectionFillPattern", sectionFillPattern);
+ setAppearanceValue(finalModel, "SectionLinewidth", sectionLinewidth);
+ setAppearanceValue(finalModel, "SectionColor", sectionColor);
+ setAppearanceValue(finalModel, "ViewColor", viewColor);
+ setAppearanceValue(finalModel, "ViewFillPattern", viewFillPattern);
+ setAppearanceValue(finalModel, "ViewLinewidth", viewLinewidth);
+ }
}
-void MaterialConfigLoader::addRendering(const QSettings& fcmat,
- std::shared_ptr finalModel)
+void MaterialConfigLoader::addRendering(const QMap& fcmat,
+ const std::shared_ptr& finalModel)
{
QString ambientColor = value(fcmat, "Rendering/AmbientColor", "");
QString diffuseColor = value(fcmat, "Rendering/DiffuseColor", "");
@@ -124,6 +227,17 @@ void MaterialConfigLoader::addRendering(const QSettings& fcmat,
QString fragmentShader = value(fcmat, "Rendering/FragmentShader", "");
QString vertexShader = value(fcmat, "Rendering/VertexShader", "");
+ // Defined by the Render WB
+ QString aDiffuse = value(fcmat, "Architectural/DiffuseColor", "");
+ QString aTransparency = value(fcmat, "Architectural/Transparency", "");
+
+ if (!aDiffuse.isEmpty()) {
+ diffuseColor = aDiffuse;
+ }
+ if (!aTransparency.isEmpty()) {
+ transparency = aTransparency;
+ }
+
// Check which model we need
bool useTexture = false;
bool useAdvanced = false;
@@ -163,7 +277,565 @@ void MaterialConfigLoader::addRendering(const QSettings& fcmat,
setAppearanceValue(finalModel, "VertexShader", vertexShader);
}
-void MaterialConfigLoader::addCosts(const QSettings& fcmat, std::shared_ptr finalModel)
+QString MaterialConfigLoader::multiLineKey(QMap& fcmat, const QString& prefix)
+{
+ // fcmat.beginGroup(QString::fromStdString("Render"));
+ QString multiLineString;
+ auto keys = fcmat.keys();
+ for (const auto& key : keys) {
+ if (key.startsWith(prefix) || key.startsWith(QString::fromStdString("Render/") + prefix)) {
+ QString string = value(fcmat, key.toStdString(), "");
+ if (multiLineString.isEmpty()) {
+ multiLineString += string;
+ }
+ else {
+ multiLineString += QString::fromStdString("\n") + string;
+ }
+ }
+ }
+ // fcmat.endGroup();
+
+ return multiLineString;
+}
+
+void MaterialConfigLoader::addRenderAppleseed(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString prefix = QString::fromStdString("Render.Appleseed");
+ QString string = multiLineKey(fcmat, prefix);
+
+ if (!string.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Appleseed);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Appleseed", string);
+ }
+}
+
+void MaterialConfigLoader::addRenderCarpaint(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString renderBaseColorValue = value(fcmat, "Render/Render.Carpaint.BaseColor", "");
+ QString renderBump = value(fcmat, "Render/Render.Carpaint.Bump", "");
+ QString renderDisplacement = value(fcmat, "Render/Render.Carpaint.Displacement", "");
+ QString renderNormal = value(fcmat, "Render/Render.Carpaint.Normal", "");
+
+ // Split out the textures
+ QString renderBaseColor;
+ QString renderBaseColorTexture;
+ QString renderBaseColorObject;
+ splitTextureObject(renderBaseColorValue,
+ &renderBaseColorTexture,
+ &renderBaseColor,
+ &renderBaseColorObject);
+
+ if (!renderBaseColorValue.isEmpty() || !renderBump.isEmpty() || !renderDisplacement.isEmpty()
+ || !renderNormal.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Carpaint);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Carpaint.BaseColor", renderBaseColor);
+ setAppearanceValue(finalModel, "Render.Carpaint.BaseColor.Texture", renderBaseColorTexture);
+ setAppearanceValue(finalModel, "Render.Carpaint.BaseColor.Object", renderBaseColorObject);
+ setAppearanceValue(finalModel, "Render.Carpaint.Bump", renderBump);
+ setAppearanceValue(finalModel, "Render.Carpaint.Displacement", renderDisplacement);
+ setAppearanceValue(finalModel, "Render.Carpaint.Normal", renderNormal);
+ }
+}
+
+void MaterialConfigLoader::addRenderCycles(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString prefix = QString::fromStdString("Render.Cycles");
+ QString string = multiLineKey(fcmat, prefix);
+ if (!string.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Cycles);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Cycles", string);
+ }
+}
+
+void MaterialConfigLoader::addRenderDiffuse(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString renderBump = value(fcmat, "Render/Render.Diffuse.Bump", "");
+ QString renderColorValue = value(fcmat, "Render/Render.Diffuse.Color", "");
+ QString renderDisplacement = value(fcmat, "Render/Render.Diffuse.Displacement", "");
+ QString renderNormal = value(fcmat, "Render/Render.Diffuse.Normal", "");
+
+ // Split out the textures
+ QString renderColor;
+ QString renderColorTexture;
+ QString renderColorObject;
+ splitTextureObject(renderColorValue, &renderColorTexture, &renderColor, &renderColorObject);
+
+ if (!renderBump.isEmpty() || !renderColorValue.isEmpty() || !renderDisplacement.isEmpty()
+ || !renderNormal.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Diffuse);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Diffuse.Bump", renderBump);
+ setAppearanceValue(finalModel, "Render.Diffuse.Color", renderColor);
+ setAppearanceValue(finalModel, "Render.Diffuse.Color.Texture", renderColorTexture);
+ setAppearanceValue(finalModel, "Render.Diffuse.Color.Object", renderColorObject);
+ setAppearanceValue(finalModel, "Render.Diffuse.Displacement", renderDisplacement);
+ setAppearanceValue(finalModel, "Render.Diffuse.Normal", renderNormal);
+ }
+}
+
+void MaterialConfigLoader::addRenderDisney(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString renderAnisotropicValue = value(fcmat, "Render/Render.Disney.Anisotropic", "");
+ QString renderBaseColorValue = value(fcmat, "Render/Render.Disney.BaseColor", "");
+ QString renderBump = value(fcmat, "Render/Render.Disney.Bump", "");
+ QString renderClearCoatValue = value(fcmat, "Render/Render.Disney.ClearCoat", "");
+ QString renderClearCoatGlossValue = value(fcmat, "Render/Render.Disney.ClearCoatGloss", "");
+ QString renderDisplacement = value(fcmat, "Render/Render.Disney.Displacement", "");
+ QString renderMetallicValue = value(fcmat, "Render/Render.Disney.Metallic", "");
+ QString renderNormal = value(fcmat, "Render/Render.Disney.Normal", "");
+ QString renderRoughnessValue = value(fcmat, "Render/Render.Disney.Roughness", "");
+ QString renderSheenValue = value(fcmat, "Render/Render.Disney.Sheen", "");
+ QString renderSheenTintValue = value(fcmat, "Render/Render.Disney.SheenTint", "");
+ QString renderSpecularValue = value(fcmat, "Render/Render.Disney.Specular", "");
+ QString renderSpecularTintValue = value(fcmat, "Render/Render.Disney.SpecularTint", "");
+ QString renderSubsurfaceValue = value(fcmat, "Render/Render.Disney.Subsurface", "");
+
+ // Split out the textures
+ QString renderAnisotropic;
+ QString renderAnisotropicTexture;
+ splitTexture(renderAnisotropicValue, &renderAnisotropicTexture, &renderAnisotropic);
+ QString renderBaseColor;
+ QString renderBaseColorTexture;
+ QString renderBaseColorObject;
+ splitTextureObject(renderBaseColorValue,
+ &renderBaseColorTexture,
+ &renderBaseColor,
+ &renderBaseColorObject);
+ QString renderClearCoat;
+ QString renderClearCoatTexture;
+ QString renderClearCoatObject;
+ splitTextureObject(renderClearCoatValue,
+ &renderClearCoatTexture,
+ &renderClearCoat,
+ &renderClearCoatObject);
+ QString renderClearCoatGloss;
+ QString renderClearCoatGlossTexture;
+ QString renderClearCoatGlossObject;
+ splitTextureObject(renderClearCoatGlossValue,
+ &renderClearCoatGlossTexture,
+ &renderClearCoatGloss,
+ &renderClearCoatGlossObject);
+ QString renderMetallic;
+ QString renderMetallicTexture;
+ splitTexture(renderMetallicValue, &renderMetallicTexture, &renderMetallic);
+ QString renderRoughness;
+ QString renderRoughnessTexture;
+ splitTexture(renderRoughnessValue, &renderRoughnessTexture, &renderRoughness);
+ QString renderSheen;
+ QString renderSheenTexture;
+ splitTexture(renderSheenValue, &renderSheenTexture, &renderSheen);
+ QString renderSheenTint;
+ QString renderSheenTintTexture;
+ splitTexture(renderSheenTintValue, &renderSheenTintTexture, &renderSheenTint);
+ QString renderSpecular;
+ QString renderSpecularTexture;
+ QString renderSpecularObject;
+ splitTextureObject(renderSpecularValue,
+ &renderSpecularTexture,
+ &renderSpecular,
+ &renderSpecularObject);
+ QString renderSpecularTint;
+ QString renderSpecularTintTexture;
+ QString renderSpecularTintObject;
+ splitTextureObject(renderSpecularTintValue,
+ &renderSpecularTintTexture,
+ &renderSpecularTint,
+ &renderSpecularTintObject);
+ QString renderSubsurface;
+ QString renderSubsurfaceTexture;
+ splitTexture(renderSubsurfaceValue, &renderSubsurfaceTexture, &renderSubsurface);
+
+ if (!renderAnisotropicValue.isEmpty() || !renderBaseColorValue.isEmpty()
+ || !renderBump.isEmpty() || !renderClearCoatValue.isEmpty()
+ || !renderClearCoatGlossValue.isEmpty() || !renderDisplacement.isEmpty()
+ || !renderMetallicValue.isEmpty() || !renderNormal.isEmpty()
+ || !renderRoughnessValue.isEmpty() || !renderSheenValue.isEmpty()
+ || !renderSheenTintValue.isEmpty() || !renderSpecularValue.isEmpty()
+ || !renderSpecularTintValue.isEmpty() || !renderSubsurfaceValue.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Disney);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Disney.Anisotropic", renderAnisotropic);
+ setAppearanceValue(finalModel,
+ "Render.Disney.Anisotropic.Texture",
+ renderAnisotropicTexture);
+ setAppearanceValue(finalModel, "Render.Disney.BaseColor", renderBaseColor);
+ setAppearanceValue(finalModel, "Render.Disney.BaseColor.Texture", renderBaseColorTexture);
+ setAppearanceValue(finalModel, "Render.Disney.Bump", renderBump);
+ setAppearanceValue(finalModel, "Render.Disney.ClearCoat", renderClearCoat);
+ setAppearanceValue(finalModel, "Render.Disney.ClearCoat.Texture", renderClearCoatTexture);
+ setAppearanceValue(finalModel, "Render.Disney.ClearCoatGloss", renderClearCoatGloss);
+ setAppearanceValue(finalModel,
+ "Render.Disney.ClearCoatGloss.Texture",
+ renderClearCoatGlossTexture);
+ setAppearanceValue(finalModel, "Render.Disney.Displacement", renderDisplacement);
+ setAppearanceValue(finalModel, "Render.Disney.Metallic", renderMetallic);
+ setAppearanceValue(finalModel, "Render.Disney.Metallic.Texture", renderMetallicTexture);
+ setAppearanceValue(finalModel, "Render.Disney.Normal", renderNormal);
+ setAppearanceValue(finalModel, "Render.Disney.Roughness", renderRoughness);
+ setAppearanceValue(finalModel, "Render.Disney.Roughness.Texture", renderRoughnessTexture);
+ setAppearanceValue(finalModel, "Render.Disney.Sheen", renderSheen);
+ setAppearanceValue(finalModel, "Render.Disney.Sheen.Texture", renderSheenTexture);
+ setAppearanceValue(finalModel, "Render.Disney.SheenTint", renderSheenTint);
+ setAppearanceValue(finalModel, "Render.Disney.SheenTint.Texture", renderSheenTintTexture);
+ setAppearanceValue(finalModel, "Render.Disney.Specular", renderSpecular);
+ setAppearanceValue(finalModel, "Render.Disney.Specular.Texture", renderSpecularTexture);
+ setAppearanceValue(finalModel, "Render.Disney.SpecularTint", renderSpecularTint);
+ setAppearanceValue(finalModel,
+ "Render.Disney.SpecularTint.Texture",
+ renderSpecularTintTexture);
+ setAppearanceValue(finalModel, "Render.Disney.Subsurface", renderSubsurface);
+ setAppearanceValue(finalModel, "Render.Disney.Subsurface.Texture", renderSubsurfaceTexture);
+ }
+}
+
+void MaterialConfigLoader::addRenderEmission(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString renderBump = value(fcmat, "Render/Render.Emission.Bump", "");
+ QString renderColorValue = value(fcmat, "Render/Render.Emission.Color", "");
+ QString renderNormal = value(fcmat, "Render/Render.Emission.Normal", "");
+ QString renderPowerValue = value(fcmat, "Render/Render.Emission.Power", "");
+
+ // Split out the textures
+ QString renderColor;
+ QString renderColorTexture;
+ QString renderColorObject;
+ splitTextureObject(renderColorValue, &renderColorTexture, &renderColor, &renderColorObject);
+ QString renderPower;
+ QString renderPowerTexture;
+ splitTexture(renderPowerValue, &renderPowerTexture, &renderPower);
+
+ if (!renderColorValue.isEmpty() || !renderBump.isEmpty() || !renderPowerValue.isEmpty()
+ || !renderNormal.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Emission);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Emission.Bump", renderBump);
+ setAppearanceValue(finalModel, "Render.Emission.Color", renderColor);
+ setAppearanceValue(finalModel, "Render.Emission.Color.Texture", renderColorTexture);
+ setAppearanceValue(finalModel, "Render.Emission.Color.Object", renderColorObject);
+ setAppearanceValue(finalModel, "Render.Emission.Normal", renderNormal);
+ setAppearanceValue(finalModel, "Render.Emission.Power", renderPower);
+ setAppearanceValue(finalModel, "Render.Emission.Power.Texture", renderPowerTexture);
+ }
+}
+
+void MaterialConfigLoader::addRenderGlass(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString renderBump = value(fcmat, "Render/Render.Glass.Bump", "");
+ QString renderColorValue = value(fcmat, "Render/Render.Glass.Color", "");
+ QString renderIORValue = value(fcmat, "Render/Render.Glass.IOR", "");
+ QString renderDisplacement = value(fcmat, "Render/Render.Glass.Displacement", "");
+ QString renderNormal = value(fcmat, "Render/Render.Glass.Normal", "");
+
+ // Split out the textures
+ QString renderColor;
+ QString renderColorTexture;
+ QString renderColorObject;
+ splitTextureObject(renderColorValue, &renderColorTexture, &renderColor, &renderColorObject);
+ QString renderIOR;
+ QString renderIORTexture;
+ splitTexture(renderIORValue, &renderIORTexture, &renderIOR);
+
+ if (!renderBump.isEmpty() || !renderColorValue.isEmpty() || !renderIORValue.isEmpty()
+ || !renderDisplacement.isEmpty() || !renderNormal.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Glass);
+
+ setAppearanceValue(finalModel, "Render.Glass.Bump", renderBump);
+ setAppearanceValue(finalModel, "Render.Glass.Color", renderColor);
+ setAppearanceValue(finalModel, "Render.Glass.Color.Texture", renderColorTexture);
+ setAppearanceValue(finalModel, "Render.Glass.Color.Object", renderColorObject);
+ setAppearanceValue(finalModel, "Render.Glass.IOR", renderIOR);
+ setAppearanceValue(finalModel, "Render.Glass.IOR.Texture", renderIORTexture);
+ setAppearanceValue(finalModel, "Render.Glass.Displacement", renderDisplacement);
+ setAppearanceValue(finalModel, "Render.Glass.Normal", renderNormal);
+ }
+}
+
+void MaterialConfigLoader::addRenderLuxcore(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString prefix = QString::fromStdString("Render.Luxcore");
+ QString string = multiLineKey(fcmat, prefix);
+
+ if (!string.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Luxcore);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Luxcore", string);
+ }
+}
+
+void MaterialConfigLoader::addRenderLuxrender(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString prefix = QString::fromStdString("Render.Luxrender");
+ QString string = multiLineKey(fcmat, prefix);
+
+ if (!string.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Luxrender);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Luxrender", string);
+ }
+}
+
+void MaterialConfigLoader::addRenderMixed(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString renderBump = value(fcmat, "Render/Render.Mixed.Bump", "");
+ QString renderDiffuseColorValue = value(fcmat, "Render/Render.Mixed.Diffuse.Color", "");
+ QString renderDisplacement = value(fcmat, "Render/Render.Mixed.Displacement", "");
+ QString renderGlassColorValue = value(fcmat, "Render/Render.Mixed.Glass.Color", "");
+ QString renderGlassIORValue = value(fcmat, "Render/Render.Mixed.Glass.IOR", "");
+ QString renderNormal = value(fcmat, "Render/Render.Mixed.Normal", "");
+ QString renderTransparencyValue = value(fcmat, "Render/Render.Mixed.Transparency", "");
+
+ // Split out the textures
+ QString renderDiffuseColor;
+ QString renderDiffuseColorTexture;
+ QString renderDiffuseColorObject;
+ splitTextureObject(renderDiffuseColorValue,
+ &renderDiffuseColorTexture,
+ &renderDiffuseColor,
+ &renderDiffuseColorObject);
+ QString renderGlassColor;
+ QString renderGlassColorTexture;
+ QString renderGlassColorObject;
+ splitTextureObject(renderGlassColorValue,
+ &renderGlassColorTexture,
+ &renderGlassColor,
+ &renderGlassColorObject);
+ QString renderGlassIOR;
+ QString renderGlassIORTexture;
+ splitTexture(renderGlassIORValue, &renderGlassIORTexture, &renderGlassIOR);
+ QString renderTransparency;
+ QString renderTransparencyTexture;
+ splitTexture(renderTransparencyValue, &renderTransparencyTexture, &renderTransparency);
+
+ if (!renderBump.isEmpty() || !renderDiffuseColorValue.isEmpty() || !renderDisplacement.isEmpty()
+ || !renderGlassColorValue.isEmpty() || !renderGlassIORValue.isEmpty()
+ || !renderNormal.isEmpty() || !renderTransparencyValue.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Mixed);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Mixed.Bump", renderBump);
+ setAppearanceValue(finalModel, "Render.Mixed.Diffuse.Color", renderDiffuseColor);
+ setAppearanceValue(finalModel,
+ "Render.Mixed.Diffuse.Color.Texture",
+ renderDiffuseColorTexture);
+ setAppearanceValue(finalModel,
+ "Render.Mixed.Diffuse.Color.Object",
+ renderDiffuseColorObject);
+ setAppearanceValue(finalModel, "Render.Mixed.Displacement", renderDisplacement);
+ setAppearanceValue(finalModel, "Render.Mixed.Glass.Color", renderGlassColor);
+ setAppearanceValue(finalModel, "Render.Mixed.Glass.Color.Texture", renderGlassColorTexture);
+ setAppearanceValue(finalModel, "Render.Mixed.Glass.Color.Object", renderGlassColorObject);
+ setAppearanceValue(finalModel, "Render.Mixed.Glass.IOR", renderGlassIOR);
+ setAppearanceValue(finalModel, "Render.Mixed.Glass.IOR.Texture", renderGlassIORTexture);
+ setAppearanceValue(finalModel, "Render.Mixed.Normal", renderNormal);
+ setAppearanceValue(finalModel, "Render.Mixed.Transparency", renderTransparency);
+ setAppearanceValue(finalModel,
+ "Render.Mixed.Transparency.Texture",
+ renderTransparencyTexture);
+ }
+}
+
+void MaterialConfigLoader::addRenderOspray(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString prefix = QString::fromStdString("Render.Ospray");
+ QString string = multiLineKey(fcmat, prefix);
+
+ if (!string.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Ospray);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Ospray", string);
+ }
+}
+
+void MaterialConfigLoader::addRenderPbrt(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString prefix = QString::fromStdString("Render.Pbrt");
+ QString string = multiLineKey(fcmat, prefix);
+
+ if (!string.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Pbrt);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Pbrt", string);
+ }
+}
+
+void MaterialConfigLoader::addRenderPovray(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString prefix = QString::fromStdString("Render.Povray");
+ QString string = multiLineKey(fcmat, prefix);
+
+ if (!string.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Povray);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Povray", string);
+ }
+}
+
+void MaterialConfigLoader::addRenderSubstancePBR(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString renderBaseColorValue = value(fcmat, "Render/Render.Substance_PBR.BaseColor", "");
+ QString renderBump = value(fcmat, "Render/Render.Substance_PBR.Bump", "");
+ QString renderMetallicValue = value(fcmat, "Render/Render.Substance_PBR.Metallic", "");
+ QString renderNormal = value(fcmat, "Render/Render.Substance_PBR.Normal", "");
+ QString renderRoughnessValue = value(fcmat, "Render/Render.Substance_PBR.Roughness", "");
+ QString renderSpecularValue = value(fcmat, "Render/Render.Substance_PBR.Specular", "");
+
+ // Split out the textures
+ QString renderBaseColor;
+ QString renderBaseColorTexture;
+ QString renderBaseColorObject;
+ splitTextureObject(renderBaseColorValue,
+ &renderBaseColorTexture,
+ &renderBaseColor,
+ &renderBaseColorObject);
+ QString renderMetallic;
+ QString renderMetallicTexture;
+ splitTexture(renderMetallicValue, &renderMetallicTexture, &renderMetallic);
+ QString renderRoughness;
+ QString renderRoughnessTexture;
+ splitTexture(renderRoughnessValue, &renderRoughnessTexture, &renderRoughness);
+ QString renderSpecular;
+ QString renderSpecularTexture;
+ splitTexture(renderSpecularValue, &renderSpecularTexture, &renderSpecular);
+
+ if (!renderBaseColorValue.isEmpty() || !renderBump.isEmpty() || !renderMetallicValue.isEmpty()
+ || !renderNormal.isEmpty() || !renderRoughnessValue.isEmpty()
+ || !renderSpecularValue.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_SubstancePBR);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Substance_PBR.BaseColor", renderBaseColor);
+ setAppearanceValue(finalModel,
+ "Render.Substance_PBR.BaseColor.Texture",
+ renderBaseColorTexture);
+ setAppearanceValue(finalModel,
+ "Render.Substance_PBR.BaseColor.Object",
+ renderBaseColorObject);
+ setAppearanceValue(finalModel, "Render.Substance_PBR.Bump", renderBump);
+ setAppearanceValue(finalModel, "Render.Substance_PBR.Metallic", renderMetallic);
+ setAppearanceValue(finalModel,
+ "Render.Substance_PBR.Metallic.Texture",
+ renderMetallicTexture);
+ setAppearanceValue(finalModel, "Render.Substance_PBR.Normal", renderNormal);
+ setAppearanceValue(finalModel, "Render.Substance_PBR.Roughness", renderRoughness);
+ setAppearanceValue(finalModel,
+ "Render.Substance_PBR.Roughness.Texture",
+ renderRoughnessTexture);
+ setAppearanceValue(finalModel, "Render.Substance_PBR.Specular", renderSpecular);
+ setAppearanceValue(finalModel,
+ "Render.Substance_PBR.Specular.Texture",
+ renderSpecularTexture);
+ }
+}
+
+void MaterialConfigLoader::addRenderTexture(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString renderName;
+ auto renderImage = std::make_shared>();
+ QString renderScale;
+ QString renderRotation;
+ QString renderTranslationU;
+ QString renderTranslationV;
+
+ auto keys = fcmat.keys();
+ for (const auto& key : keys) {
+ if (key.startsWith(QString::fromStdString("Render/Render.Textures."))) {
+ QStringList list1 = key.split(QLatin1Char('.'));
+ if (renderName.isEmpty()) {
+ renderName = list1[2];
+ }
+ if (list1[3] == QString::fromStdString("Images")) {
+ renderImage->push_back(value(fcmat, key.toStdString(), ""));
+ }
+ else if (list1[3] == QString::fromStdString("Scale")) {
+ renderScale = value(fcmat, key.toStdString(), "");
+ }
+ else if (list1[3] == QString::fromStdString("Rotation")) {
+ renderRotation = value(fcmat, key.toStdString(), "");
+ }
+ else if (list1[3] == QString::fromStdString("TranslationU")) {
+ renderTranslationU = value(fcmat, key.toStdString(), "");
+ }
+ else if (list1[3] == QString::fromStdString(" TranslationV")) {
+ renderTranslationV = value(fcmat, key.toStdString(), "");
+ }
+ }
+ }
+
+ if (!renderName.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Texture);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "Render.Textures.Name", renderName);
+ setAppearanceValue(finalModel, "Render.Textures.Images", renderImage);
+ setAppearanceValue(finalModel, "Render.Textures.Scale", renderScale);
+ setAppearanceValue(finalModel, "Render.Textures.Rotation", renderRotation);
+ setAppearanceValue(finalModel, "Render.Textures.TranslationU", renderTranslationU);
+ setAppearanceValue(finalModel, "Render.Textures.TranslationV", renderTranslationV);
+ }
+}
+
+void MaterialConfigLoader::addRenderWB(QMap& fcmat,
+ const std::shared_ptr& finalModel)
+{
+ QString useObjectColor = value(fcmat, "General/UseObjectColor", "");
+ QString renderType = value(fcmat, "Render/Render.Type", "");
+
+ if (!renderType.isEmpty()) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_RenderWB);
+
+ // Now add the data
+ setAppearanceValue(finalModel, "UseObjectColor", useObjectColor);
+ setAppearanceValue(finalModel, "Render.Type", renderType);
+ }
+
+ addRenderAppleseed(fcmat, finalModel);
+ addRenderCarpaint(fcmat, finalModel);
+ addRenderCycles(fcmat, finalModel);
+ addRenderDiffuse(fcmat, finalModel);
+ addRenderDisney(fcmat, finalModel);
+ addRenderEmission(fcmat, finalModel);
+ addRenderGlass(fcmat, finalModel);
+ addRenderLuxcore(fcmat, finalModel);
+ addRenderLuxrender(fcmat, finalModel);
+ addRenderMixed(fcmat, finalModel);
+ addRenderOspray(fcmat, finalModel);
+ addRenderPbrt(fcmat, finalModel);
+ addRenderPovray(fcmat, finalModel);
+ addRenderSubstancePBR(fcmat, finalModel);
+ addRenderTexture(fcmat, finalModel);
+}
+
+void MaterialConfigLoader::addCosts(const QMap& fcmat,
+ const std::shared_ptr& finalModel)
{
QString productURL = value(fcmat, "Cost/ProductURL", "");
QString specificPrice = value(fcmat, "Cost/SpecificPrice", "");
@@ -171,16 +843,16 @@ void MaterialConfigLoader::addCosts(const QSettings& fcmat, std::shared_ptr 0) {
finalModel->addPhysical(ModelUUIDs::ModelUUID_Costs_Default);
- }
- // Now add the data
- setPhysicalValue(finalModel, "ProductURL", productURL);
- setPhysicalValue(finalModel, "SpecificPrice", specificPrice);
- setPhysicalValue(finalModel, "Vendor", vendor);
+ // Now add the data
+ setPhysicalValue(finalModel, "ProductURL", productURL);
+ setPhysicalValue(finalModel, "SpecificPrice", specificPrice);
+ setPhysicalValue(finalModel, "Vendor", vendor);
+ }
}
-void MaterialConfigLoader::addArchitectural(const QSettings& fcmat,
- std::shared_ptr finalModel)
+void MaterialConfigLoader::addArchitectural(const QMap& fcmat,
+ const std::shared_ptr& finalModel)
{
QString color = value(fcmat, "Architectural/Color", "");
QString environmentalEfficiencyClass =
@@ -192,26 +864,30 @@ void MaterialConfigLoader::addArchitectural(const QSettings& fcmat,
QString soundTransmissionClass = value(fcmat, "Architectural/SoundTransmissionClass", "");
QString unitsPerQuantity = value(fcmat, "Architectural/UnitsPerQuantity", "");
- if (color.length() + environmentalEfficiencyClass.length() + executionInstructions.length()
- + finish.length() + fireResistanceClass.length() + model.length()
- + soundTransmissionClass.length() + unitsPerQuantity.length()
+ if (environmentalEfficiencyClass.length() + executionInstructions.length()
+ + fireResistanceClass.length() + model.length() + soundTransmissionClass.length()
+ + unitsPerQuantity.length()
> 0) {
finalModel->addPhysical(ModelUUIDs::ModelUUID_Architectural_Default);
}
+ if (color.length() + finish.length() > 0) {
+ finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Architectural);
+ }
// Now add the data
- setPhysicalValue(finalModel, "Color", color);
setPhysicalValue(finalModel, "EnvironmentalEfficiencyClass", environmentalEfficiencyClass);
setPhysicalValue(finalModel, "ExecutionInstructions", executionInstructions);
- setPhysicalValue(finalModel, "Finish", finish);
setPhysicalValue(finalModel, "FireResistanceClass", fireResistanceClass);
setPhysicalValue(finalModel, "Model", model);
setPhysicalValue(finalModel, "SoundTransmissionClass", soundTransmissionClass);
setPhysicalValue(finalModel, "UnitsPerQuantity", unitsPerQuantity);
+
+ setAppearanceValue(finalModel, "Color", color);
+ setAppearanceValue(finalModel, "Finish", finish);
}
-void MaterialConfigLoader::addElectromagnetic(const QSettings& fcmat,
- std::shared_ptr finalModel)
+void MaterialConfigLoader::addElectromagnetic(const QMap& fcmat,
+ const std::shared_ptr& finalModel)
{
QString relativePermittivity = value(fcmat, "Electromagnetic/RelativePermittivity", "");
QString electricalConductivity = value(fcmat, "Electromagnetic/ElectricalConductivity", "");
@@ -221,15 +897,16 @@ void MaterialConfigLoader::addElectromagnetic(const QSettings& fcmat,
+ relativePermeability.length()
> 0) {
finalModel->addPhysical(ModelUUIDs::ModelUUID_Electromagnetic_Default);
- }
- // Now add the data
- setPhysicalValue(finalModel, "RelativePermittivity", relativePermittivity);
- setPhysicalValue(finalModel, "ElectricalConductivity", electricalConductivity);
- setPhysicalValue(finalModel, "RelativePermeability", relativePermeability);
+ // Now add the data
+ setPhysicalValue(finalModel, "RelativePermittivity", relativePermittivity);
+ setPhysicalValue(finalModel, "ElectricalConductivity", electricalConductivity);
+ setPhysicalValue(finalModel, "RelativePermeability", relativePermeability);
+ }
}
-void MaterialConfigLoader::addThermal(const QSettings& fcmat, std::shared_ptr finalModel)
+void MaterialConfigLoader::addThermal(const QMap& fcmat,
+ const std::shared_ptr& finalModel)
{
QString specificHeat = value(fcmat, "Thermal/SpecificHeat", "");
QString thermalConductivity = value(fcmat, "Thermal/ThermalConductivity", "");
@@ -238,15 +915,16 @@ void MaterialConfigLoader::addThermal(const QSettings& fcmat, std::shared_ptr 0) {
finalModel->addPhysical(ModelUUIDs::ModelUUID_Thermal_Default);
- }
- // Now add the data
- setPhysicalValue(finalModel, "SpecificHeat", specificHeat);
- setPhysicalValue(finalModel, "ThermalConductivity", thermalConductivity);
- setPhysicalValue(finalModel, "ThermalExpansionCoefficient", thermalExpansionCoefficient);
+ // Now add the data
+ setPhysicalValue(finalModel, "SpecificHeat", specificHeat);
+ setPhysicalValue(finalModel, "ThermalConductivity", thermalConductivity);
+ setPhysicalValue(finalModel, "ThermalExpansionCoefficient", thermalExpansionCoefficient);
+ }
}
-void MaterialConfigLoader::addFluid(const QSettings& fcmat, std::shared_ptr finalModel)
+void MaterialConfigLoader::addFluid(const QMap& fcmat,
+ const std::shared_ptr& finalModel)
{
QString density = value(fcmat, "Fluidic/Density", "");
QString dynamicViscosity = value(fcmat, "Fluidic/DynamicViscosity", "");
@@ -277,8 +955,8 @@ void MaterialConfigLoader::addFluid(const QSettings& fcmat, std::shared_ptr finalModel)
+void MaterialConfigLoader::addMechanical(const QMap& fcmat,
+ const std::shared_ptr& finalModel)
{
QString density = value(fcmat, "Mechanical/Density", "");
QString bulkModulus = value(fcmat, "Mechanical/BulkModulus", "");
@@ -340,12 +1018,16 @@ void MaterialConfigLoader::addMechanical(const QSettings& fcmat,
}
std::shared_ptr
-MaterialConfigLoader::getMaterialFromPath(std::shared_ptr library,
+MaterialConfigLoader::getMaterialFromPath(const std::shared_ptr& library,
const QString& path)
{
QString author = getAuthorAndLicense(path); // Place them both in the author field
- QSettings fcmat(path, QSettings::IniFormat);
+ QMap fcmat;
+ if (!readFile(path, fcmat)) {
+ Base::Console().Log("Error reading '%s'\n", path.toStdString().c_str());
+ throw MaterialReadError();
+ }
// General section
// QString name = value(fcmat, "Name", ""); - always get the name from the filename
@@ -359,13 +1041,15 @@ MaterialConfigLoader::getMaterialFromPath(std::shared_ptr libra
QString sourceURL = value(fcmat, "SourceURL", "");
std::shared_ptr finalModel = std::make_shared(library, path, uuid, name);
+ finalModel->setOldFormat(true);
+
finalModel->setAuthor(author);
finalModel->setDescription(description);
finalModel->setReference(sourceReference);
finalModel->setURL(sourceURL);
QString father = value(fcmat, "Father", "");
- if (father.length() > 0) {
+ if (!father.isEmpty()) {
finalModel->addPhysical(ModelUUIDs::ModelUUID_Legacy_Father);
// Now add the data
@@ -396,6 +1080,7 @@ MaterialConfigLoader::getMaterialFromPath(std::shared_ptr libra
addCosts(fcmat, finalModel);
addRendering(fcmat, finalModel);
addVectorRendering(fcmat, finalModel);
+ addRenderWB(fcmat, finalModel);
return finalModel;
-}
+}
\ No newline at end of file
diff --git a/src/Mod/Material/App/MaterialConfigLoader.h b/src/Mod/Material/App/MaterialConfigLoader.h
index 5d847d944cf6..f7b3d6b57453 100644
--- a/src/Mod/Material/App/MaterialConfigLoader.h
+++ b/src/Mod/Material/App/MaterialConfigLoader.h
@@ -25,8 +25,11 @@
#include
#include
+#include
+#include
#include
#include
+#include
#include "Materials.h"
@@ -36,48 +39,114 @@ namespace Materials
class MaterialConfigLoader
{
public:
- MaterialConfigLoader();
+ MaterialConfigLoader() = default;
virtual ~MaterialConfigLoader() = default;
static bool isConfigStyle(const QString& path);
- static std::shared_ptr getMaterialFromPath(std::shared_ptr library,
- const QString& path);
+ static std::shared_ptr
+ getMaterialFromPath(const std::shared_ptr& library, const QString& path);
private:
- static QString
- value(const QSettings& fcmat, const std::string& name, const std::string& defaultValue)
+ static QString value(const QMap& fcmat,
+ const std::string& name,
+ const std::string& defaultValue)
{
- return fcmat.value(QString::fromStdString(name), QString::fromStdString(defaultValue))
- .toString();
+ try {
+ return fcmat[QString::fromStdString(name)];
+ }
+ catch (const std::out_of_range&) {
+ }
+
+ return QString::fromStdString(defaultValue);
}
- static void setPhysicalValue(std::shared_ptr finalModel,
+ static void setPhysicalValue(const std::shared_ptr& finalModel,
const std::string& name,
const QString& value)
{
- if (value.length() > 0) {
+ if (!value.isEmpty()) {
finalModel->setPhysicalValue(QString::fromStdString(name), value);
}
}
- static void setAppearanceValue(std::shared_ptr finalModel,
+ static void setAppearanceValue(const std::shared_ptr& finalModel,
const std::string& name,
const QString& value)
{
- if (value.length() > 0) {
+ if (!value.isEmpty()) {
finalModel->setAppearanceValue(QString::fromStdString(name), value);
}
}
+ static void setAppearanceValue(const std::shared_ptr& finalModel,
+ const std::string& name,
+ const std::shared_ptr>& value)
+ {
+ if (!value->isEmpty()) {
+ finalModel->setAppearanceValue(QString::fromStdString(name), value);
+ }
+ }
+
+ static bool isTexture(const QString& value)
+ {
+ return value.contains(QString::fromStdString("Texture"), Qt::CaseInsensitive);
+ }
+
+ static bool readFile(const QString& path, QMap& map);
+ static void splitTexture(const QString& value, QString* texture, QString* remain);
+ static void
+ splitTextureObject(const QString& value, QString* texture, QString* remain, QString* object);
static QString getAuthorAndLicense(const QString& path);
- static void addMechanical(const QSettings& fcmat, std::shared_ptr finalModel);
- static void addFluid(const QSettings& fcmat, std::shared_ptr finalModel);
- static void addThermal(const QSettings& fcmat, std::shared_ptr finalModel);
- static void addElectromagnetic(const QSettings& fcmat, std::shared_ptr finalModel);
- static void addArchitectural(const QSettings& fcmat, std::shared_ptr finalModel);
- static void addCosts(const QSettings& fcmat, std::shared_ptr finalModel);
- static void addRendering(const QSettings& fcmat, std::shared_ptr finalModel);
- static void addVectorRendering(const QSettings& fcmat, std::shared_ptr finalModel);
+ static void addMechanical(const QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addFluid(const QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addThermal(const QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addElectromagnetic(const QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addArchitectural(const QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addCosts(const QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRendering(const QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addVectorRendering(const QMap& fcmat,
+ const std::shared_ptr& finalModel);
+
+ static QString multiLineKey(QMap& fcmat, const QString& prefix);
+ static void addRenderAppleseed(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderCarpaint(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderCycles(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderDiffuse(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderDisney(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderEmission(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderGlass(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderLuxcore(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderLuxrender(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderMixed(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderOspray(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderPbrt(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderPovray(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderSubstancePBR(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderTexture(QMap& fcmat,
+ const std::shared_ptr& finalModel);
+ static void addRenderWB(QMap& fcmat,
+ const std::shared_ptr& finalModel);
};
} // namespace Materials
diff --git a/src/Mod/Material/App/MaterialLibrary.cpp b/src/Mod/Material/App/MaterialLibrary.cpp
index 5ccfa0346667..e68a8a777973 100644
--- a/src/Mod/Material/App/MaterialLibrary.cpp
+++ b/src/Mod/Material/App/MaterialLibrary.cpp
@@ -54,7 +54,6 @@ MaterialLibrary::MaterialLibrary(const QString& libraryName,
void MaterialLibrary::createFolder(const QString& path)
{
QString filePath = getLocalPath(path);
- // Base::Console().Log("\tfilePath = '%s'\n", filePath.toStdString().c_str());
QDir fileDir(filePath);
if (!fileDir.exists()) {
@@ -68,8 +67,6 @@ void MaterialLibrary::createFolder(const QString& path)
// This accepts the filesystem path as returned from getLocalPath
void MaterialLibrary::deleteDir(MaterialManager& manager, const QString& path)
{
- // Base::Console().Log("Removing directory '%s'\n", path.toStdString().c_str());
-
// Remove the children first
QDirIterator it(path, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
@@ -109,12 +106,9 @@ void MaterialLibrary::deleteDir(MaterialManager& manager, const QString& path)
// This accepts the filesystem path as returned from getLocalPath
void MaterialLibrary::deleteFile(MaterialManager& manager, const QString& path)
{
- // Base::Console().Log("Removing file '%s'\n", path.toStdString().c_str());
-
if (QFile::remove(path)) {
// Remove from the map
QString rPath = getRelativePath(path);
- // Base::Console().Log("\trpath '%s'\n", rPath.toStdString().c_str());
try {
auto material = getMaterialByPath(rPath);
manager.remove(material->getUUID());
@@ -132,15 +126,11 @@ void MaterialLibrary::deleteFile(MaterialManager& manager, const QString& path)
void MaterialLibrary::deleteRecursive(const QString& path)
{
- std::string pstring = path.toStdString();
- Base::Console().Log("\tdeleteRecursive '%s'\n", pstring.c_str());
-
if (isRoot(path)) {
return;
}
QString filePath = getLocalPath(path);
- // Base::Console().Log("\tfilePath = '%s'\n", filePath.toStdString().c_str());
MaterialManager manager;
QFileInfo info(filePath);
@@ -159,16 +149,13 @@ void MaterialLibrary::updatePaths(const QString& oldPath, const QString& newPath
QString np = getRelativePath(newPath);
std::unique_ptr>> pathMap =
std::make_unique>>();
- for (auto itp = _materialPathMap->begin(); itp != _materialPathMap->end(); itp++) {
- QString path = itp->first;
+ for (auto& itp : *_materialPathMap) {
+ QString path = itp.first;
if (path.startsWith(op)) {
path = np + path.remove(0, op.size());
}
- Base::Console().Error("Path '%s' -> '%s'\n",
- itp->first.toStdString().c_str(),
- path.toStdString().c_str());
- itp->second->setDirectory(path);
- (*pathMap)[path] = itp->second;
+ itp.second->setDirectory(path);
+ (*pathMap)[path] = itp.second;
}
_materialPathMap = std::move(pathMap);
@@ -177,9 +164,7 @@ void MaterialLibrary::updatePaths(const QString& oldPath, const QString& newPath
void MaterialLibrary::renameFolder(const QString& oldPath, const QString& newPath)
{
QString filePath = getLocalPath(oldPath);
- // Base::Console().Log("\tfilePath = '%s'\n", filePath.toStdString().c_str());
QString newFilePath = getLocalPath(newPath);
- // Base::Console().Log("\tnew filePath = '%s'\n", newFilePath.toStdString().c_str());
QDir fileDir(filePath);
if (fileDir.exists()) {
@@ -192,25 +177,15 @@ void MaterialLibrary::renameFolder(const QString& oldPath, const QString& newPat
updatePaths(oldPath, newPath);
}
-std::shared_ptr MaterialLibrary::saveMaterial(std::shared_ptr material,
+std::shared_ptr MaterialLibrary::saveMaterial(const std::shared_ptr& material,
const QString& path,
bool overwrite,
bool saveAsCopy,
bool saveInherited)
{
QString filePath = getLocalPath(path);
- // Base::Console().Log("\tfilePath = '%s'\n", filePath.toStdString().c_str());
QFile file(filePath);
- // Update UUID if required
- // if name changed true
- // if (material->getName() != file.fileName()) {
- // material->newUuid();
- // }
- // if overwrite false having warned the user
- // if old format true, but already set
-
-
QFileInfo info(file);
QDir fileDir(info.path());
if (!fileDir.exists()) {
@@ -252,7 +227,7 @@ bool MaterialLibrary::fileExists(const QString& path) const
return info.exists();
}
-std::shared_ptr MaterialLibrary::addMaterial(std::shared_ptr material,
+std::shared_ptr MaterialLibrary::addMaterial(const std::shared_ptr& material,
const QString& path)
{
QString filePath = getRelativePath(path);
@@ -267,11 +242,6 @@ std::shared_ptr MaterialLibrary::addMaterial(std::shared_ptr
std::shared_ptr MaterialLibrary::getMaterialByPath(const QString& path) const
{
- // Base::Console().Log("MaterialLibrary::getMaterialByPath(%s)\n", path.toStdString().c_str());
- // for (auto itp = _materialPathMap->begin(); itp != _materialPathMap->end(); itp++) {
- // Base::Console().Log("\tpath = '%s'\n", itp->first.toStdString().c_str());
- // }
-
QString filePath = getRelativePath(path);
try {
auto material = _materialPathMap->at(filePath);
@@ -282,7 +252,7 @@ std::shared_ptr MaterialLibrary::getMaterialByPath(const QString& path
}
}
-const QString MaterialLibrary::getUUIDFromPath(const QString& path) const
+QString MaterialLibrary::getUUIDFromPath(const QString& path) const
{
QString filePath = getRelativePath(path);
try {
@@ -300,34 +270,32 @@ MaterialLibrary::getMaterialTree() const
std::shared_ptr>> materialTree =
std::make_shared>>();
- for (auto it = _materialPathMap->begin(); it != _materialPathMap->end(); it++) {
- auto filename = it->first;
- auto material = it->second;
+ for (auto& it : *_materialPathMap) {
+ auto filename = it.first;
+ auto material = it.second;
- // Base::Console().Log("Relative path '%s'\n\t", filename.toStdString().c_str());
QStringList list = filename.split(QString::fromStdString("/"));
// Start at the root
std::shared_ptr>> node = materialTree;
- for (auto itp = list.begin(); itp != list.end(); itp++) {
- // Base::Console().Log("\t%s", itp->toStdString().c_str());
- if (itp->endsWith(QString::fromStdString(".FCMat"))) {
+ for (auto& itp : list) {
+ if (itp.endsWith(QString::fromStdString(".FCMat"))) {
std::shared_ptr child = std::make_shared();
child->setData(material);
- (*node)[*itp] = child;
+ (*node)[itp] = child;
}
else {
// Add the folder only if it's not already there
- if (node->count(*itp) == 0) {
+ if (node->count(itp) == 0) {
auto mapPtr =
std::make_shared>>();
std::shared_ptr child = std::make_shared();
child->setFolder(mapPtr);
- (*node)[*itp] = child;
+ (*node)[itp] = child;
node = mapPtr;
}
else {
- node = (*node)[*itp]->getFolder();
+ node = (*node)[itp]->getFolder();
}
}
}
@@ -341,18 +309,18 @@ MaterialLibrary::getMaterialTree() const
// Start at the root
auto node = materialTree;
- for (auto itp = list.begin(); itp != list.end(); itp++) {
+ for (auto& itp : list) {
// Add the folder only if it's not already there
- if (node->count(*itp) == 0) {
+ if (node->count(itp) == 0) {
std::shared_ptr>> mapPtr =
std::make_shared>>();
std::shared_ptr child = std::make_shared();
child->setFolder(mapPtr);
- (*node)[*itp] = child;
+ (*node)[itp] = child;
node = mapPtr;
}
else {
- node = (*node)[*itp]->getFolder();
+ node = (*node)[itp]->getFolder();
}
}
}
@@ -368,8 +336,3 @@ MaterialExternalLibrary::MaterialExternalLibrary(const QString& libraryName,
bool readOnly)
: MaterialLibrary(libraryName, dir, icon, readOnly)
{}
-
-MaterialExternalLibrary::~MaterialExternalLibrary()
-{
- // delete directory;
-}
diff --git a/src/Mod/Material/App/MaterialLibrary.h b/src/Mod/Material/App/MaterialLibrary.h
index 73a554ad6170..1da9c696f4bb 100644
--- a/src/Mod/Material/App/MaterialLibrary.h
+++ b/src/Mod/Material/App/MaterialLibrary.h
@@ -29,8 +29,8 @@
#include
#include
-
#include
+
#include "Materials.h"
#include "Model.h"
#include "ModelLibrary.h"
@@ -69,13 +69,14 @@ class MaterialsExport MaterialLibrary: public LibraryBase,
void renameFolder(const QString& oldPath, const QString& newPath);
void deleteRecursive(const QString& path);
- std::shared_ptr saveMaterial(std::shared_ptr material,
+ std::shared_ptr saveMaterial(const std::shared_ptr& material,
const QString& path,
bool overwrite,
bool saveAsCopy,
bool saveInherited);
bool fileExists(const QString& path) const;
- std::shared_ptr addMaterial(std::shared_ptr material, const QString& path);
+ std::shared_ptr addMaterial(const std::shared_ptr& material,
+ const QString& path);
std::shared_ptr>> getMaterialTree() const;
bool isReadOnly() const
@@ -94,7 +95,7 @@ class MaterialsExport MaterialLibrary: public LibraryBase,
void deleteFile(MaterialManager& manager, const QString& path);
void updatePaths(const QString& oldPath, const QString& newPath);
- const QString getUUIDFromPath(const QString& path) const;
+ QString getUUIDFromPath(const QString& path) const;
bool _readOnly;
std::unique_ptr>> _materialPathMap;
@@ -110,7 +111,7 @@ class MaterialsExport MaterialExternalLibrary: public MaterialLibrary
const QString& dir,
const QString& icon,
bool readOnly = true);
- ~MaterialExternalLibrary() override;
+ ~MaterialExternalLibrary() = default;
};
} // namespace Materials
diff --git a/src/Mod/Material/App/MaterialLoader.cpp b/src/Mod/Material/App/MaterialLoader.cpp
index a6b7a1f75fcd..bf2fab397831 100644
--- a/src/Mod/Material/App/MaterialLoader.cpp
+++ b/src/Mod/Material/App/MaterialLoader.cpp
@@ -26,6 +26,7 @@
#include
#include
+#include
#include
#include
@@ -62,9 +63,6 @@ MaterialYamlEntry::MaterialYamlEntry(const std::shared_ptr& lib
, _model(modelData)
{}
-// MaterialYamlEntry::~MaterialYamlEntry()
-// {}
-
QString MaterialYamlEntry::yamlValue(const YAML::Node& node,
const std::string& key,
const std::string& defaultValue)
@@ -75,38 +73,50 @@ QString MaterialYamlEntry::yamlValue(const YAML::Node& node,
return QString::fromStdString(defaultValue);
}
-std::shared_ptr> MaterialYamlEntry::readList(const YAML::Node& node)
+std::shared_ptr> MaterialYamlEntry::readList(const YAML::Node& node,
+ bool isImageList)
{
auto list = std::make_shared>();
for (auto it = node.begin(); it != node.end(); it++) {
- QVariant nodeName = QString::fromStdString(it->as());
- list->append(nodeName);
+ QVariant nodeValue;
+ if (isImageList) {
+ nodeValue = QString::fromStdString(it->as())
+ .remove(QRegExp(QString::fromStdString("[\r\n]")));
+ }
+ else {
+ nodeValue = QString::fromStdString(it->as());
+ }
+ list->append(nodeValue);
}
return list;
}
-std::shared_ptr MaterialYamlEntry::read2DArray(const YAML::Node& node)
+std::shared_ptr> MaterialYamlEntry::readImageList(const YAML::Node& node)
{
- // Base::Console().Log("Read 2D Array\n");
+ return readList(node, true);
+}
+std::shared_ptr MaterialYamlEntry::read2DArray(const YAML::Node& node, int columns)
+{
auto array2d = std::make_shared();
+ array2d->setColumns(columns);
- if (node.size() == 2) {
- // Get the default
- Base::Quantity defaultValue(
- Base::Quantity::parse(QString::fromStdString(node[0].as())));
- array2d->setDefault(QVariant::fromValue(defaultValue));
+ if (node.size() == 1 || node.size() == 2) {
+ // There used to be a default value. Ignore it.
+ auto yamlArray = node[0];
+ if (node.size() == 2) {
+ yamlArray = node[1];
+ }
- auto yamlArray = node[1];
for (std::size_t i = 0; i < yamlArray.size(); i++) {
auto yamlRow = yamlArray[i];
- auto row = std::make_shared>();
+ auto row = std::make_shared>();
for (std::size_t j = 0; j < yamlRow.size(); j++) {
- Base::Quantity q =
+ Base::Quantity qq =
Base::Quantity::parse(QString::fromStdString(yamlRow[j].as()));
- row->push_back(QVariant::fromValue(q));
+ row->push_back(QVariant::fromValue(qq));
}
array2d->addRow(row);
}
@@ -115,28 +125,21 @@ std::shared_ptr MaterialYamlEntry::read2DArray(const YAML::Node
return array2d;
}
-std::shared_ptr MaterialYamlEntry::read3DArray(const YAML::Node& node)
+std::shared_ptr MaterialYamlEntry::read3DArray(const YAML::Node& node, int columns)
{
- Base::Console().Log("Read 3D Array\n");
-
auto array3d = std::make_shared();
+ array3d->setColumns(columns - 1); // First column is third dimension
- if (node.size() == 2) {
- // Get the default
- Base::Quantity defaultValue(
- Base::Quantity::parse(QString::fromStdString(node[0].as())));
- array3d->setDefault(QVariant::fromValue(defaultValue));
-
- auto yamlArray = node[1];
+ if (node.size() == 1 || node.size() == 2) {
+ // There used to be a default value. Ignore it.
+ auto yamlArray = node[0];
+ if (node.size() == 2) {
+ yamlArray = node[1];
+ }
for (std::size_t depth = 0; depth < yamlArray.size(); depth++) {
auto yamlDepth = yamlArray[depth];
- MaterialLoader::showYaml(yamlDepth);
for (auto it = yamlDepth.begin(); it != yamlDepth.end(); it++) {
- MaterialLoader::showYaml(it->first);
- MaterialLoader::showYaml(it->second);
-
- Base::Console().Log("Depth %d '%s'\n", depth, it->first.as().c_str());
auto depthValue =
Base::Quantity::parse(QString::fromStdString(it->first.as()));
@@ -146,7 +149,7 @@ std::shared_ptr MaterialYamlEntry::read3DArray(const YAML::Node
for (std::size_t i = 0; i < yamlTable.size(); i++) {
auto yamlRow = yamlTable[i];
- auto row = std::make_shared>();
+ auto row = std::make_shared>();
for (std::size_t j = 0; j < yamlRow.size(); j++) {
row->push_back(Base::Quantity::parse(
QString::fromStdString(yamlRow[j].as())));
@@ -187,7 +190,7 @@ void MaterialYamlEntry::addToTree(
if (yamlModel["Inherits"]) {
auto inherits = yamlModel["Inherits"];
for (auto it = inherits.begin(); it != inherits.end(); it++) {
- std::string nodeName = it->second["UUID"].as();
+ auto nodeName = it->second["UUID"].as();
finalModel->setParentUUID(
QString::fromStdString(nodeName)); // Should only be one. Need to check
@@ -198,42 +201,52 @@ void MaterialYamlEntry::addToTree(
if (yamlModel["Models"]) {
auto models = yamlModel["Models"];
for (auto it = models.begin(); it != models.end(); it++) {
- std::string modelName = (it->first).as();
+ auto modelName = (it->first).as();
// Add the model uuid
auto modelNode = models[modelName];
- std::string modelUUID = modelNode["UUID"].as();
+ auto modelUUID = modelNode["UUID"].as();
finalModel->addPhysical(QString::fromStdString(modelUUID));
// Add the property values
auto properties = yamlModel["Models"][modelName];
for (auto itp = properties.begin(); itp != properties.end(); itp++) {
- std::string propertyName = (itp->first).as();
+ auto propertyName = (itp->first).as();
if (finalModel->hasPhysicalProperty(QString::fromStdString(propertyName))) {
auto prop =
finalModel->getPhysicalProperty(QString::fromStdString(propertyName));
auto type = prop->getType();
try {
- if (type == MaterialValue::List) {
+ if (type == MaterialValue::List || type == MaterialValue::FileList) {
auto list = readList(itp->second);
finalModel->setPhysicalValue(QString::fromStdString(propertyName),
list);
}
+ else if (type == MaterialValue::ImageList) {
+ auto list = readImageList(itp->second);
+ finalModel->setPhysicalValue(QString::fromStdString(propertyName),
+ list);
+ }
else if (type == MaterialValue::Array2D) {
- auto array2d = read2DArray(itp->second);
+ auto array2d = read2DArray(itp->second, prop->columns());
finalModel->setPhysicalValue(QString::fromStdString(propertyName),
array2d);
}
else if (type == MaterialValue::Array3D) {
- auto array3d = read3DArray(itp->second);
+ auto array3d = read3DArray(itp->second, prop->columns());
finalModel->setPhysicalValue(QString::fromStdString(propertyName),
array3d);
}
else {
- std::string propertyValue = (itp->second).as();
+ QString propertyValue =
+ QString::fromStdString((itp->second).as());
+ if (type == MaterialValue::Image) {
+ propertyValue =
+ propertyValue.remove(QRegExp(QString::fromStdString("[\r\n]")));
+ }
finalModel->setPhysicalValue(QString::fromStdString(propertyName),
- QString::fromStdString(propertyValue));
+ propertyValue);
}
}
catch (const YAML::BadConversion& e) {
@@ -255,40 +268,52 @@ void MaterialYamlEntry::addToTree(
if (yamlModel["AppearanceModels"]) {
auto models = yamlModel["AppearanceModels"];
for (auto it = models.begin(); it != models.end(); it++) {
- std::string modelName = (it->first).as();
+ auto modelName = (it->first).as();
// Add the model uuid
auto modelNode = models[modelName];
- std::string modelUUID = modelNode["UUID"].as();
+ auto modelUUID = modelNode["UUID"].as();
finalModel->addAppearance(QString::fromStdString(modelUUID));
// Add the property values
auto properties = yamlModel["AppearanceModels"][modelName];
for (auto itp = properties.begin(); itp != properties.end(); itp++) {
- std::string propertyName = (itp->first).as();
+ auto propertyName = (itp->first).as