diff --git a/src/Mod/Material/App/CMakeLists.txt b/src/Mod/Material/App/CMakeLists.txt index 4f04e494a6..419009ac39 100644 --- a/src/Mod/Material/App/CMakeLists.txt +++ b/src/Mod/Material/App/CMakeLists.txt @@ -69,6 +69,8 @@ SET(Material_SRCS FolderTree.h MaterialConfigLoader.cpp MaterialConfigLoader.h + MaterialFilter.cpp + MaterialFilter.h MaterialLibrary.cpp MaterialLibrary.h MaterialLoader.cpp @@ -103,7 +105,18 @@ endif(FREECAD_USE_PCH) add_library(Material SHARED ${Material_SRCS}) target_link_libraries(Material ${Material_LIBS}) -SET_BIN_DIR(Material Material /Mod/Material) +# SET_BIN_DIR(Material Material /Mod/Material) +SET_BIN_DIR(Material Material) SET_PYTHON_PREFIX_SUFFIX(Material) -INSTALL(TARGETS Material DESTINATION ${CMAKE_INSTALL_LIBDIR}) +# INSTALL(TARGETS Material DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WIN32) + INSTALL(TARGETS Material + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +else(WIN32) + INSTALL(TARGETS Material + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif(WIN32) diff --git a/src/Mod/Material/App/MaterialFilter.cpp b/src/Mod/Material/App/MaterialFilter.cpp new file mode 100644 index 0000000000..03f0e6ba75 --- /dev/null +++ b/src/Mod/Material/App/MaterialFilter.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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" +#ifndef _PreComp_ +#endif + +#include + +#include "MaterialFilter.h" +#include "Materials.h" + + +using namespace Materials; + +TYPESYSTEM_SOURCE(Materials::MaterialFilter, Base::BaseClass) + +MaterialFilter::MaterialFilter() + : _includeFolders(true) + , _includeLegacy(true) + , _required() + , _requiredComplete() +{} + +bool MaterialFilter::modelIncluded(const std::shared_ptr& material) const +{ + for (const auto& complete : _requiredComplete) { + if (!material->isModelComplete(complete)) { + return false; + } + } + for (const auto& required : _required) { + if (!material->hasModel(required)) { + return false; + } + } + + return true; +} + +void MaterialFilter::addRequired(const QString& uuid) +{ + // Ignore any uuids already present + if (!_requiredComplete.contains(uuid)) { + _required.insert(uuid); + } +} + +void MaterialFilter::addRequiredComplete(const QString& uuid) +{ + if (_required.contains(uuid)) { + // Completeness takes priority + _required.remove(uuid); + } + _requiredComplete.insert(uuid); +} diff --git a/src/Mod/Material/App/MaterialFilter.h b/src/Mod/Material/App/MaterialFilter.h new file mode 100644 index 0000000000..d49900f5bc --- /dev/null +++ b/src/Mod/Material/App/MaterialFilter.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * 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 * + * . * + * * + **************************************************************************/ + +#ifndef MATERIAL_MATERIALFILTER_H +#define MATERIAL_MATERIALFILTER_H + +#include + +#include +#include + +#include + +#include + +namespace Materials +{ + +class Material; + +/* + * This class is used to filter materials during a material tree search + * + */ +class MaterialsExport MaterialFilter: public Base::BaseClass +{ + TYPESYSTEM_HEADER_WITH_OVERRIDE(); + +public: + MaterialFilter(); + virtual ~MaterialFilter() = default; + + /* Indicates if we should include empty folders + * + * Default is to include empty folders + */ + bool includeEmptyFolders() const + { + return _includeFolders; + } + void setIncludeEmptyFolders(bool include) + { + _includeFolders = include; + } + + /* Indicates if we should include materials in the older format + * + * Default is to include legacy format materials + */ + bool includeLegacy() const + { + return _includeLegacy; + } + void setIncludeLegacy(bool legacy) + { + _includeLegacy = legacy; + } + + /* Sets of model UUIDs that should be included. Optionally, we can + * specify models that must contain values for all properties. + * + * Models only need to be included in one set. + */ + bool modelIncluded(const std::shared_ptr& material) const; + + void addRequired(const QString& uuid); + void addRequiredComplete(const QString& uuid); + +private: + bool _includeFolders; + bool _includeLegacy; + QSet _required; + QSet _requiredComplete; +}; + +} // namespace Materials + +#endif // MATERIAL_MATERIALFILTER_H diff --git a/src/Mod/Material/App/MaterialLibrary.cpp b/src/Mod/Material/App/MaterialLibrary.cpp index e68a8a7779..d1c30730f8 100644 --- a/src/Mod/Material/App/MaterialLibrary.cpp +++ b/src/Mod/Material/App/MaterialLibrary.cpp @@ -29,6 +29,7 @@ #include +#include "MaterialFilter.h" #include "MaterialLibrary.h" #include "MaterialLoader.h" #include "MaterialManager.h" @@ -264,8 +265,25 @@ QString MaterialLibrary::getUUIDFromPath(const QString& path) const } } +bool MaterialLibrary::materialInTree(const std::shared_ptr& material, + const MaterialFilter* filter) const +{ + if (!filter) { + // If there's no filter we always include + return true; + } + + // filter out old format files + if (material->isOldFormat() && !filter->includeLegacy()) { + return false; + } + + // filter based on models + return filter->modelIncluded(material); +} + std::shared_ptr>> -MaterialLibrary::getMaterialTree() const +MaterialLibrary::getMaterialTree(const MaterialFilter* filter) const { std::shared_ptr>> materialTree = std::make_shared>>(); @@ -274,20 +292,50 @@ MaterialLibrary::getMaterialTree() const auto filename = it.first; auto material = it.second; - QStringList list = filename.split(QString::fromStdString("/")); + if (materialInTree(material, filter)) { + QStringList list = filename.split(QString::fromStdString("/")); - // Start at the root - std::shared_ptr>> node = materialTree; - for (auto& itp : list) { - if (itp.endsWith(QString::fromStdString(".FCMat"))) { - std::shared_ptr child = std::make_shared(); - child->setData(material); - (*node)[itp] = child; + // Start at the root + std::shared_ptr>> node = + materialTree; + for (auto& itp : list) { + if (itp.endsWith(QString::fromStdString(".FCMat"))) { + std::shared_ptr child = std::make_shared(); + child->setData(material); + (*node)[itp] = child; + } + else { + // Add the folder only if it's not already there + if (node->count(itp) == 0) { + auto mapPtr = std::make_shared< + std::map>>(); + std::shared_ptr child = + std::make_shared(); + child->setFolder(mapPtr); + (*node)[itp] = child; + node = mapPtr; + } + else { + node = (*node)[itp]->getFolder(); + } + } } - else { + } + } + + // Empty folders aren't included in _materialPathMap, so we add them by looking at the file + // system + if (!filter || filter->includeEmptyFolders()) { + auto folderList = MaterialLoader::getMaterialFolders(*this); + for (auto& folder : *folderList) { + QStringList list = folder.split(QString::fromStdString("/")); + + // Start at the root + auto node = materialTree; + for (auto& itp : list) { // Add the folder only if it's not already there if (node->count(itp) == 0) { - auto mapPtr = + std::shared_ptr>> mapPtr = std::make_shared>>(); std::shared_ptr child = std::make_shared(); child->setFolder(mapPtr); @@ -301,30 +349,6 @@ MaterialLibrary::getMaterialTree() const } } - // Empty folders aren't included in _materialPathMap, so we add them by looking at the file - // system - auto folderList = MaterialLoader::getMaterialFolders(*this); - for (auto& folder : *folderList) { - QStringList list = folder.split(QString::fromStdString("/")); - - // Start at the root - auto node = materialTree; - for (auto& itp : list) { - // Add the folder only if it's not already there - 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 = mapPtr; - } - else { - node = (*node)[itp]->getFolder(); - } - } - } - return materialTree; } diff --git a/src/Mod/Material/App/MaterialLibrary.h b/src/Mod/Material/App/MaterialLibrary.h index 1da9c696f4..3123d091b9 100644 --- a/src/Mod/Material/App/MaterialLibrary.h +++ b/src/Mod/Material/App/MaterialLibrary.h @@ -40,6 +40,7 @@ namespace Materials class Material; class MaterialManager; +class MaterialFilter; class MaterialsExport MaterialLibrary: public LibraryBase, public std::enable_shared_from_this @@ -77,7 +78,8 @@ public: bool fileExists(const QString& path) const; std::shared_ptr addMaterial(const std::shared_ptr& material, const QString& path); - std::shared_ptr>> getMaterialTree() const; + std::shared_ptr>> + getMaterialTree(const MaterialFilter* filter = nullptr) const; bool isReadOnly() const { @@ -96,6 +98,8 @@ protected: void updatePaths(const QString& oldPath, const QString& newPath); QString getUUIDFromPath(const QString& path) const; + bool materialInTree(const std::shared_ptr& material, + const MaterialFilter* filter) const; bool _readOnly; std::unique_ptr>> _materialPathMap; @@ -111,7 +115,7 @@ public: const QString& dir, const QString& icon, bool readOnly = true); - ~MaterialExternalLibrary() = default; + ~MaterialExternalLibrary() override = default; }; } // namespace Materials diff --git a/src/Mod/Material/App/MaterialManager.h b/src/Mod/Material/App/MaterialManager.h index a4b9400227..34136038a7 100644 --- a/src/Mod/Material/App/MaterialManager.h +++ b/src/Mod/Material/App/MaterialManager.h @@ -40,6 +40,8 @@ namespace fs = boost::filesystem; namespace Materials { +class MaterialFilter; + class MaterialsExport MaterialManager: public Base::BaseClass { TYPESYSTEM_HEADER_WITH_OVERRIDE(); @@ -63,9 +65,10 @@ public: // Library management std::shared_ptr>> getMaterialLibraries() const; std::shared_ptr>> - getMaterialTree(const std::shared_ptr& library) const + getMaterialTree(const std::shared_ptr& library, + const MaterialFilter* filter = nullptr) const { - return library->getMaterialTree(); + return library->getMaterialTree(filter); } std::shared_ptr> getMaterialFolders(const std::shared_ptr& library) const; diff --git a/src/Mod/Material/App/MaterialValue.cpp b/src/Mod/Material/App/MaterialValue.cpp index 99977e0d4f..a9ccc6513e 100644 --- a/src/Mod/Material/App/MaterialValue.cpp +++ b/src/Mod/Material/App/MaterialValue.cpp @@ -41,6 +41,25 @@ using namespace Materials; TYPESYSTEM_SOURCE(Materials::MaterialValue, Base::BaseClass) +QMap MaterialValue::_typeMap { + {QString::fromStdString("String"), String}, + {QString::fromStdString("Boolean"), Boolean}, + {QString::fromStdString("Integer"), Integer}, + {QString::fromStdString("Float"), Float}, + {QString::fromStdString("Quantity"), Quantity}, + {QString::fromStdString("Distribution"), Distribution}, + {QString::fromStdString("List"), List}, + {QString::fromStdString("2DArray"), Array2D}, + {QString::fromStdString("3DArray"), Array3D}, + {QString::fromStdString("Color"), Color}, + {QString::fromStdString("Image"), Image}, + {QString::fromStdString("File"), File}, + {QString::fromStdString("URL"), URL}, + {QString::fromStdString("MultiLineString"), MultiLineString}, + {QString::fromStdString("FileList"), FileList}, + {QString::fromStdString("ImageList"), ImageList}, + {QString::fromStdString("SVG"), SVG}}; + MaterialValue::MaterialValue() : _valueType(None) { @@ -93,10 +112,16 @@ QString MaterialValue::escapeString(const QString& source) return res; } +MaterialValue::ValueType MaterialValue::mapType(const QString& stringType) +{ + // If not found, return None + return _typeMap.value(stringType, None); +} + void MaterialValue::setInitialValue(ValueType inherited) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - if (_valueType == String || _valueType == MultiLineString) { + if (_valueType == String || _valueType == MultiLineString || _valueType == SVG) { _value = QVariant(static_cast(QMetaType::QString)); } else if (_valueType == Boolean) { @@ -121,7 +146,7 @@ void MaterialValue::setInitialValue(ValueType inherited) _value = QVariant(static_cast(QMetaType::QString)); } #else - if (_valueType == String || _valueType == MultiLineString) { + if (_valueType == String || _valueType == MultiLineString || _valueType == SVG) { _value = QVariant(QMetaType(QMetaType::QString)); } else if (_valueType == Boolean) { @@ -237,7 +262,7 @@ QString MaterialValue::getYAMLStringImageList() const QString MaterialValue::getYAMLStringMultiLine() const { QString yaml; - yaml = QString::fromStdString(" >2"); + yaml = QString::fromStdString(" |2"); auto list = getValue().toString().split(QRegExp(QString::fromStdString("[\r\n]")), Qt::SkipEmptyParts); for (auto& it : list) { @@ -259,7 +284,7 @@ QString MaterialValue::getYAMLString() const if (getType() == MaterialValue::ImageList) { return getYAMLStringImageList(); } - if (getType() == MaterialValue::MultiLineString) { + if (getType() == MaterialValue::MultiLineString || getType() == MaterialValue::SVG) { return getYAMLStringMultiLine(); } if (getType() == MaterialValue::Quantity) { @@ -272,16 +297,6 @@ QString MaterialValue::getYAMLString() const yaml += QString::fromLatin1("%1").arg(value.toFloat(), 0, 'g', 6); } } - else if (getType() == MaterialValue::MultiLineString) { - yaml = QString::fromLatin1(">2"); - auto list = - getValue().toString().split(QRegularExpression(QString::fromLatin1("[\r\n]")), - Qt::SkipEmptyParts); - for (auto& it : list) { - yaml += QString::fromLatin1("\n ") + it; - } - return yaml; - } else if (getType() == MaterialValue::List) { for (auto& it : getList()) { yaml += QString::fromLatin1("\n - \"") + escapeString(it.toString()) @@ -293,7 +308,7 @@ QString MaterialValue::getYAMLString() const yaml += getValue().toString(); } } - yaml = QString::fromLatin1("\"") + escapeString(yaml) + QString::fromLatin1("\""); + yaml = QString::fromLatin1(" \"") + escapeString(yaml) + QString::fromLatin1("\""); return yaml; } diff --git a/src/Mod/Material/App/MaterialValue.h b/src/Mod/Material/App/MaterialValue.h index 89e0de8167..309966565a 100644 --- a/src/Mod/Material/App/MaterialValue.h +++ b/src/Mod/Material/App/MaterialValue.h @@ -58,7 +58,8 @@ public: URL = 13, MultiLineString = 14, FileList = 15, - ImageList = 16 + ImageList = 16, + SVG }; MaterialValue(); explicit MaterialValue(const MaterialValue& other); @@ -104,6 +105,7 @@ public: virtual QString getYAMLString() const; static QString escapeString(const QString& source); + static ValueType mapType(const QString& stringType); protected: MaterialValue(ValueType type, ValueType inherited); @@ -121,6 +123,9 @@ protected: ValueType _valueType; QVariant _value; + +private: + static QMap _typeMap; }; class MaterialsExport Material2DArray: public MaterialValue diff --git a/src/Mod/Material/App/Materials.cpp b/src/Mod/Material/App/Materials.cpp index b11d9db236..a1d7592125 100644 --- a/src/Mod/Material/App/Materials.cpp +++ b/src/Mod/Material/App/Materials.cpp @@ -148,60 +148,23 @@ void MaterialProperty::setPropertyType(const QString& type) void MaterialProperty::setType(const QString& type) { - if (type == QString::fromStdString("String")) { - _valuePtr = std::make_shared(MaterialValue::String); + auto mappedType = MaterialValue::mapType(type); + if (mappedType == MaterialValue::None) { + throw UnknownValueType(); } - else if (type == QString::fromStdString("Boolean")) { - _valuePtr = std::make_shared(MaterialValue::Boolean); - } - else if (type == QString::fromStdString("Integer")) { - _valuePtr = std::make_shared(MaterialValue::Integer); - } - else if (type == QString::fromStdString("Float")) { - _valuePtr = std::make_shared(MaterialValue::Float); - } - else if (type == QString::fromStdString("URL")) { - _valuePtr = std::make_shared(MaterialValue::URL); - } - else if (type == QString::fromStdString("Quantity")) { - _valuePtr = std::make_shared(MaterialValue::Quantity); - } - else if (type == QString::fromStdString("Color")) { - _valuePtr = std::make_shared(MaterialValue::Color); - } - else if (type == QString::fromStdString("File")) { - _valuePtr = std::make_shared(MaterialValue::File); - } - else if (type == QString::fromStdString("Image")) { - _valuePtr = std::make_shared(MaterialValue::Image); - } - else if (type == QString::fromStdString("List")) { - _valuePtr = std::make_shared(MaterialValue::List); - } - else if (type == QString::fromStdString("FileList")) { - _valuePtr = std::make_shared(MaterialValue::FileList); - } - else if (type == QString::fromStdString("ImageList")) { - _valuePtr = std::make_shared(MaterialValue::ImageList); - } - else if (type == QString::fromStdString("MultiLineString")) { - _valuePtr = std::make_shared(MaterialValue::MultiLineString); - } - else if (type == QString::fromStdString("2DArray")) { + if (mappedType == MaterialValue::Array2D) { auto arrayPtr = std::make_shared(); arrayPtr->setColumns(columns()); _valuePtr = arrayPtr; } - else if (type == QString::fromStdString("3DArray")) { + else if (mappedType == MaterialValue::Array3D) { auto arrayPtr = std::make_shared(); // First column is third dimension arrayPtr->setColumns(columns() - 1); _valuePtr = arrayPtr; } else { - // Error. Throw something - _valuePtr = std::make_shared(MaterialValue::None); - throw UnknownValueType(); + _valuePtr = std::make_shared(mappedType); } } @@ -457,16 +420,16 @@ Material::Material(const Material& other) , _editState(other._editState) { for (auto& it : other._tags) { - _tags.push_back(it); + _tags.insert(it); } for (auto& it : other._physicalUuids) { - _physicalUuids.push_back(it); + _physicalUuids.insert(it); } for (auto& it : other._appearanceUuids) { - _appearanceUuids.push_back(it); + _appearanceUuids.insert(it); } for (auto& it : other._allUuids) { - _allUuids.push_back(it); + _allUuids.insert(it); } for (auto& it : other._physical) { MaterialProperty prop(it.second); @@ -498,7 +461,7 @@ QString Material::getAuthorAndLicense() const void Material::addModel(const QString& uuid) { - for (QString& modelUUID : _allUuids) { + for (const auto& modelUUID : qAsConst(_allUuids)) { if (modelUUID == uuid) { return; } @@ -582,9 +545,9 @@ void Material::setEditState(ModelEdit newState) } } -void Material::removeUUID(QStringList& uuidList, const QString& uuid) +void Material::removeUUID(QSet& uuidList, const QString& uuid) { - uuidList.removeAll(uuid); + uuidList.remove(uuid); } void Material::addPhysical(const QString& uuid) @@ -605,7 +568,7 @@ void Material::addPhysical(const QString& uuid) removeUUID(_physicalUuids, it); } - _physicalUuids.push_back(uuid); + _physicalUuids.insert(uuid); addModel(uuid); setEditStateExtend(); @@ -637,7 +600,7 @@ void Material::removePhysical(const QString& uuid) // If it's an inherited model, do nothing bool inherited = true; - for (auto& it : _physicalUuids) { + for (const auto& it : qAsConst(_physicalUuids)) { if (it == uuid) { inherited = false; break; @@ -689,7 +652,7 @@ void Material::addAppearance(const QString& uuid) removeUUID(_appearanceUuids, it); } - _appearanceUuids.push_back(uuid); + _appearanceUuids.insert(uuid); addModel(uuid); setEditStateExtend(); @@ -715,7 +678,7 @@ void Material::removeAppearance(const QString& uuid) // If it's an inherited model, do nothing bool inherited = true; - for (auto& it : _appearanceUuids) { + for (const auto& it : qAsConst(_appearanceUuids)) { if (it == uuid) { inherited = false; break; @@ -790,56 +753,72 @@ void Material::setPhysicalValue(const QString& name, const QString& value) { setPhysicalEditState(name); - _physical[name]->setValue(value); // may not be a string type, conversion may be required + if (hasPhysicalProperty(name)) { + _physical[name]->setValue(value); // may not be a string type, conversion may be required + } } void Material::setPhysicalValue(const QString& name, int value) { setPhysicalEditState(name); - _physical[name]->setInt(value); + if (hasPhysicalProperty(name)) { + _physical[name]->setInt(value); + } } void Material::setPhysicalValue(const QString& name, double value) { setPhysicalEditState(name); - _physical[name]->setFloat(value); + if (hasPhysicalProperty(name)) { + _physical[name]->setFloat(value); + } } void Material::setPhysicalValue(const QString& name, const Base::Quantity& value) { setPhysicalEditState(name); - _physical[name]->setQuantity(value); + if (hasPhysicalProperty(name)) { + _physical[name]->setQuantity(value); + } } void Material::setPhysicalValue(const QString& name, const std::shared_ptr& value) { setPhysicalEditState(name); - _physical[name]->setValue(value); + if (hasPhysicalProperty(name)) { + _physical[name]->setValue(value); + } } void Material::setPhysicalValue(const QString& name, const std::shared_ptr>& value) { setPhysicalEditState(name); - _physical[name]->setList(*value); + if (hasPhysicalProperty(name)) { + _physical[name]->setList(*value); + } } void Material::setAppearanceValue(const QString& name, const QString& value) { setAppearanceEditState(name); - _appearance[name]->setValue(value); // may not be a string type, conversion may be required + if (hasAppearanceProperty(name)) { + _appearance[name]->setValue(value); // may not be a string type, conversion may be required + } } void Material::setAppearanceValue(const QString& name, const std::shared_ptr& value) { setAppearanceEditState(name); - _appearance[name]->setValue(value); + if (hasAppearanceProperty(name)) { + _appearance[name]->setValue(value); + } } void Material::setAppearanceValue(const QString& name, @@ -847,7 +826,9 @@ void Material::setAppearanceValue(const QString& name, { setAppearanceEditState(name); - _appearance[name]->setList(*value); + if (hasAppearanceProperty(name)) { + _appearance[name]->setList(*value); + } } std::shared_ptr Material::getPhysicalProperty(const QString& name) @@ -890,6 +871,28 @@ std::shared_ptr Material::getAppearanceProperty(const QString& } } +std::shared_ptr Material::getProperty(const QString& name) +{ + if (hasPhysicalProperty(name)) { + return getPhysicalProperty(name); + } + if (hasAppearanceProperty(name)) { + return getAppearanceProperty(name); + } + throw PropertyNotFound(); +} + +std::shared_ptr Material::getProperty(const QString& name) const +{ + if (hasPhysicalProperty(name)) { + return getPhysicalProperty(name); + } + if (hasAppearanceProperty(name)) { + return getAppearanceProperty(name); + } + throw PropertyNotFound(); +} + QVariant Material::getValue(const std::map>& propertyList, const QString& name) @@ -1295,7 +1298,8 @@ QString Material::getModelByName(const QString& name) const void Material::save(QTextStream& stream, bool overwrite, bool saveAsCopy, bool saveInherited) { if (saveInherited && !saveAsCopy) { - // Check to see if we're an original or if we're already in the list of models + // Check to see if we're an original or if we're already in the list of + // models MaterialManager materialManager; if (materialManager.exists(_uuid) && !overwrite) { // Make a new version based on the current @@ -1304,6 +1308,11 @@ void Material::save(QTextStream& stream, bool overwrite, bool saveAsCopy, bool s } } + // Prevent self inheritance + if (_parentUuid == _uuid) { + _parentUuid = QString(); + } + if (saveAsCopy) { // Save it in the same format as the parent if (_parentUuid.isEmpty()) { @@ -1315,8 +1324,8 @@ void Material::save(QTextStream& stream, bool overwrite, bool saveAsCopy, bool s } else { if (!overwrite) { - // Creating a new derived model when overwriting sets itself as a parent, - // that will no longer exist because it's been overwritten + // Creating a new derived model when overwriting sets itself as a + // parent, that will no longer exist because it's been overwritten newUuid(); } } @@ -1358,19 +1367,19 @@ Material& Material::operator=(const Material& other) _tags.clear(); for (auto& it : other._tags) { - _tags.push_back(it); + _tags.insert(it); } _physicalUuids.clear(); for (auto& it : other._physicalUuids) { - _physicalUuids.push_back(it); + _physicalUuids.insert(it); } _appearanceUuids.clear(); for (auto& it : other._appearanceUuids) { - _appearanceUuids.push_back(it); + _appearanceUuids.insert(it); } _allUuids.clear(); for (auto& it : other._allUuids) { - _allUuids.push_back(it); + _allUuids.insert(it); } // Create copies of the properties rather than modify the originals @@ -1420,14 +1429,15 @@ QStringList Material::normalizeModels(const QStringList& models) } /* - * Set or change the base material for the current material, updating the properties as - * required. + * Set or change the base material for the current material, updating the + * properties as required. */ void Material::updateInheritance([[maybe_unused]] const QString& parent) {} /* - * Return a list of models that are defined in the parent material but not in this one + * Return a list of models that are defined in the parent material but not in + * this one */ QStringList Material::inheritedMissingModels(const Material& parent) const { @@ -1457,7 +1467,8 @@ QStringList Material::inheritedAddedModels(const Material& parent) const } /* - * Return a list of properties that have different values from the parent material + * Return a list of properties that have different values from the parent + * material */ void Material::inheritedPropertyDiff([[maybe_unused]] const QString& parent) {} diff --git a/src/Mod/Material/App/Materials.h b/src/Mod/Material/App/Materials.h index 74a37a22cc..b5db7743bd 100644 --- a/src/Mod/Material/App/Materials.h +++ b/src/Mod/Material/App/Materials.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -203,15 +204,15 @@ public: { return _editState; } - const QStringList& getTags() const + const QSet& getTags() const { return _tags; } - const QStringList* getPhysicalModels() const + const QSet* getPhysicalModels() const { return &_physicalUuids; } - const QStringList* getAppearanceModels() const + const QSet* getAppearanceModels() const { return &_appearanceUuids; } @@ -282,6 +283,8 @@ public: std::shared_ptr getPhysicalProperty(const QString& name) const; std::shared_ptr getAppearanceProperty(const QString& name); std::shared_ptr getAppearanceProperty(const QString& name) const; + std::shared_ptr getProperty(const QString& name); + std::shared_ptr getProperty(const QString& name) const; QVariant getPhysicalValue(const QString& name) const; Base::Quantity getPhysicalQuantity(const QString& name) const; QString getPhysicalValueString(const QString& name) const; @@ -359,7 +362,7 @@ public: protected: void addModel(const QString& uuid); - static void removeUUID(QStringList& uuidList, const QString& uuid); + static void removeUUID(QSet& uuidList, const QString& uuid); static QVariant getValue(const std::map>& propertyList, @@ -388,10 +391,10 @@ private: QString _description; QString _url; QString _reference; - QStringList _tags; - QStringList _physicalUuids; - QStringList _appearanceUuids; - QStringList _allUuids; // Includes inherited models + QSet _tags; + QSet _physicalUuids; + QSet _appearanceUuids; + QSet _allUuids; // Includes inherited models std::map> _physical; std::map> _appearance; bool _dereferenced; diff --git a/src/Mod/Material/App/ModelLibrary.cpp b/src/Mod/Material/App/ModelLibrary.cpp index 63d06f2d06..baa244ecdd 100644 --- a/src/Mod/Material/App/ModelLibrary.cpp +++ b/src/Mod/Material/App/ModelLibrary.cpp @@ -55,7 +55,7 @@ QString LibraryBase::getLocalPath(const QString& path) const QString prefix = QString::fromStdString("/") + getName(); if (cleanPath.startsWith(prefix)) { // Remove the library name from the path - filePath += cleanPath.right(cleanPath.length() - prefix.length()); + filePath += cleanPath.rightRef(cleanPath.length() - prefix.length()); } else { filePath += cleanPath; diff --git a/src/Mod/Material/CMakeLists.txt b/src/Mod/Material/CMakeLists.txt index 4945e3febc..58422a436a 100644 --- a/src/Mod/Material/CMakeLists.txt +++ b/src/Mod/Material/CMakeLists.txt @@ -155,7 +155,7 @@ SET(FluidMaterial_Files Resources/Materials/Fluid/None.FCMat Resources/Materials/Fluid/Air.FCMat Resources/Materials/Fluid/Argon.FCMat - Resources/Materials/Fluid/Carbon_dioxide.FCMat + "Resources/Materials/Fluid/Carbon Dioxide.FCMat" Resources/Materials/Fluid/Nitrogen.FCMat Resources/Materials/Fluid/Water.FCMat ) @@ -166,25 +166,60 @@ SET(AppearanceLib_Files Resources/Materials/Appearance/Bronze.FCMat Resources/Materials/Appearance/Chrome.FCMat Resources/Materials/Appearance/Copper.FCMat - Resources/Materials/Appearance/DefaultAppearance.FCMat + Resources/Materials/Appearance/Default.FCMat Resources/Materials/Appearance/Emerald.FCMat Resources/Materials/Appearance/Gold.FCMat Resources/Materials/Appearance/Jade.FCMat Resources/Materials/Appearance/Metalized.FCMat - Resources/Materials/Appearance/NeonGNC.FCMat - Resources/Materials/Appearance/NeonPHC.FCMat + "Resources/Materials/Appearance/Neon GNC.FCMat" + "Resources/Materials/Appearance/Neon PHC.FCMat" Resources/Materials/Appearance/Obsidian.FCMat Resources/Materials/Appearance/Pewter.FCMat Resources/Materials/Appearance/Plaster.FCMat Resources/Materials/Appearance/Plastic.FCMat Resources/Materials/Appearance/Ruby.FCMat Resources/Materials/Appearance/Satin.FCMat - Resources/Materials/Appearance/ShinyPlastic.FCMat + "Resources/Materials/Appearance/Shiny Plastic.FCMat" Resources/Materials/Appearance/Silver.FCMat Resources/Materials/Appearance/Steel.FCMat Resources/Materials/Appearance/Stone.FCMat ) +SET(PatternLib_Files + Resources/Materials/Patterns/PAT/Diagonal4.FCMat + Resources/Materials/Patterns/PAT/Diagonal5.FCMat + Resources/Materials/Patterns/PAT/Diamond.FCMat + Resources/Materials/Patterns/PAT/Diamond2.FCMat + Resources/Materials/Patterns/PAT/Diamond4.FCMat + Resources/Materials/Patterns/PAT/Horizontal5.FCMat + Resources/Materials/Patterns/PAT/Square.FCMat + Resources/Materials/Patterns/PAT/Vertical5.FCMat + "Resources/Materials/Patterns/Pattern Files/aluminum.FCMat" + "Resources/Materials/Patterns/Pattern Files/brick01.FCMat" + "Resources/Materials/Patterns/Pattern Files/concrete.FCMat" + "Resources/Materials/Patterns/Pattern Files/cross.FCMat" + "Resources/Materials/Patterns/Pattern Files/cuprous.FCMat" + "Resources/Materials/Patterns/Pattern Files/diagonal1.FCMat" + "Resources/Materials/Patterns/Pattern Files/diagonal2.FCMat" + "Resources/Materials/Patterns/Pattern Files/earth.FCMat" + "Resources/Materials/Patterns/Pattern Files/general_steel.FCMat" + "Resources/Materials/Patterns/Pattern Files/glass.FCMat" + "Resources/Materials/Patterns/Pattern Files/hatch45L.FCMat" + "Resources/Materials/Patterns/Pattern Files/hatch45R.FCMat" + "Resources/Materials/Patterns/Pattern Files/hbone.FCMat" + "Resources/Materials/Patterns/Pattern Files/line.FCMat" + "Resources/Materials/Patterns/Pattern Files/plastic.FCMat" + "Resources/Materials/Patterns/Pattern Files/plus.FCMat" + "Resources/Materials/Patterns/Pattern Files/simple.FCMat" + "Resources/Materials/Patterns/Pattern Files/solid.FCMat" + "Resources/Materials/Patterns/Pattern Files/square.FCMat" + "Resources/Materials/Patterns/Pattern Files/steel.FCMat" + "Resources/Materials/Patterns/Pattern Files/titanium.FCMat" + "Resources/Materials/Patterns/Pattern Files/wood.FCMat" + "Resources/Materials/Patterns/Pattern Files/woodgrain.FCMat" + "Resources/Materials/Patterns/Pattern Files/zinc.FCMat" +) + SET(MaterialTestLib_Files "Resources/Materials/Test/Test Material.FCMat" ) @@ -202,6 +237,24 @@ SET(MaterialModel_Files Resources/Models/Mechanical/LinearElastic.yml Resources/Models/Mechanical/OgdenYld2004p18.yml Resources/Models/Mechanical/OrthotropicLinearElastic.yml + Resources/Models/Patterns/PAT.yml + "Resources/Models/Patterns/Pattern File.yml" + "Resources/Models/Render Workbench/RenderAppleseed.yml" + "Resources/Models/Render Workbench/RenderCarpaint.yml" + "Resources/Models/Render Workbench/RenderCycles.yml" + "Resources/Models/Render Workbench/RenderDiffuse.yml" + "Resources/Models/Render Workbench/RenderDisney.yml" + "Resources/Models/Render Workbench/RenderEmission.yml" + "Resources/Models/Render Workbench/RenderGlass.yml" + "Resources/Models/Render Workbench/RenderLuxcore.yml" + "Resources/Models/Render Workbench/RenderLuxrender.yml" + "Resources/Models/Render Workbench/RenderMixed.yml" + "Resources/Models/Render Workbench/RenderOspray.yml" + "Resources/Models/Render Workbench/RenderPbrt.yml" + "Resources/Models/Render Workbench/RenderPovray.yml" + "Resources/Models/Render Workbench/RenderSubstancePBR.yml" + "Resources/Models/Render Workbench/RenderTexture.yml" + "Resources/Models/Render Workbench/RenderWB.yml" Resources/Models/Rendering/AdvancedRendering.yml Resources/Models/Rendering/BasicRendering.yml Resources/Models/Rendering/TextureRendering.yml @@ -266,6 +319,9 @@ ADD_CUSTOM_TARGET(FluidMaterialLib ALL ADD_CUSTOM_TARGET(AppearanceLib ALL SOURCES ${AppearanceLib_Files} ) +ADD_CUSTOM_TARGET(PatternLib ALL + SOURCES ${PatternLib_Files} +) ADD_CUSTOM_TARGET(MaterialTestLib ALL SOURCES ${MaterialTestLib_Files} ) @@ -287,6 +343,10 @@ fc_target_copy_resource(AppearanceLib ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Material/ ${AppearanceLib_Files}) +fc_target_copy_resource(PatternLib + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Material/ + ${PatternLib_Files}) fc_target_copy_resource(MaterialTestLib ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Material/ @@ -306,7 +366,7 @@ INSTALL( DESTINATION Mod/Material/materialtests ) -foreach(file ${MaterialLib_Files} ${FluidMaterial_Files} ${AppearanceLib_Files} ${MaterialTestLib_Files} ${MaterialModel_Files}) +foreach(file ${MaterialLib_Files} ${FluidMaterial_Files} ${AppearanceLib_Files} ${PatternLib_Files} ${MaterialTestLib_Files} ${MaterialModel_Files}) get_filename_component(filepath ${file} DIRECTORY) INSTALL( FILES ${file} diff --git a/src/Mod/Material/Gui/BaseDelegate.cpp b/src/Mod/Material/Gui/BaseDelegate.cpp index 4776d737a5..d018a80e68 100644 --- a/src/Mod/Material/Gui/BaseDelegate.cpp +++ b/src/Mod/Material/Gui/BaseDelegate.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #endif @@ -55,12 +56,8 @@ using namespace MatGui; -BaseDelegate::BaseDelegate(Materials::MaterialValue::ValueType type, - const QString& units, - QObject* parent) +BaseDelegate::BaseDelegate(QObject* parent) : QStyledItemDelegate(parent) - , _type(type) - , _units(units) {} bool BaseDelegate::newRow(const QAbstractItemModel* model, const QModelIndex& index) const @@ -71,8 +68,7 @@ bool BaseDelegate::newRow(const QAbstractItemModel* model, const QModelIndex& in QString BaseDelegate::getStringValue(const QModelIndex& index) const { - auto model = index.model(); - QVariant item = model->data(index); + QVariant item = getValue(index); auto propertyValue = item.value(); return propertyValue; @@ -109,7 +105,7 @@ void BaseDelegate::paintQuantity(QPainter* painter, painter->drawText(option.rect, 0, QString()); } else { - QVariant item = model->data(index); + QVariant item = getValue(index); auto quantity = item.value(); QString text = quantity.getUserString(); painter->drawText(option.rect, 0, text); @@ -128,7 +124,6 @@ void BaseDelegate::paintImage(QPainter* painter, QImage img; if (!propertyValue.isEmpty()) { - Base::Console().Log("Loading image\n"); QByteArray by = QByteArray::fromBase64(propertyValue.toUtf8()); img = QImage::fromData(by, "PNG").scaled(64, 64, Qt::KeepAspectRatio); } @@ -144,6 +139,23 @@ void BaseDelegate::paintImage(QPainter* painter, painter->restore(); } +void BaseDelegate::paintSVG(QPainter* painter, + const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + auto propertyValue = getStringValue(index); + + painter->save(); + + if (!propertyValue.isEmpty()) { + QSvgRenderer renderer(propertyValue.toUtf8()); + + renderer.render(painter, QRectF(option.rect)); + } + + painter->restore(); +} + void BaseDelegate::paintColor(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const @@ -177,6 +189,8 @@ void BaseDelegate::paintList(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { + Q_UNUSED(index) + painter->save(); QImage list(QString::fromStdString(":/icons/list.svg")); @@ -196,6 +210,8 @@ void BaseDelegate::paintMultiLineString(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { + Q_UNUSED(index) + painter->save(); QImage table(QString::fromStdString(":/icons/multiline.svg")); @@ -215,6 +231,8 @@ void BaseDelegate::paintArray(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { + Q_UNUSED(index) + painter->save(); QImage table(QString::fromStdString(":/icons/table.svg")); @@ -228,36 +246,39 @@ void BaseDelegate::paintArray(QPainter* painter, painter->drawImage(target, table, table.rect()); painter->restore(); - return; } void BaseDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - - if (_type == Materials::MaterialValue::Quantity) { + auto type = getType(index); + if (type == Materials::MaterialValue::Quantity) { paintQuantity(painter, option, index); return; } - if (_type == Materials::MaterialValue::Image) { + if (type == Materials::MaterialValue::Image) { paintImage(painter, option, index); return; } - if (_type == Materials::MaterialValue::Color) { + if (type == Materials::MaterialValue::SVG) { + paintSVG(painter, option, index); + return; + } + if (type == Materials::MaterialValue::Color) { paintColor(painter, option, index); return; } - if (_type == Materials::MaterialValue::List || _type == Materials::MaterialValue::FileList - || _type == Materials::MaterialValue::ImageList) { + if (type == Materials::MaterialValue::List || type == Materials::MaterialValue::FileList + || type == Materials::MaterialValue::ImageList) { paintList(painter, option, index); return; } - if (_type == Materials::MaterialValue::MultiLineString) { + if (type == Materials::MaterialValue::MultiLineString) { paintMultiLineString(painter, option, index); return; } - if (_type == Materials::MaterialValue::Array2D || _type == Materials::MaterialValue::Array3D) { + if (type == Materials::MaterialValue::Array2D || type == Materials::MaterialValue::Array3D) { paintArray(painter, option, index); return; } @@ -270,16 +291,17 @@ QSize BaseDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelInd Q_UNUSED(option) Q_UNUSED(index) - if (_type == Materials::MaterialValue::Color) { + auto type = getType(index); + if (type == Materials::MaterialValue::Color) { return {75, 23}; // Standard QPushButton size } - if (_type == Materials::MaterialValue::Image || _type == Materials::MaterialValue::ImageList) { + if (type == Materials::MaterialValue::Image || type == Materials::MaterialValue::SVG) { return {64, 64}; } - if (_type == Materials::MaterialValue::Array2D || _type == Materials::MaterialValue::Array3D - || _type == Materials::MaterialValue::MultiLineString - || _type == Materials::MaterialValue::List || _type == Materials::MaterialValue::FileList - || _type == Materials::MaterialValue::ImageList) { + if (type == Materials::MaterialValue::Array2D || type == Materials::MaterialValue::Array3D + || type == Materials::MaterialValue::MultiLineString + || type == Materials::MaterialValue::List || type == Materials::MaterialValue::FileList + || type == Materials::MaterialValue::ImageList) { return {23, 23}; } @@ -288,24 +310,31 @@ QSize BaseDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelInd void BaseDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { - auto model = index.model(); - auto item = model->data(index); + if (!editor) { + return; + } - if (_type == Materials::MaterialValue::List) { + auto item = getValue(index); + auto type = getType(index); + if (type == Materials::MaterialValue::List) { auto input = dynamic_cast(editor); item = input->text(); return; } - if (_type == Materials::MaterialValue::FileList || _type == Materials::MaterialValue::File) { + if (type == Materials::MaterialValue::FileList || type == Materials::MaterialValue::File) { auto chooser = dynamic_cast(editor); chooser->setFileName(item.toString()); return; } - if (_type == Materials::MaterialValue::Quantity) { + if (type == Materials::MaterialValue::Quantity) { auto input = dynamic_cast(editor); input->setQuantityString(item.toString()); return; } + if (type == Materials::MaterialValue::List || type == Materials::MaterialValue::ImageList) { + // Handled by dialogs + return; + } QStyledItemDelegate::setEditorData(editor, index); } @@ -314,13 +343,40 @@ void BaseDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { - if (_type == Materials::MaterialValue::FileList) { + QVariant value; + auto type = getType(index); + if (type == Materials::MaterialValue::FileList || type == Materials::MaterialValue::File) { auto chooser = dynamic_cast(editor); - model->setData(index, chooser->fileName()); + value = chooser->fileName(); + } + else if (type == Materials::MaterialValue::Quantity) { + auto input = dynamic_cast(editor); + value = input->text(); + return; + } + else if (type == Materials::MaterialValue::Integer) { + auto spinner = dynamic_cast(editor); + value = spinner->value(); + } + else if (type == Materials::MaterialValue::Float) { + auto spinner = dynamic_cast(editor); + value = spinner->value(); + } + else if (type == Materials::MaterialValue::Boolean) { + auto combo = dynamic_cast(editor); + value = combo->currentText(); + } + else if (type == Materials::MaterialValue::Image || type == Materials::MaterialValue::SVG) { + // Value was already saved to the property + notifyChanged(index.model(), index); + return; } else { - QStyledItemDelegate::setModelData(editor, model, index); + auto lineEdit = dynamic_cast(editor); + value = lineEdit->text(); } + + setValue(model, index, value); } QWidget* BaseDelegate::createEditor(QWidget* parent, @@ -336,7 +392,7 @@ QWidget* BaseDelegate::createEditor(QWidget* parent, if (newRow(model, index)) { const_cast(model)->insertRows(index.row(), 1); } - auto item = model->data(index); + auto item = getValue(index); QWidget* editor = createWidget(parent, item, index); @@ -348,20 +404,15 @@ BaseDelegate::createWidget(QWidget* parent, const QVariant& item, const QModelIn { QWidget* widget = nullptr; - if (_type == Materials::MaterialValue::String || _type == Materials::MaterialValue::URL - || _type == Materials::MaterialValue::List) { - auto lineEdit = new Gui::PrefLineEdit(parent); - lineEdit->setText(item.toString()); - widget = lineEdit; - } - else if (_type == Materials::MaterialValue::Integer) { + auto type = getType(index); + if (type == Materials::MaterialValue::Integer) { auto spinner = new Gui::UIntSpinBox(parent); spinner->setMinimum(0); spinner->setMaximum(UINT_MAX); spinner->setValue(item.toUInt()); widget = spinner; } - else if (_type == Materials::MaterialValue::Float) { + else if (type == Materials::MaterialValue::Float) { auto spinner = new Gui::DoubleSpinBox(parent); // the magnetic permeability is the parameter for which many decimals matter @@ -376,7 +427,7 @@ BaseDelegate::createWidget(QWidget* parent, const QVariant& item, const QModelIn spinner->setValue(item.toDouble()); widget = spinner; } - else if (_type == Materials::MaterialValue::Boolean) { + else if (type == Materials::MaterialValue::Boolean) { auto combo = new Gui::PrefComboBox(parent); combo->insertItem(0, QString::fromStdString("")); combo->insertItem(1, tr("False")); @@ -384,16 +435,24 @@ BaseDelegate::createWidget(QWidget* parent, const QVariant& item, const QModelIn combo->setCurrentText(item.toString()); widget = combo; } - else if (_type == Materials::MaterialValue::Quantity) { + else if (type == Materials::MaterialValue::Quantity) { auto input = new Gui::QuantitySpinBox(parent); input->setMinimum(std::numeric_limits::min()); input->setMaximum(std::numeric_limits::max()); - input->setUnitText(_units); + input->setUnitText(getUnits(index)); input->setValue(item.value()); widget = input; } - else if (_type == Materials::MaterialValue::FileList) { + else if (type == Materials::MaterialValue::File) { + auto chooser = new Gui::FileChooser(parent); + if (!item.toString().isEmpty()) { + chooser->setFileName(item.toString()); + } + + widget = chooser; + } + else if (type == Materials::MaterialValue::FileList) { auto chooser = new Gui::FileChooser(parent); auto propertyValue = item.toString(); @@ -412,7 +471,9 @@ BaseDelegate::createWidget(QWidget* parent, const QVariant& item, const QModelIn } else { // Default editor - widget = new QLineEdit(parent); + auto lineEdit = new Gui::PrefLineEdit(parent); + lineEdit->setText(item.toString()); + widget = lineEdit; } return widget; diff --git a/src/Mod/Material/Gui/BaseDelegate.h b/src/Mod/Material/Gui/BaseDelegate.h index 31d3201019..db29c57898 100644 --- a/src/Mod/Material/Gui/BaseDelegate.h +++ b/src/Mod/Material/Gui/BaseDelegate.h @@ -40,12 +40,10 @@ class BaseDelegate: public QStyledItemDelegate { Q_OBJECT public: - BaseDelegate(Materials::MaterialValue::ValueType type = Materials::MaterialValue::None, - const QString& units = QString(), - QObject* parent = nullptr); + BaseDelegate(QObject* parent = nullptr); virtual ~BaseDelegate() = default; - QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; @@ -53,16 +51,21 @@ public: const QStyleOptionViewItem& styleOption, const QModelIndex& index) const override; void setEditorData(QWidget* editor, const QModelIndex& index) const override; - void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; + void setModelData(QWidget* editor, + QAbstractItemModel* model, + const QModelIndex& index) const override; // Q_SIGNALS: /** Emits this signal when a property has changed */ // void propertyChange(const QModelIndex& index, const QString value); protected: - Materials::MaterialValue::ValueType _type; - QString _units; - + virtual Materials::MaterialValue::ValueType getType(const QModelIndex& index) const = 0; + virtual QString getUnits(const QModelIndex& index) const = 0; + virtual QVariant getValue(const QModelIndex& index) const = 0; + virtual void + setValue(QAbstractItemModel* model, const QModelIndex& index, const QVariant& value) const = 0; + virtual void notifyChanged(const QAbstractItemModel* model, const QModelIndex& index) const = 0; QString getStringValue(const QModelIndex& index) const; QRgb parseColor(const QString& color) const; @@ -73,6 +76,8 @@ protected: void paintImage(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + void + paintSVG(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; void paintColor(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; diff --git a/src/Mod/Material/Gui/ImageEdit.cpp b/src/Mod/Material/Gui/ImageEdit.cpp index 7111ab8335..7ed319554c 100644 --- a/src/Mod/Material/Gui/ImageEdit.cpp +++ b/src/Mod/Material/Gui/ImageEdit.cpp @@ -25,9 +25,13 @@ #endif #include +#include #include +#include #include #include +#include +#include #include #include @@ -53,16 +57,53 @@ ImageLabel::ImageLabel(QWidget* parent) void ImageLabel::setPixmap(const QPixmap& pixmap) { _pixmap = pixmap; + _svg.clear(); QLabel::setPixmap(pixmap); } +void ImageLabel::setSVG(const QString& svg) +{ + _svg = svg; + _pixmap = QPixmap(); + update(); + // renderSVG(); +} + +void ImageLabel::renderSVG() +{ + QPainter painter(this); + QSvgRenderer renderer(_svg.toUtf8(), this); + + painter.begin(this); + + renderer.render(&painter); + + painter.end(); +} + void ImageLabel::resizeEvent(QResizeEvent* event) { - QPixmap px = _pixmap.scaled(event->size(), Qt::KeepAspectRatio); - QLabel::setPixmap(px); - QLabel::resizeEvent(event); + if (_svg.isEmpty()) { + QPixmap px = _pixmap.scaled(event->size(), Qt::KeepAspectRatio); + QLabel::setPixmap(px); + QLabel::resizeEvent(event); + } + // else { + // renderSVG(); + // } } +void ImageLabel::paintEvent(QPaintEvent* event) +{ + if (!_svg.isEmpty()) { + QSvgRenderer renderer(_svg.toUtf8()); + QPainter painter(this); + renderer.render(&painter, QRectF(event->rect())); + } + else { + QLabel::paintEvent(event); + } +} //=== ImageEdit::ImageEdit(const QString& propertyName, @@ -86,17 +127,24 @@ ImageEdit::ImageEdit(const QString& propertyName, _property = nullptr; } if (_property) { - QString value = _property->getString(); - if (!value.isEmpty()) { - QByteArray by = QByteArray::fromBase64(value.toUtf8()); - QImage img = QImage::fromData(by, "PNG"); - _pixmap = QPixmap::fromImage(img); + if (_property->getType() == Materials::MaterialValue::SVG) { + _svg = _property->getString(); + showSVG(); + } + else { + QString value = _property->getString(); + if (!value.isEmpty()) { + QByteArray by = QByteArray::fromBase64(value.toUtf8()); + QImage img = QImage::fromData(by, "PNG"); + _pixmap = QPixmap::fromImage(img); + } + showPixmap(); } } else { Base::Console().Log("No value loaded\n"); + showPixmap(); } - showPixmap(); connect(ui->buttonFileSelect, &QPushButton::clicked, this, &ImageEdit::onFileSelect); @@ -114,43 +162,92 @@ void ImageEdit::showPixmap() ui->editHeight->setText(text.setNum(_pixmap.height())); } +void ImageEdit::showSVG() +{ + ui->labelThumb->setSVG(_svg); + ui->labelThumb->setFixedSize(64, 64); + ui->labelImage->setSVG(_svg); + // QString text; + // ui->editWidth->setText(text.setNum(_pixmap.width())); + // ui->editHeight->setText(text.setNum(_pixmap.height())); +} + void ImageEdit::onFileSelect(bool checked) { Q_UNUSED(checked) + if (_property && _property->getType() == Materials::MaterialValue::SVG) { + onFileSelectSVG(); + } + else { + onFileSelectImage(); + } +} + +QString ImageEdit::selectFile(const QString& filePatterns) +{ QFileDialog::Options dlgOpt; if (Gui::DialogOptions::dontUseNativeFileDialog()) { dlgOpt = QFileDialog::DontUseNativeDialog; } QString directory = Gui::FileDialog::getWorkingDirectory(); - QString fn = Gui::FileDialog::getOpenFileName( - this, - tr("Select an image"), - directory, - tr("Image files (*.jpg *.jpeg *.png *.bmp);;All files (*)"), - nullptr, - dlgOpt); + QString fn = Gui::FileDialog::getOpenFileName(this, + tr("Select an image"), + directory, + filePatterns, + nullptr, + dlgOpt); + return fn; +} + +void ImageEdit::onFileSelectImage() +{ + QString fn = selectFile(tr("Image files (*.jpg *.jpeg *.png *.bmp);;All files (*)")); if (!fn.isEmpty()) { fn = QDir::fromNativeSeparators(fn); - Gui::FileDialog::setWorkingDirectory(fn); _pixmap = QPixmap(fn); + _svg.clear(); showPixmap(); } } +void ImageEdit::onFileSelectSVG() +{ + QString fn = selectFile(tr("Image files (*.svg);;All files (*)")); + if (!fn.isEmpty()) { + fn = QDir::fromNativeSeparators(fn); + + _pixmap = QPixmap(); + QFile file(fn); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + _svg.clear(); + } + else { + QTextStream stream(&file); + _svg = stream.readAll(); + } + showSVG(); + } +} + void ImageEdit::accept() { if (_property) { - QBuffer buffer; - buffer.open(QIODevice::WriteOnly); - _pixmap.save(&buffer, "PNG"); - QByteArray base64 = buffer.data().toBase64(); - QString encoded = QString::fromUtf8(base64); - _property->setValue(encoded); + if (_property->getType() == Materials::MaterialValue::SVG) { + _property->setValue(_svg); + } + else { + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + _pixmap.save(&buffer, "PNG"); + QByteArray base64 = buffer.data().toBase64(); + QString encoded = QString::fromUtf8(base64); + _property->setValue(encoded); + } } QDialog::accept(); } diff --git a/src/Mod/Material/Gui/ImageEdit.h b/src/Mod/Material/Gui/ImageEdit.h index d048b4da10..faa8d1b59b 100644 --- a/src/Mod/Material/Gui/ImageEdit.h +++ b/src/Mod/Material/Gui/ImageEdit.h @@ -53,12 +53,16 @@ public: ~ImageLabel() = default; void setPixmap(const QPixmap& pixmap); + void setSVG(const QString& svg); + void renderSVG(); protected: void resizeEvent(QResizeEvent* event); + void paintEvent(QPaintEvent* event); private: QPixmap _pixmap; + QString _svg; }; class ImageEdit: public QDialog @@ -71,19 +75,26 @@ public: QWidget* parent = nullptr); ~ImageEdit() override = default; - void onFileSelect(bool checked); - void accept() override; void reject() override; +private Q_SLOTS: + void onFileSelect(bool checked); + private: std::unique_ptr ui; std::shared_ptr _material; std::shared_ptr _property; QPixmap _pixmap; + QString _svg; void showPixmap(); + void showSVG(); + + QString selectFile(const QString& filePatterns); + void onFileSelectImage(); + void onFileSelectSVG(); }; } // namespace MatGui diff --git a/src/Mod/Material/Gui/ListDelegate.cpp b/src/Mod/Material/Gui/ListDelegate.cpp index 6605020cf9..1932cb396f 100644 --- a/src/Mod/Material/Gui/ListDelegate.cpp +++ b/src/Mod/Material/Gui/ListDelegate.cpp @@ -58,20 +58,47 @@ using namespace MatGui; ListDelegate::ListDelegate(Materials::MaterialValue::ValueType type, const QString& units, QObject* parent) - : BaseDelegate(type, units, parent) + : BaseDelegate(parent) + , _type(type) + , _units(units) {} +QVariant ListDelegate::getValue(const QModelIndex& index) const +{ + auto model = index.model(); + auto item = model->data(index); + + return item; +} + +void ListDelegate::setValue(QAbstractItemModel* model, + const QModelIndex& index, + const QVariant& value) const +{ + auto matModel = dynamic_cast(model); + matModel->setData(index, value); + + notifyChanged(model, index); +} + +void ListDelegate::notifyChanged(const QAbstractItemModel* model, const QModelIndex& index) const +{ + Q_UNUSED(model) + Q_UNUSED(index) +} + void ListDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - if (_type == Materials::MaterialValue::Quantity) { + auto type = getType(index); + if (type == Materials::MaterialValue::Quantity) { paintQuantity(painter, option, index); return; } - if (_type == Materials::MaterialValue::Image || _type == Materials::MaterialValue::ImageList) { + if (type == Materials::MaterialValue::Image || type == Materials::MaterialValue::ImageList) { paintImage(painter, option, index); return; } diff --git a/src/Mod/Material/Gui/ListDelegate.h b/src/Mod/Material/Gui/ListDelegate.h index adcb1edfbf..8ff627a3f2 100644 --- a/src/Mod/Material/Gui/ListDelegate.h +++ b/src/Mod/Material/Gui/ListDelegate.h @@ -51,7 +51,24 @@ public: const QStyleOptionViewItem& option, const QModelIndex& index) const override; +protected: + Materials::MaterialValue::ValueType getType(const QModelIndex& index) const override + { + return _type; + } + QString getUnits(const QModelIndex& index) const override + { + return _units; + } + QVariant getValue(const QModelIndex& index) const override; + void setValue(QAbstractItemModel* model, + const QModelIndex& index, + const QVariant& value) const override; + void notifyChanged(const QAbstractItemModel* model, const QModelIndex& index) const override; + private: + Materials::MaterialValue::ValueType _type; + QString _units; }; } // namespace MatGui diff --git a/src/Mod/Material/Gui/MaterialDelegate.cpp b/src/Mod/Material/Gui/MaterialDelegate.cpp index f10726c598..38e67cc5e1 100644 --- a/src/Mod/Material/Gui/MaterialDelegate.cpp +++ b/src/Mod/Material/Gui/MaterialDelegate.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #endif @@ -59,9 +60,109 @@ using namespace MatGui; MaterialDelegate::MaterialDelegate(QObject* parent) - : QStyledItemDelegate(parent) + : BaseDelegate(parent) {} +Materials::MaterialValue::ValueType MaterialDelegate::getType(const QModelIndex& index) const +{ + auto treeModel = dynamic_cast(index.model()); + auto item = treeModel->itemFromIndex(index); + auto group = item->parent(); + if (!group) { + return {}; + } + + int row = index.row(); + QString propertyType; + if (group->child(row, 1)) { + propertyType = group->child(row, 2)->text(); + } + + return Materials::MaterialValue::mapType(propertyType); +} + +QString MaterialDelegate::getUnits(const QModelIndex& index) const +{ + auto treeModel = dynamic_cast(index.model()); + auto item = treeModel->itemFromIndex(index); + auto group = item->parent(); + if (!group) { + return {}; + } + + int row = index.row(); + QString propertyUnits; + if (group->child(row, 1)) { + propertyUnits = group->child(row, 3)->text(); + } + return propertyUnits; +} + +QVariant MaterialDelegate::getValue(const QModelIndex& index) const +{ + auto treeModel = dynamic_cast(index.model()); + auto item = treeModel->itemFromIndex(index); + auto group = item->parent(); + if (!group) { + return {}; + } + + int row = index.row(); + QVariant propertyValue; + if (group->child(row, 1)) { + auto material = group->child(row, 1)->data().value>(); + auto propertyName = group->child(row, 0)->text(); + propertyValue = material->getProperty(propertyName)->getValue(); + } + return propertyValue; +} + +void MaterialDelegate::setValue(QAbstractItemModel* model, + const QModelIndex& index, + const QVariant& value) const +{ + auto matModel = dynamic_cast(model); + auto item = matModel->itemFromIndex(index); + auto group = item->parent(); + if (!group) { + return; + } + + int row = index.row(); + if (group->child(row, 1)) { + auto material = group->child(row, 1)->data().value>(); + auto propertyName = group->child(row, 0)->text(); + material->getProperty(propertyName)->setValue(value); + group->child(row, 1)->setText(value.toString()); + } + + notifyChanged(model, index); +} + +void MaterialDelegate::notifyChanged(const QAbstractItemModel* model, + const QModelIndex& index) const +{ + Base::Console().Log("MaterialDelegate::notifyChanged()\n"); + auto treeModel = dynamic_cast(model); + auto item = treeModel->itemFromIndex(index); + auto group = item->parent(); + if (!group) { + return; + } + + int row = index.row(); + if (group->child(row, 1)) { + auto material = group->child(row, 1)->data().value>(); + auto propertyName = group->child(row, 0)->text(); + auto propertyValue = material->getProperty(propertyName)->getValue(); + material->setEditStateAlter(); + Base::Console().Log("MaterialDelegate::notifyChanged() - marked altered\n"); + + Q_EMIT const_cast(this)->propertyChange(propertyName, + propertyValue.toString()); + } +} + bool MaterialDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, @@ -82,38 +183,35 @@ bool MaterialDelegate::editorEvent(QEvent* event, int row = index.row(); QString propertyName = group->child(row, 0)->text(); - QString propertyType = QString::fromStdString("String"); - if (group->child(row, 2)) { - propertyType = group->child(row, 2)->text(); - } - std::string type = propertyType.toStdString(); - if (type == "Color") { - showColorModal(item, propertyName); + auto type = getType(index); + if (type == Materials::MaterialValue::Color) { + showColorModal(propertyName, item); // Mark as handled return true; } - if (type == "MultiLineString") { - showMultiLineString(propertyName, item); + if (type == Materials::MaterialValue::MultiLineString) { + showMultiLineStringModal(propertyName, item); // Mark as handled return true; } - if (type == "List" || type == "FileList" || type == "ImageList") { + if (type == Materials::MaterialValue::List || type == Materials::MaterialValue::FileList + || type == Materials::MaterialValue::ImageList) { showListModal(propertyName, item); // Mark as handled return true; } - if (type == "2DArray") { + if (type == Materials::MaterialValue::Array2D) { showArray2DModal(propertyName, item); // Mark as handled return true; } - if (type == "3DArray") { + if (type == Materials::MaterialValue::Array3D) { showArray3DModal(propertyName, item); // Mark as handled return true; } - if (type == "Image") { + if (type == Materials::MaterialValue::Image || type == Materials::MaterialValue::SVG) { showImageModal(propertyName, item); // Mark as handled return true; @@ -123,7 +221,7 @@ bool MaterialDelegate::editorEvent(QEvent* event, return QStyledItemDelegate::editorEvent(event, model, option, index); } -void MaterialDelegate::showColorModal(QStandardItem* item, QString propertyName) +void MaterialDelegate::showColorModal(const QString& propertyName, QStandardItem* item) { QColor currentColor; // = d->col; currentColor.setRgba(parseColor(item->text())); @@ -166,11 +264,7 @@ void MaterialDelegate::showImageModal(const QString& propertyName, QStandardItem dlg->adjustSize(); - connect(dlg, &QDialog::finished, this, [&](int result) { - if (result == QDialog::Accepted) { - Base::Console().Log("Accepted\n"); - } - }); + connect(dlg, &QDialog::finished, this, [&](int result) {}); dlg->exec(); } @@ -184,16 +278,12 @@ void MaterialDelegate::showListModal(const QString& propertyName, QStandardItem* dlg->adjustSize(); - connect(dlg, &QDialog::finished, this, [&](int result) { - if (result == QDialog::Accepted) { - Base::Console().Log("Accepted\n"); - } - }); + connect(dlg, &QDialog::finished, this, [&](int result) {}); dlg->exec(); } -void MaterialDelegate::showMultiLineString(const QString& propertyName, QStandardItem* item) +void MaterialDelegate::showMultiLineStringModal(const QString& propertyName, QStandardItem* item) { auto material = item->data().value>(); auto dlg = new TextEdit(propertyName, material); @@ -202,11 +292,7 @@ void MaterialDelegate::showMultiLineString(const QString& propertyName, QStandar dlg->adjustSize(); - connect(dlg, &QDialog::finished, this, [&](int result) { - if (result == QDialog::Accepted) { - Base::Console().Log("Accepted\n"); - } - }); + connect(dlg, &QDialog::finished, this, [&](int result) {}); dlg->exec(); } @@ -221,11 +307,7 @@ void MaterialDelegate::showArray2DModal(const QString& propertyName, QStandardIt dlg->adjustSize(); - connect(dlg, &QDialog::finished, this, [&](int result) { - if (result == QDialog::Accepted) { - Base::Console().Log("Accepted\n"); - } - }); + connect(dlg, &QDialog::finished, this, [&](int result) {}); dlg->exec(); } @@ -239,11 +321,7 @@ void MaterialDelegate::showArray3DModal(const QString& propertyName, QStandardIt dlg->adjustSize(); - connect(dlg, &QDialog::finished, this, [&](int result) { - if (result == QDialog::Accepted) { - Base::Console().Log("Accepted\n"); - } - }); + connect(dlg, &QDialog::finished, this, [&](int result) {}); dlg->exec(); } @@ -267,207 +345,40 @@ void MaterialDelegate::paint(QPainter* painter, return; } - int row = index.row(); - - QString propertyName = group->child(row, 0)->text(); - QString propertyType = QString::fromStdString("String"); - if (group->child(row, 2)) { - propertyType = group->child(row, 2)->text(); - } - QString propertyValue = QString::fromStdString(""); - if (group->child(row, 1)) { - propertyValue = group->child(row, 1)->text(); - } - - std::string type = propertyType.toStdString(); - if (type == "Color") { - painter->save(); - ; - - QColor color; - color.setRgba(qRgba(0, 0, 0, 255)); // Black border - int left = option.rect.left() + 2; - int width = option.rect.width() - 4; - if (option.rect.width() > 75) { - left += (option.rect.width() - 75) / 2; - width = 71; - } - painter->fillRect(left, - option.rect.top() + 2, - width, - option.rect.height() - 4, - QBrush(color)); - - color.setRgba(parseColor(propertyValue)); - left = option.rect.left() + 5; - width = option.rect.width() - 10; - if (option.rect.width() > 75) { - left += (option.rect.width() - 75) / 2; - width = 65; - } - painter->fillRect(left, - option.rect.top() + 5, - width, - option.rect.height() - 10, - QBrush(color)); - - painter->restore(); + auto type = getType(index); + if (type == Materials::MaterialValue::Quantity) { + paintQuantity(painter, option, index); return; } - if (type == "Image") { - painter->save(); - - QImage img; - if (!propertyValue.isEmpty()) { - Base::Console().Log("Loading image\n"); - QByteArray by = QByteArray::fromBase64(propertyValue.toUtf8()); - img = QImage::fromData(by, "PNG").scaled(64, 64, Qt::KeepAspectRatio); - } - QRect target(option.rect); - if (target.width() > target.height()) { - target.setWidth(target.height()); - } - else { - target.setHeight(target.width()); - } - painter->drawImage(target, img, img.rect()); - - painter->restore(); + if (type == Materials::MaterialValue::Image) { + paintImage(painter, option, index); return; } - if (type == "List" || type == "FileList" || type == "ImageList") { - painter->save(); - - QImage table(QString::fromStdString(":/icons/list.svg")); - QRect target(option.rect); - if (target.width() > target.height()) { - target.setWidth(target.height()); - } - else { - target.setHeight(target.width()); - } - painter->drawImage(target, table, table.rect()); - - painter->restore(); + if (type == Materials::MaterialValue::SVG) { + paintSVG(painter, option, index); return; } - if (type == "MultiLineString") { - painter->save(); - - QImage table(QString::fromStdString(":/icons/multiline.svg")); - QRect target(option.rect); - if (target.width() > target.height()) { - target.setWidth(target.height()); - } - else { - target.setHeight(target.width()); - } - painter->drawImage(target, table, table.rect()); - - painter->restore(); + if (type == Materials::MaterialValue::Color) { + paintColor(painter, option, index); return; } - if (type == "2DArray" || type == "3DArray") { - painter->save(); - - QImage table(QString::fromStdString(":/icons/table.svg")); - QRect target(option.rect); - if (target.width() > target.height()) { - target.setWidth(target.height()); - } - else { - target.setHeight(target.width()); - } - painter->drawImage(target, table, table.rect()); - - painter->restore(); + if (type == Materials::MaterialValue::List || type == Materials::MaterialValue::FileList + || type == Materials::MaterialValue::ImageList) { + paintList(painter, option, index); + return; + } + if (type == Materials::MaterialValue::MultiLineString) { + paintMultiLineString(painter, option, index); + return; + } + if (type == Materials::MaterialValue::Array2D || type == Materials::MaterialValue::Array3D) { + paintArray(painter, option, index); return; } QStyledItemDelegate::paint(painter, option, index); } -QSize MaterialDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const -{ - if (index.column() != 1) { - return QStyledItemDelegate::sizeHint(option, index); - } - - auto treeModel = dynamic_cast(index.model()); - - // Check we're not the material model root. This is also used to access the entry columns - auto item = treeModel->itemFromIndex(index); - auto group = item->parent(); - if (!group) { - return QStyledItemDelegate::sizeHint(option, index); - } - - int row = index.row(); - - QString propertyType = QString::fromStdString("String"); - if (group->child(row, 2)) { - propertyType = group->child(row, 2)->text(); - } - - std::string type = propertyType.toStdString(); - if (type == "Color") { - return {75, 23}; // Standard QPushButton size - } - if (type == "Image") { - return {64, 64}; - } - if (type == "2DArray" || type == "3DArray" || type == "MultiLineString" || type == "List" - || type == "FileList" || type == "ImageList") { - return {23, 23}; - } - - return QStyledItemDelegate::sizeHint(option, index); -} - -void MaterialDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const -{ - QVariant propertyType = editor->property("Type"); - auto model = dynamic_cast(index.model()); - QStandardItem* item = model->itemFromIndex(index); - auto group = item->parent(); - if (!group) { - return; - } - - int row = index.row(); - QString propertyName = group->child(row, 0)->text(); - - std::string type = propertyType.toString().toStdString(); - if (type == "File") { - auto chooser = dynamic_cast(editor); - item->setText(chooser->fileName()); - } - else if (type == "Quantity") { - auto input = dynamic_cast(editor); - item->setText(input->getQuantityString()); - } - else { - QStyledItemDelegate::setEditorData(editor, index); - } -} - -void MaterialDelegate::setModelData(QWidget* editor, - QAbstractItemModel* model, - const QModelIndex& index) const -{ - QStyledItemDelegate::setModelData(editor, model, index); - - auto item = dynamic_cast(model)->itemFromIndex(index); - auto group = item->parent(); - if (!group) { - return; - } - - int row = index.row(); - QString propertyName = group->child(row, 0)->text(); - Q_EMIT const_cast(this)->propertyChange(propertyName, item->text()); -} - QWidget* MaterialDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& styleOption, const QModelIndex& index) const @@ -487,52 +398,27 @@ QWidget* MaterialDelegate::createEditor(QWidget* parent, return nullptr; } - int row = index.row(); - - QString propertyName = group->child(row, 0)->text(); - QString propertyType = QString::fromStdString("String"); - if (group->child(row, 2)) { - propertyType = group->child(row, 2)->text(); - } - - QString propertyValue = QString::fromStdString(""); - if (group->child(row, 1)) { - propertyValue = group->child(row, 1)->text(); - } - - QString propertyUnits = QString::fromStdString(""); - if (group->child(row, 1)) { - propertyUnits = group->child(row, 3)->text(); - } - - QWidget* editor = - createWidget(parent, propertyName, propertyType, propertyValue, propertyUnits); + QVariant value = treeModel->data(index); + QWidget* editor = createWidget(parent, value, index); return editor; } QWidget* MaterialDelegate::createWidget(QWidget* parent, - const QString& propertyName, - const QString& propertyType, - const QString& propertyValue, - const QString& propertyUnits) const + const QVariant& item, + const QModelIndex& index) const { - Q_UNUSED(propertyName); - QWidget* widget = nullptr; - std::string type = propertyType.toStdString(); - if (type == "String" || type == "URL") { - widget = new Gui::PrefLineEdit(parent); - } - else if (type == "Integer") { + auto type = getType(index); + if (type == Materials::MaterialValue::Integer) { auto spinner = new Gui::IntSpinBox(parent); spinner->setMinimum(0); spinner->setMaximum(INT_MAX); - spinner->setValue(propertyValue.toInt()); + spinner->setValue(item.toInt()); widget = spinner; } - else if (type == "Float") { + else if (type == Materials::MaterialValue::Float) { auto spinner = new Gui::DoubleSpinBox(parent); // the magnetic permeability is the parameter for which many decimals matter @@ -544,64 +430,43 @@ QWidget* MaterialDelegate::createWidget(QWidget* parent, spinner->setMinimum(std::numeric_limits::min()); spinner->setMaximum(std::numeric_limits::max()); - spinner->setValue(propertyValue.toDouble()); + spinner->setValue(item.toDouble()); widget = spinner; } - else if (type == "Boolean") { + else if (type == Materials::MaterialValue::Boolean) { auto combo = new Gui::PrefComboBox(parent); combo->insertItem(0, QString::fromStdString("")); combo->insertItem(1, tr("False")); combo->insertItem(2, tr("True")); - combo->setCurrentText(propertyValue); + combo->setCurrentText(item.toString()); widget = combo; } - else if (type == "Quantity") { + else if (type == Materials::MaterialValue::Quantity) { auto input = new Gui::InputField(parent); input->setMinimum(std::numeric_limits::min()); input->setMaximum(std::numeric_limits::max()); - input->setUnitText(propertyUnits); // TODO: Ensure this exists + input->setUnitText(getUnits(index)); input->setPrecision(6); - input->setQuantityString(propertyValue); + input->setValue(item.value()); widget = input; } - else if (type == "File") { + else if (type == Materials::MaterialValue::File) { auto chooser = new Gui::FileChooser(parent); - if (!propertyValue.isEmpty()) { - chooser->setFileName(propertyValue); + if (!item.toString().isEmpty()) { + chooser->setFileName(item.toString()); } widget = chooser; } else { // Default editor - widget = new QLineEdit(parent); + auto lineEdit = new Gui::PrefLineEdit(parent); + lineEdit->setText(item.toString()); + widget = lineEdit; } - widget->setProperty("Type", propertyType); - // widget->setParent(parent); - return widget; } -QRgb MaterialDelegate::parseColor(const QString& color) const -{ - QString trimmed = color; - trimmed.replace(QRegularExpression(QString::fromStdString("\\(([^<]*)\\)")), - QString::fromStdString("\\1")); - QStringList parts = trimmed.split(QString::fromStdString(",")); - if (parts.length() < 3) { - return qRgba(0, 0, 0, 255); - } - int red = parts.at(0).toDouble() * 255; - int green = parts.at(1).toDouble() * 255; - int blue = parts.at(2).toDouble() * 255; - int alpha = 255; - if (parts.length() > 3) { - alpha = parts.at(3).toDouble() * 255; - } - - return qRgba(red, green, blue, alpha); -} - #include "moc_MaterialDelegate.cpp" diff --git a/src/Mod/Material/Gui/MaterialDelegate.h b/src/Mod/Material/Gui/MaterialDelegate.h index 83c4f3a83a..9a37cfc091 100644 --- a/src/Mod/Material/Gui/MaterialDelegate.h +++ b/src/Mod/Material/Gui/MaterialDelegate.h @@ -33,10 +33,12 @@ #include #include +#include "BaseDelegate.h" + namespace MatGui { -class MaterialDelegate: public QStyledItemDelegate +class MaterialDelegate: public BaseDelegate { Q_OBJECT public: @@ -46,14 +48,14 @@ public: QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& styleOption, const QModelIndex& index) const override; - QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; + // QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; - void setEditorData(QWidget* editor, const QModelIndex& index) const override; - void setModelData(QWidget* editor, - QAbstractItemModel* model, - const QModelIndex& index) const override; + // void setEditorData(QWidget* editor, const QModelIndex& index) const override; + // void setModelData(QWidget* editor, + // QAbstractItemModel* model, + // const QModelIndex& index) const override; protected: bool editorEvent(QEvent* event, @@ -61,21 +63,25 @@ protected: const QStyleOptionViewItem& option, const QModelIndex& index) override; + Materials::MaterialValue::ValueType getType(const QModelIndex& index) const override; + QString getUnits(const QModelIndex& index) const override; + QVariant getValue(const QModelIndex& index) const override; + void setValue(QAbstractItemModel* model, + const QModelIndex& index, + const QVariant& value) const override; + void notifyChanged(const QAbstractItemModel* model, const QModelIndex& index) const override; + Q_SIGNALS: /** Emits this signal when a property has changed */ void propertyChange(const QString& property, const QString value); private: - QWidget* createWidget(QWidget* parent, - const QString& propertyName, - const QString& propertyType, - const QString& propertyValue, - const QString& propertyUnits) const; - QRgb parseColor(const QString& color) const; - void showColorModal(QStandardItem* item, QString propertyName); + QWidget* createWidget(QWidget* parent, const QVariant& item, const QModelIndex& index) const; + // QRgb parseColor(const QString& color) const; + void showColorModal(const QString& propertyName, QStandardItem* item); void showImageModal(const QString& propertyName, QStandardItem* item); void showListModal(const QString& propertyName, QStandardItem* item); - void showMultiLineString(const QString& propertyName, QStandardItem* item); + void showMultiLineStringModal(const QString& propertyName, QStandardItem* item); void showArray2DModal(const QString& propertyName, QStandardItem* item); void showArray3DModal(const QString& propertyName, QStandardItem* item); }; diff --git a/src/Mod/Material/Gui/MaterialsEditor.cpp b/src/Mod/Material/Gui/MaterialsEditor.cpp index a75b8801b4..3c23ec20f8 100644 --- a/src/Mod/Material/Gui/MaterialsEditor.cpp +++ b/src/Mod/Material/Gui/MaterialsEditor.cpp @@ -156,7 +156,7 @@ void MaterialsEditor::getFavorites() auto param = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Material/Favorites"); int count = param->GetInt("Favorites", 0); - for (int i = 0; i < count; i++) { + for (int i = 0; static_cast(i) < count; i++) { QString key = QString::fromLatin1("FAV%1").arg(i); QString uuid = QString::fromStdString(param->GetASCII(key.toStdString().c_str(), "")); _favorites.push_back(uuid); @@ -170,7 +170,7 @@ void MaterialsEditor::saveFavorites() // Clear out the existing favorites int count = param->GetInt("Favorites", 0); - for (int i = 0; i < count; i++) { + for (int i = 0; static_cast(i) < count; i++) { QString key = QString::fromLatin1("FAV%1").arg(i); param->RemoveASCII(key.toStdString().c_str()); } @@ -232,7 +232,7 @@ void MaterialsEditor::getRecents() "User parameter:BaseApp/Preferences/Mod/Material/Recent"); _recentMax = param->GetInt("RecentMax", 5); int count = param->GetInt("Recent", 0); - for (int i = 0; i < count; i++) { + for (int i = 0; static_cast(i) < count; i++) { QString key = QString::fromLatin1("MRU%1").arg(i); QString uuid = QString::fromStdString(param->GetASCII(key.toStdString().c_str(), "")); _recents.push_back(uuid); @@ -246,7 +246,7 @@ void MaterialsEditor::saveRecents() // Clear out the existing favorites int count = param->GetInt("Recent", 0); - for (int i = 0; i < count; i++) { + for (int i = 0; static_cast(i) < count; i++) { QString key = QString::fromLatin1("MRU%1").arg(i); param->RemoveASCII(key.toStdString().c_str()); } @@ -342,6 +342,7 @@ void MaterialsEditor::propertyChange(const QString& property, const QString valu _material->setAppearanceValue(property, value); updatePreview(); } + update(); _edited = true; } @@ -514,6 +515,15 @@ void MaterialsEditor::onOk(bool checked) { Q_UNUSED(checked) + // Ensure data is saved (or discarded) before exiting + if (_material->getEditState() != Materials::Material::ModelEdit_None) { + // Prompt the user to save or discard changes + int res = confirmSave(this); + if (res == QMessageBox::Cancel) { + return; + } + } + accept(); } @@ -606,7 +616,7 @@ void MaterialsEditor::saveMaterialTree(const Base::Reference& para treeParam->Clear(); auto tree = ui->treeMaterials; - auto model = static_cast(tree->model()); + auto model = dynamic_cast(tree->model()); auto root = model->invisibleRootItem(); for (int i = 0; i < root->rowCount(); i++) { @@ -796,7 +806,7 @@ void MaterialsEditor::fillMaterialTree() "User parameter:BaseApp/Preferences/Mod/Material/Editor/MaterialTree"); auto tree = ui->treeMaterials; - auto model = static_cast(tree->model()); + auto model = dynamic_cast(tree->model()); auto lib = new QStandardItem(tr("Favorites")); lib->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled); @@ -835,7 +845,7 @@ void MaterialsEditor::createMaterialTree() void MaterialsEditor::refreshMaterialTree() { auto tree = ui->treeMaterials; - auto model = static_cast(tree->model()); + auto model = dynamic_cast(tree->model()); model->clear(); fillMaterialTree(); @@ -925,7 +935,7 @@ QString MaterialsEditor::getColorHash(const QString& colorString, int colorRange void MaterialsEditor::updateMaterialAppearance() { QTreeView* tree = ui->treeAppearance; - auto treeModel = static_cast(tree->model()); + auto treeModel = dynamic_cast(tree->model()); treeModel->clear(); QStringList headers; @@ -1099,7 +1109,7 @@ void MaterialsEditor::onSelectMaterial(const QItemSelection& selected, // Get the UUID before changing the underlying data model QString uuid; - auto model = static_cast(ui->treeMaterials->model()); + auto model = dynamic_cast(ui->treeMaterials->model()); QModelIndexList indexes = selected.indexes(); for (auto it = indexes.begin(); it != indexes.end(); it++) { QStandardItem* item = model->itemFromIndex(*it); @@ -1140,6 +1150,15 @@ void MaterialsEditor::onDoubleClick(const QModelIndex& index) { Q_UNUSED(index) + // Ensure data is saved (or discarded) before exiting + if (_material->getEditState() != Materials::Material::ModelEdit_None) { + // Prompt the user to save or discard changes + int res = confirmSave(this); + if (res == QMessageBox::Cancel) { + return; + } + } + accept(); } diff --git a/src/Mod/Material/Gui/ModelSelect.cpp b/src/Mod/Material/Gui/ModelSelect.cpp index 4a874939c5..82a17956fb 100644 --- a/src/Mod/Material/Gui/ModelSelect.cpp +++ b/src/Mod/Material/Gui/ModelSelect.cpp @@ -82,7 +82,7 @@ void ModelSelect::getFavorites() auto param = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Material/Models/Favorites"); int count = param->GetInt("Favorites", 0); - for (int i = 0; i < count; i++) { + for (int i = 0; static_cast(i) < count; i++) { QString key = QString::fromLatin1("FAV%1").arg(i); QString uuid = QString::fromStdString(param->GetASCII(key.toStdString().c_str(), "")); _favorites.push_back(uuid); @@ -96,7 +96,7 @@ void ModelSelect::saveFavorites() // Clear out the existing favorites int count = param->GetInt("Favorites", 0); - for (int i = 0; i < count; i++) { + for (int i = 0; static_cast(i) < count; i++) { QString key = QString::fromLatin1("FAV%1").arg(i); param->RemoveASCII(key.toStdString().c_str()); } @@ -149,7 +149,7 @@ void ModelSelect::getRecents() "User parameter:BaseApp/Preferences/Mod/Material/Models/Recent"); _recentMax = param->GetInt("RecentMax", 5); int count = param->GetInt("Recent", 0); - for (int i = 0; i < count; i++) { + for (int i = 0; static_cast(i) < count; i++) { QString key = QString::fromLatin1("MRU%1").arg(i); QString uuid = QString::fromStdString(param->GetASCII(key.toStdString().c_str(), "")); _recents.push_back(uuid); @@ -163,7 +163,7 @@ void ModelSelect::saveRecents() // Clear out the existing favorites int count = param->GetInt("Recent", 0); - for (int i = 0; i < count; i++) { + for (int i = 0; static_cast(i) < count; i++) { QString key = QString::fromLatin1("MRU%1").arg(i); param->RemoveASCII(key.toStdString().c_str()); } diff --git a/src/Mod/Material/Resources/Materials/Appearance/DefaultAppearance.FCMat b/src/Mod/Material/Resources/Materials/Appearance/Default.FCMat similarity index 94% rename from src/Mod/Material/Resources/Materials/Appearance/DefaultAppearance.FCMat rename to src/Mod/Material/Resources/Materials/Appearance/Default.FCMat index 44ce8d6970..e17d466801 100644 --- a/src/Mod/Material/Resources/Materials/Appearance/DefaultAppearance.FCMat +++ b/src/Mod/Material/Resources/Materials/Appearance/Default.FCMat @@ -4,7 +4,7 @@ General: UUID: "5dbb7be6-8b63-479b-ab4c-87be02ead973" Author: "David Carter" License: "GPL-2.0-or-later" - Name: "Default Appearance" + Name: "Default" Description: "Defines the default appearance properties" AppearanceModels: BasicRendering: diff --git a/src/Mod/Material/Resources/Materials/Appearance/NeonGNC.FCMat b/src/Mod/Material/Resources/Materials/Appearance/Neon GNC.FCMat similarity index 100% rename from src/Mod/Material/Resources/Materials/Appearance/NeonGNC.FCMat rename to src/Mod/Material/Resources/Materials/Appearance/Neon GNC.FCMat diff --git a/src/Mod/Material/Resources/Materials/Appearance/NeonPHC.FCMat b/src/Mod/Material/Resources/Materials/Appearance/Neon PHC.FCMat similarity index 100% rename from src/Mod/Material/Resources/Materials/Appearance/NeonPHC.FCMat rename to src/Mod/Material/Resources/Materials/Appearance/Neon PHC.FCMat diff --git a/src/Mod/Material/Resources/Materials/Appearance/ShinyPlastic.FCMat b/src/Mod/Material/Resources/Materials/Appearance/Shiny Plastic.FCMat similarity index 100% rename from src/Mod/Material/Resources/Materials/Appearance/ShinyPlastic.FCMat rename to src/Mod/Material/Resources/Materials/Appearance/Shiny Plastic.FCMat diff --git a/src/Mod/Material/Resources/Materials/Fluid/Carbon_dioxide.FCMat b/src/Mod/Material/Resources/Materials/Fluid/Carbon Dioxide.FCMat similarity index 97% rename from src/Mod/Material/Resources/Materials/Fluid/Carbon_dioxide.FCMat rename to src/Mod/Material/Resources/Materials/Fluid/Carbon Dioxide.FCMat index c9535fe16b..3bf5e02d0f 100644 --- a/src/Mod/Material/Resources/Materials/Fluid/Carbon_dioxide.FCMat +++ b/src/Mod/Material/Resources/Materials/Fluid/Carbon Dioxide.FCMat @@ -3,7 +3,7 @@ General: UUID: "ef0e4040-a498-48c3-a87b-e996bfd89195" License: "GPL-2.0-or-later" - Name: "Carbon dioxide" + Name: "Carbon Dioxide" Description: "Carbon dioxide properties at 20 Degrees Celsius and 1 atm" Models: Father: diff --git a/src/Mod/Material/Resources/Materials/Patterns/PAT/Diagonal4.FCMat b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diagonal4.FCMat new file mode 100644 index 0000000000..17a4429d20 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diagonal4.FCMat @@ -0,0 +1,16 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35279 +19 (Git) +General: + UUID: "c8bb743d-0f50-4109-b452-725037c3e3ec" + Name: "Diagonal4" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + PAT: + UUID: "0326c759-4e3d-46ca-bb7d-146ebebea65e" + Hatch Color: "(0,0,0,1)" + Hatch Pattern: |2 + *Diagonal4, 45 diagonal R, Solid, 4.0 mm separation + 45,0,0,0,4.0 + Hatch Scale: "1" + Hatch Weight: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/PAT/Diagonal5.FCMat b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diagonal5.FCMat new file mode 100644 index 0000000000..3c8e26d402 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diagonal5.FCMat @@ -0,0 +1,16 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35279 +19 (Git) +General: + UUID: "bf7789e6-227d-4859-a75b-18008723fb51" + Name: "Diagonal5" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + PAT: + UUID: "0326c759-4e3d-46ca-bb7d-146ebebea65e" + Hatch Color: "(0,0,0,1)" + Hatch Pattern: |2 + *Diagonal5, 45 diagonal L, Solid, 4.0 mm separation + -45,0,0,0,4.0 + Hatch Scale: "1" + Hatch Weight: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/PAT/Diamond.FCMat b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diamond.FCMat new file mode 100644 index 0000000000..aa171216df --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diamond.FCMat @@ -0,0 +1,17 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35279 +19 (Git) +General: + UUID: "7cc39c57-f49c-400d-a985-8f8d141f5478" + Name: "Diamond" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + PAT: + UUID: "0326c759-4e3d-46ca-bb7d-146ebebea65e" + Hatch Color: "(0,0,0,1)" + Hatch Pattern: |2 + *Diamond, 45 diagonals L & R, Solid, 1.0 mm separation + 45,0,0,0,1.0 + -45,0,0,0,1.0 + Hatch Scale: "1" + Hatch Weight: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/PAT/Diamond2.FCMat b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diamond2.FCMat new file mode 100644 index 0000000000..d727ea94c5 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diamond2.FCMat @@ -0,0 +1,17 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35279 +19 (Git) +General: + UUID: "b8940cab-1fbb-4ba5-9e32-2179589d6593" + Name: "Diamond2" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + PAT: + UUID: "0326c759-4e3d-46ca-bb7d-146ebebea65e" + Hatch Color: "(0,0,0,1)" + Hatch Pattern: |2 + *Diamond2, 45 diagonals L & R, Solid, 2.0 mm separation + 45,0,0,0,2.0 + -45,0,0,0,2.0 + Hatch Scale: "1" + Hatch Weight: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/PAT/Diamond4.FCMat b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diamond4.FCMat new file mode 100644 index 0000000000..c338c3d00d --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/PAT/Diamond4.FCMat @@ -0,0 +1,17 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35279 +19 (Git) +General: + UUID: "a9146fcf-4168-4065-8a58-ec78735e471d" + Name: "Diamond4" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + PAT: + UUID: "0326c759-4e3d-46ca-bb7d-146ebebea65e" + Hatch Color: "(0,0,0,1)" + Hatch Pattern: |2 + *Diamond4, 45 diagonals L & R, Solid, 4.0 mm separation + 45,0,0,0,4.0 + -45,0,0,0,4.0 + Hatch Scale: "1" + Hatch Weight: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/PAT/Horizontal5.FCMat b/src/Mod/Material/Resources/Materials/Patterns/PAT/Horizontal5.FCMat new file mode 100644 index 0000000000..3552b6bba9 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/PAT/Horizontal5.FCMat @@ -0,0 +1,16 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35279 +19 (Git) +General: + UUID: "0902d885-ac66-441e-9c3f-e0086a4817fc" + Name: "Horizontal5" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + PAT: + UUID: "0326c759-4e3d-46ca-bb7d-146ebebea65e" + Hatch Color: "(0,0,0,1)" + Hatch Pattern: |2 + *Horizontal5, horizontal lines, Solid 5.0 separation + 0,0,0,0,5.0 + Hatch Scale: "1" + Hatch Weight: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/PAT/Square.FCMat b/src/Mod/Material/Resources/Materials/Patterns/PAT/Square.FCMat new file mode 100644 index 0000000000..3cf218a692 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/PAT/Square.FCMat @@ -0,0 +1,17 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35279 +19 (Git) +General: + UUID: "7e8510f7-7d87-4782-894d-068b0d3f04b7" + Name: "Square" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + PAT: + UUID: "0326c759-4e3d-46ca-bb7d-146ebebea65e" + Hatch Color: "(0,0,0,1)" + Hatch Pattern: |2 + *Square, square grid, Solid, 5.0 mm separation + 90,1,1,0,5.0 + 0,0,0,1,5.0 + Hatch Scale: "1" + Hatch Weight: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/PAT/Vertical5.FCMat b/src/Mod/Material/Resources/Materials/Patterns/PAT/Vertical5.FCMat new file mode 100644 index 0000000000..a888f82eaf --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/PAT/Vertical5.FCMat @@ -0,0 +1,16 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35279 +19 (Git) +General: + UUID: "eaa335a5-3bee-4da7-9e26-0ebbdac2e182" + Name: "Vertical5" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + PAT: + UUID: "0326c759-4e3d-46ca-bb7d-146ebebea65e" + Hatch Color: "(0,0,0,1)" + Hatch Pattern: |2 + *Vertical5, vertical lines, Solid, 5.0 separation + 90,0,0,0,5.0 + Hatch Scale: "1" + Hatch Weight: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/aluminum.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/aluminum.FCMat new file mode 100644 index 0000000000..90ec8c8979 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/aluminum.FCMat @@ -0,0 +1,43 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +10 (Git) +General: + UUID: "abab7c4a-464a-40af-bf9e-32f658adf224" + Name: "aluminum" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/brick01.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/brick01.FCMat new file mode 100644 index 0000000000..9c9e0b872c --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/brick01.FCMat @@ -0,0 +1,74 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "37b63834-928e-444c-a1b7-49a3f3fba3d1" + Name: "brick01" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Pablo Gil + + + + + SVG + template + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/concrete.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/concrete.FCMat new file mode 100644 index 0000000000..c67f68982e --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/concrete.FCMat @@ -0,0 +1,65 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "39221178-f9a4-40f5-927f-eed2f17c748d" + Name: "concrete" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/cross.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/cross.FCMat new file mode 100644 index 0000000000..cf7eaed3fb --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/cross.FCMat @@ -0,0 +1,47 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "e321248b-de79-4573-b68b-53df020052b0" + Name: "cross" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/cuprous.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/cuprous.FCMat new file mode 100644 index 0000000000..2328d71025 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/cuprous.FCMat @@ -0,0 +1,87 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "50e78494-a675-413f-a541-70d1904f0189" + Name: "cuprous" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/diagonal1.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/diagonal1.FCMat new file mode 100644 index 0000000000..eac8cabfa9 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/diagonal1.FCMat @@ -0,0 +1,102 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "2b4e5304-13ab-47d1-b530-e438eeda4ed0" + Name: "diagonal1" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + image/svg+xml + + + + + Pablo Gil + + + + + SVG + template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/diagonal2.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/diagonal2.FCMat new file mode 100644 index 0000000000..8717e8c59c --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/diagonal2.FCMat @@ -0,0 +1,102 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "91efc25f-a841-4bb3-a4ca-6b4d70fd4e05" + Name: "diagonal2" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + image/svg+xml + + + + + Pablo Gil + + + + + SVG + template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/earth.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/earth.FCMat new file mode 100644 index 0000000000..00c831812c --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/earth.FCMat @@ -0,0 +1,51 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "94149a01-f4ad-4e6a-a6df-acb3ea97eb0b" + Name: "earth" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + image/svg+xml + + + + + Pablo Gil + + + + + SVG + template + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/general_steel.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/general_steel.FCMat new file mode 100644 index 0000000000..069b355ae9 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/general_steel.FCMat @@ -0,0 +1,37 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "29329280-1e89-4e8f-8e22-4582965654b4" + Name: "general_steel" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/glass.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/glass.FCMat new file mode 100644 index 0000000000..37e6736d72 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/glass.FCMat @@ -0,0 +1,108 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "0f8f1e63-885e-4940-a562-afed029b172a" + Name: "glass" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/hatch45L.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/hatch45L.FCMat new file mode 100644 index 0000000000..16c0abae8d --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/hatch45L.FCMat @@ -0,0 +1,39 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "f2421e27-1b54-4c6e-8da9-e0be3f1783a5" + Name: "hatch45L" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/hatch45R.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/hatch45R.FCMat new file mode 100644 index 0000000000..cccb5ee1f6 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/hatch45R.FCMat @@ -0,0 +1,39 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "169e4200-586d-4bde-aae5-4527392012f8" + Name: "hatch45R" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/hbone.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/hbone.FCMat new file mode 100644 index 0000000000..7768784551 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/hbone.FCMat @@ -0,0 +1,169 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "92232ced-d96b-4cc8-a052-4e13f7d943ab" + Name: "hbone" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Pablo Gil + + + + + SVG + template + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/line.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/line.FCMat new file mode 100644 index 0000000000..80713096c1 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/line.FCMat @@ -0,0 +1,36 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "bf024194-da67-4c3c-a482-08c7efa6dbde" + Name: "line" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/plastic.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/plastic.FCMat new file mode 100644 index 0000000000..34f40aa0da --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/plastic.FCMat @@ -0,0 +1,42 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "2fc720b1-19b3-4a30-a0f4-a782135559f5" + Name: "plastic" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/plus.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/plus.FCMat new file mode 100644 index 0000000000..8ab7f45c9e --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/plus.FCMat @@ -0,0 +1,47 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "90b1bd10-7df1-4338-bb74-f82040570afd" + Name: "plus" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + image/svg+xml + + + + + Pablo Gil + + + + + SVG + template + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/simple.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/simple.FCMat new file mode 100644 index 0000000000..ba4663e536 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/simple.FCMat @@ -0,0 +1,39 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "52d16497-4e67-45f0-b366-62fdf93dcbe7" + Name: "simple" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/solid.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/solid.FCMat new file mode 100644 index 0000000000..ada25db37e --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/solid.FCMat @@ -0,0 +1,40 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "d7c6b577-b41b-4d4b-a2b3-2139a1a9a7af" + Name: "solid" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + image/svg+xml + + + + + Pablo Gil + + + + + SVG + template + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/square.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/square.FCMat new file mode 100644 index 0000000000..301cafe72a --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/square.FCMat @@ -0,0 +1,41 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "836b307f-542d-466b-ba67-d96401b2fa8f" + Name: "square" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/steel.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/steel.FCMat new file mode 100644 index 0000000000..16c9aede54 --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/steel.FCMat @@ -0,0 +1,71 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "e8555d5c-c9ff-458f-9ad3-ecabd02b5327" + Name: "steel" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + image/svg+xml + + + + + Pablo Gil + + + + + SVG + template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/titanium.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/titanium.FCMat new file mode 100644 index 0000000000..9067ab3a0a --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/titanium.FCMat @@ -0,0 +1,83 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "5c66ffe9-6556-4361-9da7-ed3b187e3cfe" + Name: "titanium" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/wood.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/wood.FCMat new file mode 100644 index 0000000000..5af0eb461c --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/wood.FCMat @@ -0,0 +1,158 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "c693952c-5f5a-4f8f-9e6f-714464219a8b" + Name: "wood" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/woodgrain.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/woodgrain.FCMat new file mode 100644 index 0000000000..68ed74332a --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/woodgrain.FCMat @@ -0,0 +1,49 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "f3ffddec-9468-41c4-b107-035287283e45" + Name: "woodgrain" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/zinc.FCMat b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/zinc.FCMat new file mode 100644 index 0000000000..348417a22a --- /dev/null +++ b/src/Mod/Material/Resources/Materials/Patterns/Pattern Files/zinc.FCMat @@ -0,0 +1,46 @@ +--- +# File created by FreeCAD 0.22.0 Revision: 35329 +8 (Git) +General: + UUID: "957f8af7-7a3f-4086-9aaa-2bc7aa07a54f" + Name: "zinc" + Author: "David Carter" + License: "All rights reserved" +AppearanceModels: + Pattern File: + UUID: "c6596294-e97d-4812-87db-28e1d66521a3" + Pattern Color: "(0,0,0,1)" + Pattern File: |2 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pattern Scale: "1" diff --git a/src/Mod/Material/Resources/Materials/Test/Test Material.FCMat b/src/Mod/Material/Resources/Materials/Test/Test Material.FCMat index 6cee496965..b0e68fc574 100644 --- a/src/Mod/Material/Resources/Materials/Test/Test Material.FCMat +++ b/src/Mod/Material/Resources/Materials/Test/Test Material.FCMat @@ -39,14 +39,10 @@ Models: - "Single quote '" - "Double quote \"" - "Backslash \\" - TestMultiLineString: >2 + TestMultiLineString: |2 Now is the time for 'all' \ "men" come to the aid of the party Indentation is significant Similar to Python TestQuantity: "19.76 kg/m^3" TestString: "Now is the time for 'all' \\ \"men\" come to the aid of the party" - TestMultiLineString: >2 - Now is the time for 'all' \ "men" come to the aid of the party - Indentation is significant - Similar to Python TestURL: "https://www.freecad.org/" diff --git a/src/Mod/Material/Resources/Models/Patterns/PAT.yml b/src/Mod/Material/Resources/Models/Patterns/PAT.yml new file mode 100644 index 0000000000..775b967ecd --- /dev/null +++ b/src/Mod/Material/Resources/Models/Patterns/PAT.yml @@ -0,0 +1,49 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: 'PAT' + UUID: '0326c759-4e3d-46ca-bb7d-146ebebea65e' + URL: 'https://wiki.freecad.org/TechDraw_Hatching' + Description: 'AutoDesk® PAT format pattern' + DOI: '' + Hatch Pattern: + Type: 'MultiLineString' + Units: '' + URL: '' + Description: "The format pattern" + Hatch Scale: + Type: 'Float' + Units: '' + URL: '' + Description: "The scale to be applied to the pattern (must be > 0.0)" + Hatch Weight: + Type: 'Float' + Units: '' + URL: '' + Description: "The thickness of the pattern lines" + Hatch Color: + Type: 'Color' + Units: '' + URL: '' + Description: "The color for the pattern lines" diff --git a/src/Mod/Material/Resources/Models/Patterns/Pattern File.yml b/src/Mod/Material/Resources/Models/Patterns/Pattern File.yml new file mode 100644 index 0000000000..3b9bf40754 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Patterns/Pattern File.yml @@ -0,0 +1,44 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: 'Pattern File' + UUID: 'c6596294-e97d-4812-87db-28e1d66521a3' + URL: 'https://wiki.freecad.org/TechDraw_Hatching' + Description: 'SVG based pattern' + DOI: '' + Pattern File: + Type: 'SVG' + Units: '' + URL: '' + Description: "The SVG format pattern" + Pattern Scale: + Type: 'Float' + Units: '' + URL: '' + Description: "The pattern size modifier (must be > 0.0)" + Pattern Color: + Type: 'Color' + Units: '' + URL: '' + Description: "The pattern will be displayed in this color" diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderAppleseed.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderAppleseed.yml new file mode 100644 index 0000000000..1d6aa5c99c --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderAppleseed.yml @@ -0,0 +1,34 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Appleseed" + UUID: 'b0a10f70-13bf-4598-ab63-bcfbbcd813e3' + URL: '' + Description: "Rendering model aspects specific to the Appleseed renderer" + DOI: "" + Render.Appleseed: + Type: 'MultiLineString' + Units: '' + URL: '' + Description: "Passthrough Options" diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderCarpaint.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderCarpaint.yml new file mode 100644 index 0000000000..f8fc937f26 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderCarpaint.yml @@ -0,0 +1,59 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Carpaint" + UUID: '4d2cc163-0707-40e2-a9f7-14288c4b97bd' + URL: '' + Description: "Rendering Workbench Carpaint rendering model" + DOI: "" + Render.Carpaint.BaseColor: + Type: 'Color' + Units: '' + URL: '' + Description: " " + Render.Carpaint.BaseColor.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Carpaint.BaseColor.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Carpaint.Bump: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Carpaint.Displacement: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Carpaint.Normal: + Type: 'String' + Units: '' + URL: '' + Description: " " diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderCycles.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderCycles.yml new file mode 100644 index 0000000000..19024cd98f --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderCycles.yml @@ -0,0 +1,34 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Cycles" + UUID: 'a6da1b66-929c-48bf-ae80-3b0495c7b50b' + URL: '' + Description: "Rendering model aspects specific to the Cycles renderer" + DOI: "" + Render.Cycles: + Type: 'MultiLineString' + Units: '' + URL: '' + Description: "Passthrough Options" diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderDiffuse.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderDiffuse.yml new file mode 100644 index 0000000000..0aa67c4975 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderDiffuse.yml @@ -0,0 +1,59 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Diffuse" + UUID: 'c19b2d30-c55b-48aa-a938-df9e2f7779cf' + URL: '' + Description: "Rendering Workbench Diffuse rendering model" + DOI: "" + Render.Diffuse.Bump: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Diffuse.Color: + Type: 'Color' + Units: '' + URL: '' + Description: " " + Render.Diffuse.Color.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Diffuse.Color.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Diffuse.Displacement: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Diffuse.Normal: + Type: 'String' + Units: '' + URL: '' + Description: " " diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderDisney.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderDisney.yml new file mode 100644 index 0000000000..f26edfa6b6 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderDisney.yml @@ -0,0 +1,179 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Disney" + UUID: 'f8723572-4470-4c39-a749-6d3b71358a5b' + URL: '' + Description: "Rendering Workbench Disney rendering model" + DOI: "" + Render.Disney.Anisotropic: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.Anisotropic.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.BaseColor: + Type: 'Color' + Units: '' + URL: '' + Description: " " + Render.Disney.BaseColor.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.BaseColor.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Disney.Bump: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.ClearCoat: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.ClearCoat.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.ClearCoat.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Disney.ClearCoatGloss: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.ClearCoatGloss.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.ClearCoatGloss.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Disney.Displacement: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.Metallic: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.Metallic.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.Normal: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.Roughness: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.Roughness.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.Sheen: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.Sheen.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.SheenTint: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.SheenTint.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.Specular: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.Specular.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.Specular.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Disney.SpecularTint: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.SpecularTint.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Disney.SpecularTint.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Disney.Subsurface: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Disney.Subsurface.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderEmission.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderEmission.yml new file mode 100644 index 0000000000..400caf2298 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderEmission.yml @@ -0,0 +1,64 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Emission" + UUID: '9f6cb588-c89d-4a74-9d0f-2786a8568cec' + URL: '' + Description: "Rendering Workbench Emission rendering model" + DOI: "" + Render.Emission.Bump: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Emission.Color: + Type: 'Color' + Units: '' + URL: '' + Description: " " + Render.Emission.Color.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Emission.Color.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Emission.Normal: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Emission.Power: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Emission.Power.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderGlass.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderGlass.yml new file mode 100644 index 0000000000..13b0a391ab --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderGlass.yml @@ -0,0 +1,69 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Glass" + UUID: 'd76a56f5-7250-4efb-bb89-8ea0a9ccaa6b' + URL: '' + Description: "Rendering Workbench Glass rendering model" + DOI: "" + Render.Glass.Bump: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Glass.Color: + Type: 'Color' + Units: '' + URL: '' + Description: " " + Render.Glass.Color.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Glass.Color.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Glass.IOR: + Type: 'Float' + Units: '' + URL: '' + Description: "Index of Refraction" + Render.Glass.IOR.Texture: + Type: 'String' + Units: '' + URL: '' + Description: "Index of Refraction" + Render.Glass.Displacement: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Glass.Normal: + Type: 'String' + Units: '' + URL: '' + Description: " " diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderLuxcore.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderLuxcore.yml new file mode 100644 index 0000000000..49658c2d70 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderLuxcore.yml @@ -0,0 +1,34 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Luxcore" + UUID: '6b992304-33e0-490b-a391-e9d0af79bb69' + URL: '' + Description: "Rendering model aspects specific to the Luxcore renderer" + DOI: "" + Render.Luxcore: + Type: 'MultiLineString' + Units: '' + URL: '' + Description: "Passthrough Options" diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderLuxrender.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderLuxrender.yml new file mode 100644 index 0000000000..6250973a20 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderLuxrender.yml @@ -0,0 +1,34 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Luxrender" + UUID: '67ac6a63-e173-4e05-898b-af743f1f9563' + URL: '' + Description: "Rendering model aspects specific to the Luxrender renderer" + DOI: "" + Render.Luxrender: + Type: 'MultiLineString' + Units: '' + URL: '' + Description: "Passthrough Options" diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderMixed.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderMixed.yml new file mode 100644 index 0000000000..fa8f754016 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderMixed.yml @@ -0,0 +1,94 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Mixed" + UUID: '84bab333-984f-47fe-a512-d17c7cb2daa9' + URL: '' + Description: "Rendering Workbench Mixed rendering model" + DOI: "" + Render.Mixed.Bump: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Mixed.Diffuse.Color: + Type: 'Color' + Units: '' + URL: '' + Description: " " + Render.Mixed.Diffuse.Color.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Mixed.Diffuse.Color.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Mixed.Displacement: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Mixed.Glass.Color: + Type: 'Color' + Units: '' + URL: '' + Description: " " + Render.Mixed.Glass.Color.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Mixed.Glass.Color.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Mixed.Glass.IOR: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Mixed.Glass.IOR.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Mixed.Normal: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Mixed.Transparency: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Mixed.Transparency.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderOspray.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderOspray.yml new file mode 100644 index 0000000000..b09d06b132 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderOspray.yml @@ -0,0 +1,34 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Ospray" + UUID: 'a4792c23-0be9-47c2-b16d-47b2d2d5efd6' + URL: '' + Description: "Rendering model aspects specific to the Ospray renderer" + DOI: "" + Render.Ospray: + Type: 'MultiLineString' + Units: '' + URL: '' + Description: "Passthrough Options" diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderPbrt.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderPbrt.yml new file mode 100644 index 0000000000..32721427be --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderPbrt.yml @@ -0,0 +1,34 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Pbrt" + UUID: '35b34b82-4325-4d27-97bd-d10bb2c56586' + URL: '' + Description: "Rendering model aspects specific to the Pbrt renderer" + DOI: "" + Render.Pbrt: + Type: 'MultiLineString' + Units: '' + URL: '' + Description: "Passthrough Options" diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderPovray.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderPovray.yml new file mode 100644 index 0000000000..be0a296352 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderPovray.yml @@ -0,0 +1,34 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Povray" + UUID: '6ec8b415-4c7b-4206-a80b-2ea64101f34b' + URL: '' + Description: "Rendering model aspects specific to the Povray renderer" + DOI: "" + Render.Povray: + Type: 'MultiLineString' + Units: '' + URL: '' + Description: "Passthrough Options" diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderSubstancePBR.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderSubstancePBR.yml new file mode 100644 index 0000000000..da5bf93227 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderSubstancePBR.yml @@ -0,0 +1,84 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Substance_PBR" + UUID: 'f212b643-db96-452e-8428-376a4534e5ab' + URL: '' + Description: "Rendering Workbench Substance_PBR rendering model" + DOI: "" + Render.Substance_PBR.BaseColor: + Type: 'Color' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.BaseColor.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.BaseColor.Object: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.Bump: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.Metallic: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.Metallic.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.Normal: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.Roughness: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.Roughness.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.Specular: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Substance_PBR.Specular.Texture: + Type: 'String' + Units: '' + URL: '' + Description: " " diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderTexture.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderTexture.yml new file mode 100644 index 0000000000..03112ac081 --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderTexture.yml @@ -0,0 +1,59 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Texture" + UUID: 'fc9b6135-95cd-4ba8-ad9a-0972caeebad2' + URL: '' + Description: "Render Workbench texture model" + DOI: "" + Render.Textures.Name: + Type: 'String' + Units: '' + URL: '' + Description: " " + Render.Textures.Images: + Type: 'FileList' + Units: '' + URL: '' + Description: " " + Render.Textures.Scale: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Textures.Rotation: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Textures.TranslationU: + Type: 'Float' + Units: '' + URL: '' + Description: " " + Render.Textures.TranslationV: + Type: 'Float' + Units: '' + URL: '' + Description: " " diff --git a/src/Mod/Material/Resources/Models/Render Workbench/RenderWB.yml b/src/Mod/Material/Resources/Models/Render Workbench/RenderWB.yml new file mode 100644 index 0000000000..8cf261e9aa --- /dev/null +++ b/src/Mod/Material/Resources/Models/Render Workbench/RenderWB.yml @@ -0,0 +1,39 @@ +--- +# *************************************************************************** +# * * +# * Copyright (c) 2023 David Carter * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +AppearanceModel: + Name: "Render Workbench" + UUID: '344008be-a837-43af-90bc-f795f277b309' + URL: '' + Description: "Rendering model aspects specific to the Render Workbench" + DOI: "" + UseObjectColor: + Type: 'Boolean' + Units: '' + URL: '' + Description: " " + Render.Type: + Type: 'String' + Units: '' + URL: '' + Description: " " diff --git a/src/Mod/Material/Resources/Models/Test/Test Model.yml b/src/Mod/Material/Resources/Models/Test/Test Model.yml index 783dd913c6..97906f7465 100644 --- a/src/Mod/Material/Resources/Models/Test/Test Model.yml +++ b/src/Mod/Material/Resources/Models/Test/Test Model.yml @@ -77,6 +77,11 @@ Model: Units: '' URL: '' Description: "A File" + TestSVG: + Type: 'SVG' + Units: '' + URL: '' + Description: "An SVG" TestImage: Type: 'Image' Units: '' diff --git a/src/Mod/Material/materialtests/TestMaterials.py b/src/Mod/Material/materialtests/TestMaterials.py index 256342026f..0c4c50e77d 100644 --- a/src/Mod/Material/materialtests/TestMaterials.py +++ b/src/Mod/Material/materialtests/TestMaterials.py @@ -20,8 +20,10 @@ # USA * #************************************************************************** -# import FreeCAD -from os import walk +""" +Test module for FreeCAD material cards and APIs +""" + import unittest import FreeCAD import Material @@ -29,16 +31,29 @@ import Material parseQuantity = FreeCAD.Units.parseQuantity class MaterialTestCases(unittest.TestCase): + """ + Test class for FreeCAD material cards and APIs + """ + def setUp(self): + """ Setup function to initialize test data """ self.ModelManager = Material.ModelManager() self.MaterialManager = Material.MaterialManager() self.uuids = Material.UUIDs() def testMaterialManager(self): + """ Ensure the MaterialManager has been initialized correctly """ self.assertIn("MaterialLibraries", dir(self.MaterialManager)) self.assertIn("Materials", dir(self.MaterialManager)) def testCalculiXSteel(self): + """ + Test a representative material card for CalculX Steel + + As a well populated material card, the CalculiX Steel material is a good subject + for testing as many of the properties and API access methods as possible. + """ + steel = self.MaterialManager.getMaterial("92589471-a6cb-4bbc-b748-d425a17dea7d") self.assertIsNotNone(steel) self.assertEqual(steel.Name, "CalculiX-Steel") @@ -53,8 +68,8 @@ class MaterialTestCases(unittest.TestCase): self.assertTrue(steel.isPhysicalModelComplete(self.uuids.Density)) self.assertFalse(steel.isPhysicalModelComplete(self.uuids.IsotropicLinearElastic)) self.assertTrue(steel.isPhysicalModelComplete(self.uuids.Thermal)) - self.assertFalse(steel.isPhysicalModelComplete(self.uuids.LinearElastic)) # Not in the model - self.assertTrue(steel.isAppearanceModelComplete(self.uuids.BasicRendering)) # inherited from Steel.FCMat + self.assertFalse(steel.isPhysicalModelComplete(self.uuids.LinearElastic)) + self.assertTrue(steel.isAppearanceModelComplete(self.uuids.BasicRendering)) self.assertTrue(steel.hasPhysicalProperty("Density")) self.assertTrue(steel.hasPhysicalProperty("BulkModulus")) @@ -155,20 +170,27 @@ class MaterialTestCases(unittest.TestCase): self.assertTrue(len(properties["SpecularColor"]) > 0) self.assertTrue(len(properties["Transparency"]) > 0) - self.assertEqual(properties["Density"], parseQuantity("7900.00 kg/m^3").UserString) + self.assertEqual(properties["Density"], + parseQuantity("7900.00 kg/m^3").UserString) # self.assertEqual(properties["BulkModulus"], "") - self.assertAlmostEqual(parseQuantity(properties["PoissonRatio"]).Value, parseQuantity("0.3").Value) - self.assertEqual(properties["YoungsModulus"], parseQuantity("210.00 GPa").UserString) + self.assertAlmostEqual(parseQuantity(properties["PoissonRatio"]).Value, + parseQuantity("0.3").Value) + self.assertEqual(properties["YoungsModulus"], + parseQuantity("210.00 GPa").UserString) # self.assertEqual(properties["ShearModulus"], "") - self.assertEqual(properties["SpecificHeat"], parseQuantity("590.00 J/kg/K").UserString) - self.assertEqual(properties["ThermalConductivity"], parseQuantity("43.00 W/m/K").UserString) - self.assertEqual(properties["ThermalExpansionCoefficient"], parseQuantity("12.00 µm/m/K").UserString) + self.assertEqual(properties["SpecificHeat"], + parseQuantity("590.00 J/kg/K").UserString) + self.assertEqual(properties["ThermalConductivity"], + parseQuantity("43.00 W/m/K").UserString) + self.assertEqual(properties["ThermalExpansionCoefficient"], + parseQuantity("12.00 µm/m/K").UserString) self.assertEqual(properties["AmbientColor"], "(0.0020, 0.0020, 0.0020, 1.0)") self.assertEqual(properties["DiffuseColor"], "(0.0000, 0.0000, 0.0000, 1.0)") self.assertEqual(properties["EmissiveColor"], "(0.0000, 0.0000, 0.0000, 1.0)") self.assertAlmostEqual(parseQuantity(properties["Shininess"]).Value, parseQuantity("0.06").Value) self.assertEqual(properties["SpecularColor"], "(0.9800, 0.9800, 0.9800, 1.0)") - self.assertAlmostEqual(parseQuantity(properties["Transparency"]).Value, parseQuantity("0").Value) + self.assertAlmostEqual(parseQuantity(properties["Transparency"]).Value, + parseQuantity("0").Value) print("Density " + steel.getPhysicalValue("Density").UserString) # print("BulkModulus " + properties["BulkModulus"]) @@ -177,7 +199,8 @@ class MaterialTestCases(unittest.TestCase): # print("ShearModulus " + properties["ShearModulus"]) print("SpecificHeat " + steel.getPhysicalValue("SpecificHeat").UserString) print("ThermalConductivity " + steel.getPhysicalValue("ThermalConductivity").UserString) - print("ThermalExpansionCoefficient " + steel.getPhysicalValue("ThermalExpansionCoefficient").UserString) + print("ThermalExpansionCoefficient " + \ + steel.getPhysicalValue("ThermalExpansionCoefficient").UserString) print("AmbientColor " + steel.getAppearanceValue("AmbientColor")) print("DiffuseColor " + steel.getAppearanceValue("DiffuseColor")) print("EmissiveColor " + steel.getAppearanceValue("EmissiveColor")) @@ -199,12 +222,18 @@ class MaterialTestCases(unittest.TestCase): self.assertAlmostEqual(steel.getAppearanceValue("Transparency"), 0.0) def testMaterialsWithModel(self): - materials = self.MaterialManager.materialsWithModel('f6f9e48c-b116-4e82-ad7f-3659a9219c50') # IsotropicLinearElastic - materialsComplete = self.MaterialManager.materialsWithModelComplete('f6f9e48c-b116-4e82-ad7f-3659a9219c50') # IsotropicLinearElastic + """ + Test functions that return a list of models supporting specific material models + """ + # IsotropicLinearElastic + materials = self.MaterialManager.materialsWithModel('f6f9e48c-b116-4e82-ad7f-3659a9219c50') + materialsComplete = self.MaterialManager \ + .materialsWithModelComplete('f6f9e48c-b116-4e82-ad7f-3659a9219c50') self.assertTrue(len(materialsComplete) <= len(materials)) # Not all will be complete - materialsLinearElastic = self.MaterialManager.materialsWithModel('7b561d1d-fb9b-44f6-9da9-56a4f74d7536') # LinearElastic + materialsLinearElastic = self.MaterialManager \ + .materialsWithModel('7b561d1d-fb9b-44f6-9da9-56a4f74d7536') # LinearElastic # All LinearElastic models should be in IsotropicLinearElastic since it is inherited self.assertTrue(len(materialsLinearElastic) <= len(materials)) @@ -212,22 +241,34 @@ class MaterialTestCases(unittest.TestCase): self.assertIn(mat, materials) def testMaterialByPath(self): - steel = self.MaterialManager.getMaterialByPath('Standard/Metal/Steel/CalculiX-Steel.FCMat', 'System') + """ + Test loading models by path + + Valid models may have different prefixes + """ + steel = self.MaterialManager \ + .getMaterialByPath('Standard/Metal/Steel/CalculiX-Steel.FCMat', 'System') self.assertIsNotNone(steel) self.assertEqual(steel.Name, "CalculiX-Steel") self.assertEqual(steel.UUID, "92589471-a6cb-4bbc-b748-d425a17dea7d") - steel2 = self.MaterialManager.getMaterialByPath('/Standard/Metal/Steel/CalculiX-Steel.FCMat', 'System') + steel2 = self.MaterialManager \ + .getMaterialByPath('/Standard/Metal/Steel/CalculiX-Steel.FCMat', 'System') self.assertIsNotNone(steel2) self.assertEqual(steel2.Name, "CalculiX-Steel") self.assertEqual(steel2.UUID, "92589471-a6cb-4bbc-b748-d425a17dea7d") - steel3 = self.MaterialManager.getMaterialByPath('/System/Standard/Metal/Steel/CalculiX-Steel.FCMat', 'System') + steel3 = self.MaterialManager \ + .getMaterialByPath('/System/Standard/Metal/Steel/CalculiX-Steel.FCMat', 'System') self.assertIsNotNone(steel3) self.assertEqual(steel3.Name, "CalculiX-Steel") self.assertEqual(steel3.UUID, "92589471-a6cb-4bbc-b748-d425a17dea7d") def testLists(self): + """ + Test API access to lists + """ + mat = self.MaterialManager.getMaterial("c6c64159-19c1-40b5-859c-10561f20f979") self.assertIsNotNone(mat) self.assertEqual(mat.Name, "Test Material") @@ -238,27 +279,32 @@ class MaterialTestCases(unittest.TestCase): self.assertTrue(mat.hasPhysicalProperty("TestList")) - list = mat.getPhysicalValue("TestList") - self.assertEqual(len(list), 6) - self.assertEqual(list[0], "Now is the time for all good men to come to the aid of the party") - self.assertEqual(list[1], "The quick brown fox jumps over the lazy dogs back") - self.assertEqual(list[2], "Lore Ipsum") - self.assertEqual(list[3], "Single quote '") - self.assertEqual(list[4], "Double quote \"") - self.assertEqual(list[5], "Backslash \\") + testList = mat.getPhysicalValue("TestList") + self.assertEqual(len(testList), 6) + self.assertEqual(testList[0], + "Now is the time for all good men to come to the aid of the party") + self.assertEqual(testList[1], "The quick brown fox jumps over the lazy dogs back") + self.assertEqual(testList[2], "Lore Ipsum") + self.assertEqual(testList[3], "Single quote '") + self.assertEqual(testList[4], "Double quote \"") + self.assertEqual(testList[5], "Backslash \\") properties = mat.Properties self.assertIn("TestList", properties) self.assertTrue(len(properties["TestList"]) == 0) def test2DArray(self): + """ + Test API access to 2D arrays + """ + mat = self.MaterialManager.getMaterial("c6c64159-19c1-40b5-859c-10561f20f979") self.assertIsNotNone(mat) self.assertEqual(mat.Name, "Test Material") self.assertEqual(mat.UUID, "c6c64159-19c1-40b5-859c-10561f20f979") self.assertTrue(mat.hasPhysicalModel(self.uuids.TestModel)) - self.assertTrue(mat.isPhysicalModelComplete(self.uuids.TestModel)) + self.assertFalse(mat.isPhysicalModelComplete(self.uuids.TestModel)) self.assertTrue(mat.hasPhysicalProperty("TestArray2D")) @@ -328,7 +374,11 @@ class MaterialTestCases(unittest.TestCase): with self.assertRaises(IndexError): row = array.getRow(3) - def test2DArray(self): + def test3DArray(self): + """ + Test API access to 3D arrays + """ + mat = self.MaterialManager.getMaterial("c6c64159-19c1-40b5-859c-10561f20f979") self.assertIsNotNone(mat) self.assertEqual(mat.Name, "Test Material") @@ -383,9 +433,11 @@ class MaterialTestCases(unittest.TestCase): self.assertEqual(arrayData[3][0][0].UserString, parseQuantity("11.00 Pa").UserString) with self.assertRaises(IndexError): - self.assertEqual(array.getDepthValue(-1).UserString, parseQuantity("10.00 C").UserString) + self.assertEqual(array.getDepthValue(-1).UserString, + parseQuantity("10.00 C").UserString) with self.assertRaises(IndexError): - self.assertEqual(array.getDepthValue(3).UserString, parseQuantity("10.00 C").UserString) + self.assertEqual(array.getDepthValue(3).UserString, + parseQuantity("10.00 C").UserString) self.assertEqual(array.getValue(0,0,0).UserString, parseQuantity("11.00 Pa").UserString) self.assertEqual(array.getValue(0,0,1).UserString, parseQuantity("12.00 Pa").UserString) @@ -399,16 +451,23 @@ class MaterialTestCases(unittest.TestCase): self.assertEqual(array.getValue(2,2,1).UserString, parseQuantity("31.00 Pa").UserString) with self.assertRaises(IndexError): - self.assertEqual(array.getValue(0,0,-1).UserString, parseQuantity("11.00 Pa").UserString) + self.assertEqual(array.getValue(0,0,-1).UserString, + parseQuantity("11.00 Pa").UserString) with self.assertRaises(IndexError): - self.assertEqual(array.getValue(0,0,2).UserString, parseQuantity("11.00 Pa").UserString) + self.assertEqual(array.getValue(0,0,2).UserString, + parseQuantity("11.00 Pa").UserString) with self.assertRaises(IndexError): - self.assertEqual(array.getValue(0,-1,0).UserString, parseQuantity("11.00 Pa").UserString) + self.assertEqual(array.getValue(0,-1,0).UserString, + parseQuantity("11.00 Pa").UserString) with self.assertRaises(IndexError): - self.assertEqual(array.getValue(0,2,0).UserString, parseQuantity("11.00 Pa").UserString) + self.assertEqual(array.getValue(0,2,0).UserString, + parseQuantity("11.00 Pa").UserString) with self.assertRaises(IndexError): - self.assertEqual(array.getValue(1,0,0).UserString, parseQuantity("11.00 Pa").UserString) + self.assertEqual(array.getValue(1,0,0).UserString, + parseQuantity("11.00 Pa").UserString) with self.assertRaises(IndexError): - self.assertEqual(array.getValue(-1,0,0).UserString, parseQuantity("11.00 Pa").UserString) + self.assertEqual(array.getValue(-1,0,0).UserString, + parseQuantity("11.00 Pa").UserString) with self.assertRaises(IndexError): - self.assertEqual(array.getValue(3,0,0).UserString, parseQuantity("11.00 Pa").UserString) + self.assertEqual(array.getValue(3,0,0).UserString, + parseQuantity("11.00 Pa").UserString) diff --git a/src/Mod/Material/materialtests/TestModels.py b/src/Mod/Material/materialtests/TestModels.py index 69e1e5def6..0956fdb20b 100644 --- a/src/Mod/Material/materialtests/TestModels.py +++ b/src/Mod/Material/materialtests/TestModels.py @@ -20,26 +20,32 @@ # USA * #************************************************************************** -# import FreeCAD -from os import walk +""" +Test module for FreeCAD material models +""" + import unittest import FreeCAD import Material parseQuantity = FreeCAD.Units.parseQuantity -# import locale -# locale.setpreferredencoding("UTF8") class ModelTestCases(unittest.TestCase): + """ + Test class for FreeCAD material models + """ def setUp(self): + """ Setup function to initialize test data """ self.ModelManager = Material.ModelManager() self.uuids = Material.UUIDs() def testModelManager(self): + """ Ensure we can access ModelManager member functions """ self.assertIn("ModelLibraries", dir(self.ModelManager)) self.assertIn("Models", dir(self.ModelManager)) def testUUIDs(self): + """ Verify the common UUIDs are defined and correct """ self.assertTrue(self.uuids.Father, "9cdda8b6-b606-4778-8f13-3934d8668e67") self.assertTrue(self.uuids.MaterialStandard, "1e2c0088-904a-4537-925f-64064c07d700") @@ -85,6 +91,7 @@ class ModelTestCases(unittest.TestCase): self.assertTrue(self.uuids.TestModel, "34d0583d-f999-49ba-99e6-aa40bd5c3a6b") def testModelLoad(self): + """ Test that the Density model has been loaded correctly """ density = self.ModelManager.getModel(self.uuids.Density) self.assertIsNotNone(density) self.assertEqual(density.Name, "Density") diff --git a/src/Mod/TechDraw/App/DrawProjectSplit.cpp b/src/Mod/TechDraw/App/DrawProjectSplit.cpp index dddb0483b9..28205e8b58 100644 --- a/src/Mod/TechDraw/App/DrawProjectSplit.cpp +++ b/src/Mod/TechDraw/App/DrawProjectSplit.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -45,6 +44,7 @@ #include #include #endif +#include #include #include diff --git a/tests/src/Mod/Material/App/TestMaterialCards.cpp b/tests/src/Mod/Material/App/TestMaterialCards.cpp index ab2c2096a3..f040900852 100644 --- a/tests/src/Mod/Material/App/TestMaterialCards.cpp +++ b/tests/src/Mod/Material/App/TestMaterialCards.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -46,10 +47,7 @@ class TestMaterialCards : public ::testing::Test { protected: static void SetUpTestSuite() { if (App::Application::GetARGC() == 0) { - constexpr int argc = 1; - std::array argv {"FreeCAD"}; - App::Application::Config()["ExeName"] = "FreeCAD"; - App::Application::init(argc, argv.data()); + tests::initApplication(); } } @@ -78,8 +76,8 @@ protected: TEST_F(TestMaterialCards, TestCopy) { - EXPECT_NE(_modelManager, nullptr); - EXPECT_TRUE(_library); + ASSERT_NE(_modelManager, nullptr); + ASSERT_TRUE(_library); // FAIL() << "Test library " << _library->getDirectoryPath().toStdString() << "\n"; auto testMaterial = _materialManager->getMaterial(_testMaterialUUID); @@ -181,25 +179,25 @@ TEST_F(TestMaterialCards, TestCopy) TEST_F(TestMaterialCards, TestColumns) { - EXPECT_NE(_modelManager, nullptr); - EXPECT_TRUE(_library); + ASSERT_NE(_modelManager, nullptr); + ASSERT_TRUE(_library); auto testMaterial = _materialManager->getMaterial(_testMaterialUUID); EXPECT_TRUE(testMaterial->hasPhysicalProperty(QString::fromStdString("TestArray2D"))); auto array2d = testMaterial->getPhysicalProperty(QString::fromStdString("TestArray2D"))->getMaterialValue(); EXPECT_TRUE(array2d); - EXPECT_EQ(static_cast(*array2d).columns(), 2); + EXPECT_EQ(dynamic_cast(*array2d).columns(), 2); EXPECT_TRUE(testMaterial->hasPhysicalProperty(QString::fromStdString("TestArray2D3Column"))); auto array2d3Column = testMaterial->getPhysicalProperty(QString::fromStdString("TestArray2D3Column"))->getMaterialValue(); EXPECT_TRUE(array2d3Column); - EXPECT_EQ(static_cast(*array2d3Column).columns(), 3); + EXPECT_EQ(dynamic_cast(*array2d3Column).columns(), 3); EXPECT_TRUE(testMaterial->hasPhysicalProperty(QString::fromStdString("TestArray3D"))); auto array3d = testMaterial->getPhysicalProperty(QString::fromStdString("TestArray3D"))->getMaterialValue(); EXPECT_TRUE(array3d); - EXPECT_EQ(static_cast(*array3d).columns(), 2); + EXPECT_EQ(dynamic_cast(*array3d).columns(), 2); } // clang-format on diff --git a/tests/src/Mod/Material/App/TestMaterialValue.cpp b/tests/src/Mod/Material/App/TestMaterialValue.cpp index d1f27335ad..65282e0cf9 100644 --- a/tests/src/Mod/Material/App/TestMaterialValue.cpp +++ b/tests/src/Mod/Material/App/TestMaterialValue.cpp @@ -42,22 +42,7 @@ class TestMaterialValue : public ::testing::Test { protected: static void SetUpTestSuite() { - // if (App::Application::GetARGC() == 0) { - // constexpr int argc = 1; - // std::array argv {"FreeCAD"}; - // App::Application::Config()["ExeName"] = "FreeCAD"; - // App::Application::init(argc, argv.data()); - // } } - -// void SetUp() override { -// _modelManager = new Materials::ModelManager(); -// _materialManager = new Materials::MaterialManager(); -// } - - // void TearDown() override {} -// Materials::ModelManager* _modelManager; -// Materials::MaterialManager* _materialManager; }; TEST_F(TestMaterialValue, TestNoneType) diff --git a/tests/src/Mod/Material/App/TestMaterials.cpp b/tests/src/Mod/Material/App/TestMaterials.cpp index de9447c34b..b0c5080569 100644 --- a/tests/src/Mod/Material/App/TestMaterials.cpp +++ b/tests/src/Mod/Material/App/TestMaterials.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -48,10 +49,7 @@ class TestMaterial : public ::testing::Test { protected: static void SetUpTestSuite() { if (App::Application::GetARGC() == 0) { - constexpr int argc = 1; - std::array argv {"FreeCAD"}; - App::Application::Config()["ExeName"] = "FreeCAD"; - App::Application::init(argc, argv.data()); + tests::initApplication(); } } @@ -67,7 +65,7 @@ class TestMaterial : public ::testing::Test { TEST_F(TestMaterial, TestInstallation) { - EXPECT_NE(_modelManager, nullptr); + ASSERT_NE(_modelManager, nullptr); // We should have loaded at least the system library auto libraries = _materialManager->getMaterialLibraries(); @@ -80,6 +78,8 @@ TEST_F(TestMaterial, TestInstallation) TEST_F(TestMaterial, TestMaterialsWithModel) { + ASSERT_NE(_materialManager, nullptr); + auto materials = _materialManager->materialsWithModel( QString::fromStdString("f6f9e48c-b116-4e82-ad7f-3659a9219c50")); // IsotropicLinearElastic EXPECT_GT(materials->size(), 0); @@ -93,14 +93,16 @@ TEST_F(TestMaterial, TestMaterialsWithModel) // All LinearElastic models should be in IsotropicLinearElastic since it is inherited EXPECT_LE(materialsLinearElastic->size(), materials->size()); - for (auto itp = materialsLinearElastic->begin(); itp != materialsLinearElastic->end(); itp++) { - auto mat = itp->first; + for (auto itp : *materialsLinearElastic) { + auto mat = itp.first; EXPECT_NO_THROW(materials->at(mat)); } } TEST_F(TestMaterial, TestMaterialByPath) { + ASSERT_NE(_materialManager, nullptr); + auto steel = _materialManager->getMaterialByPath( QString::fromStdString("Standard/Metal/Steel/CalculiX-Steel.FCMat"), QString::fromStdString("System")); @@ -223,6 +225,8 @@ QString parseQuantity(const char *string) TEST_F(TestMaterial, TestCalculiXSteel) { + ASSERT_NE(_materialManager, nullptr); + auto steel = _materialManager->getMaterial(QString::fromStdString("92589471-a6cb-4bbc-b748-d425a17dea7d")); EXPECT_EQ(steel->getName(), QString::fromStdString("CalculiX-Steel")); EXPECT_EQ(steel->getUUID(), QString::fromStdString("92589471-a6cb-4bbc-b748-d425a17dea7d")); @@ -356,17 +360,17 @@ TEST_F(TestMaterial, TestColumns) EXPECT_TRUE(testMaterial.hasPhysicalProperty(QString::fromStdString("TestArray2D"))); auto array2d = testMaterial.getPhysicalProperty(QString::fromStdString("TestArray2D"))->getMaterialValue(); EXPECT_TRUE(array2d); - EXPECT_EQ(static_cast(*array2d).columns(), 2); + EXPECT_EQ(dynamic_cast(*array2d).columns(), 2); EXPECT_TRUE(testMaterial.hasPhysicalProperty(QString::fromStdString("TestArray2D3Column"))); auto array2d3Column = testMaterial.getPhysicalProperty(QString::fromStdString("TestArray2D3Column"))->getMaterialValue(); EXPECT_TRUE(array2d3Column); - EXPECT_EQ(static_cast(*array2d3Column).columns(), 3); + EXPECT_EQ(dynamic_cast(*array2d3Column).columns(), 3); EXPECT_TRUE(testMaterial.hasPhysicalProperty(QString::fromStdString("TestArray3D"))); auto array3d = testMaterial.getPhysicalProperty(QString::fromStdString("TestArray3D"))->getMaterialValue(); EXPECT_TRUE(array3d); - EXPECT_EQ(static_cast(*array3d).columns(), 2); + EXPECT_EQ(dynamic_cast(*array3d).columns(), 2); } // clang-format on diff --git a/tests/src/Mod/Material/App/TestModel.cpp b/tests/src/Mod/Material/App/TestModel.cpp index c3f6e1b127..3050c5046b 100644 --- a/tests/src/Mod/Material/App/TestModel.cpp +++ b/tests/src/Mod/Material/App/TestModel.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -40,10 +41,7 @@ class TestModel : public ::testing::Test { protected: static void SetUpTestSuite() { if (App::Application::GetARGC() == 0) { - constexpr int argc = 1; - std::array argv {"FreeCAD"}; - App::Application::Config()["ExeName"] = "FreeCAD"; - App::Application::init(argc, argv.data()); + tests::initApplication(); } } @@ -75,7 +73,7 @@ TEST_F(TestModel, TestResources) TEST_F(TestModel, TestInstallation) { - EXPECT_NE(_modelManager, nullptr); + ASSERT_NE(_modelManager, nullptr); // We should have loaded at least the system library auto libraries = _modelManager->getModelLibraries(); @@ -88,7 +86,7 @@ TEST_F(TestModel, TestInstallation) TEST_F(TestModel, TestModelLoad) { - EXPECT_NE(_modelManager, nullptr); + ASSERT_NE(_modelManager, nullptr); auto density = _modelManager->getModel(QString::fromStdString("454661e5-265b-4320-8e6f-fcf6223ac3af")); EXPECT_EQ(density->getName(), QString::fromStdString("Density")); @@ -100,6 +98,8 @@ TEST_F(TestModel, TestModelLoad) TEST_F(TestModel, TestModelByPath) { + ASSERT_NE(_modelManager, nullptr); + auto linearElastic = _modelManager->getModelByPath( QString::fromStdString("Mechanical/LinearElastic.yml"), QString::fromStdString("System")); diff --git a/tests/src/Mod/Material/App/TestModelProperties.cpp b/tests/src/Mod/Material/App/TestModelProperties.cpp index 06d21c689e..c018608034 100644 --- a/tests/src/Mod/Material/App/TestModelProperties.cpp +++ b/tests/src/Mod/Material/App/TestModelProperties.cpp @@ -42,22 +42,7 @@ class TestModelProperties : public ::testing::Test { protected: static void SetUpTestSuite() { - // if (App::Application::GetARGC() == 0) { - // constexpr int argc = 1; - // std::array argv {"FreeCAD"}; - // App::Application::Config()["ExeName"] = "FreeCAD"; - // App::Application::init(argc, argv.data()); - // } } - -// void SetUp() override { -// _modelManager = new Materials::ModelManager(); -// _materialManager = new Materials::MaterialManager(); -// } - - // void TearDown() override {} -// Materials::ModelManager* _modelManager; -// Materials::MaterialManager* _materialManager; }; TEST_F(TestModelProperties, TestEmpty)