Material: Material editor enhancements
Continues the work of the material subsystem improvements. This merge covers the continued development of the material editor. The primary improvements are in the handling of 2D and 3D array properties. These properties are now fully editable, and can be saved and restored. The cards now separate the author and license. These were previously saved as a single item. Future support will be provided for standard open source licenses. Saving operations validate the cards to ensure UUIDs of materials are considered. Warnings are given when a save could potentially impact the models, such as saving over a material instead of creating a new instance. The editor is still not complete. There are a number of functional elements, such as drag/drop operations, folder creation, and deletion operations that need to be added to the main tree. State needs to be saved and restored to improve the user experience. The appearance preview also needs significant work. This will be handled in a future PR.
This commit is contained in:
@@ -187,4 +187,4 @@ PyMOD_INIT_FUNC(FemGui)
|
||||
// clang-format on
|
||||
|
||||
PyMOD_Return(mod);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,12 @@ elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
add_compile_options(-Wno-pedantic) # needed for vtk headers
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-DFCGuiFem -DHAVE_ACOSH -DHAVE_ASINH -DHAVE_ATANH)
|
||||
else(MSVC)
|
||||
add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H)
|
||||
endif(MSVC)
|
||||
|
||||
if(BUILD_FEM_NETGEN)
|
||||
add_definitions(-DFCWithNetgen)
|
||||
endif(BUILD_FEM_NETGEN)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "ModelManagerPy.h"
|
||||
#include "ModelPropertyPy.h"
|
||||
#include "ModelPy.h"
|
||||
#include "UUIDsPy.h"
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
@@ -68,6 +69,7 @@ PyMOD_INIT_FUNC(Material)
|
||||
Base::Interpreter().addType(&Materials::ModelManagerPy ::Type, module, "ModelManager");
|
||||
Base::Interpreter().addType(&Materials::ModelPropertyPy ::Type, module, "ModelProperty");
|
||||
Base::Interpreter().addType(&Materials::ModelPy ::Type, module, "Model");
|
||||
Base::Interpreter().addType(&Materials::UUIDsPy ::Type, module, "UUIDs");
|
||||
|
||||
PyMOD_Return(module);
|
||||
}
|
||||
|
||||
36
src/Mod/Material/App/Array2DPy.xml
Normal file
36
src/Mod/Material/App/Array2DPy.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="BaseClassPy"
|
||||
Name="Array2DPy"
|
||||
Twin="Material2DArray"
|
||||
TwinPointer="Material2DArray"
|
||||
Include="Mod/Material/App/MaterialValue.h"
|
||||
Namespace="Materials"
|
||||
FatherInclude="Base/BaseClassPy.h"
|
||||
FatherNamespace="Base"
|
||||
Constructor="true"
|
||||
Delete="true">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="DavidCarter" EMail="dcarter@davidcarter.ca" />
|
||||
<UserDocu>2D Array of material properties.</UserDocu>
|
||||
</Documentation>
|
||||
<Attribute Name="Rows" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The number of rows in the array.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Rows" Type="Int"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Columns" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The number of columns in the array.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Columns" Type="Int"/>
|
||||
</Attribute>
|
||||
<Methode Name="getDefaultValue" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Get the default value for the first column of the array</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
85
src/Mod/Material/App/Array2DPyImpl.cpp
Normal file
85
src/Mod/Material/App/Array2DPyImpl.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include "Array2DPy.h"
|
||||
#include "Model.h"
|
||||
#include "ModelLibrary.h"
|
||||
#include "ModelPropertyPy.h"
|
||||
#include "ModelUuids.h"
|
||||
|
||||
#include "Array2DPy.cpp"
|
||||
|
||||
using namespace Materials;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string Array2DPy::representation() const
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "<Array2D object at " << getMaterial2DArrayPtr() << ">";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject* Array2DPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// never create such objects with the constructor
|
||||
return new Array2DPy(new Material2DArray());
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int Array2DPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py::Int Array2DPy::getRows() const
|
||||
{
|
||||
return Py::Int(getMaterial2DArrayPtr()->rows());
|
||||
}
|
||||
|
||||
Py::Int Array2DPy::getColumns() const
|
||||
{
|
||||
return Py::Int(getMaterial2DArrayPtr()->columns());
|
||||
}
|
||||
|
||||
PyObject* Array2DPy::getDefaultValue(PyObject* args)
|
||||
{
|
||||
char* name;
|
||||
if (!PyArg_ParseTuple(args, "s", &name)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// QVariant value = getMaterial2DArrayPtr()->getPhysicalValue(QString::fromStdString(name));
|
||||
// return _pyObjectFromVariant(value);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* Array2DPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Array2DPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -33,14 +33,18 @@ list(APPEND Material_LIBS
|
||||
${YAML_CPP_LIBRARIES}
|
||||
)
|
||||
|
||||
generate_from_xml(Array2DPy)
|
||||
generate_from_xml(MaterialManagerPy)
|
||||
generate_from_xml(MaterialPy)
|
||||
generate_from_xml(ModelManagerPy)
|
||||
generate_from_xml(ModelPropertyPy)
|
||||
generate_from_xml(ModelPy)
|
||||
generate_from_xml(UUIDsPy)
|
||||
|
||||
SET(Python_SRCS
|
||||
Exceptions.h
|
||||
Array2DPy.xml
|
||||
Array2DPyImpl.cpp
|
||||
MaterialManagerPy.xml
|
||||
MaterialManagerPyImpl.cpp
|
||||
MaterialPy.xml
|
||||
@@ -51,6 +55,8 @@ SET(Python_SRCS
|
||||
ModelPropertyPyImpl.cpp
|
||||
ModelPy.xml
|
||||
ModelPyImpl.cpp
|
||||
UUIDsPy.xml
|
||||
UUIDsPyImpl.cpp
|
||||
)
|
||||
SOURCE_GROUP("Python" FILES ${Python_SRCS})
|
||||
|
||||
@@ -78,6 +84,7 @@ SET(Material_SRCS
|
||||
ModelLoader.h
|
||||
ModelManager.cpp
|
||||
ModelManager.h
|
||||
ModelUuids.cpp
|
||||
ModelUuids.h
|
||||
PreCompiled.cpp
|
||||
PreCompiled.h
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#ifndef MATERIAL_EXCEPTIONS_H
|
||||
#define MATERIAL_EXCEPTIONS_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <Base/BaseClass.h>
|
||||
#include <Base/Exception.h>
|
||||
|
||||
@@ -37,6 +39,10 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit Uninitialized(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~Uninitialized() noexcept override = default;
|
||||
};
|
||||
|
||||
@@ -49,9 +55,29 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit ModelNotFound(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~ModelNotFound() noexcept override = default;
|
||||
};
|
||||
|
||||
class InvalidMaterialType: public Base::Exception
|
||||
{
|
||||
public:
|
||||
InvalidMaterialType()
|
||||
{}
|
||||
explicit InvalidMaterialType(const char* msg)
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit InvalidMaterialType(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~InvalidMaterialType() noexcept override = default;
|
||||
};
|
||||
|
||||
class MaterialNotFound: public Base::Exception
|
||||
{
|
||||
public:
|
||||
@@ -61,9 +87,29 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit MaterialNotFound(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~MaterialNotFound() noexcept override = default;
|
||||
};
|
||||
|
||||
class MaterialExists: public Base::Exception
|
||||
{
|
||||
public:
|
||||
MaterialExists()
|
||||
{}
|
||||
explicit MaterialExists(const char* msg)
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit MaterialExists(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~MaterialExists() noexcept override = default;
|
||||
};
|
||||
|
||||
class PropertyNotFound: public Base::Exception
|
||||
{
|
||||
public:
|
||||
@@ -73,6 +119,10 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit PropertyNotFound(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~PropertyNotFound() noexcept override = default;
|
||||
};
|
||||
|
||||
@@ -85,6 +135,10 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit LibraryNotFound(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~LibraryNotFound() noexcept override = default;
|
||||
};
|
||||
|
||||
@@ -97,6 +151,10 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit InvalidModel(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~InvalidModel() noexcept override = default;
|
||||
};
|
||||
|
||||
@@ -109,6 +167,10 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit InvalidRow(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~InvalidRow() noexcept override = default;
|
||||
};
|
||||
|
||||
@@ -121,9 +183,29 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit InvalidColumn(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~InvalidColumn() noexcept override = default;
|
||||
};
|
||||
|
||||
class InvalidDepth: public Base::Exception
|
||||
{
|
||||
public:
|
||||
InvalidDepth()
|
||||
{}
|
||||
explicit InvalidDepth(char* msg)
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit InvalidDepth(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~InvalidDepth() noexcept override = default;
|
||||
};
|
||||
|
||||
class InvalidIndex: public Base::Exception
|
||||
{
|
||||
public:
|
||||
@@ -133,6 +215,10 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit InvalidIndex(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~InvalidIndex() noexcept override = default;
|
||||
};
|
||||
|
||||
@@ -145,9 +231,29 @@ public:
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit UnknownValueType(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~UnknownValueType() noexcept override = default;
|
||||
};
|
||||
|
||||
class DeleteError: public Base::Exception
|
||||
{
|
||||
public:
|
||||
DeleteError()
|
||||
{}
|
||||
explicit DeleteError(char* msg)
|
||||
{
|
||||
this->setMessage(msg);
|
||||
}
|
||||
explicit DeleteError(const QString& msg)
|
||||
{
|
||||
this->setMessage(msg.toStdString().c_str());
|
||||
}
|
||||
~DeleteError() noexcept override = default;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
#endif // MATERIAL_EXCEPTIONS_H
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
#ifndef MATERIAL_FOLDERTREE_H
|
||||
#define MATERIAL_FOLDERTREE_H
|
||||
|
||||
#include <QString>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
@@ -53,25 +53,25 @@ public:
|
||||
_type = type;
|
||||
}
|
||||
|
||||
const std::shared_ptr<std::map<QString, FolderTreeNode<T>*>> getFolder() const
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<FolderTreeNode<T>>>> getFolder() const
|
||||
{
|
||||
return _folder;
|
||||
}
|
||||
std::shared_ptr<std::map<QString, FolderTreeNode<T>*>> getFolder()
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<FolderTreeNode<T>>>> getFolder()
|
||||
{
|
||||
return _folder;
|
||||
}
|
||||
const T* getData() const
|
||||
std::shared_ptr<T> getData() const
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
void setFolder(std::shared_ptr<std::map<QString, FolderTreeNode<T>*>> folder)
|
||||
void setFolder(std::shared_ptr<std::map<QString, std::shared_ptr<FolderTreeNode<T>>>> folder)
|
||||
{
|
||||
setType(FolderNode);
|
||||
_folder = folder;
|
||||
}
|
||||
void setData(const T* data)
|
||||
void setData(std::shared_ptr<T> data)
|
||||
{
|
||||
setType(DataNode);
|
||||
_data = data;
|
||||
@@ -79,8 +79,8 @@ public:
|
||||
|
||||
private:
|
||||
NodeType _type;
|
||||
std::shared_ptr<std::map<QString, FolderTreeNode<T>*>> _folder;
|
||||
const T* _data;
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<FolderTreeNode<T>>>> _folder;
|
||||
std::shared_ptr<T> _data;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
@@ -85,7 +85,8 @@ QString MaterialConfigLoader::getAuthorAndLicense(const QString& path)
|
||||
return noAuthor;
|
||||
}
|
||||
|
||||
void MaterialConfigLoader::addVectorRendering(const QSettings& fcmat, Material* finalModel)
|
||||
void MaterialConfigLoader::addVectorRendering(const QSettings& fcmat,
|
||||
std::shared_ptr<Material> finalModel)
|
||||
{
|
||||
QString sectionFillPattern = value(fcmat, "VectorRendering/SectionFillPattern", "");
|
||||
QString sectionLinewidth = value(fcmat, "VectorRendering/SectionLinewidth", "");
|
||||
@@ -97,7 +98,7 @@ void MaterialConfigLoader::addVectorRendering(const QSettings& fcmat, Material*
|
||||
if (sectionFillPattern.length() + sectionLinewidth.length() + sectionColor.length()
|
||||
+ viewColor.length() + viewFillPattern.length() + viewLinewidth.length()
|
||||
> 0) {
|
||||
finalModel->addAppearance(ModelUUID_Rendering_Vector);
|
||||
finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Vector);
|
||||
}
|
||||
|
||||
// Now add the data
|
||||
@@ -109,7 +110,8 @@ void MaterialConfigLoader::addVectorRendering(const QSettings& fcmat, Material*
|
||||
setAppearanceValue(finalModel, "ViewLinewidth", viewLinewidth);
|
||||
}
|
||||
|
||||
void MaterialConfigLoader::addRendering(const QSettings& fcmat, Material* finalModel)
|
||||
void MaterialConfigLoader::addRendering(const QSettings& fcmat,
|
||||
std::shared_ptr<Material> finalModel)
|
||||
{
|
||||
QString ambientColor = value(fcmat, "Rendering/AmbientColor", "");
|
||||
QString diffuseColor = value(fcmat, "Rendering/DiffuseColor", "");
|
||||
@@ -139,13 +141,13 @@ void MaterialConfigLoader::addRendering(const QSettings& fcmat, Material* finalM
|
||||
}
|
||||
|
||||
if (useAdvanced) {
|
||||
finalModel->addAppearance(ModelUUID_Rendering_Advanced);
|
||||
finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Advanced);
|
||||
}
|
||||
else if (useTexture) {
|
||||
finalModel->addAppearance(ModelUUID_Rendering_Texture);
|
||||
finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Texture);
|
||||
}
|
||||
else if (useBasic) {
|
||||
finalModel->addAppearance(ModelUUID_Rendering_Basic);
|
||||
finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Basic);
|
||||
}
|
||||
|
||||
// Now add the data
|
||||
@@ -161,14 +163,14 @@ void MaterialConfigLoader::addRendering(const QSettings& fcmat, Material* finalM
|
||||
setAppearanceValue(finalModel, "VertexShader", vertexShader);
|
||||
}
|
||||
|
||||
void MaterialConfigLoader::addCosts(const QSettings& fcmat, Material* finalModel)
|
||||
void MaterialConfigLoader::addCosts(const QSettings& fcmat, std::shared_ptr<Material> finalModel)
|
||||
{
|
||||
QString productURL = value(fcmat, "Cost/ProductURL", "");
|
||||
QString specificPrice = value(fcmat, "Cost/SpecificPrice", "");
|
||||
QString vendor = value(fcmat, "Cost/Vendor", "");
|
||||
|
||||
if (productURL.length() + specificPrice.length() + vendor.length() > 0) {
|
||||
finalModel->addPhysical(ModelUUID_Costs_Default);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Costs_Default);
|
||||
}
|
||||
|
||||
// Now add the data
|
||||
@@ -177,7 +179,8 @@ void MaterialConfigLoader::addCosts(const QSettings& fcmat, Material* finalModel
|
||||
setPhysicalValue(finalModel, "Vendor", vendor);
|
||||
}
|
||||
|
||||
void MaterialConfigLoader::addArchitectural(const QSettings& fcmat, Material* finalModel)
|
||||
void MaterialConfigLoader::addArchitectural(const QSettings& fcmat,
|
||||
std::shared_ptr<Material> finalModel)
|
||||
{
|
||||
QString color = value(fcmat, "Architectural/Color", "");
|
||||
QString environmentalEfficiencyClass =
|
||||
@@ -193,7 +196,7 @@ void MaterialConfigLoader::addArchitectural(const QSettings& fcmat, Material* fi
|
||||
+ finish.length() + fireResistanceClass.length() + model.length()
|
||||
+ soundTransmissionClass.length() + unitsPerQuantity.length()
|
||||
> 0) {
|
||||
finalModel->addPhysical(ModelUUID_Architectural_Default);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Architectural_Default);
|
||||
}
|
||||
|
||||
// Now add the data
|
||||
@@ -207,7 +210,8 @@ void MaterialConfigLoader::addArchitectural(const QSettings& fcmat, Material* fi
|
||||
setPhysicalValue(finalModel, "UnitsPerQuantity", unitsPerQuantity);
|
||||
}
|
||||
|
||||
void MaterialConfigLoader::addElectromagnetic(const QSettings& fcmat, Material* finalModel)
|
||||
void MaterialConfigLoader::addElectromagnetic(const QSettings& fcmat,
|
||||
std::shared_ptr<Material> finalModel)
|
||||
{
|
||||
QString relativePermittivity = value(fcmat, "Electromagnetic/RelativePermittivity", "");
|
||||
QString electricalConductivity = value(fcmat, "Electromagnetic/ElectricalConductivity", "");
|
||||
@@ -216,7 +220,7 @@ void MaterialConfigLoader::addElectromagnetic(const QSettings& fcmat, Material*
|
||||
if (relativePermittivity.length() + electricalConductivity.length()
|
||||
+ relativePermeability.length()
|
||||
> 0) {
|
||||
finalModel->addPhysical(ModelUUID_Electromagnetic_Default);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Electromagnetic_Default);
|
||||
}
|
||||
|
||||
// Now add the data
|
||||
@@ -225,7 +229,7 @@ void MaterialConfigLoader::addElectromagnetic(const QSettings& fcmat, Material*
|
||||
setPhysicalValue(finalModel, "RelativePermeability", relativePermeability);
|
||||
}
|
||||
|
||||
void MaterialConfigLoader::addThermal(const QSettings& fcmat, Material* finalModel)
|
||||
void MaterialConfigLoader::addThermal(const QSettings& fcmat, std::shared_ptr<Material> finalModel)
|
||||
{
|
||||
QString specificHeat = value(fcmat, "Thermal/SpecificHeat", "");
|
||||
QString thermalConductivity = value(fcmat, "Thermal/ThermalConductivity", "");
|
||||
@@ -233,7 +237,7 @@ void MaterialConfigLoader::addThermal(const QSettings& fcmat, Material* finalMod
|
||||
|
||||
if (specificHeat.length() + thermalConductivity.length() + thermalExpansionCoefficient.length()
|
||||
> 0) {
|
||||
finalModel->addPhysical(ModelUUID_Thermal_Default);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Thermal_Default);
|
||||
}
|
||||
|
||||
// Now add the data
|
||||
@@ -242,7 +246,7 @@ void MaterialConfigLoader::addThermal(const QSettings& fcmat, Material* finalMod
|
||||
setPhysicalValue(finalModel, "ThermalExpansionCoefficient", thermalExpansionCoefficient);
|
||||
}
|
||||
|
||||
void MaterialConfigLoader::addFluid(const QSettings& fcmat, Material* finalModel)
|
||||
void MaterialConfigLoader::addFluid(const QSettings& fcmat, std::shared_ptr<Material> finalModel)
|
||||
{
|
||||
QString density = value(fcmat, "Fluidic/Density", "");
|
||||
QString dynamicViscosity = value(fcmat, "Fluidic/DynamicViscosity", "");
|
||||
@@ -260,10 +264,10 @@ void MaterialConfigLoader::addFluid(const QSettings& fcmat, Material* finalModel
|
||||
}
|
||||
|
||||
if (useFluid) {
|
||||
finalModel->addPhysical(ModelUUID_Fluid_Default);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Fluid_Default);
|
||||
}
|
||||
else if (useDensity) {
|
||||
finalModel->addPhysical(ModelUUID_Mechanical_Density);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Mechanical_Density);
|
||||
}
|
||||
|
||||
// Now add the data
|
||||
@@ -273,7 +277,8 @@ void MaterialConfigLoader::addFluid(const QSettings& fcmat, Material* finalModel
|
||||
setPhysicalValue(finalModel, "PrandtlNumber", prandtlNumber);
|
||||
}
|
||||
|
||||
void MaterialConfigLoader::addMechanical(const QSettings& fcmat, Material* finalModel)
|
||||
void MaterialConfigLoader::addMechanical(const QSettings& fcmat,
|
||||
std::shared_ptr<Material> finalModel)
|
||||
{
|
||||
QString density = value(fcmat, "Mechanical/Density", "");
|
||||
QString bulkModulus = value(fcmat, "Mechanical/BulkModulus", "");
|
||||
@@ -308,14 +313,14 @@ void MaterialConfigLoader::addMechanical(const QSettings& fcmat, Material* final
|
||||
}
|
||||
|
||||
if (useLinearElastic) {
|
||||
finalModel->addPhysical(ModelUUID_Mechanical_LinearElastic);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Mechanical_LinearElastic);
|
||||
}
|
||||
else {
|
||||
if (useIso) {
|
||||
finalModel->addPhysical(ModelUUID_Mechanical_IsotropicLinearElastic);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Mechanical_IsotropicLinearElastic);
|
||||
}
|
||||
if (useDensity) {
|
||||
finalModel->addPhysical(ModelUUID_Mechanical_Density);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Mechanical_Density);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,10 +339,11 @@ void MaterialConfigLoader::addMechanical(const QSettings& fcmat, Material* final
|
||||
setPhysicalValue(finalModel, "Stiffness", stiffness);
|
||||
}
|
||||
|
||||
Material* MaterialConfigLoader::getMaterialFromPath(const MaterialLibrary& library,
|
||||
const QString& path)
|
||||
std::shared_ptr<Material>
|
||||
MaterialConfigLoader::getMaterialFromPath(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& path)
|
||||
{
|
||||
QString authorAndLicense = getAuthorAndLicense(path);
|
||||
QString author = getAuthorAndLicense(path); // Place them both in the author field
|
||||
|
||||
QSettings fcmat(path, QSettings::IniFormat);
|
||||
|
||||
@@ -352,15 +358,15 @@ Material* MaterialConfigLoader::getMaterialFromPath(const MaterialLibrary& libra
|
||||
QString sourceReference = value(fcmat, "ReferenceSource", "");
|
||||
QString sourceURL = value(fcmat, "SourceURL", "");
|
||||
|
||||
Material* finalModel = new Material(library, path, uuid, name);
|
||||
finalModel->setAuthorAndLicense(authorAndLicense);
|
||||
std::shared_ptr<Material> finalModel = std::make_shared<Material>(library, path, uuid, name);
|
||||
finalModel->setAuthor(author);
|
||||
finalModel->setDescription(description);
|
||||
finalModel->setReference(sourceReference);
|
||||
finalModel->setURL(sourceURL);
|
||||
|
||||
QString father = value(fcmat, "Father", "");
|
||||
if (father.length() > 0) {
|
||||
finalModel->addPhysical(ModelUUID_Legacy_Father);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Legacy_Father);
|
||||
|
||||
// Now add the data
|
||||
setPhysicalValue(finalModel, "Father", father);
|
||||
@@ -372,7 +378,7 @@ Material* MaterialConfigLoader::getMaterialFromPath(const MaterialLibrary& libra
|
||||
QString standardCode = value(fcmat, "StandardCode", "");
|
||||
if (kindOfMaterial.length() + materialNumber.length() + norm.length() + standardCode.length()
|
||||
> 0) {
|
||||
finalModel->addPhysical(ModelUUID_Legacy_MaterialStandard);
|
||||
finalModel->addPhysical(ModelUUIDs::ModelUUID_Legacy_MaterialStandard);
|
||||
|
||||
// Now add the data
|
||||
setPhysicalValue(finalModel, "KindOfMaterial", kindOfMaterial);
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#ifndef MATERIAL_MATERIALCONFIGLOADER_H
|
||||
#define MATERIAL_MATERIALCONFIGLOADER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QDir>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
@@ -39,7 +41,8 @@ public:
|
||||
|
||||
|
||||
static bool isConfigStyle(const QString& path);
|
||||
static Material* getMaterialFromPath(const MaterialLibrary& library, const QString& path);
|
||||
static std::shared_ptr<Material> getMaterialFromPath(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& path);
|
||||
|
||||
private:
|
||||
static QString
|
||||
@@ -49,15 +52,17 @@ private:
|
||||
.toString();
|
||||
}
|
||||
|
||||
static void
|
||||
setPhysicalValue(Material* finalModel, const std::string& name, const QString& value)
|
||||
static void setPhysicalValue(std::shared_ptr<Material> finalModel,
|
||||
const std::string& name,
|
||||
const QString& value)
|
||||
{
|
||||
if (value.length() > 0) {
|
||||
finalModel->setPhysicalValue(QString::fromStdString(name), value);
|
||||
}
|
||||
}
|
||||
static void
|
||||
setAppearanceValue(Material* finalModel, const std::string& name, const QString& value)
|
||||
static void setAppearanceValue(std::shared_ptr<Material> finalModel,
|
||||
const std::string& name,
|
||||
const QString& value)
|
||||
{
|
||||
if (value.length() > 0) {
|
||||
finalModel->setAppearanceValue(QString::fromStdString(name), value);
|
||||
@@ -65,14 +70,14 @@ private:
|
||||
}
|
||||
|
||||
static QString getAuthorAndLicense(const QString& path);
|
||||
static void addMechanical(const QSettings& fcmat, Material* finalModel);
|
||||
static void addFluid(const QSettings& fcmat, Material* finalModel);
|
||||
static void addThermal(const QSettings& fcmat, Material* finalModel);
|
||||
static void addElectromagnetic(const QSettings& fcmat, Material* finalModel);
|
||||
static void addArchitectural(const QSettings& fcmat, Material* finalModel);
|
||||
static void addCosts(const QSettings& fcmat, Material* finalModel);
|
||||
static void addRendering(const QSettings& fcmat, Material* finalModel);
|
||||
static void addVectorRendering(const QSettings& fcmat, Material* finalModel);
|
||||
static void addMechanical(const QSettings& fcmat, std::shared_ptr<Material> finalModel);
|
||||
static void addFluid(const QSettings& fcmat, std::shared_ptr<Material> finalModel);
|
||||
static void addThermal(const QSettings& fcmat, std::shared_ptr<Material> finalModel);
|
||||
static void addElectromagnetic(const QSettings& fcmat, std::shared_ptr<Material> finalModel);
|
||||
static void addArchitectural(const QSettings& fcmat, std::shared_ptr<Material> finalModel);
|
||||
static void addCosts(const QSettings& fcmat, std::shared_ptr<Material> finalModel);
|
||||
static void addRendering(const QSettings& fcmat, std::shared_ptr<Material> finalModel);
|
||||
static void addVectorRendering(const QSettings& fcmat, std::shared_ptr<Material> finalModel);
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
@@ -21,11 +21,17 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <QVector>
|
||||
#endif
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <App/Application.h>
|
||||
|
||||
#include "MaterialLibrary.h"
|
||||
#include "MaterialLoader.h"
|
||||
#include "MaterialManager.h"
|
||||
#include "Materials.h"
|
||||
#include "ModelManager.h"
|
||||
|
||||
@@ -34,9 +40,6 @@ using namespace Materials;
|
||||
|
||||
/* TRANSLATOR Material::Materials */
|
||||
|
||||
std::unique_ptr<std::map<QString, Material*>> MaterialLibrary::_materialPathMap =
|
||||
std::make_unique<std::map<QString, Material*>>();
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::MaterialLibrary, LibraryBase)
|
||||
|
||||
MaterialLibrary::MaterialLibrary()
|
||||
@@ -48,24 +51,165 @@ MaterialLibrary::MaterialLibrary(const QString& libraryName,
|
||||
bool readOnly)
|
||||
: LibraryBase(libraryName, dir, icon)
|
||||
, _readOnly(readOnly)
|
||||
, _materialPathMap(std::make_unique<std::map<QString, std::shared_ptr<Material>>>())
|
||||
{}
|
||||
|
||||
void MaterialLibrary::createPath(const QString& path)
|
||||
{
|
||||
Q_UNUSED(path)
|
||||
}
|
||||
|
||||
Material* MaterialLibrary::saveMaterial(Material& material, const QString& path, bool saveAsCopy)
|
||||
void MaterialLibrary::createFolder(const QString& path)
|
||||
{
|
||||
QString filePath = getLocalPath(path);
|
||||
Base::Console().Log("\tfilePath = '%s'\n", filePath.toStdString().c_str());
|
||||
// Base::Console().Log("\tfilePath = '%s'\n", filePath.toStdString().c_str());
|
||||
|
||||
QDir fileDir(filePath);
|
||||
if (!fileDir.exists()) {
|
||||
if (!fileDir.mkpath(filePath)) {
|
||||
Base::Console().Error("Unable to create directory path '%s'\n",
|
||||
filePath.toStdString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This accepts the filesystem path as returned from getLocalPath
|
||||
void MaterialLibrary::deleteDir(MaterialManager& manager, const QString& path)
|
||||
{
|
||||
// Base::Console().Log("Removing directory '%s'\n", path.toStdString().c_str());
|
||||
|
||||
// Remove the children first
|
||||
QDirIterator it(path, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||
|
||||
// Add paths to a list so there are no iterator errors
|
||||
QVector<QString> dirList;
|
||||
QVector<QString> fileList;
|
||||
while (it.hasNext()) {
|
||||
auto pathname = it.next();
|
||||
QFileInfo file(pathname);
|
||||
if (file.isFile()) {
|
||||
fileList.push_back(pathname);
|
||||
}
|
||||
else if (file.isDir()) {
|
||||
dirList.push_back(pathname);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the subdirs first
|
||||
while (!dirList.isEmpty()) {
|
||||
QString dirPath = dirList.takeFirst();
|
||||
deleteDir(manager, dirPath);
|
||||
}
|
||||
|
||||
// Remove the files
|
||||
while (!fileList.isEmpty()) {
|
||||
QString filePath = fileList.takeFirst();
|
||||
deleteFile(manager, filePath);
|
||||
}
|
||||
|
||||
// Finally, remove ourself
|
||||
QDir dir;
|
||||
if (!dir.rmdir(path)) {
|
||||
throw DeleteError(path);
|
||||
}
|
||||
}
|
||||
|
||||
// This accepts the filesystem path as returned from getLocalPath
|
||||
void MaterialLibrary::deleteFile(MaterialManager& manager, const QString& path)
|
||||
{
|
||||
// Base::Console().Log("Removing file '%s'\n", path.toStdString().c_str());
|
||||
|
||||
if (QFile::remove(path)) {
|
||||
// Remove from the map
|
||||
QString rPath = getRelativePath(path);
|
||||
// Base::Console().Log("\trpath '%s'\n", rPath.toStdString().c_str());
|
||||
try {
|
||||
auto material = getMaterialByPath(rPath);
|
||||
manager.remove(material->getUUID());
|
||||
}
|
||||
catch (const MaterialNotFound&) {
|
||||
Base::Console().Log("Unable to remove file from materials list\n");
|
||||
}
|
||||
_materialPathMap->erase(rPath);
|
||||
}
|
||||
else {
|
||||
QString error = QString::fromStdString("DeleteError: Unable to delete ") + path;
|
||||
throw DeleteError(error);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialLibrary::deleteRecursive(const QString& path)
|
||||
{
|
||||
std::string pstring = path.toStdString();
|
||||
Base::Console().Log("\tdeleteRecursive '%s'\n", pstring.c_str());
|
||||
|
||||
if (isRoot(path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString filePath = getLocalPath(path);
|
||||
// Base::Console().Log("\tfilePath = '%s'\n", filePath.toStdString().c_str());
|
||||
MaterialManager manager;
|
||||
|
||||
QFileInfo info(filePath);
|
||||
if (info.isDir()) {
|
||||
deleteDir(manager, filePath);
|
||||
}
|
||||
else {
|
||||
deleteFile(manager, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialLibrary::updatePaths(const QString& oldPath, const QString& newPath)
|
||||
{
|
||||
// Update the path map
|
||||
QString op = getRelativePath(oldPath);
|
||||
QString np = getRelativePath(newPath);
|
||||
std::unique_ptr<std::map<QString, std::shared_ptr<Material>>> pathMap =
|
||||
std::make_unique<std::map<QString, std::shared_ptr<Material>>>();
|
||||
for (auto itp = _materialPathMap->begin(); itp != _materialPathMap->end(); itp++) {
|
||||
QString path = itp->first;
|
||||
if (path.startsWith(op)) {
|
||||
path = np + path.remove(0, op.size());
|
||||
}
|
||||
Base::Console().Error("Path '%s' -> '%s'\n",
|
||||
itp->first.toStdString().c_str(),
|
||||
path.toStdString().c_str());
|
||||
itp->second->setDirectory(path);
|
||||
(*pathMap)[path] = itp->second;
|
||||
}
|
||||
|
||||
_materialPathMap = std::move(pathMap);
|
||||
}
|
||||
|
||||
void MaterialLibrary::renameFolder(const QString& oldPath, const QString& newPath)
|
||||
{
|
||||
QString filePath = getLocalPath(oldPath);
|
||||
// Base::Console().Log("\tfilePath = '%s'\n", filePath.toStdString().c_str());
|
||||
QString newFilePath = getLocalPath(newPath);
|
||||
// Base::Console().Log("\tnew filePath = '%s'\n", newFilePath.toStdString().c_str());
|
||||
|
||||
QDir fileDir(filePath);
|
||||
if (fileDir.exists()) {
|
||||
if (!fileDir.rename(filePath, newFilePath)) {
|
||||
Base::Console().Error("Unable to rename directory path '%s'\n",
|
||||
filePath.toStdString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
updatePaths(oldPath, newPath);
|
||||
}
|
||||
|
||||
std::shared_ptr<Material> MaterialLibrary::saveMaterial(std::shared_ptr<Material> material,
|
||||
const QString& path,
|
||||
bool overwrite,
|
||||
bool saveAsCopy,
|
||||
bool saveInherited)
|
||||
{
|
||||
QString filePath = getLocalPath(path);
|
||||
// Base::Console().Log("\tfilePath = '%s'\n", filePath.toStdString().c_str());
|
||||
QFile file(filePath);
|
||||
|
||||
// Update UUID if required
|
||||
// if name changed true
|
||||
if (material.getName() != file.fileName()) {
|
||||
material.newUuid();
|
||||
}
|
||||
// if (material->getName() != file.fileName()) {
|
||||
// material->newUuid();
|
||||
// }
|
||||
// if overwrite false having warned the user
|
||||
// if old format true, but already set
|
||||
|
||||
@@ -79,43 +223,49 @@ Material* MaterialLibrary::saveMaterial(Material& material, const QString& path,
|
||||
}
|
||||
}
|
||||
|
||||
if (info.exists()) {
|
||||
if (!overwrite) {
|
||||
Base::Console().Error("File already exists '%s'\n", info.path().toStdString().c_str());
|
||||
throw MaterialExists();
|
||||
}
|
||||
}
|
||||
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream stream(&file);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
stream.setCodec("UTF-8");
|
||||
#endif
|
||||
stream.setGenerateByteOrderMark(true);
|
||||
|
||||
// Write the contents
|
||||
material.setLibrary(*this);
|
||||
material.setDirectory(getRelativePath(path));
|
||||
material.save(stream, saveAsCopy);
|
||||
material->setLibrary(getptr());
|
||||
material->setDirectory(getRelativePath(path));
|
||||
material->save(stream, saveAsCopy, saveInherited);
|
||||
}
|
||||
|
||||
return addMaterial(material, path);
|
||||
}
|
||||
|
||||
Material* MaterialLibrary::addMaterial(const Material& material, const QString& path)
|
||||
bool MaterialLibrary::fileExists(const QString& path) const
|
||||
{
|
||||
QString filePath = getLocalPath(path);
|
||||
QFileInfo info(filePath);
|
||||
|
||||
return info.exists();
|
||||
}
|
||||
|
||||
std::shared_ptr<Material> MaterialLibrary::addMaterial(std::shared_ptr<Material> material,
|
||||
const QString& path)
|
||||
{
|
||||
QString filePath = getRelativePath(path);
|
||||
Material* newMaterial = new Material(material);
|
||||
newMaterial->setLibrary(*this);
|
||||
std::shared_ptr<Material> newMaterial = std::make_shared<Material>(*material);
|
||||
newMaterial->setLibrary(getptr());
|
||||
newMaterial->setDirectory(filePath);
|
||||
|
||||
try {
|
||||
// If there's already a material at that path we'll replace it
|
||||
Material* old = _materialPathMap->at(filePath);
|
||||
delete old;
|
||||
}
|
||||
catch (const std::out_of_range&) {
|
||||
}
|
||||
|
||||
(*_materialPathMap)[filePath] = newMaterial;
|
||||
|
||||
return newMaterial;
|
||||
}
|
||||
|
||||
const Material& MaterialLibrary::getMaterialByPath(const QString& path) const
|
||||
std::shared_ptr<Material> MaterialLibrary::getMaterialByPath(const QString& path) const
|
||||
{
|
||||
// Base::Console().Log("MaterialLibrary::getMaterialByPath(%s)\n", path.toStdString().c_str());
|
||||
// for (auto itp = _materialPathMap->begin(); itp != _materialPathMap->end(); itp++) {
|
||||
@@ -124,10 +274,10 @@ const Material& MaterialLibrary::getMaterialByPath(const QString& path) const
|
||||
|
||||
QString filePath = getRelativePath(path);
|
||||
try {
|
||||
Material* material = _materialPathMap->at(filePath);
|
||||
return *material;
|
||||
auto material = _materialPathMap->at(filePath);
|
||||
return material;
|
||||
}
|
||||
catch (std::out_of_range&) {
|
||||
catch (std::out_of_range& e) {
|
||||
throw MaterialNotFound();
|
||||
}
|
||||
}
|
||||
@@ -136,14 +286,80 @@ const QString MaterialLibrary::getUUIDFromPath(const QString& path) const
|
||||
{
|
||||
QString filePath = getRelativePath(path);
|
||||
try {
|
||||
Material* material = _materialPathMap->at(filePath);
|
||||
auto material = _materialPathMap->at(filePath);
|
||||
return material->getUUID();
|
||||
}
|
||||
catch (std::out_of_range&) {
|
||||
catch (std::out_of_range& e) {
|
||||
throw MaterialNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
MaterialLibrary::getMaterialTree() const
|
||||
{
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> materialTree =
|
||||
std::make_shared<std::map<QString, std::shared_ptr<MaterialTreeNode>>>();
|
||||
|
||||
for (auto it = _materialPathMap->begin(); it != _materialPathMap->end(); it++) {
|
||||
auto filename = it->first;
|
||||
auto material = it->second;
|
||||
|
||||
// Base::Console().Log("Relative path '%s'\n\t", filename.toStdString().c_str());
|
||||
QStringList list = filename.split(QString::fromStdString("/"));
|
||||
|
||||
// Start at the root
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> node = materialTree;
|
||||
for (auto itp = list.begin(); itp != list.end(); itp++) {
|
||||
// Base::Console().Log("\t%s", itp->toStdString().c_str());
|
||||
if (itp->endsWith(QString::fromStdString(".FCMat"))) {
|
||||
std::shared_ptr<MaterialTreeNode> child = std::make_shared<MaterialTreeNode>();
|
||||
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<QString, std::shared_ptr<MaterialTreeNode>>>();
|
||||
std::shared_ptr<MaterialTreeNode> child = std::make_shared<MaterialTreeNode>();
|
||||
child->setFolder(mapPtr);
|
||||
(*node)[*itp] = child;
|
||||
node = mapPtr;
|
||||
}
|
||||
else {
|
||||
node = (*node)[*itp]->getFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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.begin(); itp != list.end(); itp++) {
|
||||
// Add the folder only if it's not already there
|
||||
if (node->count(*itp) == 0) {
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> mapPtr =
|
||||
std::make_shared<std::map<QString, std::shared_ptr<MaterialTreeNode>>>();
|
||||
std::shared_ptr<MaterialTreeNode> child = std::make_shared<MaterialTreeNode>();
|
||||
child->setFolder(mapPtr);
|
||||
(*node)[*itp] = child;
|
||||
node = mapPtr;
|
||||
}
|
||||
else {
|
||||
node = (*node)[*itp]->getFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return materialTree;
|
||||
}
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::MaterialExternalLibrary, MaterialLibrary::MaterialLibrary)
|
||||
|
||||
MaterialExternalLibrary::MaterialExternalLibrary()
|
||||
|
||||
@@ -22,14 +22,17 @@
|
||||
#ifndef MATERIAL_MATERIALLIBRARY_H
|
||||
#define MATERIAL_MATERIALLIBRARY_H
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
|
||||
#include <Base/BaseClass.h>
|
||||
#include <memory>
|
||||
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
#include <Base/BaseClass.h>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
|
||||
#include "Materials.h"
|
||||
#include "Model.h"
|
||||
#include "ModelLibrary.h"
|
||||
|
||||
@@ -37,17 +40,19 @@ namespace Materials
|
||||
{
|
||||
|
||||
class Material;
|
||||
class MaterialManager;
|
||||
|
||||
class MaterialsExport MaterialLibrary: public LibraryBase
|
||||
class MaterialsExport MaterialLibrary: public LibraryBase,
|
||||
public std::enable_shared_from_this<MaterialLibrary>
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
MaterialLibrary();
|
||||
explicit MaterialLibrary(const QString& libraryName,
|
||||
const QString& dir,
|
||||
const QString& icon,
|
||||
bool readOnly = true);
|
||||
MaterialLibrary(const QString& libraryName,
|
||||
const QString& dir,
|
||||
const QString& icon,
|
||||
bool readOnly = true);
|
||||
~MaterialLibrary() override = default;
|
||||
|
||||
bool operator==(const MaterialLibrary& library) const
|
||||
@@ -58,40 +63,60 @@ public:
|
||||
{
|
||||
return !operator==(library);
|
||||
}
|
||||
const Material& getMaterialByPath(const QString& path) const;
|
||||
std::shared_ptr<Material> getMaterialByPath(const QString& path) const;
|
||||
|
||||
void createPath(const QString& path);
|
||||
Material* saveMaterial(Material& material, const QString& path, bool saveAsCopy);
|
||||
Material* addMaterial(const Material& material, const QString& path);
|
||||
void createFolder(const QString& path);
|
||||
void renameFolder(const QString& oldPath, const QString& newPath);
|
||||
void deleteRecursive(const QString& path);
|
||||
|
||||
std::shared_ptr<Material> saveMaterial(std::shared_ptr<Material> material,
|
||||
const QString& path,
|
||||
bool overwrite,
|
||||
bool saveAsCopy,
|
||||
bool saveInherited);
|
||||
bool fileExists(const QString& path) const;
|
||||
std::shared_ptr<Material> addMaterial(std::shared_ptr<Material> material, const QString& path);
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> getMaterialTree() const;
|
||||
|
||||
bool isReadOnly() const
|
||||
{
|
||||
return _readOnly;
|
||||
}
|
||||
|
||||
// Use this to get a shared_ptr for *this
|
||||
std::shared_ptr<MaterialLibrary> getptr()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
protected:
|
||||
MaterialLibrary(const MaterialLibrary&) = default;
|
||||
|
||||
void deleteDir(MaterialManager& manager, const QString& path);
|
||||
void deleteFile(MaterialManager& manager, const QString& path);
|
||||
|
||||
void updatePaths(const QString& oldPath, const QString& newPath);
|
||||
const QString getUUIDFromPath(const QString& path) const;
|
||||
|
||||
bool _readOnly;
|
||||
static std::unique_ptr<std::map<QString, Material*>> _materialPathMap;
|
||||
std::unique_ptr<std::map<QString, std::shared_ptr<Material>>> _materialPathMap;
|
||||
};
|
||||
|
||||
class MaterialsExport MaterialExternalLibrary: public MaterialLibrary
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
MaterialExternalLibrary();
|
||||
explicit MaterialExternalLibrary(const QString& libraryName,
|
||||
const QString& dir,
|
||||
const QString& icon,
|
||||
bool readOnly = true);
|
||||
MaterialExternalLibrary(const QString& libraryName,
|
||||
const QString& dir,
|
||||
const QString& icon,
|
||||
bool readOnly = true);
|
||||
~MaterialExternalLibrary() override;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
Q_DECLARE_METATYPE(Materials::MaterialLibrary)
|
||||
Q_DECLARE_METATYPE(Materials::MaterialExternalLibrary)
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<Materials::MaterialLibrary>)
|
||||
|
||||
#endif // MATERIAL_MATERIALLIBRARY_H
|
||||
|
||||
@@ -24,13 +24,18 @@
|
||||
#include <QString>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/Interpreter.h>
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QFileInfo>
|
||||
#include <QMetaType>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Gui/MetaTypes.h>
|
||||
|
||||
#include "Materials.h"
|
||||
|
||||
#include "MaterialConfigLoader.h"
|
||||
#include "MaterialLibrary.h"
|
||||
#include "MaterialLoader.h"
|
||||
#include "Model.h"
|
||||
#include "ModelManager.h"
|
||||
@@ -41,7 +46,7 @@ using namespace Materials;
|
||||
MaterialEntry::MaterialEntry()
|
||||
{}
|
||||
|
||||
MaterialEntry::MaterialEntry(const MaterialLibrary& library,
|
||||
MaterialEntry::MaterialEntry(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& modelName,
|
||||
const QString& dir,
|
||||
const QString& modelUuid)
|
||||
@@ -51,7 +56,7 @@ MaterialEntry::MaterialEntry(const MaterialLibrary& library,
|
||||
, _uuid(modelUuid)
|
||||
{}
|
||||
|
||||
MaterialYamlEntry::MaterialYamlEntry(const MaterialLibrary& library,
|
||||
MaterialYamlEntry::MaterialYamlEntry(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& modelName,
|
||||
const QString& dir,
|
||||
const QString& modelUuid,
|
||||
@@ -73,7 +78,82 @@ QString MaterialYamlEntry::yamlValue(const YAML::Node& node,
|
||||
return QString::fromStdString(defaultValue);
|
||||
}
|
||||
|
||||
void MaterialYamlEntry::addToTree(std::shared_ptr<std::map<QString, Material*>> materialMap)
|
||||
std::shared_ptr<Material2DArray> MaterialYamlEntry::read2DArray(const YAML::Node& node)
|
||||
{
|
||||
// Base::Console().Log("Read 2D Array\n");
|
||||
|
||||
auto array2d = std::make_shared<Material2DArray>();
|
||||
|
||||
if (node.size() == 2) {
|
||||
// Get the default
|
||||
Base::Quantity defaultValue =
|
||||
Base::Quantity::parse(QString::fromStdString(node[0].as<std::string>()));
|
||||
array2d->setDefault(QVariant::fromValue(defaultValue));
|
||||
|
||||
auto yamlArray = node[1];
|
||||
for (std::size_t i = 0; i < yamlArray.size(); i++) {
|
||||
auto yamlRow = yamlArray[i];
|
||||
|
||||
auto row = std::make_shared<std::vector<QVariant>>();
|
||||
for (std::size_t j = 0; j < yamlRow.size(); j++) {
|
||||
Base::Quantity q =
|
||||
Base::Quantity::parse(QString::fromStdString(yamlRow[j].as<std::string>()));
|
||||
row->push_back(QVariant::fromValue(q));
|
||||
}
|
||||
array2d->addRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
return array2d;
|
||||
}
|
||||
|
||||
std::shared_ptr<Material3DArray> MaterialYamlEntry::read3DArray(const YAML::Node& node)
|
||||
{
|
||||
Base::Console().Log("Read 3D Array\n");
|
||||
|
||||
auto array3d = std::make_shared<Material3DArray>();
|
||||
|
||||
if (node.size() == 2) {
|
||||
// Get the default
|
||||
Base::Quantity defaultValue =
|
||||
Base::Quantity::parse(QString::fromStdString(node[0].as<std::string>()));
|
||||
array3d->setDefault(QVariant::fromValue(defaultValue));
|
||||
|
||||
auto yamlArray = node[1];
|
||||
|
||||
for (std::size_t depth = 0; depth < yamlArray.size(); depth++) {
|
||||
auto yamlDepth = yamlArray[depth];
|
||||
MaterialLoader::showYaml(yamlDepth);
|
||||
for (auto it = yamlDepth.begin(); it != yamlDepth.end(); it++) {
|
||||
MaterialLoader::showYaml(it->first);
|
||||
MaterialLoader::showYaml(it->second);
|
||||
|
||||
Base::Console().Log("Depth %d '%s'\n", depth, it->first.as<std::string>().c_str());
|
||||
auto depthValue =
|
||||
Base::Quantity::parse(QString::fromStdString(it->first.as<std::string>()));
|
||||
|
||||
array3d->addDepth(depth, depthValue);
|
||||
|
||||
auto yamlTable = it->second;
|
||||
for (std::size_t i = 0; i < yamlTable.size(); i++) {
|
||||
auto yamlRow = yamlTable[i];
|
||||
|
||||
auto row = std::make_shared<std::vector<Base::Quantity>>();
|
||||
for (std::size_t j = 0; j < yamlRow.size(); j++) {
|
||||
row->push_back(Base::Quantity::parse(
|
||||
QString::fromStdString(yamlRow[j].as<std::string>())));
|
||||
}
|
||||
array3d->addRow(depth, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array3d;
|
||||
}
|
||||
|
||||
void MaterialYamlEntry::addToTree(
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> materialMap)
|
||||
{
|
||||
std::set<QString> exclude;
|
||||
exclude.insert(QString::fromStdString("General"));
|
||||
@@ -85,11 +165,14 @@ void MaterialYamlEntry::addToTree(std::shared_ptr<std::map<QString, Material*>>
|
||||
auto directory = getDirectory();
|
||||
QString uuid = getUUID();
|
||||
|
||||
QString authorAndLicense = yamlValue(yamlModel["General"], "AuthorAndLicense", "");
|
||||
QString author = yamlValue(yamlModel["General"], "Author", "");
|
||||
QString license = yamlValue(yamlModel["General"], "License", "");
|
||||
QString description = yamlValue(yamlModel["General"], "Description", "");
|
||||
|
||||
Material* finalModel = new Material(library, directory, uuid, name);
|
||||
finalModel->setAuthorAndLicense(authorAndLicense);
|
||||
std::shared_ptr<Material> finalModel =
|
||||
std::make_shared<Material>(library, directory, uuid, name);
|
||||
finalModel->setAuthor(author);
|
||||
finalModel->setLicense(license);
|
||||
finalModel->setDescription(description);
|
||||
|
||||
// Add inheritance list
|
||||
@@ -118,11 +201,34 @@ void MaterialYamlEntry::addToTree(std::shared_ptr<std::map<QString, Material*>>
|
||||
auto properties = yamlModel["Models"][modelName];
|
||||
for (auto itp = properties.begin(); itp != properties.end(); itp++) {
|
||||
std::string propertyName = (itp->first).as<std::string>();
|
||||
std::string propertyValue = (itp->second).as<std::string>();
|
||||
|
||||
if (finalModel->hasPhysicalProperty(QString::fromStdString(propertyName))) {
|
||||
finalModel->setPhysicalValue(QString::fromStdString(propertyName),
|
||||
QString::fromStdString(propertyValue));
|
||||
auto prop =
|
||||
finalModel->getPhysicalProperty(QString::fromStdString(propertyName));
|
||||
auto type = prop->getType();
|
||||
|
||||
try {
|
||||
if (type == MaterialValue::Array2D) {
|
||||
auto array2d = read2DArray(itp->second);
|
||||
finalModel->setPhysicalValue(QString::fromStdString(propertyName),
|
||||
array2d);
|
||||
}
|
||||
else if (type == MaterialValue::Array3D) {
|
||||
auto array3d = read3DArray(itp->second);
|
||||
finalModel->setPhysicalValue(QString::fromStdString(propertyName),
|
||||
array3d);
|
||||
}
|
||||
else {
|
||||
std::string propertyValue = (itp->second).as<std::string>();
|
||||
finalModel->setPhysicalValue(QString::fromStdString(propertyName),
|
||||
QString::fromStdString(propertyValue));
|
||||
}
|
||||
}
|
||||
catch (const YAML::BadConversion& e) {
|
||||
Base::Console().Log("Exception %s <%s:%s> - ignored\n",
|
||||
e.what(),
|
||||
name.toStdString().c_str(),
|
||||
propertyName.c_str());
|
||||
}
|
||||
}
|
||||
else if (propertyName != "UUID") {
|
||||
Base::Console().Log("\tProperty '%s' is not described by any model. Ignored\n",
|
||||
@@ -147,11 +253,32 @@ void MaterialYamlEntry::addToTree(std::shared_ptr<std::map<QString, Material*>>
|
||||
auto properties = yamlModel["AppearanceModels"][modelName];
|
||||
for (auto itp = properties.begin(); itp != properties.end(); itp++) {
|
||||
std::string propertyName = (itp->first).as<std::string>();
|
||||
std::string propertyValue = (itp->second).as<std::string>();
|
||||
|
||||
if (finalModel->hasAppearanceProperty(QString::fromStdString(propertyName))) {
|
||||
finalModel->setAppearanceValue(QString::fromStdString(propertyName),
|
||||
QString::fromStdString(propertyValue));
|
||||
auto prop =
|
||||
finalModel->getAppearanceProperty(QString::fromStdString(propertyName));
|
||||
auto type = prop->getType();
|
||||
|
||||
try {
|
||||
if (type == MaterialValue::Array2D) {
|
||||
auto array2d = read2DArray(itp->second);
|
||||
finalModel->setAppearanceValue(QString::fromStdString(propertyName),
|
||||
array2d);
|
||||
}
|
||||
else if (type == MaterialValue::Array3D) {
|
||||
Base::Console().Log("Read 3D Array\n");
|
||||
}
|
||||
else {
|
||||
std::string propertyValue = (itp->second).as<std::string>();
|
||||
finalModel->setAppearanceValue(QString::fromStdString(propertyName),
|
||||
QString::fromStdString(propertyValue));
|
||||
}
|
||||
}
|
||||
catch (const YAML::BadConversion& e) {
|
||||
Base::Console().Log("Exception %s <%s:%s> - ignored\n",
|
||||
e.what(),
|
||||
name.toStdString().c_str(),
|
||||
propertyName.c_str());
|
||||
}
|
||||
}
|
||||
else if (propertyName != "UUID") {
|
||||
Base::Console().Log("\tProperty '%s' is not described by any model. Ignored\n",
|
||||
@@ -163,13 +290,15 @@ void MaterialYamlEntry::addToTree(std::shared_ptr<std::map<QString, Material*>>
|
||||
|
||||
QString path = QDir(directory).absolutePath();
|
||||
// Base::Console().Log("\tPath '%s'\n", path.toStdString().c_str());
|
||||
(*materialMap)[uuid] = library.addMaterial(*finalModel, path);
|
||||
(*materialMap)[uuid] = library->addMaterial(finalModel, path);
|
||||
}
|
||||
|
||||
std::unique_ptr<std::map<QString, MaterialEntry*>> MaterialLoader::_materialEntryMap = nullptr;
|
||||
std::unique_ptr<std::map<QString, std::shared_ptr<MaterialEntry>>>
|
||||
MaterialLoader::_materialEntryMap = nullptr;
|
||||
|
||||
MaterialLoader::MaterialLoader(std::shared_ptr<std::map<QString, Material*>> materialMap,
|
||||
std::shared_ptr<std::list<MaterialLibrary*>> libraryList)
|
||||
MaterialLoader::MaterialLoader(
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> materialMap,
|
||||
std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> libraryList)
|
||||
: _materialMap(materialMap)
|
||||
, _libraryList(libraryList)
|
||||
{
|
||||
@@ -182,25 +311,58 @@ MaterialLoader::MaterialLoader(std::shared_ptr<std::map<QString, Material*>> mat
|
||||
MaterialLoader::~MaterialLoader()
|
||||
{}
|
||||
|
||||
void MaterialLoader::addLibrary(MaterialLibrary* model)
|
||||
void MaterialLoader::addLibrary(std::shared_ptr<MaterialLibrary> model)
|
||||
{
|
||||
_libraryList->push_back(model);
|
||||
}
|
||||
|
||||
MaterialEntry* MaterialLoader::getMaterialFromPath(MaterialLibrary& library,
|
||||
const QString& path) const
|
||||
std::shared_ptr<MaterialEntry>
|
||||
MaterialLoader::getMaterialFromYAML(std::shared_ptr<MaterialLibrary> library,
|
||||
YAML::Node& yamlroot,
|
||||
const QString& path) const
|
||||
{
|
||||
MaterialEntry* model = nullptr;
|
||||
std::shared_ptr<MaterialEntry> model = nullptr;
|
||||
|
||||
try {
|
||||
const std::string uuid = yamlroot["General"]["UUID"].as<std::string>();
|
||||
|
||||
// Always get the name from the filename
|
||||
// QString name = QString::fromStdString(yamlroot["General"]["Name"].as<std::string>());
|
||||
QFileInfo filepath(path);
|
||||
QString name =
|
||||
filepath.fileName().remove(QString::fromStdString(".FCMat"), Qt::CaseInsensitive);
|
||||
|
||||
model = std::make_shared<MaterialYamlEntry>(library,
|
||||
name,
|
||||
path,
|
||||
QString::fromStdString(uuid),
|
||||
yamlroot);
|
||||
// showYaml(yamlroot);
|
||||
}
|
||||
catch (YAML::Exception const& e) {
|
||||
Base::Console().Error("YAML parsing error: '%s'\n", path.toStdString().c_str());
|
||||
Base::Console().Error("\t'%s'\n", e.what());
|
||||
showYaml(yamlroot);
|
||||
}
|
||||
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
std::shared_ptr<MaterialEntry>
|
||||
MaterialLoader::getMaterialFromPath(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& path) const
|
||||
{
|
||||
std::shared_ptr<MaterialEntry> model = nullptr;
|
||||
|
||||
// Used for debugging
|
||||
std::string uuid;
|
||||
std::string pathName = path.toStdString();
|
||||
|
||||
if (MaterialConfigLoader::isConfigStyle(path)) {
|
||||
Base::Console().Log("Old format .FCMat file: '%s'\n", pathName.c_str());
|
||||
Material* material = MaterialConfigLoader::getMaterialFromPath(library, path);
|
||||
// Base::Console().Log("Old format .FCMat file: '%s'\n", pathName.c_str());
|
||||
auto material = MaterialConfigLoader::getMaterialFromPath(library, path);
|
||||
if (material) {
|
||||
(*_materialMap)[material->getUUID()] = library.addMaterial(*material, path);
|
||||
(*_materialMap)[material->getUUID()] = library->addMaterial(material, path);
|
||||
}
|
||||
|
||||
// Return the nullptr as there are no intermediate steps to take, such
|
||||
@@ -212,15 +374,7 @@ MaterialEntry* MaterialLoader::getMaterialFromPath(MaterialLibrary& library,
|
||||
try {
|
||||
yamlroot = YAML::LoadFile(pathName);
|
||||
|
||||
const std::string uuid = yamlroot["General"]["UUID"].as<std::string>();
|
||||
// Always get the name from the filename
|
||||
// QString name = QString::fromStdString(yamlroot["General"]["Name"].as<std::string>());
|
||||
QFileInfo filepath(path);
|
||||
QString name =
|
||||
filepath.fileName().remove(QString::fromStdString(".FCMat"), Qt::CaseInsensitive);
|
||||
|
||||
model = new MaterialYamlEntry(library, name, path, QString::fromStdString(uuid), yamlroot);
|
||||
// showYaml(yamlroot);
|
||||
model = getMaterialFromYAML(library, yamlroot, path);
|
||||
}
|
||||
catch (YAML::Exception const& e) {
|
||||
Base::Console().Error("YAML parsing error: '%s'\n", pathName.c_str());
|
||||
@@ -242,7 +396,9 @@ void MaterialLoader::showYaml(const YAML::Node& yaml)
|
||||
}
|
||||
|
||||
|
||||
void MaterialLoader::dereference(Material* material)
|
||||
void MaterialLoader::dereference(
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> materialMap,
|
||||
std::shared_ptr<Material> material)
|
||||
{
|
||||
// Avoid recursion
|
||||
if (material->getDereferenced()) {
|
||||
@@ -254,19 +410,20 @@ void MaterialLoader::dereference(Material* material)
|
||||
|
||||
auto parentUUID = material->getParentUUID();
|
||||
if (parentUUID.size() > 0) {
|
||||
Material* parent;
|
||||
std::shared_ptr<Material> parent;
|
||||
try {
|
||||
parent = (*_materialMap)[parentUUID];
|
||||
parent = materialMap->at(parentUUID);
|
||||
}
|
||||
catch (std::out_of_range&) {
|
||||
catch (std::out_of_range& e) {
|
||||
Base::Console().Log(
|
||||
"Unable to apply inheritance for material '%s', parent '%s' not found.\n",
|
||||
material->getName().toStdString().c_str(),
|
||||
parentUUID.toStdString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the parent has been dereferenced
|
||||
dereference(parent);
|
||||
dereference(materialMap, parent);
|
||||
|
||||
// Add physical models
|
||||
auto modelVector = parent->getPhysicalModels();
|
||||
@@ -288,20 +445,20 @@ void MaterialLoader::dereference(Material* material)
|
||||
auto properties = parent->getPhysicalProperties();
|
||||
for (auto itp = properties.begin(); itp != properties.end(); itp++) {
|
||||
auto name = itp->first;
|
||||
auto property = static_cast<const MaterialProperty>(itp->second);
|
||||
auto property = itp->second;
|
||||
|
||||
if (material->getPhysicalProperty(name).isNull()) {
|
||||
material->getPhysicalProperty(name).setValue(property.getValue());
|
||||
if (material->getPhysicalProperty(name)->isNull()) {
|
||||
material->getPhysicalProperty(name)->setValue(property->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
properties = parent->getAppearanceProperties();
|
||||
for (auto itp = properties.begin(); itp != properties.end(); itp++) {
|
||||
auto name = itp->first;
|
||||
auto property = static_cast<const MaterialProperty>(itp->second);
|
||||
auto property = itp->second;
|
||||
|
||||
if (material->getAppearanceProperty(name).isNull()) {
|
||||
material->getAppearanceProperty(name).setValue(property.getValue());
|
||||
if (material->getAppearanceProperty(name)->isNull()) {
|
||||
material->getAppearanceProperty(name)->setValue(property->getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,13 +466,18 @@ void MaterialLoader::dereference(Material* material)
|
||||
material->markDereferenced();
|
||||
}
|
||||
|
||||
void MaterialLoader::loadLibrary(MaterialLibrary& library)
|
||||
void MaterialLoader::dereference(std::shared_ptr<Material> material)
|
||||
{
|
||||
dereference(_materialMap, material);
|
||||
}
|
||||
|
||||
void MaterialLoader::loadLibrary(std::shared_ptr<MaterialLibrary> library)
|
||||
{
|
||||
if (_materialEntryMap == nullptr) {
|
||||
_materialEntryMap = std::make_unique<std::map<QString, MaterialEntry*>>();
|
||||
_materialEntryMap = std::make_unique<std::map<QString, std::shared_ptr<MaterialEntry>>>();
|
||||
}
|
||||
|
||||
QDirIterator it(library.getDirectory(), QDirIterator::Subdirectories);
|
||||
QDirIterator it(library->getDirectory(), QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
auto pathname = it.next();
|
||||
QFileInfo file(pathname);
|
||||
@@ -341,7 +503,7 @@ void MaterialLoader::loadLibraries()
|
||||
auto _libraryList = getMaterialLibraries();
|
||||
if (_libraryList) {
|
||||
for (auto it = _libraryList->begin(); it != _libraryList->end(); it++) {
|
||||
loadLibrary(**it);
|
||||
loadLibrary(*it);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +512,7 @@ void MaterialLoader::loadLibraries()
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<std::list<MaterialLibrary*>> MaterialLoader::getMaterialLibraries()
|
||||
std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> MaterialLoader::getMaterialLibraries()
|
||||
{
|
||||
auto param = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/Resources");
|
||||
@@ -362,10 +524,11 @@ std::shared_ptr<std::list<MaterialLibrary*>> MaterialLoader::getMaterialLibrarie
|
||||
if (useBuiltInMaterials) {
|
||||
QString resourceDir = QString::fromStdString(App::Application::getResourceDir()
|
||||
+ "/Mod/Material/Resources/Materials");
|
||||
auto libData = new MaterialLibrary(QString::fromStdString("System"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/freecad.svg"),
|
||||
true);
|
||||
auto libData =
|
||||
std::make_shared<MaterialLibrary>(QString::fromStdString("System"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/freecad.svg"),
|
||||
true);
|
||||
_libraryList->push_back(libData);
|
||||
}
|
||||
|
||||
@@ -382,10 +545,10 @@ std::shared_ptr<std::list<MaterialLibrary*>> MaterialLoader::getMaterialLibrarie
|
||||
if (materialDir.length() > 0) {
|
||||
QDir dir(materialDir);
|
||||
if (dir.exists()) {
|
||||
auto libData = new MaterialLibrary(moduleName,
|
||||
materialDir,
|
||||
materialIcon,
|
||||
materialReadOnly);
|
||||
auto libData = std::make_shared<MaterialLibrary>(moduleName,
|
||||
materialDir,
|
||||
materialIcon,
|
||||
materialReadOnly);
|
||||
_libraryList->push_back(libData);
|
||||
}
|
||||
}
|
||||
@@ -397,12 +560,19 @@ std::shared_ptr<std::list<MaterialLibrary*>> MaterialLoader::getMaterialLibrarie
|
||||
QString::fromStdString(App::Application::getUserAppDataDir() + "/Material");
|
||||
if (!resourceDir.isEmpty()) {
|
||||
QDir materialDir(resourceDir);
|
||||
if (!materialDir.exists()) {
|
||||
// Try creating the user dir if it doesn't exist
|
||||
if (!materialDir.mkpath(resourceDir)) {
|
||||
Base::Console().Log("Unable to create user library '%s'\n",
|
||||
resourceDir.toStdString().c_str());
|
||||
}
|
||||
}
|
||||
if (materialDir.exists()) {
|
||||
auto libData =
|
||||
new MaterialLibrary(QString::fromStdString("User"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/preferences-general.svg"),
|
||||
false);
|
||||
auto libData = std::make_shared<MaterialLibrary>(
|
||||
QString::fromStdString("User"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/preferences-general.svg"),
|
||||
false);
|
||||
_libraryList->push_back(libData);
|
||||
}
|
||||
}
|
||||
@@ -413,10 +583,11 @@ std::shared_ptr<std::list<MaterialLibrary*>> MaterialLoader::getMaterialLibrarie
|
||||
if (!resourceDir.isEmpty()) {
|
||||
QDir materialDir(resourceDir);
|
||||
if (materialDir.exists()) {
|
||||
auto libData = new MaterialLibrary(QString::fromStdString("Custom"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/user.svg"),
|
||||
false);
|
||||
auto libData =
|
||||
std::make_shared<MaterialLibrary>(QString::fromStdString("Custom"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/user.svg"),
|
||||
false);
|
||||
_libraryList->push_back(libData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#ifndef MATERIAL_MATERIALLOADER_H
|
||||
#define MATERIAL_MATERIALLOADER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
@@ -36,15 +38,16 @@ class MaterialEntry
|
||||
{
|
||||
public:
|
||||
MaterialEntry();
|
||||
explicit MaterialEntry(const MaterialLibrary& library,
|
||||
const QString& modelName,
|
||||
const QString& dir,
|
||||
const QString& modelUuid);
|
||||
MaterialEntry(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& modelName,
|
||||
const QString& dir,
|
||||
const QString& modelUuid);
|
||||
virtual ~MaterialEntry() = default;
|
||||
|
||||
virtual void addToTree(std::shared_ptr<std::map<QString, Material*>> materialMap) = 0;
|
||||
virtual void
|
||||
addToTree(std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> materialMap) = 0;
|
||||
|
||||
const MaterialLibrary& getLibrary() const
|
||||
std::shared_ptr<MaterialLibrary> getLibrary() const
|
||||
{
|
||||
return _library;
|
||||
}
|
||||
@@ -62,7 +65,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
MaterialLibrary _library;
|
||||
std::shared_ptr<MaterialLibrary> _library;
|
||||
QString _name;
|
||||
QString _directory;
|
||||
QString _uuid;
|
||||
@@ -71,14 +74,15 @@ protected:
|
||||
class MaterialYamlEntry: public MaterialEntry
|
||||
{
|
||||
public:
|
||||
explicit MaterialYamlEntry(const MaterialLibrary& library,
|
||||
const QString& modelName,
|
||||
const QString& dir,
|
||||
const QString& modelUuid,
|
||||
const YAML::Node& modelData);
|
||||
MaterialYamlEntry(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& modelName,
|
||||
const QString& dir,
|
||||
const QString& modelUuid,
|
||||
const YAML::Node& modelData);
|
||||
~MaterialYamlEntry() override = default;
|
||||
|
||||
void addToTree(std::shared_ptr<std::map<QString, Material*>> materialMap) override;
|
||||
void
|
||||
addToTree(std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> materialMap) override;
|
||||
|
||||
const YAML::Node& getModel() const
|
||||
{
|
||||
@@ -94,6 +98,8 @@ private:
|
||||
|
||||
QString
|
||||
yamlValue(const YAML::Node& node, const std::string& key, const std::string& defaultValue);
|
||||
std::shared_ptr<Material2DArray> read2DArray(const YAML::Node& node);
|
||||
std::shared_ptr<Material3DArray> read3DArray(const YAML::Node& node);
|
||||
|
||||
YAML::Node _model;
|
||||
};
|
||||
@@ -101,26 +107,34 @@ private:
|
||||
class MaterialLoader
|
||||
{
|
||||
public:
|
||||
explicit MaterialLoader(std::shared_ptr<std::map<QString, Material*>> materialMap,
|
||||
std::shared_ptr<std::list<MaterialLibrary*>> libraryList);
|
||||
MaterialLoader(std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> materialMap,
|
||||
std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> libraryList);
|
||||
virtual ~MaterialLoader();
|
||||
|
||||
std::shared_ptr<std::list<MaterialLibrary*>> getMaterialLibraries();
|
||||
std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> getMaterialLibraries();
|
||||
static std::shared_ptr<std::list<QString>> getMaterialFolders(const MaterialLibrary& library);
|
||||
static void showYaml(const YAML::Node& yaml);
|
||||
static void
|
||||
dereference(std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> materialMap,
|
||||
std::shared_ptr<Material> material);
|
||||
std::shared_ptr<MaterialEntry> getMaterialFromYAML(std::shared_ptr<MaterialLibrary> library,
|
||||
YAML::Node& yamlroot,
|
||||
const QString& path) const;
|
||||
|
||||
private:
|
||||
MaterialLoader();
|
||||
|
||||
void addToTree(MaterialEntry* model);
|
||||
void dereference(Material* material);
|
||||
MaterialEntry* getMaterialFromPath(MaterialLibrary& library, const QString& path) const;
|
||||
void addLibrary(MaterialLibrary* model);
|
||||
void loadLibrary(MaterialLibrary& library);
|
||||
void addToTree(std::shared_ptr<MaterialEntry> model);
|
||||
void dereference(std::shared_ptr<Material> material);
|
||||
std::shared_ptr<MaterialEntry> getMaterialFromPath(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& path) const;
|
||||
void addLibrary(std::shared_ptr<MaterialLibrary> model);
|
||||
void loadLibrary(std::shared_ptr<MaterialLibrary> library);
|
||||
void loadLibraries();
|
||||
static std::unique_ptr<std::map<QString, MaterialEntry*>> _materialEntryMap;
|
||||
std::shared_ptr<std::map<QString, Material*>> _materialMap;
|
||||
std::shared_ptr<std::list<MaterialLibrary*>> _libraryList;
|
||||
|
||||
static std::unique_ptr<std::map<QString, std::shared_ptr<MaterialEntry>>> _materialEntryMap;
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> _materialMap;
|
||||
std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> _libraryList;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include <App/Application.h>
|
||||
@@ -37,8 +38,10 @@ using namespace Materials;
|
||||
|
||||
/* TRANSLATOR Material::Materials */
|
||||
|
||||
std::shared_ptr<std::list<MaterialLibrary*>> MaterialManager::_libraryList = nullptr;
|
||||
std::shared_ptr<std::map<QString, Material*>> MaterialManager::_materialMap = nullptr;
|
||||
std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> MaterialManager::_libraryList =
|
||||
nullptr;
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> MaterialManager::_materialMap =
|
||||
nullptr;
|
||||
QMutex MaterialManager::_mutex;
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::MaterialManager, Base::BaseClass)
|
||||
@@ -60,10 +63,10 @@ void MaterialManager::initLibraries()
|
||||
|
||||
delete manager;
|
||||
|
||||
_materialMap = std::make_shared<std::map<QString, Material*>>();
|
||||
_materialMap = std::make_shared<std::map<QString, std::shared_ptr<Material>>>();
|
||||
|
||||
if (_libraryList == nullptr) {
|
||||
_libraryList = std::make_shared<std::list<MaterialLibrary*>>();
|
||||
_libraryList = std::make_shared<std::list<std::shared_ptr<MaterialLibrary>>>();
|
||||
}
|
||||
|
||||
// Load the libraries
|
||||
@@ -71,23 +74,15 @@ void MaterialManager::initLibraries()
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialManager::saveMaterial(MaterialLibrary* library,
|
||||
Material& material,
|
||||
void MaterialManager::saveMaterial(std::shared_ptr<MaterialLibrary> library,
|
||||
std::shared_ptr<Material> material,
|
||||
const QString& path,
|
||||
bool saveAsCopy)
|
||||
bool overwrite,
|
||||
bool saveAsCopy,
|
||||
bool saveInherited)
|
||||
{
|
||||
Material* newMaterial = library->saveMaterial(material, path, saveAsCopy);
|
||||
|
||||
try {
|
||||
Material* old = _materialMap->at(newMaterial->getUUID());
|
||||
if (old) {
|
||||
delete old;
|
||||
}
|
||||
}
|
||||
catch (const std::out_of_range&) {
|
||||
}
|
||||
|
||||
(*_materialMap)[material.getUUID()] = newMaterial;
|
||||
auto newMaterial = library->saveMaterial(material, path, overwrite, saveAsCopy, saveInherited);
|
||||
(*_materialMap)[newMaterial->getUUID()] = newMaterial;
|
||||
}
|
||||
|
||||
bool MaterialManager::isMaterial(const fs::path& p)
|
||||
@@ -102,31 +97,43 @@ bool MaterialManager::isMaterial(const fs::path& p)
|
||||
return false;
|
||||
}
|
||||
|
||||
const Material& MaterialManager::getMaterial(const QString& uuid) const
|
||||
bool MaterialManager::isMaterial(const QFileInfo& file)
|
||||
{
|
||||
if (!file.isFile()) {
|
||||
return false;
|
||||
}
|
||||
// check file extension
|
||||
if (file.suffix() == QString::fromStdString("FCMat")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<Material> MaterialManager::getMaterial(const QString& uuid) const
|
||||
{
|
||||
try {
|
||||
return *(_materialMap->at(uuid));
|
||||
return _materialMap->at(uuid);
|
||||
}
|
||||
catch (std::out_of_range&) {
|
||||
catch (std::out_of_range& e) {
|
||||
throw MaterialNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
const Material& MaterialManager::getMaterialByPath(const QString& path) const
|
||||
std::shared_ptr<Material> MaterialManager::getMaterialByPath(const QString& path) const
|
||||
{
|
||||
QString cleanPath = QDir::cleanPath(path);
|
||||
|
||||
for (auto library : *_libraryList) {
|
||||
Base::Console().Log("MaterialManager::getMaterialByPath() Checking library '%s'->'%s'\n",
|
||||
library->getName().toStdString().c_str(),
|
||||
library->getDirectory().toStdString().c_str());
|
||||
// Base::Console().Log("MaterialManager::getMaterialByPath() Checking library '%s'->'%s'\n",
|
||||
// library->getName().toStdString().c_str(),
|
||||
// library->getDirectory().toStdString().c_str());
|
||||
|
||||
|
||||
if (cleanPath.startsWith(library->getDirectory())) {
|
||||
Base::Console().Log("MaterialManager::getMaterialByPath() Library '%s'\n",
|
||||
library->getDirectory().toStdString().c_str());
|
||||
Base::Console().Log("MaterialManager::getMaterialByPath() Path '%s'\n",
|
||||
cleanPath.toStdString().c_str());
|
||||
// Base::Console().Log("MaterialManager::getMaterialByPath() Library '%s'\n",
|
||||
// library->getDirectory().toStdString().c_str());
|
||||
// Base::Console().Log("MaterialManager::getMaterialByPath() Path '%s'\n",
|
||||
// cleanPath.toStdString().c_str());
|
||||
return library->getMaterialByPath(cleanPath);
|
||||
}
|
||||
}
|
||||
@@ -136,13 +143,51 @@ const Material& MaterialManager::getMaterialByPath(const QString& path) const
|
||||
throw MaterialNotFound();
|
||||
}
|
||||
|
||||
const Material& MaterialManager::getMaterialByPath(const QString& path, const QString& lib) const
|
||||
std::shared_ptr<Material> MaterialManager::getMaterialByPath(const QString& path,
|
||||
const QString& lib) const
|
||||
{
|
||||
auto library = getLibrary(lib); // May throw LibraryNotFound
|
||||
return library->getMaterialByPath(path); // May throw MaterialNotFound
|
||||
}
|
||||
|
||||
MaterialLibrary* MaterialManager::getLibrary(const QString& name) const
|
||||
bool MaterialManager::exists(const QString& uuid) const
|
||||
{
|
||||
try {
|
||||
auto material = getMaterial(uuid);
|
||||
if (material.get() != nullptr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (const MaterialNotFound&) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<Material> MaterialManager::getParent(std::shared_ptr<Material> material)
|
||||
{
|
||||
if (material->getParentUUID().isEmpty()) {
|
||||
throw MaterialNotFound();
|
||||
}
|
||||
|
||||
return getMaterial(material->getParentUUID());
|
||||
}
|
||||
|
||||
bool MaterialManager::exists(std::shared_ptr<MaterialLibrary> library, const QString& uuid) const
|
||||
{
|
||||
try {
|
||||
auto material = getMaterial(uuid);
|
||||
if (material.get() != nullptr) {
|
||||
return (*material->getLibrary() == *library);
|
||||
}
|
||||
}
|
||||
catch (const MaterialNotFound&) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<MaterialLibrary> MaterialManager::getLibrary(const QString& name) const
|
||||
{
|
||||
for (auto library : *_libraryList) {
|
||||
if (library->getName() == name) {
|
||||
@@ -153,13 +198,13 @@ MaterialLibrary* MaterialManager::getLibrary(const QString& name) const
|
||||
throw LibraryNotFound();
|
||||
}
|
||||
|
||||
std::shared_ptr<std::list<MaterialLibrary*>> MaterialManager::getMaterialLibraries()
|
||||
std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> MaterialManager::getMaterialLibraries()
|
||||
{
|
||||
if (_libraryList == nullptr) {
|
||||
if (_materialMap == nullptr) {
|
||||
_materialMap = std::make_shared<std::map<QString, Material*>>();
|
||||
_materialMap = std::make_shared<std::map<QString, std::shared_ptr<Material>>>();
|
||||
}
|
||||
_libraryList = std::make_shared<std::list<MaterialLibrary*>>();
|
||||
_libraryList = std::make_shared<std::list<std::shared_ptr<MaterialLibrary>>>();
|
||||
|
||||
// Load the libraries
|
||||
MaterialLoader loader(_materialMap, _libraryList);
|
||||
@@ -167,87 +212,21 @@ std::shared_ptr<std::list<MaterialLibrary*>> MaterialManager::getMaterialLibrari
|
||||
return _libraryList;
|
||||
}
|
||||
|
||||
std::shared_ptr<std::map<QString, MaterialTreeNode*>>
|
||||
MaterialManager::getMaterialTree(const MaterialLibrary& library) const
|
||||
{
|
||||
std::shared_ptr<std::map<QString, MaterialTreeNode*>> materialTree =
|
||||
std::make_shared<std::map<QString, MaterialTreeNode*>>();
|
||||
|
||||
for (auto it = _materialMap->begin(); it != _materialMap->end(); it++) {
|
||||
auto filename = it->first;
|
||||
auto material = it->second;
|
||||
|
||||
if (material->getLibrary() == library) {
|
||||
fs::path path = material->getDirectory().toStdString();
|
||||
|
||||
// Start at the root
|
||||
auto node = materialTree;
|
||||
for (auto itp = path.begin(); itp != path.end(); itp++) {
|
||||
if (QString::fromStdString(itp->string())
|
||||
.endsWith(QString::fromStdString(".FCMat"))) {
|
||||
MaterialTreeNode* child = new MaterialTreeNode();
|
||||
child->setData(material);
|
||||
(*node)[QString::fromStdString(itp->string())] = child;
|
||||
}
|
||||
else {
|
||||
// Add the folder only if it's not already there
|
||||
QString folderName = QString::fromStdString(itp->string());
|
||||
std::shared_ptr<std::map<QString, MaterialTreeNode*>> mapPtr;
|
||||
if (node->count(folderName) == 0) {
|
||||
mapPtr = std::make_shared<std::map<QString, MaterialTreeNode*>>();
|
||||
MaterialTreeNode* child = new MaterialTreeNode();
|
||||
child->setFolder(mapPtr);
|
||||
(*node)[folderName] = child;
|
||||
node = mapPtr;
|
||||
}
|
||||
else {
|
||||
node = (*node)[folderName]->getFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto folderList = getMaterialFolders(library);
|
||||
for (auto folder : *folderList) {
|
||||
fs::path path = folder.toStdString();
|
||||
|
||||
// Start at the root
|
||||
auto node = materialTree;
|
||||
for (auto itp = path.begin(); itp != path.end(); itp++) {
|
||||
// Add the folder only if it's not already there
|
||||
QString folderName = QString::fromStdString(itp->string());
|
||||
if (node->count(folderName) == 0) {
|
||||
std::shared_ptr<std::map<QString, MaterialTreeNode*>> mapPtr =
|
||||
std::make_shared<std::map<QString, MaterialTreeNode*>>();
|
||||
MaterialTreeNode* child = new MaterialTreeNode();
|
||||
child->setFolder(mapPtr);
|
||||
(*node)[folderName] = child;
|
||||
node = mapPtr;
|
||||
}
|
||||
else {
|
||||
node = (*node)[folderName]->getFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return materialTree;
|
||||
}
|
||||
|
||||
std::shared_ptr<std::list<QString>>
|
||||
MaterialManager::getMaterialFolders(const MaterialLibrary& library) const
|
||||
MaterialManager::getMaterialFolders(std::shared_ptr<MaterialLibrary> library) const
|
||||
{
|
||||
return MaterialLoader::getMaterialFolders(library);
|
||||
return MaterialLoader::getMaterialFolders(*library);
|
||||
}
|
||||
|
||||
std::shared_ptr<std::map<QString, Material*>> MaterialManager::materialsWithModel(QString uuid)
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>>
|
||||
MaterialManager::materialsWithModel(QString uuid)
|
||||
{
|
||||
std::shared_ptr<std::map<QString, Material*>> dict =
|
||||
std::make_shared<std::map<QString, Material*>>();
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> dict =
|
||||
std::make_shared<std::map<QString, std::shared_ptr<Material>>>();
|
||||
|
||||
for (auto it = _materialMap->begin(); it != _materialMap->end(); it++) {
|
||||
QString key = it->first;
|
||||
Material* material = it->second;
|
||||
auto material = it->second;
|
||||
|
||||
if (material->hasModel(uuid)) {
|
||||
(*dict)[key] = material;
|
||||
@@ -257,15 +236,15 @@ std::shared_ptr<std::map<QString, Material*>> MaterialManager::materialsWithMode
|
||||
return dict;
|
||||
}
|
||||
|
||||
std::shared_ptr<std::map<QString, Material*>>
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>>
|
||||
MaterialManager::materialsWithModelComplete(QString uuid)
|
||||
{
|
||||
std::shared_ptr<std::map<QString, Material*>> dict =
|
||||
std::make_shared<std::map<QString, Material*>>();
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> dict =
|
||||
std::make_shared<std::map<QString, std::shared_ptr<Material>>>();
|
||||
|
||||
for (auto it = _materialMap->begin(); it != _materialMap->end(); it++) {
|
||||
QString key = it->first;
|
||||
Material* material = it->second;
|
||||
auto material = it->second;
|
||||
|
||||
if (material->isModelComplete(uuid)) {
|
||||
(*dict)[key] = material;
|
||||
@@ -274,3 +253,8 @@ MaterialManager::materialsWithModelComplete(QString uuid)
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
void MaterialManager::dereference(std::shared_ptr<Material> material)
|
||||
{
|
||||
MaterialLoader::dereference(_materialMap, material);
|
||||
}
|
||||
|
||||
@@ -22,61 +22,90 @@
|
||||
#ifndef MATERIAL_MATERIALMANAGER_H
|
||||
#define MATERIAL_MATERIALMANAGER_H
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
#include <memory>
|
||||
|
||||
#include <QMutex>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
|
||||
#include "FolderTree.h"
|
||||
#include "Materials.h"
|
||||
|
||||
#include "MaterialLibrary.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
typedef FolderTreeNode<Material> MaterialTreeNode;
|
||||
|
||||
class MaterialsExport MaterialManager: public Base::BaseClass
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
MaterialManager();
|
||||
~MaterialManager() override = default;
|
||||
|
||||
std::shared_ptr<std::map<QString, Material*>> getMaterials()
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> getMaterials()
|
||||
{
|
||||
return _materialMap;
|
||||
}
|
||||
const Material& getMaterial(const QString& uuid) const;
|
||||
const Material& getMaterialByPath(const QString& path) const;
|
||||
const Material& getMaterialByPath(const QString& path, const QString& library) const;
|
||||
MaterialLibrary* getLibrary(const QString& name) const;
|
||||
std::shared_ptr<Material> getMaterial(const QString& uuid) const;
|
||||
std::shared_ptr<Material> getMaterialByPath(const QString& path) const;
|
||||
std::shared_ptr<Material> getMaterialByPath(const QString& path, const QString& library) const;
|
||||
std::shared_ptr<Material> getParent(std::shared_ptr<Material> material);
|
||||
std::shared_ptr<MaterialLibrary> getLibrary(const QString& name) const;
|
||||
bool exists(const QString& uuid) const;
|
||||
bool exists(std::shared_ptr<MaterialLibrary> library, const QString& uuid) const;
|
||||
|
||||
// Library management
|
||||
static std::shared_ptr<std::list<MaterialLibrary*>> getMaterialLibraries();
|
||||
std::shared_ptr<std::map<QString, MaterialTreeNode*>>
|
||||
getMaterialTree(const MaterialLibrary& library) const;
|
||||
std::shared_ptr<std::list<QString>> getMaterialFolders(const MaterialLibrary& library) const;
|
||||
void createPath(MaterialLibrary* library, const QString& path)
|
||||
static std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> getMaterialLibraries();
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
getMaterialTree(std::shared_ptr<MaterialLibrary> library) const
|
||||
{
|
||||
library->createPath(path);
|
||||
return library->getMaterialTree();
|
||||
}
|
||||
void saveMaterial(MaterialLibrary* library,
|
||||
Material& material,
|
||||
std::shared_ptr<std::list<QString>>
|
||||
getMaterialFolders(std::shared_ptr<MaterialLibrary> library) const;
|
||||
void createFolder(std::shared_ptr<MaterialLibrary> library, const QString& path)
|
||||
{
|
||||
library->createFolder(path);
|
||||
}
|
||||
void renameFolder(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& oldPath,
|
||||
const QString& newPath)
|
||||
{
|
||||
library->renameFolder(oldPath, newPath);
|
||||
}
|
||||
void deleteRecursive(std::shared_ptr<MaterialLibrary> library, const QString& path)
|
||||
{
|
||||
library->deleteRecursive(path);
|
||||
}
|
||||
void remove(const QString& uuid)
|
||||
{
|
||||
_materialMap->erase(uuid);
|
||||
}
|
||||
|
||||
void saveMaterial(std::shared_ptr<MaterialLibrary> library,
|
||||
std::shared_ptr<Material> material,
|
||||
const QString& path,
|
||||
bool saveAsCopy = true);
|
||||
bool overwrite,
|
||||
bool saveAsCopy,
|
||||
bool saveInherited);
|
||||
|
||||
static bool isMaterial(const fs::path& p);
|
||||
static bool isMaterial(const QFileInfo& file);
|
||||
|
||||
std::shared_ptr<std::map<QString, Material*>> materialsWithModel(QString uuid);
|
||||
std::shared_ptr<std::map<QString, Material*>> materialsWithModelComplete(QString uuid);
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> materialsWithModel(QString uuid);
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Material>>>
|
||||
materialsWithModelComplete(QString uuid);
|
||||
void dereference(std::shared_ptr<Material> material);
|
||||
|
||||
private:
|
||||
static std::shared_ptr<std::list<MaterialLibrary*>> _libraryList;
|
||||
static std::shared_ptr<std::map<QString, Material*>> _materialMap;
|
||||
static std::shared_ptr<std::list<std::shared_ptr<MaterialLibrary>>> _libraryList;
|
||||
static std::shared_ptr<std::map<QString, std::shared_ptr<Material>>> _materialMap;
|
||||
static QMutex _mutex;
|
||||
|
||||
static void initLibraries();
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#endif
|
||||
|
||||
#include "Exceptions.h"
|
||||
#include "MaterialManager.h"
|
||||
#include "MaterialManagerPy.h"
|
||||
@@ -64,9 +60,8 @@ PyObject* MaterialManagerPy::getMaterial(PyObject* args)
|
||||
}
|
||||
|
||||
try {
|
||||
const Material& material =
|
||||
getMaterialManagerPtr()->getMaterial(QString::fromStdString(uuid));
|
||||
return new MaterialPy(new Material(material));
|
||||
auto material = getMaterialManagerPtr()->getMaterial(QString::fromStdString(uuid));
|
||||
return new MaterialPy(new Material(*material));
|
||||
}
|
||||
catch (const MaterialNotFound&) {
|
||||
PyErr_SetString(PyExc_LookupError, "Material not found");
|
||||
@@ -85,9 +80,9 @@ PyObject* MaterialManagerPy::getMaterialByPath(PyObject* args)
|
||||
QString libPath(QString::fromStdString(lib));
|
||||
if (!libPath.isEmpty()) {
|
||||
try {
|
||||
const Material& material =
|
||||
auto material =
|
||||
getMaterialManagerPtr()->getMaterialByPath(QString::fromStdString(path), libPath);
|
||||
return new MaterialPy(new Material(material));
|
||||
return new MaterialPy(new Material(*material));
|
||||
}
|
||||
catch (const MaterialNotFound&) {
|
||||
PyErr_SetString(PyExc_LookupError, "Material not found");
|
||||
@@ -100,9 +95,8 @@ PyObject* MaterialManagerPy::getMaterialByPath(PyObject* args)
|
||||
}
|
||||
|
||||
try {
|
||||
const Material& material =
|
||||
getMaterialManagerPtr()->getMaterialByPath(QString::fromStdString(path));
|
||||
return new MaterialPy(new Material(material));
|
||||
auto material = getMaterialManagerPtr()->getMaterialByPath(QString::fromStdString(path));
|
||||
return new MaterialPy(new Material(*material));
|
||||
}
|
||||
catch (const MaterialNotFound&) {
|
||||
PyErr_SetString(PyExc_LookupError, "Material not found");
|
||||
@@ -116,7 +110,7 @@ Py::List MaterialManagerPy::getMaterialLibraries() const
|
||||
Py::List list;
|
||||
|
||||
for (auto it = libraries->begin(); it != libraries->end(); it++) {
|
||||
MaterialLibrary* lib = *it;
|
||||
auto lib = *it;
|
||||
Py::Tuple libTuple(3);
|
||||
libTuple.setItem(0, Py::String(lib->getName().toStdString()));
|
||||
libTuple.setItem(1, Py::String(lib->getDirectoryPath().toStdString()));
|
||||
@@ -136,7 +130,7 @@ Py::Dict MaterialManagerPy::getMaterials() const
|
||||
|
||||
for (auto it = materials->begin(); it != materials->end(); it++) {
|
||||
QString key = it->first;
|
||||
Material* material = it->second;
|
||||
auto material = it->second;
|
||||
|
||||
PyObject* materialPy = new MaterialPy(new Material(*material));
|
||||
dict.setItem(Py::String(key.toStdString()), Py::Object(materialPy, true));
|
||||
@@ -168,7 +162,7 @@ PyObject* MaterialManagerPy::materialsWithModel(PyObject* args)
|
||||
|
||||
for (auto it = materials->begin(); it != materials->end(); it++) {
|
||||
QString key = it->first;
|
||||
Material* material = it->second;
|
||||
auto material = it->second;
|
||||
|
||||
PyObject* materialPy = new MaterialPy(new Material(*material));
|
||||
PyDict_SetItem(dict, PyUnicode_FromString(key.toStdString().c_str()), materialPy);
|
||||
@@ -190,7 +184,7 @@ PyObject* MaterialManagerPy::materialsWithModelComplete(PyObject* args)
|
||||
|
||||
for (auto it = materials->begin(); it != materials->end(); it++) {
|
||||
QString key = it->first;
|
||||
Material* material = it->second;
|
||||
auto material = it->second;
|
||||
|
||||
PyObject* materialPy = new MaterialPy(new Material(*material));
|
||||
PyDict_SetItem(dict, PyUnicode_FromString(key.toStdString().c_str()), materialPy);
|
||||
|
||||
@@ -77,10 +77,22 @@
|
||||
</Attribute>
|
||||
<Attribute Name="AuthorAndLicense" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Author and license information.</UserDocu>
|
||||
<UserDocu>deprecated -- Author and license information.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="AuthorAndLicense" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Author" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Author information.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Author" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="License" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>License information.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="License" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="PhysicalModels" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>List of implemented models.</UserDocu>
|
||||
|
||||
@@ -21,20 +21,18 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#endif
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
#include <Base/Quantity.h>
|
||||
#include <Base/QuantityPy.h>
|
||||
#include <Gui/MetaTypes.h>
|
||||
|
||||
#include "Exceptions.h"
|
||||
#include "MaterialPy.h"
|
||||
#include "Materials.h"
|
||||
|
||||
#include "Exceptions.h"
|
||||
#include "MaterialLibrary.h"
|
||||
#include "MaterialPy.h"
|
||||
|
||||
#include "MaterialPy.cpp"
|
||||
|
||||
using namespace Materials;
|
||||
@@ -49,11 +47,11 @@ std::string MaterialPy::representation() const
|
||||
str << "), UUID=(";
|
||||
str << ptr->getUUID().toStdString();
|
||||
str << "), Library Name=(";
|
||||
str << ptr->getLibrary().getName().toStdString();
|
||||
str << ptr->getLibrary()->getName().toStdString();
|
||||
str << "), Library Root=(";
|
||||
str << ptr->getLibrary().getDirectoryPath().toStdString();
|
||||
str << ptr->getLibrary()->getDirectoryPath().toStdString();
|
||||
str << "), Library Icon=(";
|
||||
str << ptr->getLibrary().getIconPath().toStdString();
|
||||
str << ptr->getLibrary()->getIconPath().toStdString();
|
||||
str << "), Directory=(";
|
||||
str << ptr->getDirectory().toStdString();
|
||||
// str << "), URL=(";
|
||||
@@ -93,17 +91,17 @@ int MaterialPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
|
||||
Py::String MaterialPy::getLibraryName() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getLibrary().getName().toStdString());
|
||||
return Py::String(getMaterialPtr()->getLibrary()->getName().toStdString());
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getLibraryRoot() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getLibrary().getDirectoryPath().toStdString());
|
||||
return Py::String(getMaterialPtr()->getLibrary()->getDirectoryPath().toStdString());
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getLibraryIcon() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getLibrary().getIconPath().toStdString());
|
||||
return Py::String(getMaterialPtr()->getLibrary()->getIconPath().toStdString());
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getName() const
|
||||
@@ -146,15 +144,23 @@ Py::String MaterialPy::getAuthorAndLicense() const
|
||||
return Py::String(getMaterialPtr()->getAuthorAndLicense().toStdString());
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getAuthor() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getAuthor().toStdString());
|
||||
}
|
||||
|
||||
Py::String MaterialPy::getLicense() const
|
||||
{
|
||||
return Py::String(getMaterialPtr()->getLicense().toStdString());
|
||||
}
|
||||
|
||||
Py::List MaterialPy::getPhysicalModels() const
|
||||
{
|
||||
const std::vector<QString>* models = getMaterialPtr()->getPhysicalModels();
|
||||
auto models = getMaterialPtr()->getPhysicalModels();
|
||||
Py::List list;
|
||||
|
||||
for (auto it = models->begin(); it != models->end(); it++) {
|
||||
QString uuid = *it;
|
||||
|
||||
list.append(Py::String(uuid.toStdString()));
|
||||
list.append(Py::String(it->toStdString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -162,13 +168,11 @@ Py::List MaterialPy::getPhysicalModels() const
|
||||
|
||||
Py::List MaterialPy::getAppearanceModels() const
|
||||
{
|
||||
const std::vector<QString>* models = getMaterialPtr()->getAppearanceModels();
|
||||
auto models = getMaterialPtr()->getAppearanceModels();
|
||||
Py::List list;
|
||||
|
||||
for (auto it = models->begin(); it != models->end(); it++) {
|
||||
QString uuid = *it;
|
||||
|
||||
list.append(Py::String(uuid.toStdString()));
|
||||
list.append(Py::String(it->toStdString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -176,13 +180,11 @@ Py::List MaterialPy::getAppearanceModels() const
|
||||
|
||||
Py::List MaterialPy::getTags() const
|
||||
{
|
||||
const std::list<QString>& tags = getMaterialPtr()->getTags();
|
||||
auto& tags = getMaterialPtr()->getTags();
|
||||
Py::List list;
|
||||
|
||||
for (auto it = tags.begin(); it != tags.end(); it++) {
|
||||
QString uuid = *it;
|
||||
|
||||
list.append(Py::String(uuid.toStdString()));
|
||||
list.append(Py::String(it->toStdString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -272,6 +274,8 @@ Py::Dict MaterialPy::getProperties() const
|
||||
dict.setItem(Py::String("CardName"), Py::String(getMaterialPtr()->getName().toStdString()));
|
||||
dict.setItem(Py::String("AuthorAndLicense"),
|
||||
Py::String(getMaterialPtr()->getAuthorAndLicense().toStdString()));
|
||||
dict.setItem(Py::String("Author"), Py::String(getMaterialPtr()->getAuthor().toStdString()));
|
||||
dict.setItem(Py::String("License"), Py::String(getMaterialPtr()->getLicense().toStdString()));
|
||||
dict.setItem(Py::String("Name"), Py::String(getMaterialPtr()->getName().toStdString()));
|
||||
dict.setItem(Py::String("Description"),
|
||||
Py::String(getMaterialPtr()->getDescription().toStdString()));
|
||||
@@ -282,10 +286,10 @@ Py::Dict MaterialPy::getProperties() const
|
||||
auto properties = getMaterialPtr()->getPhysicalProperties();
|
||||
for (auto it = properties.begin(); it != properties.end(); it++) {
|
||||
QString key = it->first;
|
||||
MaterialProperty& materialProperty = it->second;
|
||||
auto materialProperty = it->second;
|
||||
|
||||
if (!materialProperty.isNull()) {
|
||||
auto value = materialProperty.getString();
|
||||
if (!materialProperty->isNull()) {
|
||||
auto value = materialProperty->getString();
|
||||
dict.setItem(Py::String(key.toStdString()), Py::String(value.toStdString()));
|
||||
}
|
||||
}
|
||||
@@ -293,10 +297,10 @@ Py::Dict MaterialPy::getProperties() const
|
||||
properties = getMaterialPtr()->getAppearanceProperties();
|
||||
for (auto it = properties.begin(); it != properties.end(); it++) {
|
||||
QString key = it->first;
|
||||
MaterialProperty& materialProperty = it->second;
|
||||
auto materialProperty = it->second;
|
||||
|
||||
if (!materialProperty.isNull()) {
|
||||
auto value = materialProperty.getString();
|
||||
if (!materialProperty->isNull()) {
|
||||
auto value = materialProperty->getString();
|
||||
dict.setItem(Py::String(key.toStdString()), Py::String(value.toStdString()));
|
||||
}
|
||||
}
|
||||
@@ -311,10 +315,10 @@ Py::Dict MaterialPy::getPhysicalProperties() const
|
||||
auto properties = getMaterialPtr()->getPhysicalProperties();
|
||||
for (auto it = properties.begin(); it != properties.end(); it++) {
|
||||
QString key = it->first;
|
||||
MaterialProperty& materialProperty = it->second;
|
||||
auto materialProperty = it->second;
|
||||
|
||||
if (!materialProperty.isNull()) {
|
||||
auto value = materialProperty.getString();
|
||||
if (!materialProperty->isNull()) {
|
||||
auto value = materialProperty->getString();
|
||||
dict.setItem(Py::String(key.toStdString()), Py::String(value.toStdString()));
|
||||
}
|
||||
}
|
||||
@@ -329,10 +333,10 @@ Py::Dict MaterialPy::getAppearanceProperties() const
|
||||
auto properties = getMaterialPtr()->getAppearanceProperties();
|
||||
for (auto it = properties.begin(); it != properties.end(); it++) {
|
||||
QString key = it->first;
|
||||
MaterialProperty& materialProperty = it->second;
|
||||
auto materialProperty = it->second;
|
||||
|
||||
if (!materialProperty.isNull()) {
|
||||
auto value = materialProperty.getString();
|
||||
if (!materialProperty->isNull()) {
|
||||
auto value = materialProperty->getString();
|
||||
dict.setItem(Py::String(key.toStdString()), Py::String(value.toStdString()));
|
||||
}
|
||||
}
|
||||
@@ -346,7 +350,7 @@ static PyObject* _pyObjectFromVariant(const QVariant& value)
|
||||
return new PyObject();
|
||||
}
|
||||
|
||||
if (value.userType() == qMetaTypeId<Base::Quantity>()) {
|
||||
if (value.userType() == QMetaType::type("Base::Quantity")) {
|
||||
return new Base::QuantityPy(new Base::Quantity(value.value<Base::Quantity>()));
|
||||
}
|
||||
else if (value.userType() == QMetaType::Double) {
|
||||
|
||||
@@ -23,7 +23,11 @@
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/Quantity.h>
|
||||
#include <Gui/MetaTypes.h>
|
||||
|
||||
#include "Exceptions.h"
|
||||
#include "MaterialValue.h"
|
||||
@@ -33,29 +37,203 @@ using namespace Materials;
|
||||
|
||||
/* TRANSLATOR Material::MaterialValue */
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::MaterialValue, Base::BaseClass)
|
||||
|
||||
MaterialValue::MaterialValue()
|
||||
: _valueType(None)
|
||||
{
|
||||
this->setInitialValue(None);
|
||||
}
|
||||
|
||||
MaterialValue::MaterialValue(const MaterialValue& other)
|
||||
: _valueType(other._valueType)
|
||||
, _value(other._value)
|
||||
{}
|
||||
|
||||
MaterialValue::MaterialValue(ValueType type)
|
||||
: _valueType(type)
|
||||
{}
|
||||
{
|
||||
this->setInitialValue(None);
|
||||
}
|
||||
|
||||
MaterialValue::MaterialValue(ValueType type, ValueType inherited)
|
||||
: _valueType(type)
|
||||
{
|
||||
this->setInitialValue(inherited);
|
||||
}
|
||||
|
||||
MaterialValue& MaterialValue::operator=(const MaterialValue& other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
_valueType = other._valueType;
|
||||
_value = other._value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool MaterialValue::operator==(const MaterialValue& other) const
|
||||
{
|
||||
if (this == &other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (_valueType == other._valueType) && (_value == other._value);
|
||||
}
|
||||
|
||||
void MaterialValue::setInitialValue(ValueType inherited)
|
||||
{
|
||||
if (_valueType == String) {
|
||||
_value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
|
||||
}
|
||||
else if (_valueType == Boolean) {
|
||||
_value = QVariant(static_cast<QVariant::Type>(QMetaType::Bool));
|
||||
}
|
||||
else if (_valueType == Integer) {
|
||||
_value = QVariant(static_cast<QVariant::Type>(QMetaType::Int));
|
||||
}
|
||||
else if (_valueType == Float) {
|
||||
_value = QVariant(static_cast<QVariant::Type>(QMetaType::Float));
|
||||
}
|
||||
else if (_valueType == URL) {
|
||||
_value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
|
||||
}
|
||||
else if (_valueType == Quantity) {
|
||||
Base::Quantity q;
|
||||
q.setInvalid();
|
||||
_value = QVariant::fromValue(q);
|
||||
}
|
||||
else if (_valueType == Color) {
|
||||
_value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
|
||||
}
|
||||
else if (_valueType == File) {
|
||||
_value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
|
||||
}
|
||||
else if (_valueType == Image) {
|
||||
_value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
|
||||
}
|
||||
else if (_valueType == List) {
|
||||
_value = QVariant(static_cast<QVariant::Type>(QMetaType::QString));
|
||||
}
|
||||
else if (_valueType == Array2D) {
|
||||
if (_valueType != inherited) {
|
||||
throw InvalidMaterialType("Initializing a regular material value as a 2D Array");
|
||||
}
|
||||
|
||||
_value = QVariant(); // Uninitialized default value
|
||||
}
|
||||
else if (_valueType == Array3D) {
|
||||
if (_valueType != inherited) {
|
||||
throw InvalidMaterialType("Initializing a regular material value as a 3D Array");
|
||||
}
|
||||
|
||||
_value = QVariant(); // Uninitialized default value
|
||||
}
|
||||
else {
|
||||
// Default is to set the type to None and leave the variant uninitialized
|
||||
_valueType = None;
|
||||
_value = QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
bool MaterialValue::isNull() const
|
||||
{
|
||||
if (_value.isNull()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_valueType == Quantity) {
|
||||
return !_value.value<Base::Quantity>().isValid();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString MaterialValue::getYAMLString() const
|
||||
{
|
||||
QString yaml = QString::fromStdString("\"");
|
||||
if (!isNull()) {
|
||||
if (getType() == MaterialValue::Quantity) {
|
||||
Base::Quantity quantity = getValue().value<Base::Quantity>();
|
||||
yaml += quantity.getUserString();
|
||||
}
|
||||
else if (getType() == MaterialValue::Float) {
|
||||
auto value = getValue();
|
||||
if (!value.isNull()) {
|
||||
yaml += QString(QString::fromStdString("%1")).arg(value.toFloat(), 0, 'g', 6);
|
||||
}
|
||||
}
|
||||
else {
|
||||
yaml += getValue().toString();
|
||||
}
|
||||
}
|
||||
yaml += QString::fromStdString("\"");
|
||||
return yaml;
|
||||
}
|
||||
|
||||
//===
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::Material2DArray, Materials::MaterialValue)
|
||||
|
||||
Material2DArray::Material2DArray()
|
||||
: MaterialValue(Array2D)
|
||||
: MaterialValue(Array2D, Array2D)
|
||||
, _defaultSet(false)
|
||||
{}
|
||||
|
||||
MaterialValue Material2DArray::getDefault() const
|
||||
{
|
||||
MaterialValue ret(_valueType);
|
||||
ret.setValue(_value);
|
||||
return ret;
|
||||
// Initialize separatelt to prevent recursion
|
||||
// setType(Array2D);
|
||||
}
|
||||
|
||||
const std::vector<QVariant>* Material2DArray::getRow(int row) const
|
||||
Material2DArray::Material2DArray(const Material2DArray& other)
|
||||
: MaterialValue(other)
|
||||
, _defaultSet(other._defaultSet)
|
||||
{
|
||||
deepCopy(other);
|
||||
}
|
||||
|
||||
Material2DArray& Material2DArray::operator=(const Material2DArray& other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialValue::operator=(other);
|
||||
_defaultSet = other._defaultSet;
|
||||
|
||||
deepCopy(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Material2DArray::deepCopy(const Material2DArray& other)
|
||||
{
|
||||
// Deep copy
|
||||
for (auto row : other._rows) {
|
||||
std::vector<QVariant> v;
|
||||
for (auto col : *row) {
|
||||
QVariant newVariant(col);
|
||||
v.push_back(newVariant);
|
||||
}
|
||||
addRow(std::make_shared<std::vector<QVariant>>(v));
|
||||
}
|
||||
}
|
||||
|
||||
bool Material2DArray::isNull() const
|
||||
{
|
||||
return rows() <= 0;
|
||||
}
|
||||
|
||||
const QVariant Material2DArray::getDefault() const
|
||||
{
|
||||
if (_defaultSet) {
|
||||
return _value;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
std::shared_ptr<std::vector<QVariant>> Material2DArray::getRow(int row) const
|
||||
{
|
||||
try {
|
||||
return _rows.at(row);
|
||||
@@ -65,7 +243,7 @@ const std::vector<QVariant>* Material2DArray::getRow(int row) const
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QVariant>* Material2DArray::getRow(int row)
|
||||
std::shared_ptr<std::vector<QVariant>> Material2DArray::getRow(int row)
|
||||
{
|
||||
try {
|
||||
return _rows.at(row);
|
||||
@@ -75,12 +253,12 @@ std::vector<QVariant>* Material2DArray::getRow(int row)
|
||||
}
|
||||
}
|
||||
|
||||
void Material2DArray::addRow(std::vector<QVariant>* row)
|
||||
void Material2DArray::addRow(std::shared_ptr<std::vector<QVariant>> row)
|
||||
{
|
||||
_rows.push_back(row);
|
||||
}
|
||||
|
||||
void Material2DArray::insertRow(int index, std::vector<QVariant>* row)
|
||||
void Material2DArray::insertRow(int index, std::shared_ptr<std::vector<QVariant>> row)
|
||||
{
|
||||
_rows.insert(_rows.begin() + index, row);
|
||||
}
|
||||
@@ -99,7 +277,7 @@ void Material2DArray::setValue(int row, int column, const QVariant& value)
|
||||
throw InvalidIndex();
|
||||
}
|
||||
|
||||
std::vector<QVariant>* val = getRow(row);
|
||||
auto val = getRow(row);
|
||||
try {
|
||||
val->at(column) = value;
|
||||
}
|
||||
@@ -124,10 +302,10 @@ const QVariant Material2DArray::getValue(int row, int column) const
|
||||
}
|
||||
}
|
||||
|
||||
void Material2DArray::dumpRow(const std::vector<QVariant>& row) const
|
||||
void Material2DArray::dumpRow(std::shared_ptr<std::vector<QVariant>> row) const
|
||||
{
|
||||
Base::Console().Log("row: ");
|
||||
for (auto column : row) {
|
||||
for (auto column : *row) {
|
||||
Base::Console().Log("'%s' ", column.toString().toStdString().c_str());
|
||||
}
|
||||
Base::Console().Log("\n");
|
||||
@@ -136,107 +314,389 @@ void Material2DArray::dumpRow(const std::vector<QVariant>& row) const
|
||||
void Material2DArray::dump() const
|
||||
{
|
||||
for (auto row : _rows) {
|
||||
dumpRow(*row);
|
||||
dumpRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
const QString Material2DArray::getYAMLString() const
|
||||
{
|
||||
if (isNull()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Set the correct indentation. 9 chars in this case
|
||||
QString pad;
|
||||
pad.fill(QChar::fromLatin1(' '), 9);
|
||||
|
||||
// Save the default value
|
||||
QString yaml = QString::fromStdString("\n - \"");
|
||||
Base::Quantity quantity = getDefault().value<Base::Quantity>();
|
||||
yaml += quantity.getUserString();
|
||||
yaml += QString::fromStdString("\"\n");
|
||||
|
||||
// Next the array contents
|
||||
yaml += QString::fromStdString(" - [");
|
||||
bool firstRow = true;
|
||||
for (auto row : _rows) {
|
||||
if (!firstRow) {
|
||||
// Each row is on its own line, padded for correct indentation
|
||||
yaml += QString::fromStdString(",\n") + pad;
|
||||
}
|
||||
else {
|
||||
firstRow = false;
|
||||
}
|
||||
yaml += QString::fromStdString("[");
|
||||
|
||||
bool first = true;
|
||||
for (auto column : *row) {
|
||||
if (!first) {
|
||||
// TODO: Fix for arrays with too many columns to fit on a single line
|
||||
yaml += QString::fromStdString(", ");
|
||||
}
|
||||
else {
|
||||
first = false;
|
||||
}
|
||||
yaml += QString::fromStdString("\"");
|
||||
Base::Quantity quantity = column.value<Base::Quantity>();
|
||||
yaml += quantity.getUserString();
|
||||
yaml += QString::fromStdString("\"");
|
||||
}
|
||||
|
||||
yaml += QString::fromStdString("]");
|
||||
}
|
||||
yaml += QString::fromStdString("]");
|
||||
return yaml;
|
||||
}
|
||||
|
||||
//===
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::Material3DArray, Materials::MaterialValue)
|
||||
|
||||
Material3DArray::Material3DArray()
|
||||
: MaterialValue(Array3D)
|
||||
: MaterialValue(Array3D, Array3D)
|
||||
, _defaultSet(false)
|
||||
{}
|
||||
|
||||
MaterialValue Material3DArray::getDefault() const
|
||||
, _currentDepth(0)
|
||||
{
|
||||
MaterialValue ret(_valueType);
|
||||
ret.setValue(_value);
|
||||
return ret;
|
||||
// Initialize separatelt to prevent recursion
|
||||
// setType(Array3D);
|
||||
}
|
||||
|
||||
const std::vector<std::vector<QVariant>*>& Material3DArray::getTable(const QVariant& depth) const
|
||||
bool Material3DArray::isNull() const
|
||||
{
|
||||
return depth() <= 0;
|
||||
}
|
||||
|
||||
const QVariant Material3DArray::getDefault() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
const std::shared_ptr<std::vector<std::shared_ptr<std::vector<Base::Quantity>>>>&
|
||||
Material3DArray::getTable(const Base::Quantity& depth) const
|
||||
{
|
||||
for (auto it = _rowMap.begin(); it != _rowMap.end(); it++) {
|
||||
if (std::get<0>(*it) == depth) {
|
||||
return std::get<1>(*it);
|
||||
}
|
||||
}
|
||||
|
||||
throw InvalidDepth();
|
||||
}
|
||||
|
||||
const std::shared_ptr<std::vector<std::shared_ptr<std::vector<Base::Quantity>>>>&
|
||||
Material3DArray::getTable(int depthIndex) const
|
||||
{
|
||||
try {
|
||||
return _rowMap.at(depth);
|
||||
return std::get<1>(_rowMap.at(depthIndex));
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw InvalidDepth();
|
||||
}
|
||||
}
|
||||
|
||||
const std::shared_ptr<std::vector<Base::Quantity>> Material3DArray::getRow(int depth, int row) const
|
||||
{
|
||||
try {
|
||||
return getTable(depth)->at(row);
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw InvalidRow();
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<QVariant>& Material3DArray::getRow(const QVariant& depth, int row) const
|
||||
std::shared_ptr<std::vector<Base::Quantity>> Material3DArray::getRow(int row) const
|
||||
{
|
||||
// Check if we can convert otherwise throw error
|
||||
return getRow(_currentDepth, row);
|
||||
}
|
||||
|
||||
std::shared_ptr<std::vector<Base::Quantity>> Material3DArray::getRow(int depth, int row)
|
||||
{
|
||||
try {
|
||||
return *(_rowMap.at(depth).at(row));
|
||||
return getTable(depth)->at(row);
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw InvalidRow();
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<QVariant>& Material3DArray::getRow(int row) const
|
||||
std::shared_ptr<std::vector<Base::Quantity>> Material3DArray::getRow(int row)
|
||||
{
|
||||
return getRow(getDefault().getValue().toString(), row);
|
||||
return getRow(_currentDepth, row);
|
||||
}
|
||||
|
||||
std::vector<QVariant>& Material3DArray::getRow(const QVariant& depth, int row)
|
||||
void Material3DArray::addRow(int depth, std::shared_ptr<std::vector<Base::Quantity>> row)
|
||||
{
|
||||
try {
|
||||
return *(_rowMap.at(depth).at(row));
|
||||
getTable(depth)->push_back(row);
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw InvalidRow();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QVariant>& Material3DArray::getRow(int row)
|
||||
void Material3DArray::addRow(std::shared_ptr<std::vector<Base::Quantity>> row)
|
||||
{
|
||||
return getRow(getDefault().getValue().toString(), row);
|
||||
addRow(_currentDepth, row);
|
||||
}
|
||||
|
||||
void Material3DArray::addRow(const QVariant& depth, std::vector<QVariant>* row)
|
||||
int Material3DArray::addDepth(int depth, Base::Quantity value)
|
||||
{
|
||||
_rowMap[depth].push_back(row);
|
||||
if (depth == this->depth()) {
|
||||
// Append to the end
|
||||
return addDepth(value);
|
||||
}
|
||||
else if (depth > this->depth()) {
|
||||
throw InvalidDepth();
|
||||
}
|
||||
auto rowVector = std::make_shared<std::vector<std::shared_ptr<std::vector<Base::Quantity>>>>();
|
||||
auto entry = std::make_pair(value, rowVector);
|
||||
_rowMap.insert(_rowMap.begin() + depth, entry);
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
void Material3DArray::deleteRow(const QVariant& depth, int row)
|
||||
int Material3DArray::addDepth(Base::Quantity value)
|
||||
{
|
||||
Q_UNUSED(depth)
|
||||
Q_UNUSED(row)
|
||||
auto rowVector = std::make_shared<std::vector<std::shared_ptr<std::vector<Base::Quantity>>>>();
|
||||
auto entry = std::make_pair(value, rowVector);
|
||||
_rowMap.push_back(entry);
|
||||
|
||||
return depth() - 1;
|
||||
}
|
||||
|
||||
void Material3DArray::deleteDepth(int depth)
|
||||
{
|
||||
deleteRows(depth); // This may throw an InvalidDepth
|
||||
_rowMap.erase(_rowMap.begin() + depth);
|
||||
}
|
||||
|
||||
void Material3DArray::insertRow(int depth,
|
||||
int row,
|
||||
std::shared_ptr<std::vector<Base::Quantity>> rowData)
|
||||
{
|
||||
try {
|
||||
auto table = getTable(depth);
|
||||
// auto it = table->begin();
|
||||
// std::advance(it, row);
|
||||
table->insert(table->begin() + row, rowData);
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw InvalidRow();
|
||||
}
|
||||
}
|
||||
|
||||
void Material3DArray::insertRow(int row, std::shared_ptr<std::vector<Base::Quantity>> rowData)
|
||||
{
|
||||
insertRow(_currentDepth, row, rowData);
|
||||
}
|
||||
|
||||
void Material3DArray::deleteRow(int depth, int row)
|
||||
{
|
||||
auto table = getTable(depth);
|
||||
if (static_cast<std::size_t>(row) >= table->size() || row < 0) {
|
||||
throw InvalidRow();
|
||||
}
|
||||
table->erase(table->begin() + row);
|
||||
}
|
||||
|
||||
void Material3DArray::deleteRow(int row)
|
||||
{
|
||||
deleteRow(_currentDepth, row);
|
||||
}
|
||||
|
||||
void Material3DArray::deleteRows(int depth)
|
||||
{
|
||||
Q_UNUSED(depth)
|
||||
auto table = getTable(depth);
|
||||
table->clear();
|
||||
}
|
||||
|
||||
void Material3DArray::setValue(const QVariant& depth, int row, int column, const QVariant& value)
|
||||
void Material3DArray::deleteRows()
|
||||
{
|
||||
Q_UNUSED(depth)
|
||||
Q_UNUSED(row)
|
||||
Q_UNUSED(column)
|
||||
Q_UNUSED(value)
|
||||
deleteRows(_currentDepth);
|
||||
}
|
||||
|
||||
void Material3DArray::setValue(int row, int column, const QVariant& value)
|
||||
int Material3DArray::rows(int depth) const
|
||||
{
|
||||
Q_UNUSED(row)
|
||||
Q_UNUSED(column)
|
||||
Q_UNUSED(value)
|
||||
if (depth < 0 || (depth == 0 && this->depth() == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return getTable(depth)->size();
|
||||
}
|
||||
|
||||
const QVariant Material3DArray::getValue(const QVariant& depth, int row, int column)
|
||||
int Material3DArray::columns(int depth) const
|
||||
{
|
||||
if (depth < 0 || (depth == 0 && this->depth() == 0)) {
|
||||
return 0;
|
||||
}
|
||||
if (rows() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return getTable(depth)->at(0)->size();
|
||||
}
|
||||
|
||||
void Material3DArray::setValue(int depth, int row, int column, const Base::Quantity& value)
|
||||
{
|
||||
auto val = getRow(depth, row);
|
||||
try {
|
||||
return val.at(column);
|
||||
val->at(column) = value;
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw InvalidColumn();
|
||||
}
|
||||
}
|
||||
|
||||
const QVariant Material3DArray::getValue(int row, int column)
|
||||
void Material3DArray::setValue(int row, int column, const Base::Quantity& value)
|
||||
{
|
||||
return getValue(getDefault().getValue().toString(), row, column);
|
||||
setValue(_currentDepth, row, column, value);
|
||||
}
|
||||
|
||||
void Material3DArray::setDepthValue(int depth, const Base::Quantity& value)
|
||||
{
|
||||
try {
|
||||
auto oldRows = getTable(depth);
|
||||
_rowMap.at(depth) = std::pair(value, oldRows);
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw InvalidRow();
|
||||
}
|
||||
}
|
||||
|
||||
void Material3DArray::setDepthValue(const Base::Quantity& value)
|
||||
{
|
||||
setDepthValue(_currentDepth, value);
|
||||
}
|
||||
|
||||
|
||||
const Base::Quantity Material3DArray::getValue(int depth, int row, int column) const
|
||||
{
|
||||
auto val = getRow(depth, row);
|
||||
try {
|
||||
return val->at(column);
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw InvalidColumn();
|
||||
}
|
||||
}
|
||||
|
||||
const Base::Quantity Material3DArray::getValue(int row, int column) const
|
||||
{
|
||||
return getValue(_currentDepth, row, column);
|
||||
}
|
||||
|
||||
const Base::Quantity Material3DArray::getDepthValue(int depth) const
|
||||
{
|
||||
try {
|
||||
return std::get<0>(_rowMap.at(depth));
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw InvalidRow();
|
||||
}
|
||||
}
|
||||
|
||||
int Material3DArray::currentDepth() const
|
||||
{
|
||||
return _currentDepth;
|
||||
}
|
||||
|
||||
void Material3DArray::setCurrentDepth(int depth)
|
||||
{
|
||||
if (depth < 0 || _rowMap.size() == 0) {
|
||||
_currentDepth = 0;
|
||||
}
|
||||
else if (static_cast<std::size_t>(depth) >= _rowMap.size()) {
|
||||
_currentDepth = _rowMap.size() - 1;
|
||||
}
|
||||
else {
|
||||
_currentDepth = depth;
|
||||
}
|
||||
}
|
||||
|
||||
const QString Material3DArray::getYAMLString() const
|
||||
{
|
||||
if (isNull()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Set the correct indentation. 7 chars + name length
|
||||
QString pad;
|
||||
pad.fill(QChar::fromLatin1(' '), 9);
|
||||
|
||||
// Save the default value
|
||||
QString yaml = QString::fromStdString("\n - \"");
|
||||
Base::Quantity quantity = getDefault().value<Base::Quantity>();
|
||||
yaml += quantity.getUserString();
|
||||
yaml += QString::fromStdString("\"\n");
|
||||
|
||||
// Next the array contents
|
||||
yaml += QString::fromStdString(" - [");
|
||||
for (int depth = 0; depth < this->depth(); depth++) {
|
||||
if (depth > 0) {
|
||||
// Each row is on its own line, padded for correct indentation
|
||||
yaml += QString::fromStdString(",\n") + pad;
|
||||
}
|
||||
|
||||
yaml += QString::fromStdString("\"");
|
||||
auto value = getDepthValue(depth).getUserString();
|
||||
yaml += value;
|
||||
yaml += QString::fromStdString("\": [");
|
||||
|
||||
QString pad2;
|
||||
pad2.fill(QChar::fromLatin1(' '), 14 + value.length());
|
||||
|
||||
bool firstRow = true;
|
||||
auto rows = getTable(depth);
|
||||
for (auto row : *rows) {
|
||||
if (!firstRow) {
|
||||
// Each row is on its own line, padded for correct indentation
|
||||
yaml += QString::fromStdString(",\n") + pad2;
|
||||
}
|
||||
else {
|
||||
firstRow = false;
|
||||
}
|
||||
yaml += QString::fromStdString("[");
|
||||
|
||||
bool first = true;
|
||||
for (auto column : *row) {
|
||||
if (!first) {
|
||||
// TODO: Fix for arrays with too many columns to fit on a single line
|
||||
yaml += QString::fromStdString(", ");
|
||||
}
|
||||
else {
|
||||
first = false;
|
||||
}
|
||||
yaml += QString::fromStdString("\"");
|
||||
// Base::Quantity quantity = column.value<Base::Quantity>();
|
||||
yaml += column.getUserString();
|
||||
yaml += QString::fromStdString("\"");
|
||||
}
|
||||
|
||||
yaml += QString::fromStdString("]");
|
||||
}
|
||||
yaml += QString::fromStdString("]");
|
||||
}
|
||||
yaml += QString::fromStdString("]");
|
||||
return yaml;
|
||||
}
|
||||
|
||||
@@ -22,15 +22,22 @@
|
||||
#ifndef MATERIAL_MATERIALVALUE_H
|
||||
#define MATERIAL_MATERIALVALUE_H
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
#include <memory>
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QVariant>
|
||||
|
||||
#include <Gui/MetaTypes.h>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
class MaterialsExport MaterialValue
|
||||
class MaterialsExport MaterialValue: public Base::BaseClass
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
enum ValueType
|
||||
{
|
||||
@@ -50,9 +57,17 @@ public:
|
||||
URL = 13
|
||||
};
|
||||
MaterialValue();
|
||||
explicit MaterialValue(ValueType type);
|
||||
MaterialValue(const MaterialValue& other);
|
||||
MaterialValue(ValueType type);
|
||||
virtual ~MaterialValue() = default;
|
||||
|
||||
MaterialValue& operator=(const MaterialValue& other);
|
||||
virtual bool operator==(const MaterialValue& other) const;
|
||||
bool operator!=(const MaterialValue& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
ValueType getType() const
|
||||
{
|
||||
return _valueType;
|
||||
@@ -62,10 +77,8 @@ public:
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
bool isNull() const
|
||||
{
|
||||
return _value.isNull();
|
||||
}
|
||||
virtual bool isNull() const;
|
||||
|
||||
virtual const QVariant getValueAt(const QVariant& value) const
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
@@ -76,126 +89,182 @@ public:
|
||||
_value = value;
|
||||
}
|
||||
|
||||
virtual const QString getYAMLString() const;
|
||||
|
||||
protected:
|
||||
ValueType _valueType;
|
||||
QVariant _value;
|
||||
MaterialValue(ValueType type, ValueType inherited);
|
||||
|
||||
void setType(ValueType type)
|
||||
{
|
||||
_valueType = type;
|
||||
}
|
||||
void setInitialValue(ValueType inherited);
|
||||
|
||||
ValueType _valueType;
|
||||
QVariant _value;
|
||||
};
|
||||
|
||||
class MaterialsExport Material2DArray: public MaterialValue
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
Material2DArray();
|
||||
Material2DArray(const Material2DArray& other);
|
||||
~Material2DArray() override = default;
|
||||
|
||||
void setDefault(MaterialValue value)
|
||||
Material2DArray& operator=(const Material2DArray& other);
|
||||
|
||||
bool isNull() const override;
|
||||
|
||||
void setDefault(MaterialValue value, bool markSet = true)
|
||||
{
|
||||
_value = value.getValue();
|
||||
_defaultSet = true;
|
||||
_defaultSet = markSet;
|
||||
}
|
||||
void setDefault(const QVariant& value)
|
||||
void setDefault(const QVariant& value, bool markSet = true)
|
||||
{
|
||||
_value = value;
|
||||
_defaultSet = true;
|
||||
_defaultSet = markSet;
|
||||
}
|
||||
MaterialValue getDefault() const;
|
||||
void setDefault(const Base::Quantity& value, bool markSet = true)
|
||||
{
|
||||
_value = QVariant::fromValue(value);
|
||||
_defaultSet = markSet;
|
||||
}
|
||||
const QVariant getDefault() const;
|
||||
bool defaultSet() const
|
||||
{
|
||||
return _defaultSet;
|
||||
}
|
||||
|
||||
const std::vector<QVariant>* getRow(int row) const;
|
||||
std::vector<QVariant>* getRow(int row);
|
||||
std::shared_ptr<std::vector<QVariant>> getRow(int row) const;
|
||||
std::shared_ptr<std::vector<QVariant>> getRow(int row);
|
||||
int rows() const
|
||||
{
|
||||
return _rows.size();
|
||||
}
|
||||
void addRow(std::vector<QVariant>* row);
|
||||
void insertRow(int index, std::vector<QVariant>* row);
|
||||
int columns() const
|
||||
{
|
||||
if (rows() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _rows.at(0)->size();
|
||||
}
|
||||
void addRow(std::shared_ptr<std::vector<QVariant>> row);
|
||||
void insertRow(int index, std::shared_ptr<std::vector<QVariant>> row);
|
||||
void deleteRow(int row);
|
||||
|
||||
void setValue(int row, int column, const QVariant& value);
|
||||
const QVariant getValue(int row, int column) const;
|
||||
|
||||
const QString getYAMLString() const override;
|
||||
|
||||
protected:
|
||||
std::vector<std::vector<QVariant>*> _rows;
|
||||
void deepCopy(const Material2DArray& other);
|
||||
|
||||
std::vector<std::shared_ptr<std::vector<QVariant>>> _rows;
|
||||
bool _defaultSet;
|
||||
|
||||
private:
|
||||
void dumpRow(const std::vector<QVariant>& row) const;
|
||||
void dumpRow(std::shared_ptr<std::vector<QVariant>> row) const;
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
class MaterialsExport Material3DArray: public MaterialValue
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
Material3DArray();
|
||||
~Material3DArray() override = default;
|
||||
|
||||
void setDefault(MaterialValue value)
|
||||
bool isNull() const override;
|
||||
|
||||
void setDefault(MaterialValue value, bool markSet = true)
|
||||
{
|
||||
_value = value.getValue();
|
||||
_defaultSet = true;
|
||||
_defaultSet = markSet;
|
||||
}
|
||||
void setDefault(const QVariant& value)
|
||||
void setDefault(const QVariant& value, bool markSet = true)
|
||||
{
|
||||
_value = value;
|
||||
_defaultSet = true;
|
||||
_defaultSet = markSet;
|
||||
}
|
||||
MaterialValue getDefault() const;
|
||||
void setDefault(const Base::Quantity& value, bool markSet = true)
|
||||
{
|
||||
_value = QVariant::fromValue(value);
|
||||
_defaultSet = markSet;
|
||||
}
|
||||
const QVariant getDefault() const;
|
||||
bool defaultSet() const
|
||||
{
|
||||
return _defaultSet;
|
||||
}
|
||||
|
||||
const std::vector<std::vector<QVariant>*>& getTable(const QVariant& depth) const;
|
||||
const std::vector<QVariant>& getRow(const QVariant& depth, int row) const;
|
||||
const std::vector<QVariant>& getRow(int row) const;
|
||||
std::vector<QVariant>& getRow(const QVariant& depth, int row);
|
||||
std::vector<QVariant>& getRow(int row);
|
||||
void addRow(const QVariant& depth, std::vector<QVariant>* row);
|
||||
void deleteRow(const QVariant& depth, int row);
|
||||
const std::shared_ptr<std::vector<std::shared_ptr<std::vector<Base::Quantity>>>>&
|
||||
getTable(const Base::Quantity& depth) const;
|
||||
const std::shared_ptr<std::vector<std::shared_ptr<std::vector<Base::Quantity>>>>&
|
||||
getTable(int depthIndex) const;
|
||||
const std::shared_ptr<std::vector<Base::Quantity>> getRow(int depth, int row) const;
|
||||
std::shared_ptr<std::vector<Base::Quantity>> getRow(int row) const;
|
||||
std::shared_ptr<std::vector<Base::Quantity>> getRow(int depth, int row);
|
||||
std::shared_ptr<std::vector<Base::Quantity>> getRow(int row);
|
||||
void addRow(int depth, std::shared_ptr<std::vector<Base::Quantity>> row);
|
||||
void addRow(std::shared_ptr<std::vector<Base::Quantity>> row);
|
||||
int addDepth(int depth, Base::Quantity value);
|
||||
int addDepth(Base::Quantity value);
|
||||
void deleteDepth(int depth);
|
||||
void insertRow(int depth, int row, std::shared_ptr<std::vector<Base::Quantity>> rowData);
|
||||
void insertRow(int row, std::shared_ptr<std::vector<Base::Quantity>> rowData);
|
||||
void deleteRow(int depth, int row);
|
||||
void deleteRow(int row);
|
||||
void deleteRows(int depth);
|
||||
void deleteRows();
|
||||
int depth() const
|
||||
{
|
||||
return _rowMap.size();
|
||||
}
|
||||
int rows(const QVariant& depth) const
|
||||
int rows(int depth) const;
|
||||
int rows() const
|
||||
{
|
||||
return getTable(depth).size();
|
||||
return rows(_currentDepth);
|
||||
}
|
||||
int columns(int depth) const;
|
||||
int columns() const
|
||||
{
|
||||
return columns(_currentDepth);
|
||||
}
|
||||
|
||||
void setValue(const QVariant& depth, int row, int column, const QVariant& value);
|
||||
void setValue(int row, int column, const QVariant& value);
|
||||
const QVariant getValue(const QVariant& depth, int row, int column);
|
||||
const QVariant getValue(int row, int column);
|
||||
void setValue(int depth, int row, int column, const Base::Quantity& value);
|
||||
void setValue(int row, int column, const Base::Quantity& value);
|
||||
void setDepthValue(int depth, const Base::Quantity& value);
|
||||
void setDepthValue(const Base::Quantity& value);
|
||||
const Base::Quantity getValue(int depth, int row, int column) const;
|
||||
const Base::Quantity getValue(int row, int column) const;
|
||||
const Base::Quantity getDepthValue(int depth) const;
|
||||
|
||||
int currentDepth() const;
|
||||
void setCurrentDepth(int depth);
|
||||
|
||||
const QString getYAMLString() const override;
|
||||
|
||||
protected:
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
std::map<QVariant, std::vector<std::vector<QVariant>*>> _rowMap;
|
||||
#else
|
||||
struct variant_comp
|
||||
{
|
||||
bool operator()(const QVariant& var1,
|
||||
const QVariant& var2) const
|
||||
{
|
||||
return QVariant::compare(var1, var2) == QPartialOrdering::Less;
|
||||
}
|
||||
};
|
||||
std::map<QVariant, std::vector<std::vector<QVariant>*>, variant_comp> _rowMap;
|
||||
#endif
|
||||
|
||||
std::vector<
|
||||
std::pair<Base::Quantity,
|
||||
std::shared_ptr<std::vector<std::shared_ptr<std::vector<Base::Quantity>>>>>>
|
||||
_rowMap;
|
||||
bool _defaultSet;
|
||||
int _currentDepth;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
Q_DECLARE_METATYPE(Materials::MaterialValue)
|
||||
Q_DECLARE_METATYPE(Materials::Material2DArray)
|
||||
Q_DECLARE_METATYPE(Materials::Material3DArray)
|
||||
// Q_DECLARE_METATYPE(Materials::Material2DArray)
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<Materials::Material2DArray>)
|
||||
// Q_DECLARE_METATYPE(Materials::Material3DArray)
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<Materials::Material3DArray>)
|
||||
|
||||
#endif // MATERIAL_MATERIALVALUE_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,31 +22,34 @@
|
||||
#ifndef MATERIAL_MATERIALS_H
|
||||
#define MATERIAL_MATERIALS_H
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
#include <memory>
|
||||
|
||||
#include <Base/BaseClass.h>
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/BaseClass.h>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
|
||||
#include "MaterialLibrary.h"
|
||||
#include "Model.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
class MaterialLibrary;
|
||||
|
||||
class MaterialsExport MaterialProperty: public ModelProperty
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
MaterialProperty();
|
||||
explicit MaterialProperty(const ModelProperty& property);
|
||||
explicit MaterialProperty(const MaterialProperty& property);
|
||||
MaterialProperty(const ModelProperty& property);
|
||||
MaterialProperty(const MaterialProperty& property);
|
||||
MaterialProperty(std::shared_ptr<MaterialProperty> property);
|
||||
~MaterialProperty() override = default;
|
||||
|
||||
MaterialValue::ValueType getType() const
|
||||
@@ -63,6 +66,7 @@ public:
|
||||
std::shared_ptr<MaterialValue> getMaterialValue();
|
||||
const std::shared_ptr<MaterialValue> getMaterialValue() const;
|
||||
const QString getString() const;
|
||||
const QString getYAMLString() const;
|
||||
bool getBoolean() const;
|
||||
int getInt() const;
|
||||
double getFloat() const;
|
||||
@@ -79,6 +83,7 @@ public:
|
||||
void setPropertyType(const QString& type) override;
|
||||
void setValue(const QVariant& value);
|
||||
void setValue(const QString& value);
|
||||
void setValue(std::shared_ptr<MaterialValue> value);
|
||||
void setString(const QString& value);
|
||||
void setBoolean(bool value);
|
||||
void setBoolean(int value);
|
||||
@@ -93,10 +98,23 @@ public:
|
||||
void setURL(const QString& value);
|
||||
|
||||
MaterialProperty& operator=(const MaterialProperty& other);
|
||||
friend QTextStream& operator<<(QTextStream& output, const MaterialProperty& property)
|
||||
{
|
||||
output << property.getName() << ": " << property.getYAMLString();
|
||||
return output;
|
||||
}
|
||||
bool operator==(const MaterialProperty& other) const;
|
||||
bool operator!=(const MaterialProperty& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// void save(QTextStream& stream);
|
||||
|
||||
protected:
|
||||
void setType(const QString& type);
|
||||
// void setType(MaterialValue::ValueType type) { _valueType = type; }
|
||||
void copyValuePtr(std::shared_ptr<MaterialValue> value);
|
||||
|
||||
void addColumn(MaterialProperty& column)
|
||||
{
|
||||
@@ -122,14 +140,14 @@ public:
|
||||
};
|
||||
|
||||
Material();
|
||||
explicit Material(const MaterialLibrary& library,
|
||||
const QString& directory,
|
||||
const QString& uuid,
|
||||
const QString& name);
|
||||
explicit Material(const Material& other);
|
||||
virtual ~Material();
|
||||
Material(std::shared_ptr<MaterialLibrary> library,
|
||||
const QString& directory,
|
||||
const QString& uuid,
|
||||
const QString& name);
|
||||
Material(const Material& other);
|
||||
~Material() override = default;
|
||||
|
||||
const MaterialLibrary& getLibrary() const
|
||||
std::shared_ptr<MaterialLibrary> getLibrary() const
|
||||
{
|
||||
return _library;
|
||||
}
|
||||
@@ -145,9 +163,14 @@ public:
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
const QString getAuthorAndLicense() const
|
||||
const QString getAuthorAndLicense() const;
|
||||
const QString getAuthor() const
|
||||
{
|
||||
return _authorAndLicense;
|
||||
return _author;
|
||||
}
|
||||
const QString getLicense() const
|
||||
{
|
||||
return _license;
|
||||
}
|
||||
const QString getParentUUID() const
|
||||
{
|
||||
@@ -169,56 +192,39 @@ public:
|
||||
{
|
||||
return _editState;
|
||||
}
|
||||
const std::list<QString>& getTags() const
|
||||
const QStringList& getTags() const
|
||||
{
|
||||
return _tags;
|
||||
}
|
||||
const std::vector<QString>* getPhysicalModels() const
|
||||
const QStringList* getPhysicalModels() const
|
||||
{
|
||||
return &_physicalUuids;
|
||||
}
|
||||
const std::vector<QString>* getAppearanceModels() const
|
||||
const QStringList* getAppearanceModels() const
|
||||
{
|
||||
return &_appearanceUuids;
|
||||
}
|
||||
|
||||
void setLibrary(const MaterialLibrary& library)
|
||||
void setLibrary(std::shared_ptr<MaterialLibrary> library)
|
||||
{
|
||||
_library = library;
|
||||
}
|
||||
void setDirectory(const QString& directory)
|
||||
{
|
||||
Base::Console().Log("Materials::setDirectory(%s)\n", directory.toStdString().c_str());
|
||||
_directory = directory;
|
||||
}
|
||||
void setUUID(const QString& uuid)
|
||||
{
|
||||
_uuid = uuid;
|
||||
}
|
||||
void setName(const QString& name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
void setAuthorAndLicense(const QString& authorAndLicense)
|
||||
{
|
||||
_authorAndLicense = authorAndLicense;
|
||||
}
|
||||
void setParentUUID(const QString& uuid)
|
||||
{
|
||||
_parentUuid = uuid;
|
||||
}
|
||||
void setDescription(const QString& description)
|
||||
{
|
||||
_description = description;
|
||||
}
|
||||
void setURL(const QString& url)
|
||||
{
|
||||
_url = url;
|
||||
}
|
||||
void setReference(const QString& reference)
|
||||
{
|
||||
_reference = reference;
|
||||
}
|
||||
void setName(const QString& name);
|
||||
void setAuthor(const QString& author);
|
||||
void setLicense(const QString& license);
|
||||
void setParentUUID(const QString& uuid);
|
||||
void setDescription(const QString& description);
|
||||
void setURL(const QString& url);
|
||||
void setReference(const QString& reference);
|
||||
|
||||
void setEditState(ModelEdit newState);
|
||||
void setEditStateAlter()
|
||||
{
|
||||
@@ -228,6 +234,7 @@ public:
|
||||
{
|
||||
setEditState(ModelEdit_Extend);
|
||||
}
|
||||
void setPropertyEditState(const QString& name);
|
||||
void setPhysicalEditState(const QString& name);
|
||||
void setAppearanceEditState(const QString& name);
|
||||
void resetEditState()
|
||||
@@ -243,23 +250,30 @@ public:
|
||||
Q_UNUSED(tag);
|
||||
}
|
||||
void addPhysical(const QString& uuid);
|
||||
void removePhysical(const QString& uuid);
|
||||
void addAppearance(const QString& uuid);
|
||||
void removeAppearance(const QString& uuid);
|
||||
void clearModels();
|
||||
void newUuid();
|
||||
|
||||
void setPhysicalValue(const QString& name, const QString& value);
|
||||
void setPhysicalValue(const QString& name, int value);
|
||||
void setPhysicalValue(const QString& name, double value);
|
||||
void setPhysicalValue(const QString& name, const Base::Quantity value);
|
||||
void setPhysicalValue(const QString& name, std::shared_ptr<MaterialValue> value);
|
||||
|
||||
void setAppearanceValue(const QString& name, const QString& value);
|
||||
void setAppearanceValue(const QString& name, std::shared_ptr<MaterialValue> value);
|
||||
|
||||
MaterialProperty& getPhysicalProperty(const QString& name);
|
||||
const MaterialProperty& getPhysicalProperty(const QString& name) const;
|
||||
MaterialProperty& getAppearanceProperty(const QString& name);
|
||||
const MaterialProperty& getAppearanceProperty(const QString& name) const;
|
||||
std::shared_ptr<MaterialProperty> getPhysicalProperty(const QString& name);
|
||||
const std::shared_ptr<MaterialProperty> getPhysicalProperty(const QString& name) const;
|
||||
std::shared_ptr<MaterialProperty> getAppearanceProperty(const QString& name);
|
||||
const std::shared_ptr<MaterialProperty> getAppearanceProperty(const QString& name) const;
|
||||
const QVariant getPhysicalValue(const QString& name) const;
|
||||
const Base::Quantity getPhysicalQuantity(const QString& name) const;
|
||||
const QString getPhysicalValueString(const QString& name) const;
|
||||
const QVariant getAppearanceValue(const QString& name) const;
|
||||
const Base::Quantity getAppearanceQuantity(const QString& name) const;
|
||||
const QString getAppearanceValueString(const QString& name) const;
|
||||
bool hasPhysicalProperty(const QString& name) const;
|
||||
bool hasAppearanceProperty(const QString& name) const;
|
||||
@@ -275,15 +289,17 @@ public:
|
||||
bool isPhysicalModelComplete(const QString& uuid) const;
|
||||
bool isAppearanceModelComplete(const QString& uuid) const;
|
||||
|
||||
const std::map<QString, MaterialProperty>& getPhysicalProperties() const
|
||||
std::map<QString, std::shared_ptr<MaterialProperty>>& getPhysicalProperties()
|
||||
{
|
||||
return _physical;
|
||||
}
|
||||
const std::map<QString, MaterialProperty>& getAppearanceProperties() const
|
||||
std::map<QString, std::shared_ptr<MaterialProperty>>& getAppearanceProperties()
|
||||
{
|
||||
return _appearance;
|
||||
}
|
||||
|
||||
QString getModelByName(const QString& name) const;
|
||||
|
||||
bool getDereferenced() const
|
||||
{
|
||||
return _dereferenced;
|
||||
@@ -293,45 +309,80 @@ public:
|
||||
_dereferenced = true;
|
||||
}
|
||||
|
||||
void save(QTextStream& stream, bool saveAsCopy);
|
||||
/*
|
||||
* Normalize models by removing any inherited models
|
||||
*/
|
||||
QStringList normalizeModels(const QStringList& models);
|
||||
|
||||
/*
|
||||
* Set or change the base material for the current material, updating the properties as
|
||||
* required.
|
||||
*/
|
||||
void updateInheritance(const QString& parent);
|
||||
/*
|
||||
* Return a list of models that are defined in the parent material but not in this one
|
||||
*/
|
||||
QStringList inheritedMissingModels(const Material& parent);
|
||||
/*
|
||||
* Return a list of models that are defined in this model but not the parent
|
||||
*/
|
||||
QStringList inheritedAddedModels(const Material& parent);
|
||||
/*
|
||||
* Return a list of properties that have different values from the parent material
|
||||
*/
|
||||
void inheritedPropertyDiff(const QString& parent);
|
||||
|
||||
void save(QTextStream& stream, bool saveAsCopy, bool saveInherited);
|
||||
|
||||
Material& operator=(const Material& other);
|
||||
|
||||
protected:
|
||||
void addModel(const QString& uuid);
|
||||
void removeModel(const QString& uuid);
|
||||
void removeUUID(QStringList& uuidList, const QString& uuid);
|
||||
|
||||
const QVariant getValue(const std::map<QString, MaterialProperty>& propertyList,
|
||||
const QString& name) const;
|
||||
const QString getValueString(const std::map<QString, MaterialProperty>& propertyList,
|
||||
const QString& name) const;
|
||||
const QVariant
|
||||
getValue(const std::map<QString, std::shared_ptr<MaterialProperty>>& propertyList,
|
||||
const QString& name) const;
|
||||
const QString
|
||||
getValueString(const std::map<QString, std::shared_ptr<MaterialProperty>>& propertyList,
|
||||
const QString& name) const;
|
||||
|
||||
bool modelChanged(const std::shared_ptr<Material> parent,
|
||||
const std::shared_ptr<Model> model) const;
|
||||
bool modelAppearanceChanged(const std::shared_ptr<Material> parent,
|
||||
const std::shared_ptr<Model> model) const;
|
||||
void saveGeneral(QTextStream& stream) const;
|
||||
void saveInherits(QTextStream& stream) const;
|
||||
void saveModels(QTextStream& stream) const;
|
||||
void saveAppearanceModels(QTextStream& stream) const;
|
||||
void saveModels(QTextStream& stream, bool saveInherited) const;
|
||||
void saveAppearanceModels(QTextStream& stream, bool saveInherited) const;
|
||||
|
||||
private:
|
||||
MaterialLibrary _library;
|
||||
std::shared_ptr<MaterialLibrary> _library;
|
||||
QString _directory;
|
||||
QString _uuid;
|
||||
QString _name;
|
||||
QString _authorAndLicense;
|
||||
QString _author;
|
||||
QString _license;
|
||||
QString _parentUuid;
|
||||
QString _description;
|
||||
QString _url;
|
||||
QString _reference;
|
||||
std::list<QString> _tags;
|
||||
std::vector<QString> _physicalUuids;
|
||||
std::vector<QString> _appearanceUuids;
|
||||
std::vector<QString> _allUuids; // Includes inherited models
|
||||
std::map<QString, MaterialProperty> _physical;
|
||||
std::map<QString, MaterialProperty> _appearance;
|
||||
QStringList _tags;
|
||||
QStringList _physicalUuids;
|
||||
QStringList _appearanceUuids;
|
||||
QStringList _allUuids; // Includes inherited models
|
||||
std::map<QString, std::shared_ptr<MaterialProperty>> _physical;
|
||||
std::map<QString, std::shared_ptr<MaterialProperty>> _appearance;
|
||||
bool _dereferenced;
|
||||
ModelEdit _editState;
|
||||
};
|
||||
|
||||
typedef FolderTreeNode<Material> MaterialTreeNode;
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
Q_DECLARE_METATYPE(Materials::Material*)
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<Materials::Material>)
|
||||
|
||||
#endif // MATERIAL_MATERIALS_H
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <App/Application.h>
|
||||
|
||||
#include "Exceptions.h"
|
||||
#include "Model.h"
|
||||
#include "ModelLibrary.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
using namespace Materials;
|
||||
@@ -81,12 +84,27 @@ ModelProperty& ModelProperty::operator=(const ModelProperty& other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool ModelProperty::operator==(const ModelProperty& other) const
|
||||
{
|
||||
if (this == &other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (&other == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (_name == other._name) && (_propertyType == other._propertyType)
|
||||
&& (_units == other._units) && (_url == other._url) && (_description == other._description)
|
||||
&& (_inheritance == other._inheritance);
|
||||
}
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::Model, Base::BaseClass)
|
||||
|
||||
Model::Model()
|
||||
{}
|
||||
|
||||
Model::Model(const ModelLibrary& library,
|
||||
Model::Model(std::shared_ptr<ModelLibrary> library,
|
||||
ModelType type,
|
||||
const QString& name,
|
||||
const QString& directory,
|
||||
|
||||
@@ -22,31 +22,45 @@
|
||||
#ifndef MATERIAL_MODEL_H
|
||||
#define MATERIAL_MODEL_H
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
#include <memory>
|
||||
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <Base/BaseClass.h>
|
||||
#include <Base/Quantity.h>
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
|
||||
#include "FolderTree.h"
|
||||
#include "MaterialValue.h"
|
||||
#include "ModelLibrary.h"
|
||||
// #include "ModelLibrary.h"
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
class ModelLibrary;
|
||||
|
||||
enum ModelFilter
|
||||
{
|
||||
ModelFilter_None,
|
||||
ModelFilter_Physical,
|
||||
ModelFilter_Appearance
|
||||
};
|
||||
|
||||
class MaterialsExport ModelProperty: public Base::BaseClass
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
ModelProperty();
|
||||
explicit ModelProperty(const QString& name,
|
||||
const QString& type,
|
||||
const QString& units,
|
||||
const QString& url,
|
||||
const QString& description);
|
||||
explicit ModelProperty(const ModelProperty& other);
|
||||
ModelProperty(const QString& name,
|
||||
const QString& type,
|
||||
const QString& units,
|
||||
const QString& url,
|
||||
const QString& description);
|
||||
ModelProperty(const ModelProperty& other);
|
||||
~ModelProperty() override = default;
|
||||
|
||||
const QString getName() const
|
||||
@@ -117,6 +131,11 @@ public:
|
||||
}
|
||||
|
||||
ModelProperty& operator=(const ModelProperty& other);
|
||||
bool operator==(const ModelProperty& other) const;
|
||||
bool operator!=(const ModelProperty& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
private:
|
||||
QString _name;
|
||||
@@ -140,17 +159,17 @@ public:
|
||||
};
|
||||
|
||||
Model();
|
||||
explicit Model(const ModelLibrary& library,
|
||||
ModelType type,
|
||||
const QString& name,
|
||||
const QString& directory,
|
||||
const QString& uuid,
|
||||
const QString& description,
|
||||
const QString& url,
|
||||
const QString& doi);
|
||||
Model(std::shared_ptr<ModelLibrary> library,
|
||||
ModelType type,
|
||||
const QString& name,
|
||||
const QString& directory,
|
||||
const QString& uuid,
|
||||
const QString& description,
|
||||
const QString& url,
|
||||
const QString& doi);
|
||||
~Model() override = default;
|
||||
|
||||
const ModelLibrary& getLibrary() const
|
||||
std::shared_ptr<ModelLibrary> getLibrary() const
|
||||
{
|
||||
return _library;
|
||||
}
|
||||
@@ -175,10 +194,10 @@ public:
|
||||
{
|
||||
return QDir(_directory).absolutePath();
|
||||
}
|
||||
const QString getRelativePath() const
|
||||
{
|
||||
return QDir(_directory).relativeFilePath(QDir(_directory).absolutePath());
|
||||
}
|
||||
// const QString getRelativePath() const
|
||||
// {
|
||||
// return QDir(_directory).relativeFilePath(QDir(_directory).absolutePath());
|
||||
// }
|
||||
const QString getUUID() const
|
||||
{
|
||||
return _uuid;
|
||||
@@ -196,7 +215,7 @@ public:
|
||||
return _doi;
|
||||
}
|
||||
|
||||
void setLibrary(const ModelLibrary& library)
|
||||
void setLibrary(std::shared_ptr<ModelLibrary> library)
|
||||
{
|
||||
_library = library;
|
||||
}
|
||||
@@ -231,12 +250,16 @@ public:
|
||||
|
||||
void addInheritance(const QString& uuid)
|
||||
{
|
||||
_inheritedUuids.push_back(uuid);
|
||||
_inheritedUuids << uuid;
|
||||
}
|
||||
const std::vector<QString>& getInheritance() const
|
||||
const QStringList& getInheritance() const
|
||||
{
|
||||
return _inheritedUuids;
|
||||
}
|
||||
bool inherits(const QString& uuid) const
|
||||
{
|
||||
return _inheritedUuids.contains(uuid);
|
||||
}
|
||||
|
||||
bool operator==(const Model& m) const
|
||||
{
|
||||
@@ -281,7 +304,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
ModelLibrary _library;
|
||||
std::shared_ptr<ModelLibrary> _library;
|
||||
ModelType _type;
|
||||
QString _name;
|
||||
QString _directory;
|
||||
@@ -289,10 +312,12 @@ private:
|
||||
QString _description;
|
||||
QString _url;
|
||||
QString _doi;
|
||||
std::vector<QString> _inheritedUuids;
|
||||
QStringList _inheritedUuids;
|
||||
std::map<QString, ModelProperty> _properties;
|
||||
};
|
||||
|
||||
typedef FolderTreeNode<Model> ModelTreeNode;
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
#endif // MATERIAL_MODEL_H
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "Exceptions.h"
|
||||
#include "Model.h"
|
||||
#include "ModelLibrary.h"
|
||||
#include "ModelManager.h"
|
||||
|
||||
|
||||
using namespace Materials;
|
||||
@@ -66,6 +67,15 @@ QString LibraryBase::getLocalPath(const QString& path) const
|
||||
return filePath;
|
||||
}
|
||||
|
||||
bool LibraryBase::isRoot(const QString& path) const
|
||||
{
|
||||
QString localPath = getLocalPath(path);
|
||||
QString cleanPath = getLocalPath(QString::fromStdString(""));
|
||||
std::string pLocal = localPath.toStdString();
|
||||
std::string pclean = cleanPath.toStdString();
|
||||
return (cleanPath == localPath);
|
||||
}
|
||||
|
||||
QString LibraryBase::getRelativePath(const QString& path) const
|
||||
{
|
||||
QString filePath;
|
||||
@@ -97,17 +107,80 @@ TYPESYSTEM_SOURCE(Materials::ModelLibrary, LibraryBase)
|
||||
|
||||
ModelLibrary::ModelLibrary(const QString& libraryName, const QString& dir, const QString& icon)
|
||||
: LibraryBase(libraryName, dir, icon)
|
||||
{}
|
||||
{
|
||||
_modelPathMap = std::make_unique<std::map<QString, std::shared_ptr<Model>>>();
|
||||
}
|
||||
|
||||
ModelLibrary::ModelLibrary()
|
||||
{}
|
||||
{
|
||||
_modelPathMap = std::make_unique<std::map<QString, std::shared_ptr<Model>>>();
|
||||
}
|
||||
|
||||
Model* ModelLibrary::addModel(const Model& model, const QString& path)
|
||||
std::shared_ptr<Model> ModelLibrary::getModelByPath(const QString& path) const
|
||||
{
|
||||
QString filePath = getRelativePath(path);
|
||||
Model* newModel = new Model(model);
|
||||
newModel->setLibrary(*this);
|
||||
try {
|
||||
std::shared_ptr<Model> model = _modelPathMap->at(filePath);
|
||||
return model;
|
||||
}
|
||||
catch (std::out_of_range& e) {
|
||||
throw ModelNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Model> ModelLibrary::addModel(const Model& model, const QString& path)
|
||||
{
|
||||
QString filePath = getRelativePath(path);
|
||||
std::shared_ptr<Model> newModel = std::make_shared<Model>(model);
|
||||
newModel->setLibrary(getptr());
|
||||
newModel->setDirectory(filePath);
|
||||
|
||||
(*_modelPathMap)[filePath] = newModel;
|
||||
|
||||
return newModel;
|
||||
}
|
||||
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<ModelTreeNode>>>
|
||||
ModelLibrary::getModelTree(ModelFilter filter) const
|
||||
{
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<ModelTreeNode>>> modelTree =
|
||||
std::make_shared<std::map<QString, std::shared_ptr<ModelTreeNode>>>();
|
||||
|
||||
for (auto it = _modelPathMap->begin(); it != _modelPathMap->end(); it++) {
|
||||
auto filename = it->first;
|
||||
auto model = it->second;
|
||||
|
||||
if (ModelManager::passFilter(filter, model->getType())) {
|
||||
// Base::Console().Log("Relative path '%s'\n\t", filename.toStdString().c_str());
|
||||
QStringList list = filename.split(QString::fromStdString("/"));
|
||||
|
||||
// Start at the root
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<ModelTreeNode>>> node = modelTree;
|
||||
for (auto itp = list.begin(); itp != list.end(); itp++) {
|
||||
// Base::Console().Log("\t%s", itp->toStdString().c_str());
|
||||
if (ModelManager::isModel(*itp)) {
|
||||
std::shared_ptr<ModelTreeNode> child = std::make_shared<ModelTreeNode>();
|
||||
child->setData(model);
|
||||
(*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<QString, std::shared_ptr<ModelTreeNode>>>();
|
||||
std::shared_ptr<ModelTreeNode> child = std::make_shared<ModelTreeNode>();
|
||||
child->setFolder(mapPtr);
|
||||
(*node)[*itp] = child;
|
||||
node = mapPtr;
|
||||
}
|
||||
else {
|
||||
node = (*node)[*itp]->getFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Base::Console().Log("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return modelTree;
|
||||
}
|
||||
|
||||
@@ -22,27 +22,30 @@
|
||||
#ifndef MATERIAL_MODELLIBRARY_H
|
||||
#define MATERIAL_MODELLIBRARY_H
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
#include <memory>
|
||||
|
||||
#include <Base/BaseClass.h>
|
||||
#include <Base/Quantity.h>
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
|
||||
#include "MaterialValue.h"
|
||||
#include <Base/BaseClass.h>
|
||||
#include <Base/Quantity.h>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
|
||||
#include "MaterialValue.h"
|
||||
#include "Model.h"
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
class Model;
|
||||
// class Model;
|
||||
|
||||
class MaterialsExport LibraryBase: public Base::BaseClass
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
LibraryBase();
|
||||
explicit LibraryBase(const QString& libraryName, const QString& dir, const QString& icon);
|
||||
LibraryBase(const QString& libraryName, const QString& dir, const QString& icon);
|
||||
~LibraryBase() override = default;
|
||||
|
||||
const QString getName() const
|
||||
@@ -68,20 +71,24 @@ public:
|
||||
}
|
||||
QString getLocalPath(const QString& path) const;
|
||||
QString getRelativePath(const QString& path) const;
|
||||
bool isRoot(const QString& path) const;
|
||||
|
||||
private:
|
||||
LibraryBase(const LibraryBase&);
|
||||
|
||||
QString _name;
|
||||
QString _directory;
|
||||
QString _iconPath;
|
||||
};
|
||||
|
||||
class MaterialsExport ModelLibrary: public LibraryBase
|
||||
class MaterialsExport ModelLibrary: public LibraryBase,
|
||||
public std::enable_shared_from_this<ModelLibrary>
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
ModelLibrary();
|
||||
explicit ModelLibrary(const QString& libraryName, const QString& dir, const QString& icon);
|
||||
ModelLibrary(const QString& libraryName, const QString& dir, const QString& icon);
|
||||
~ModelLibrary() override = default;
|
||||
|
||||
bool operator==(const ModelLibrary& library) const
|
||||
@@ -92,8 +99,22 @@ public:
|
||||
{
|
||||
return !operator==(library);
|
||||
}
|
||||
std::shared_ptr<Model> getModelByPath(const QString& path) const;
|
||||
|
||||
Model* addModel(const Model& model, const QString& path);
|
||||
std::shared_ptr<Model> addModel(const Model& model, const QString& path);
|
||||
|
||||
// Use this to get a shared_ptr for *this
|
||||
std::shared_ptr<ModelLibrary> getptr()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<ModelTreeNode>>>
|
||||
getModelTree(ModelFilter filter) const;
|
||||
|
||||
private:
|
||||
ModelLibrary(const ModelLibrary&);
|
||||
|
||||
std::unique_ptr<std::map<QString, std::shared_ptr<Model>>> _modelPathMap;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
using namespace Materials;
|
||||
|
||||
ModelEntry::ModelEntry(const ModelLibrary& library,
|
||||
ModelEntry::ModelEntry(std::shared_ptr<ModelLibrary> library,
|
||||
const QString& baseName,
|
||||
const QString& modelName,
|
||||
const QString& dir,
|
||||
@@ -52,17 +52,18 @@ ModelEntry::ModelEntry(const ModelLibrary& library,
|
||||
, _dereferenced(false)
|
||||
{}
|
||||
|
||||
std::unique_ptr<std::map<QString, ModelEntry*>> ModelLoader::_modelEntryMap = nullptr;
|
||||
std::unique_ptr<std::map<QString, std::shared_ptr<ModelEntry>>> ModelLoader::_modelEntryMap =
|
||||
nullptr;
|
||||
|
||||
ModelLoader::ModelLoader(std::shared_ptr<std::map<QString, Model*>> modelMap,
|
||||
std::shared_ptr<std::list<ModelLibrary*>> libraryList)
|
||||
ModelLoader::ModelLoader(std::shared_ptr<std::map<QString, std::shared_ptr<Model>>> modelMap,
|
||||
std::shared_ptr<std::list<std::shared_ptr<ModelLibrary>>> libraryList)
|
||||
: _modelMap(modelMap)
|
||||
, _libraryList(libraryList)
|
||||
{
|
||||
loadLibraries();
|
||||
}
|
||||
|
||||
void ModelLoader::addLibrary(ModelLibrary* model)
|
||||
void ModelLoader::addLibrary(std::shared_ptr<ModelLibrary> model)
|
||||
{
|
||||
_libraryList->push_back(model);
|
||||
}
|
||||
@@ -84,12 +85,13 @@ const QString ModelLoader::getUUIDFromPath(const QString& path)
|
||||
const QString uuid = QString::fromStdString(yamlroot[base]["UUID"].as<std::string>());
|
||||
return uuid;
|
||||
}
|
||||
catch (YAML::Exception&) {
|
||||
catch (YAML::Exception& ex) {
|
||||
throw ModelNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
ModelEntry* ModelLoader::getModelFromPath(const ModelLibrary& library, const QString& path) const
|
||||
std::shared_ptr<ModelEntry> ModelLoader::getModelFromPath(std::shared_ptr<ModelLibrary> library,
|
||||
const QString& path) const
|
||||
{
|
||||
QFile file(path);
|
||||
if (!file.exists()) {
|
||||
@@ -113,12 +115,12 @@ ModelEntry* ModelLoader::getModelFromPath(const ModelLibrary& library, const QSt
|
||||
throw InvalidModel();
|
||||
}
|
||||
|
||||
ModelEntry* model = new ModelEntry(library,
|
||||
QString::fromStdString(base),
|
||||
QString::fromStdString(name),
|
||||
path,
|
||||
QString::fromStdString(uuid),
|
||||
yamlroot);
|
||||
std::shared_ptr<ModelEntry> model = std::make_shared<ModelEntry>(library,
|
||||
QString::fromStdString(base),
|
||||
QString::fromStdString(name),
|
||||
path,
|
||||
QString::fromStdString(uuid),
|
||||
yamlroot);
|
||||
|
||||
return model;
|
||||
}
|
||||
@@ -133,8 +135,8 @@ void ModelLoader::showYaml(const YAML::Node& yaml) const
|
||||
}
|
||||
|
||||
void ModelLoader::dereference(const QString& uuid,
|
||||
ModelEntry* parent,
|
||||
const ModelEntry* child,
|
||||
std::shared_ptr<ModelEntry> parent,
|
||||
std::shared_ptr<ModelEntry> child,
|
||||
std::map<std::pair<QString, QString>, QString>* inheritances)
|
||||
{
|
||||
auto parentPtr = parent->getModelPtr();
|
||||
@@ -168,7 +170,7 @@ void ModelLoader::dereference(const QString& uuid,
|
||||
}
|
||||
|
||||
|
||||
void ModelLoader::dereference(ModelEntry* model,
|
||||
void ModelLoader::dereference(std::shared_ptr<ModelEntry> model,
|
||||
std::map<std::pair<QString, QString>, QString>* inheritances)
|
||||
{
|
||||
// Avoid recursion
|
||||
@@ -185,10 +187,10 @@ void ModelLoader::dereference(ModelEntry* model,
|
||||
|
||||
// This requires that all models have already been loaded undereferenced
|
||||
try {
|
||||
const ModelEntry* child = (*_modelEntryMap)[nodeName];
|
||||
std::shared_ptr<ModelEntry> child = (*_modelEntryMap)[nodeName];
|
||||
dereference(model->getUUID(), model, child, inheritances);
|
||||
}
|
||||
catch (const std::out_of_range&) {
|
||||
catch (const std::out_of_range& oor) {
|
||||
Base::Console().Log("Unable to find '%s' in model map\n",
|
||||
nodeName.toStdString().c_str());
|
||||
}
|
||||
@@ -208,7 +210,7 @@ QString ModelLoader::yamlValue(const YAML::Node& node,
|
||||
return QString::fromStdString(defaultValue);
|
||||
}
|
||||
|
||||
void ModelLoader::addToTree(ModelEntry* model,
|
||||
void ModelLoader::addToTree(std::shared_ptr<ModelEntry> model,
|
||||
std::map<std::pair<QString, QString>, QString>* inheritances)
|
||||
{
|
||||
std::set<QString> exclude;
|
||||
@@ -268,12 +270,12 @@ void ModelLoader::addToTree(ModelEntry* model,
|
||||
|
||||
if (propType == QString::fromStdString("2DArray")
|
||||
|| propType == QString::fromStdString("3DArray")) {
|
||||
Base::Console().Log("Reading columns\n");
|
||||
// Base::Console().Log("Reading columns\n");
|
||||
// Read the columns
|
||||
auto cols = yamlProp["Columns"];
|
||||
for (auto col : cols) {
|
||||
std::string colName = col.first.as<std::string>();
|
||||
Base::Console().Log("\tColumns '%s'\n", colName.c_str());
|
||||
// Base::Console().Log("\tColumns '%s'\n", colName.c_str());
|
||||
|
||||
auto colProp = cols[colName];
|
||||
auto colPropType = yamlValue(colProp, "Type", "");
|
||||
@@ -299,16 +301,16 @@ void ModelLoader::addToTree(ModelEntry* model,
|
||||
}
|
||||
}
|
||||
|
||||
(*_modelMap)[uuid] = library.addModel(*finalModel, directory);
|
||||
(*_modelMap)[uuid] = library->addModel(*finalModel, directory);
|
||||
}
|
||||
|
||||
void ModelLoader::loadLibrary(const ModelLibrary& library)
|
||||
void ModelLoader::loadLibrary(std::shared_ptr<ModelLibrary> library)
|
||||
{
|
||||
if (_modelEntryMap == nullptr) {
|
||||
_modelEntryMap = std::make_unique<std::map<QString, ModelEntry*>>();
|
||||
_modelEntryMap = std::make_unique<std::map<QString, std::shared_ptr<ModelEntry>>>();
|
||||
}
|
||||
|
||||
QDirIterator it(library.getDirectory(), QDirIterator::Subdirectories);
|
||||
QDirIterator it(library->getDirectory(), QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
auto pathname = it.next();
|
||||
QFileInfo file(pathname);
|
||||
@@ -345,7 +347,7 @@ void ModelLoader::loadLibraries()
|
||||
getModelLibraries();
|
||||
if (_libraryList) {
|
||||
for (auto it = _libraryList->begin(); it != _libraryList->end(); it++) {
|
||||
loadLibrary(**it);
|
||||
loadLibrary(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,9 +364,10 @@ void ModelLoader::getModelLibraries()
|
||||
if (useBuiltInMaterials) {
|
||||
QString resourceDir = QString::fromStdString(App::Application::getResourceDir()
|
||||
+ "/Mod/Material/Resources/Models");
|
||||
auto libData = new ModelLibrary(QString::fromStdString("System"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/freecad.svg"));
|
||||
auto libData =
|
||||
std::make_shared<ModelLibrary>(QString::fromStdString("System"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/freecad.svg"));
|
||||
_libraryList->push_back(libData);
|
||||
}
|
||||
|
||||
@@ -380,7 +383,7 @@ void ModelLoader::getModelLibraries()
|
||||
if (modelDir.length() > 0) {
|
||||
QDir dir(modelDir);
|
||||
if (dir.exists()) {
|
||||
auto libData = new ModelLibrary(moduleName, modelDir, modelIcon);
|
||||
auto libData = std::make_shared<ModelLibrary>(moduleName, modelDir, modelIcon);
|
||||
_libraryList->push_back(libData);
|
||||
}
|
||||
}
|
||||
@@ -393,10 +396,10 @@ void ModelLoader::getModelLibraries()
|
||||
if (!resourceDir.isEmpty()) {
|
||||
QDir materialDir(resourceDir);
|
||||
if (materialDir.exists()) {
|
||||
auto libData =
|
||||
new ModelLibrary(QString::fromStdString("User"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/preferences-general.svg"));
|
||||
auto libData = std::make_shared<ModelLibrary>(
|
||||
QString::fromStdString("User"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/preferences-general.svg"));
|
||||
_libraryList->push_back(libData);
|
||||
}
|
||||
}
|
||||
@@ -407,9 +410,10 @@ void ModelLoader::getModelLibraries()
|
||||
if (!resourceDir.isEmpty()) {
|
||||
QDir materialDir(resourceDir);
|
||||
if (materialDir.exists()) {
|
||||
auto libData = new ModelLibrary(QString::fromStdString("Custom"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/user.svg"));
|
||||
auto libData =
|
||||
std::make_shared<ModelLibrary>(QString::fromStdString("Custom"),
|
||||
resourceDir,
|
||||
QString::fromStdString(":/icons/user.svg"));
|
||||
_libraryList->push_back(libData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#ifndef MATERIAL_MODELLOADER_H
|
||||
#define MATERIAL_MODELLOADER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
@@ -34,15 +36,15 @@ namespace Materials
|
||||
class ModelEntry
|
||||
{
|
||||
public:
|
||||
explicit ModelEntry(const ModelLibrary& library,
|
||||
const QString& baseName,
|
||||
const QString& modelName,
|
||||
const QString& dir,
|
||||
const QString& modelUuid,
|
||||
const YAML::Node& modelData);
|
||||
ModelEntry(std::shared_ptr<ModelLibrary> library,
|
||||
const QString& baseName,
|
||||
const QString& modelName,
|
||||
const QString& dir,
|
||||
const QString& modelUuid,
|
||||
const YAML::Node& modelData);
|
||||
virtual ~ModelEntry() = default;
|
||||
|
||||
const ModelLibrary& getLibrary() const
|
||||
std::shared_ptr<ModelLibrary> getLibrary() const
|
||||
{
|
||||
return _library;
|
||||
}
|
||||
@@ -83,7 +85,7 @@ public:
|
||||
private:
|
||||
ModelEntry();
|
||||
|
||||
ModelLibrary _library;
|
||||
std::shared_ptr<ModelLibrary> _library;
|
||||
QString _base;
|
||||
QString _name;
|
||||
QString _directory;
|
||||
@@ -95,8 +97,8 @@ private:
|
||||
class ModelLoader
|
||||
{
|
||||
public:
|
||||
explicit ModelLoader(std::shared_ptr<std::map<QString, Model*>> modelMap,
|
||||
std::shared_ptr<std::list<ModelLibrary*>> libraryList);
|
||||
ModelLoader(std::shared_ptr<std::map<QString, std::shared_ptr<Model>>> modelMap,
|
||||
std::shared_ptr<std::list<std::shared_ptr<ModelLibrary>>> libraryList);
|
||||
virtual ~ModelLoader() = default;
|
||||
|
||||
static const QString getUUIDFromPath(const QString& path);
|
||||
@@ -107,21 +109,24 @@ private:
|
||||
void getModelLibraries();
|
||||
QString
|
||||
yamlValue(const YAML::Node& node, const std::string& key, const std::string& defaultValue);
|
||||
void addToTree(ModelEntry* model, std::map<std::pair<QString, QString>, QString>* inheritances);
|
||||
void addToTree(std::shared_ptr<ModelEntry> model,
|
||||
std::map<std::pair<QString, QString>, QString>* inheritances);
|
||||
void showYaml(const YAML::Node& yaml) const;
|
||||
void dereference(const QString& uuid,
|
||||
ModelEntry* parent,
|
||||
const ModelEntry* child,
|
||||
std::shared_ptr<ModelEntry> parent,
|
||||
std::shared_ptr<ModelEntry> child,
|
||||
std::map<std::pair<QString, QString>, QString>* inheritances);
|
||||
void dereference(ModelEntry* model,
|
||||
void dereference(std::shared_ptr<ModelEntry> model,
|
||||
std::map<std::pair<QString, QString>, QString>* inheritances);
|
||||
ModelEntry* getModelFromPath(const ModelLibrary& library, const QString& path) const;
|
||||
void addLibrary(ModelLibrary* model);
|
||||
void loadLibrary(const ModelLibrary& library);
|
||||
std::shared_ptr<ModelEntry> getModelFromPath(std::shared_ptr<ModelLibrary> library,
|
||||
const QString& path) const;
|
||||
void addLibrary(std::shared_ptr<ModelLibrary> model);
|
||||
void loadLibrary(std::shared_ptr<ModelLibrary> library);
|
||||
void loadLibraries();
|
||||
static std::unique_ptr<std::map<QString, ModelEntry*>> _modelEntryMap;
|
||||
std::shared_ptr<std::map<QString, Model*>> _modelMap;
|
||||
std::shared_ptr<std::list<ModelLibrary*>> _libraryList;
|
||||
|
||||
static std::unique_ptr<std::map<QString, std::shared_ptr<ModelEntry>>> _modelEntryMap;
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Model>>> _modelMap;
|
||||
std::shared_ptr<std::list<std::shared_ptr<ModelLibrary>>> _libraryList;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include <Base/Console.h>
|
||||
@@ -34,8 +35,8 @@
|
||||
|
||||
using namespace Materials;
|
||||
|
||||
std::shared_ptr<std::list<ModelLibrary*>> ModelManager::_libraryList = nullptr;
|
||||
std::shared_ptr<std::map<QString, Model*>> ModelManager::_modelMap = nullptr;
|
||||
std::shared_ptr<std::list<std::shared_ptr<ModelLibrary>>> ModelManager::_libraryList = nullptr;
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Model>>> ModelManager::_modelMap = nullptr;
|
||||
QMutex ModelManager::_mutex;
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::ModelManager, Base::BaseClass)
|
||||
@@ -50,9 +51,9 @@ void ModelManager::initLibraries()
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
if (_modelMap == nullptr) {
|
||||
_modelMap = std::make_shared<std::map<QString, Model*>>();
|
||||
_modelMap = std::make_shared<std::map<QString, std::shared_ptr<Model>>>();
|
||||
if (_libraryList == nullptr) {
|
||||
_libraryList = std::make_shared<std::list<ModelLibrary*>>();
|
||||
_libraryList = std::make_shared<std::list<std::shared_ptr<ModelLibrary>>>();
|
||||
}
|
||||
|
||||
// Load the libraries
|
||||
@@ -60,12 +61,12 @@ void ModelManager::initLibraries()
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelManager::isModel(const fs::path& p)
|
||||
bool ModelManager::isModel(const QString& file)
|
||||
{
|
||||
// if (!fs::is_regular_file(p))
|
||||
// return false;
|
||||
// check file extension
|
||||
if (p.extension() == ".yml") {
|
||||
if (file.endsWith(QString::fromStdString(".yml"))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -80,36 +81,62 @@ void ModelManager::refresh()
|
||||
ModelLoader loader(_modelMap, _libraryList);
|
||||
}
|
||||
|
||||
const Model& ModelManager::getModel(const QString& uuid) const
|
||||
std::shared_ptr<Model> ModelManager::getModel(const QString& uuid) const
|
||||
{
|
||||
try {
|
||||
if (_modelMap == nullptr) {
|
||||
throw Uninitialized();
|
||||
}
|
||||
|
||||
return *(_modelMap->at(uuid));
|
||||
return _modelMap->at(uuid);
|
||||
}
|
||||
catch (std::out_of_range const&) {
|
||||
throw ModelNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
const Model& ModelManager::getModelByPath(const QString& path) const
|
||||
std::shared_ptr<Model> ModelManager::getModelByPath(const QString& path) const
|
||||
{
|
||||
const QString& uuid = ModelLoader::getUUIDFromPath(path);
|
||||
const Model& model = getModel(uuid);
|
||||
QString cleanPath = QDir::cleanPath(path);
|
||||
|
||||
return model;
|
||||
for (auto library : *_libraryList) {
|
||||
// Base::Console().Log("ModelManager::getModelByPath() Checking library '%s'->'%s'\n",
|
||||
// library->getName().toStdString().c_str(),
|
||||
// library->getDirectory().toStdString().c_str());
|
||||
|
||||
|
||||
if (cleanPath.startsWith(library->getDirectory())) {
|
||||
// Base::Console().Log("ModelManager::getModelByPath() Library '%s'\n",
|
||||
// library->getDirectory().toStdString().c_str());
|
||||
// Base::Console().Log("ModelManager::getModelByPath() Path '%s'\n",
|
||||
// cleanPath.toStdString().c_str());
|
||||
return library->getModelByPath(cleanPath);
|
||||
}
|
||||
}
|
||||
Base::Console().Log("ModelManager::getModelByPath() Library not found for path '%s'\n",
|
||||
cleanPath.toStdString().c_str());
|
||||
|
||||
throw MaterialNotFound();
|
||||
}
|
||||
|
||||
const Model& ModelManager::getModelByPath(const QString& path, const QString& libraryPath) const
|
||||
std::shared_ptr<Model> ModelManager::getModelByPath(const QString& path, const QString& lib) const
|
||||
{
|
||||
QDir modelDir(QDir::cleanPath(libraryPath + QString::fromStdString("/") + path));
|
||||
QString absPath = modelDir.absolutePath();
|
||||
return getModelByPath(absPath);
|
||||
auto library = getLibrary(lib); // May throw LibraryNotFound
|
||||
return library->getModelByPath(path); // May throw ModelNotFound
|
||||
}
|
||||
|
||||
bool ModelManager::passFilter(ModelFilter filter, Model::ModelType modelType) const
|
||||
std::shared_ptr<ModelLibrary> ModelManager::getLibrary(const QString& name) const
|
||||
{
|
||||
for (auto library : *_libraryList) {
|
||||
if (library->getName() == name) {
|
||||
return library;
|
||||
}
|
||||
}
|
||||
|
||||
throw LibraryNotFound();
|
||||
}
|
||||
|
||||
bool ModelManager::passFilter(ModelFilter filter, Model::ModelType modelType)
|
||||
{
|
||||
switch (filter) {
|
||||
case ModelFilter_None:
|
||||
@@ -124,49 +151,3 @@ bool ModelManager::passFilter(ModelFilter filter, Model::ModelType modelType) co
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<std::map<QString, ModelTreeNode*>>
|
||||
ModelManager::getModelTree(const ModelLibrary& library, ModelFilter filter) const
|
||||
{
|
||||
std::shared_ptr<std::map<QString, ModelTreeNode*>> modelTree =
|
||||
std::make_shared<std::map<QString, ModelTreeNode*>>();
|
||||
|
||||
for (auto it = _modelMap->begin(); it != _modelMap->end(); it++) {
|
||||
auto filename = it->first;
|
||||
auto model = it->second;
|
||||
|
||||
if (model->getLibrary() == library && passFilter(filter, model->getType())) {
|
||||
fs::path path = model->getDirectory().toStdString();
|
||||
Base::Console().Log("Relative path '%s'\n\t", path.string().c_str());
|
||||
|
||||
// Start at the root
|
||||
std::shared_ptr<std::map<QString, ModelTreeNode*>> node = modelTree;
|
||||
for (auto itp = path.begin(); itp != path.end(); itp++) {
|
||||
if (isModel(itp->string())) {
|
||||
ModelTreeNode* child = new ModelTreeNode();
|
||||
child->setData(model);
|
||||
(*node)[QString::fromStdString(itp->string())] = child;
|
||||
}
|
||||
else {
|
||||
// Add the folder only if it's not already there
|
||||
QString folderName = QString::fromStdString(itp->string());
|
||||
std::shared_ptr<std::map<QString, ModelTreeNode*>> mapPtr;
|
||||
if (node->count(QString::fromStdString(itp->string())) == 0) {
|
||||
mapPtr = std::make_shared<std::map<QString, ModelTreeNode*>>();
|
||||
ModelTreeNode* child = new ModelTreeNode();
|
||||
child->setFolder(mapPtr);
|
||||
(*node)[QString::fromStdString(itp->string())] = child;
|
||||
node = mapPtr;
|
||||
}
|
||||
else {
|
||||
node = (*node)[QString::fromStdString(itp->string())]->getFolder();
|
||||
}
|
||||
}
|
||||
Base::Console().Log("'%s' ", itp->string().c_str());
|
||||
}
|
||||
Base::Console().Log("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return modelTree;
|
||||
}
|
||||
|
||||
@@ -22,62 +22,57 @@
|
||||
#ifndef MATERIAL_MODELMANAGER_H
|
||||
#define MATERIAL_MODELMANAGER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
|
||||
#include <QMutex>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "Exceptions.h"
|
||||
#include "FolderTree.h"
|
||||
#include "Model.h"
|
||||
#include "ModelLibrary.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
typedef FolderTreeNode<Model> ModelTreeNode;
|
||||
|
||||
class MaterialsExport ModelManager: public Base::BaseClass
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
enum ModelFilter
|
||||
{
|
||||
ModelFilter_None,
|
||||
ModelFilter_Physical,
|
||||
ModelFilter_Appearance
|
||||
};
|
||||
|
||||
ModelManager();
|
||||
~ModelManager() override = default;
|
||||
|
||||
void refresh();
|
||||
|
||||
std::shared_ptr<std::list<ModelLibrary*>> getModelLibraries()
|
||||
std::shared_ptr<std::list<std::shared_ptr<ModelLibrary>>> getModelLibraries()
|
||||
{
|
||||
return _libraryList;
|
||||
}
|
||||
std::shared_ptr<std::map<QString, Model*>> getModels()
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<Model>>> getModels()
|
||||
{
|
||||
return _modelMap;
|
||||
}
|
||||
std::shared_ptr<std::map<QString, ModelTreeNode*>>
|
||||
getModelTree(const ModelLibrary& library, ModelFilter filter = ModelFilter_None) const;
|
||||
const Model& getModel(const QString& uuid) const;
|
||||
const Model& getModelByPath(const QString& path) const;
|
||||
const Model& getModelByPath(const QString& path, const QString& libraryPath) const;
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<ModelTreeNode>>>
|
||||
getModelTree(std::shared_ptr<ModelLibrary> library, ModelFilter filter = ModelFilter_None) const
|
||||
{
|
||||
return library->getModelTree(filter);
|
||||
}
|
||||
std::shared_ptr<Model> getModel(const QString& uuid) const;
|
||||
std::shared_ptr<Model> getModelByPath(const QString& path) const;
|
||||
std::shared_ptr<Model> getModelByPath(const QString& path, const QString& lib) const;
|
||||
std::shared_ptr<ModelLibrary> getLibrary(const QString& name) const;
|
||||
|
||||
static bool isModel(const fs::path& p);
|
||||
bool passFilter(ModelFilter filter, Model::ModelType modelType) const;
|
||||
static bool isModel(const QString& file);
|
||||
static bool passFilter(ModelFilter filter, Model::ModelType modelType);
|
||||
|
||||
private:
|
||||
static void initLibraries();
|
||||
|
||||
static std::shared_ptr<std::list<ModelLibrary*>> _libraryList;
|
||||
static std::shared_ptr<std::map<QString, Model*>> _modelMap;
|
||||
static std::shared_ptr<std::list<std::shared_ptr<ModelLibrary>>> _libraryList;
|
||||
static std::shared_ptr<std::map<QString, std::shared_ptr<Model>>> _modelMap;
|
||||
static QMutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,10 +21,8 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#endif
|
||||
|
||||
#include "Model.h"
|
||||
#include "ModelLibrary.h"
|
||||
#include "ModelManager.h"
|
||||
#include "ModelManagerPy.h"
|
||||
#include "ModelPy.h"
|
||||
@@ -62,8 +60,8 @@ PyObject* ModelManagerPy::getModel(PyObject* args)
|
||||
}
|
||||
|
||||
try {
|
||||
const Model model = getModelManagerPtr()->getModel(QString::fromStdString(uuid));
|
||||
return new ModelPy(new Model(model));
|
||||
auto model = getModelManagerPtr()->getModel(QString::fromStdString(uuid));
|
||||
return new ModelPy(new Model(*model));
|
||||
}
|
||||
catch (ModelNotFound const&) {
|
||||
QString error = QString::fromStdString("Model not found:\n");
|
||||
@@ -96,10 +94,9 @@ PyObject* ModelManagerPy::getModelByPath(PyObject* args)
|
||||
std::string libPath(lib);
|
||||
if (libPath.length() > 0) {
|
||||
try {
|
||||
const Model& model =
|
||||
getModelManagerPtr()->getModelByPath(QString::fromStdString(path),
|
||||
QString::fromStdString(libPath));
|
||||
return new ModelPy(new Model(model));
|
||||
auto model = getModelManagerPtr()->getModelByPath(QString::fromStdString(path),
|
||||
QString::fromStdString(libPath));
|
||||
return new ModelPy(new Model(*model));
|
||||
}
|
||||
catch (ModelNotFound const&) {
|
||||
PyErr_SetString(PyExc_LookupError, "Model not found");
|
||||
@@ -108,8 +105,8 @@ PyObject* ModelManagerPy::getModelByPath(PyObject* args)
|
||||
}
|
||||
|
||||
try {
|
||||
const Model& model = getModelManagerPtr()->getModelByPath(QString::fromStdString(path));
|
||||
return new ModelPy(new Model(model));
|
||||
auto model = getModelManagerPtr()->getModelByPath(QString::fromStdString(path));
|
||||
return new ModelPy(new Model(*model));
|
||||
}
|
||||
catch (ModelNotFound const&) {
|
||||
PyErr_SetString(PyExc_LookupError, "Model not found");
|
||||
@@ -119,11 +116,11 @@ PyObject* ModelManagerPy::getModelByPath(PyObject* args)
|
||||
|
||||
Py::List ModelManagerPy::getModelLibraries() const
|
||||
{
|
||||
std::shared_ptr<std::list<ModelLibrary*>> libraries = getModelManagerPtr()->getModelLibraries();
|
||||
auto libraries = getModelManagerPtr()->getModelLibraries();
|
||||
Py::List list;
|
||||
|
||||
for (auto it = libraries->begin(); it != libraries->end(); it++) {
|
||||
ModelLibrary* lib = *it;
|
||||
auto lib = *it;
|
||||
Py::Tuple libTuple(3);
|
||||
libTuple.setItem(0, Py::String(lib->getName().toStdString()));
|
||||
libTuple.setItem(1, Py::String(lib->getDirectoryPath().toStdString()));
|
||||
@@ -142,7 +139,7 @@ Py::Dict ModelManagerPy::getModels() const
|
||||
|
||||
for (auto it = models->begin(); it != models->end(); it++) {
|
||||
QString key = it->first;
|
||||
Model* model = it->second;
|
||||
auto model = it->second;
|
||||
|
||||
PyObject* modelPy = new ModelPy(new Model(*model));
|
||||
dict.setItem(Py::String(key.toStdString()), Py::Object(modelPy, true));
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#endif
|
||||
|
||||
#include "Model.h"
|
||||
#include "ModelPropertyPy.h"
|
||||
|
||||
|
||||
@@ -21,13 +21,11 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#endif
|
||||
|
||||
#include "Model.h"
|
||||
#include "ModelLibrary.h"
|
||||
#include "ModelPropertyPy.h"
|
||||
#include "ModelPy.h"
|
||||
#include "ModelUuids.h"
|
||||
|
||||
#include "ModelPy.cpp"
|
||||
|
||||
@@ -43,11 +41,11 @@ std::string ModelPy::representation() const
|
||||
str << "), UUID=(";
|
||||
str << ptr->getUUID().toStdString();
|
||||
str << "), Library Name=(";
|
||||
str << ptr->getLibrary().getName().toStdString();
|
||||
str << ptr->getLibrary()->getName().toStdString();
|
||||
str << "), Library Root=(";
|
||||
str << ptr->getLibrary().getDirectoryPath().toStdString();
|
||||
str << ptr->getLibrary()->getDirectoryPath().toStdString();
|
||||
str << "), Library Icon=(";
|
||||
str << ptr->getLibrary().getIconPath().toStdString();
|
||||
str << ptr->getLibrary()->getIconPath().toStdString();
|
||||
str << "), Directory=(";
|
||||
str << ptr->getDirectory().toStdString();
|
||||
str << "), URL=(";
|
||||
@@ -57,7 +55,7 @@ std::string ModelPy::representation() const
|
||||
str << "), Description=(";
|
||||
str << ptr->getDescription().toStdString();
|
||||
str << "), Inherits=[";
|
||||
const std::vector<QString>& inherited = getModelPtr()->getInheritance();
|
||||
auto& inherited = getModelPtr()->getInheritance();
|
||||
for (auto it = inherited.begin(); it != inherited.end(); it++) {
|
||||
QString uuid = *it;
|
||||
if (it != inherited.begin()) {
|
||||
@@ -87,17 +85,17 @@ int ModelPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
|
||||
Py::String ModelPy::getLibraryName() const
|
||||
{
|
||||
return Py::String(getModelPtr()->getLibrary().getName().toStdString());
|
||||
return Py::String(getModelPtr()->getLibrary()->getName().toStdString());
|
||||
}
|
||||
|
||||
Py::String ModelPy::getLibraryRoot() const
|
||||
{
|
||||
return Py::String(getModelPtr()->getLibrary().getDirectoryPath().toStdString());
|
||||
return Py::String(getModelPtr()->getLibrary()->getDirectoryPath().toStdString());
|
||||
}
|
||||
|
||||
Py::String ModelPy::getLibraryIcon() const
|
||||
{
|
||||
return Py::String(getModelPtr()->getLibrary().getIconPath().toStdString());
|
||||
return Py::String(getModelPtr()->getLibrary()->getIconPath().toStdString());
|
||||
}
|
||||
|
||||
Py::String ModelPy::getName() const
|
||||
@@ -132,13 +130,11 @@ Py::String ModelPy::getDOI() const
|
||||
|
||||
Py::List ModelPy::getInherited() const
|
||||
{
|
||||
const std::vector<QString>& inherited = getModelPtr()->getInheritance();
|
||||
auto& inherited = getModelPtr()->getInheritance();
|
||||
Py::List list;
|
||||
|
||||
for (auto it = inherited.begin(); it != inherited.end(); it++) {
|
||||
QString uuid = *it;
|
||||
|
||||
list.append(Py::String(uuid.toStdString()));
|
||||
list.append(Py::String(it->toStdString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
70
src/Mod/Material/App/ModelUuids.cpp
Normal file
70
src/Mod/Material/App/ModelUuids.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include "ModelUuids.h"
|
||||
|
||||
using namespace Materials;
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::ModelUUIDs, Base::BaseClass)
|
||||
|
||||
const QString ModelUUIDs::ModelUUID_Legacy_Father =
|
||||
QString::fromStdString("9cdda8b6-b606-4778-8f13-3934d8668e67");
|
||||
const QString ModelUUIDs::ModelUUID_Legacy_MaterialStandard =
|
||||
QString::fromStdString("1e2c0088-904a-4537-925f-64064c07d700");
|
||||
|
||||
const QString ModelUUIDs::ModelUUID_Mechanical_Density =
|
||||
QString::fromStdString("454661e5-265b-4320-8e6f-fcf6223ac3af");
|
||||
const QString ModelUUIDs::ModelUUID_Mechanical_IsotropicLinearElastic =
|
||||
QString::fromStdString("f6f9e48c-b116-4e82-ad7f-3659a9219c50");
|
||||
const QString ModelUUIDs::ModelUUID_Mechanical_LinearElastic =
|
||||
QString::fromStdString("7b561d1d-fb9b-44f6-9da9-56a4f74d7536");
|
||||
const QString ModelUUIDs::ModelUUID_Mechanical_OgdenYld2004p18 =
|
||||
QString::fromStdString("3ef9e427-cc25-43f7-817f-79ff0d49625f");
|
||||
const QString ModelUUIDs::ModelUUID_Mechanical_OrthotropicLinearElastic =
|
||||
QString::fromStdString("b19ccc6b-a431-418e-91c2-0ac8c649d146");
|
||||
|
||||
const QString ModelUUIDs::ModelUUID_Fluid_Default =
|
||||
QString::fromStdString("1ae66d8c-1ba1-4211-ad12-b9917573b202");
|
||||
|
||||
const QString ModelUUIDs::ModelUUID_Thermal_Default =
|
||||
QString::fromStdString("9959d007-a970-4ea7-bae4-3eb1b8b883c7");
|
||||
|
||||
const QString ModelUUIDs::ModelUUID_Electromagnetic_Default =
|
||||
QString::fromStdString("b2eb5f48-74b3-4193-9fbb-948674f427f3");
|
||||
|
||||
const QString ModelUUIDs::ModelUUID_Architectural_Default =
|
||||
QString::fromStdString("32439c3b-262f-4b7b-99a8-f7f44e5894c8");
|
||||
|
||||
const QString ModelUUIDs::ModelUUID_Costs_Default =
|
||||
QString::fromStdString("881df808-8726-4c2e-be38-688bb6cce466");
|
||||
|
||||
const QString ModelUUIDs::ModelUUID_Rendering_Basic =
|
||||
QString::fromStdString("f006c7e4-35b7-43d5-bbf9-c5d572309e6e");
|
||||
const QString ModelUUIDs::ModelUUID_Rendering_Texture =
|
||||
QString::fromStdString("bbdcc65b-67ca-489c-bd5c-a36e33d1c160");
|
||||
const QString ModelUUIDs::ModelUUID_Rendering_Advanced =
|
||||
QString::fromStdString("c880f092-cdae-43d6-a24b-55e884aacbbf");
|
||||
const QString ModelUUIDs::ModelUUID_Rendering_Vector =
|
||||
QString::fromStdString("fdf5a80e-de50-4157-b2e5-b6e5f88b680e");
|
||||
@@ -24,50 +24,48 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <Base/BaseClass.h>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
// UUIDs for predefined material models
|
||||
class MaterialsExport ModelUUIDs: public Base::BaseClass
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
static const QString ModelUUID_Legacy_Father =
|
||||
QString::fromStdString("9cdda8b6-b606-4778-8f13-3934d8668e67");
|
||||
static const QString ModelUUID_Legacy_MaterialStandard =
|
||||
QString::fromStdString("1e2c0088-904a-4537-925f-64064c07d700");
|
||||
public:
|
||||
ModelUUIDs()
|
||||
{}
|
||||
~ModelUUIDs() override = default;
|
||||
|
||||
static const QString ModelUUID_Mechanical_Density =
|
||||
QString::fromStdString("454661e5-265b-4320-8e6f-fcf6223ac3af");
|
||||
static const QString ModelUUID_Mechanical_IsotropicLinearElastic =
|
||||
QString::fromStdString("f6f9e48c-b116-4e82-ad7f-3659a9219c50");
|
||||
static const QString ModelUUID_Mechanical_LinearElastic =
|
||||
QString::fromStdString("7b561d1d-fb9b-44f6-9da9-56a4f74d7536");
|
||||
static const QString ModelUUID_Mechanical_OgdenYld2004p18 =
|
||||
QString::fromStdString("3ef9e427-cc25-43f7-817f-79ff0d49625f");
|
||||
static const QString ModelUUID_Mechanical_OrthotropicLinearElastic =
|
||||
QString::fromStdString("b19ccc6b-a431-418e-91c2-0ac8c649d146");
|
||||
// UUIDs for predefined material models
|
||||
|
||||
static const QString ModelUUID_Fluid_Default =
|
||||
QString::fromStdString("1ae66d8c-1ba1-4211-ad12-b9917573b202");
|
||||
static const QString ModelUUID_Legacy_Father;
|
||||
static const QString ModelUUID_Legacy_MaterialStandard;
|
||||
|
||||
static const QString ModelUUID_Thermal_Default =
|
||||
QString::fromStdString("9959d007-a970-4ea7-bae4-3eb1b8b883c7");
|
||||
static const QString ModelUUID_Mechanical_Density;
|
||||
static const QString ModelUUID_Mechanical_IsotropicLinearElastic;
|
||||
static const QString ModelUUID_Mechanical_LinearElastic;
|
||||
static const QString ModelUUID_Mechanical_OgdenYld2004p18;
|
||||
static const QString ModelUUID_Mechanical_OrthotropicLinearElastic;
|
||||
|
||||
static const QString ModelUUID_Electromagnetic_Default =
|
||||
QString::fromStdString("b2eb5f48-74b3-4193-9fbb-948674f427f3");
|
||||
static const QString ModelUUID_Fluid_Default;
|
||||
|
||||
static const QString ModelUUID_Architectural_Default =
|
||||
QString::fromStdString("32439c3b-262f-4b7b-99a8-f7f44e5894c8");
|
||||
static const QString ModelUUID_Thermal_Default;
|
||||
|
||||
static const QString ModelUUID_Costs_Default =
|
||||
QString::fromStdString("881df808-8726-4c2e-be38-688bb6cce466");
|
||||
static const QString ModelUUID_Electromagnetic_Default;
|
||||
|
||||
static const QString ModelUUID_Rendering_Basic =
|
||||
QString::fromStdString("f006c7e4-35b7-43d5-bbf9-c5d572309e6e");
|
||||
static const QString ModelUUID_Rendering_Texture =
|
||||
QString::fromStdString("bbdcc65b-67ca-489c-bd5c-a36e33d1c160");
|
||||
static const QString ModelUUID_Rendering_Advanced =
|
||||
QString::fromStdString("c880f092-cdae-43d6-a24b-55e884aacbbf");
|
||||
static const QString ModelUUID_Rendering_Vector =
|
||||
QString::fromStdString("fdf5a80e-de50-4157-b2e5-b6e5f88b680e");
|
||||
static const QString ModelUUID_Architectural_Default;
|
||||
|
||||
static const QString ModelUUID_Costs_Default;
|
||||
|
||||
static const QString ModelUUID_Rendering_Basic;
|
||||
static const QString ModelUUID_Rendering_Texture;
|
||||
static const QString ModelUUID_Rendering_Advanced;
|
||||
static const QString ModelUUID_Rendering_Vector;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
|
||||
@@ -55,10 +55,6 @@
|
||||
// Qt
|
||||
#include <QtGlobal>
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#endif //_PreComp_
|
||||
|
||||
#endif // MATERIAL_PRECOMPILED_H
|
||||
|
||||
116
src/Mod/Material/App/UUIDsPy.xml
Normal file
116
src/Mod/Material/App/UUIDsPy.xml
Normal file
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="BaseClassPy"
|
||||
Name="UUIDsPy"
|
||||
PythonName="Material.UUIDs"
|
||||
Twin="ModelUUIDs"
|
||||
TwinPointer="ModelUUIDs"
|
||||
Include="Mod/Material/App/ModelUuids.h"
|
||||
Namespace="Materials"
|
||||
FatherInclude="Base/BaseClassPy.h"
|
||||
FatherNamespace="Base"
|
||||
Constructor="true"
|
||||
Delete="true">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="DavidCarter" EMail="dcarter@davidcarter.ca" />
|
||||
<UserDocu>Material model UUID identifiers.</UserDocu>
|
||||
</Documentation>
|
||||
<Attribute Name="Father" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Legacy/Father</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Father" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="MaterialStandard" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Legacy/MaterialStandard</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="MaterialStandard" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Density" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Mechanical/Density</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Density" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="IsotropicLinearElastic" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Mechanical/IsotropicLinearElastic</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IsotropicLinearElastic" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="LinearElastic" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Mechanical/LinearElastic</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="LinearElastic" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="OgdenYld2004p18" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Mechanical/OgdenYld2004p18</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="OgdenYld2004p18" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="OrthotropicLinearElastic" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Mechanical/OrthotropicLinearElastic</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="OrthotropicLinearElastic" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Fluid" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Fluid/Fluid</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Fluid" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Thermal" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Thermal/Thermal</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Thermal" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Electromagnetic" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Electromagnetic/Electromagnetic</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Electromagnetic" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Architectural" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Architectural/Architectural</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Architectural" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Costs" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Costs/Costs</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Costs" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="BasicRendering" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Rendering/BasicRendering</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="BasicRendering" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="TextureRendering" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Rendering/TextureRendering</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="TextureRendering" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="AdvancedRendering" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Rendering/AdvancedRendering</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="AdvancedRendering" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="VectorRendering" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>UUID for model System:Rendering/VectorRendering</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="VectorRendering" Type="String"/>
|
||||
</Attribute>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
139
src/Mod/Material/App/UUIDsPyImpl.cpp
Normal file
139
src/Mod/Material/App/UUIDsPyImpl.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include "ModelUuids.h"
|
||||
|
||||
#include "UUIDsPy.h"
|
||||
|
||||
#include "UUIDsPy.cpp"
|
||||
|
||||
using namespace Materials;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string UUIDsPy::representation() const
|
||||
{
|
||||
return {"<ModelUUIDs object>"};
|
||||
}
|
||||
|
||||
PyObject* UUIDsPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// create a new instance of UUIDsPy and the Twin object
|
||||
return new UUIDsPy(new ModelUUIDs);
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int UUIDsPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getFather() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Legacy_Father.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getMaterialStandard() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Legacy_MaterialStandard.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getDensity() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Mechanical_Density.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getIsotropicLinearElastic() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Mechanical_IsotropicLinearElastic.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getLinearElastic() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Mechanical_LinearElastic.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getOgdenYld2004p18() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Mechanical_OgdenYld2004p18.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getOrthotropicLinearElastic() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Mechanical_OrthotropicLinearElastic.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getFluid() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Fluid_Default.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getThermal() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Thermal_Default.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getElectromagnetic() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Electromagnetic_Default.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getArchitectural() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Architectural_Default.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getCosts() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Costs_Default.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getBasicRendering() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Rendering_Basic.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getTextureRendering() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Rendering_Texture.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getAdvancedRendering() const
|
||||
{
|
||||
Base::Console().Log(getModelUUIDsPtr()->ModelUUID_Rendering_Advanced.toStdString().c_str());
|
||||
return Py::String(getModelUUIDsPtr()->ModelUUID_Rendering_Advanced.toStdString());
|
||||
}
|
||||
|
||||
Py::String UUIDsPy::getVectorRendering() const
|
||||
{
|
||||
return Py::String(ModelUUIDs::ModelUUID_Rendering_Vector.toStdString());
|
||||
}
|
||||
|
||||
PyObject* UUIDsPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int UUIDsPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -22,7 +22,6 @@
|
||||
#ifndef MATERIAL_TRIM_H
|
||||
#define MATERIAL_TRIM_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
namespace Materials
|
||||
|
||||
@@ -194,7 +194,6 @@ SET(MaterialModel_Files
|
||||
Resources/Models/Legacy/Father.yml
|
||||
Resources/Models/Legacy/MaterialStandard.yml
|
||||
Resources/Models/Mechanical/Density.yml
|
||||
Resources/Models/Mechanical/HypotheticalExample.yml
|
||||
Resources/Models/Mechanical/IsotropicLinearElastic.yml
|
||||
Resources/Models/Mechanical/LinearElastic.yml
|
||||
Resources/Models/Mechanical/OgdenYld2004p18.yml
|
||||
@@ -206,6 +205,21 @@ SET(MaterialModel_Files
|
||||
Resources/Models/Thermal/Thermal.yml
|
||||
)
|
||||
|
||||
set(MaterialTest_Files
|
||||
materialtests/__init__.py
|
||||
materialtests/TestModels.py
|
||||
materialtests/TestMaterials.py
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(MateriaTestLib ALL
|
||||
SOURCES ${MaterialTest_Files}
|
||||
)
|
||||
|
||||
fc_target_copy_resource(MateriaTestLib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR}/Mod/Material
|
||||
${MaterialTest_Files})
|
||||
|
||||
ADD_CUSTOM_TARGET(MaterialScripts ALL
|
||||
SOURCES ${MaterialScripts_Files} ${Material_QRC_SRCS}
|
||||
)
|
||||
@@ -275,8 +289,13 @@ INSTALL(
|
||||
DESTINATION Mod/Material
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES ${MaterialTest_Files}
|
||||
DESTINATION Mod/Material/materialtests
|
||||
)
|
||||
|
||||
foreach(file ${MaterialLib_Files} ${FluidMaterial_Files} ${AppearanceLib_Files} ${MaterialModel_Files})
|
||||
get_filename_component(filepath ${file} DIRECTORY)
|
||||
cmake_path(REMOVE_FILENAME file OUTPUT_VARIABLE filepath)
|
||||
INSTALL(
|
||||
FILES ${file}
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/Material/${filepath}
|
||||
|
||||
@@ -96,6 +96,9 @@ PyMOD_INIT_FUNC(MatGui)
|
||||
|
||||
// register preferences pages on Material, the order here will be the order of the tabs in pref
|
||||
// widget
|
||||
Gui::Dialog::DlgPreferencesImp::setGroupData("Material",
|
||||
"Material",
|
||||
QObject::tr("Material workbench"));
|
||||
new Gui::PrefPageProducer<MatGui::DlgSettingsMaterial>(
|
||||
QT_TRANSLATE_NOOP("QObject", "Material"));
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
#include <Gui/MainWindow.h>
|
||||
|
||||
#include <Mod/Material/App/Exceptions.h>
|
||||
@@ -39,32 +41,52 @@ using namespace MatGui;
|
||||
|
||||
/* TRANSLATOR MatGui::Array2D */
|
||||
|
||||
Array2D::Array2D(const QString& propertyName, Materials::Material* material, QWidget* parent)
|
||||
Array2D::Array2D(const QString& propertyName,
|
||||
std::shared_ptr<Materials::Material> material,
|
||||
QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui_Array2D)
|
||||
, _material(material)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
if (material->hasPhysicalProperty(propertyName)) {
|
||||
_property = &(material->getPhysicalProperty(propertyName));
|
||||
_property = material->getPhysicalProperty(propertyName);
|
||||
}
|
||||
else if (material->hasAppearanceProperty(propertyName)) {
|
||||
_property = &(material->getAppearanceProperty(propertyName));
|
||||
_property = material->getAppearanceProperty(propertyName);
|
||||
}
|
||||
else {
|
||||
Base::Console().Log("Property '%s' not found\n", propertyName.toStdString().c_str());
|
||||
_property = nullptr;
|
||||
}
|
||||
if (_property) {
|
||||
Base::Console().Log("Value type %d\n",
|
||||
static_cast<int>(_property->getMaterialValue()->getType()));
|
||||
_value =
|
||||
std::static_pointer_cast<Materials::Material2DArray>(_property->getMaterialValue());
|
||||
}
|
||||
else {
|
||||
Base::Console().Log("No value loaded\n");
|
||||
_value = nullptr;
|
||||
}
|
||||
if (_value) {
|
||||
Base::Console().Log("Value type %d\n", static_cast<int>(_value->getType()));
|
||||
// auto value = _property->getMaterialValue()->getValue();
|
||||
// Base::Console().Log("\tQVariant type %d\n", value.userType());
|
||||
}
|
||||
|
||||
setupDefault();
|
||||
setupArray();
|
||||
|
||||
ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->tableView, &QWidget::customContextMenuRequested, this, &Array2D::onContextMenu);
|
||||
|
||||
_deleteAction.setText(tr("Delete row"));
|
||||
_deleteAction.setShortcut(Qt::Key_Delete);
|
||||
connect(&_deleteAction, &QAction::triggered, this, &Array2D::onDelete);
|
||||
ui->tableView->addAction(&_deleteAction);
|
||||
|
||||
connect(ui->standardButtons, &QDialogButtonBox::accepted, this, &Array2D::accept);
|
||||
connect(ui->standardButtons, &QDialogButtonBox::rejected, this, &Array2D::reject);
|
||||
}
|
||||
@@ -77,13 +99,16 @@ void Array2D::setupDefault()
|
||||
|
||||
try {
|
||||
const Materials::MaterialProperty& column1 = _property->getColumn(0);
|
||||
QString label = QString::fromStdString("Default ") + column1.getName();
|
||||
QString label = tr("Default ") + column1.getName();
|
||||
ui->labelDefault->setText(label);
|
||||
if (column1.getPropertyType() == QString::fromStdString("Quantity")) {
|
||||
ui->editDefault->setMinimum(std::numeric_limits<double>::min());
|
||||
ui->editDefault->setMaximum(std::numeric_limits<double>::max());
|
||||
ui->editDefault->setUnitText(_property->getColumnUnits(0));
|
||||
ui->editDefault->setValue(_value->getDefault().getValue().value<Base::Quantity>());
|
||||
if (!_value->defaultSet()) {
|
||||
_value->setDefault(_property->getColumnNull(0).value<Base::Quantity>());
|
||||
}
|
||||
ui->editDefault->setValue(_value->getDefault().value<Base::Quantity>());
|
||||
|
||||
connect(ui->editDefault,
|
||||
qOverload<const Base::Quantity&>(&Gui::QuantitySpinBox::valueChanged),
|
||||
@@ -134,15 +159,99 @@ void Array2D::setupArray()
|
||||
auto table = ui->tableView;
|
||||
auto model = new Array2DModel(_property, _value, this);
|
||||
table->setModel(model);
|
||||
table->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
// table->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
table->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
setColumnWidths(table);
|
||||
setColumnDelegates(table);
|
||||
connect(model, &QAbstractItemModel::dataChanged, this, &Array2D::onDataChanged);
|
||||
}
|
||||
|
||||
void Array2D::onDataChanged(const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight,
|
||||
const QVector<int>& roles)
|
||||
{
|
||||
Q_UNUSED(topLeft)
|
||||
Q_UNUSED(bottomRight)
|
||||
Q_UNUSED(roles)
|
||||
|
||||
_material->setEditStateAlter();
|
||||
}
|
||||
|
||||
void Array2D::defaultValueChanged(const Base::Quantity& value)
|
||||
{
|
||||
_value->setDefault(QVariant::fromValue(value));
|
||||
_material->setEditStateAlter();
|
||||
}
|
||||
|
||||
void Array2D::onContextMenu(const QPoint& pos)
|
||||
{
|
||||
Base::Console().Log("Array2D::onContextMenu(%d,%d)\n", pos.x(), pos.y());
|
||||
QModelIndex index = ui->tableView->indexAt(pos);
|
||||
Base::Console().Log("\tindex at (%d,%d)\n", index.row(), index.column());
|
||||
|
||||
|
||||
QMenu contextMenu(tr("Context menu"), this);
|
||||
|
||||
contextMenu.addAction(&_deleteAction);
|
||||
|
||||
contextMenu.exec(ui->tableView->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
bool Array2D::newRow(const QModelIndex& index)
|
||||
{
|
||||
Array2DModel* model = static_cast<Array2DModel*>(ui->tableView->model());
|
||||
return model->newRow(index);
|
||||
}
|
||||
|
||||
void Array2D::onDelete(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("Array2D::onDelete()\n");
|
||||
QItemSelectionModel* selectionModel = ui->tableView->selectionModel();
|
||||
if (!selectionModel->hasSelection() || newRow(selectionModel->currentIndex())) {
|
||||
Base::Console().Log("\tNothing selected\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int res = confirmDelete();
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int Array2D::confirmDelete()
|
||||
{
|
||||
QMessageBox box(this);
|
||||
box.setIcon(QMessageBox::Question);
|
||||
box.setWindowTitle(QObject::tr("Confirm Delete"));
|
||||
|
||||
QString prompt = QObject::tr("Are you sure you want to delete the row?");
|
||||
box.setText(prompt);
|
||||
|
||||
box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
box.setDefaultButton(QMessageBox::Cancel);
|
||||
box.setEscapeButton(QMessageBox::Cancel);
|
||||
|
||||
int res = QMessageBox::Cancel;
|
||||
box.adjustSize(); // Silence warnings from Qt on Windows
|
||||
switch (box.exec()) {
|
||||
case QMessageBox::Ok:
|
||||
deleteSelected();
|
||||
res = QMessageBox::Ok;
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Array2D::deleteSelected()
|
||||
{
|
||||
Array2DModel* model = static_cast<Array2DModel*>(ui->tableView->model());
|
||||
QItemSelectionModel* selectionModel = ui->tableView->selectionModel();
|
||||
auto index = selectionModel->currentIndex();
|
||||
model->deleteRow(index);
|
||||
}
|
||||
|
||||
void Array2D::accept()
|
||||
|
||||
@@ -22,14 +22,20 @@
|
||||
#ifndef MATGUI_ARRAY2D_H
|
||||
#define MATGUI_ARRAY2D_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAction>
|
||||
#include <QDialog>
|
||||
#include <QPoint>
|
||||
#include <QStandardItem>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableView>
|
||||
|
||||
#include "ArrayModel.h"
|
||||
#include <Mod/Material/App/Model.h>
|
||||
|
||||
#include "ArrayModel.h"
|
||||
|
||||
namespace MatGui
|
||||
{
|
||||
|
||||
@@ -40,26 +46,38 @@ class Array2D: public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Array2D(const QString& propertyName,
|
||||
Materials::Material* material,
|
||||
QWidget* parent = nullptr);
|
||||
Array2D(const QString& propertyName,
|
||||
std::shared_ptr<Materials::Material> material,
|
||||
QWidget* parent = nullptr);
|
||||
~Array2D() override = default;
|
||||
|
||||
void onDataChanged(const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight,
|
||||
const QVector<int>& roles = QVector<int>());
|
||||
void defaultValueChanged(const Base::Quantity& value);
|
||||
void onDelete(bool checked);
|
||||
void onContextMenu(const QPoint& pos);
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui_Array2D> ui;
|
||||
const Materials::MaterialProperty* _property;
|
||||
std::shared_ptr<Materials::Material> _material;
|
||||
std::shared_ptr<Materials::MaterialProperty> _property;
|
||||
std::shared_ptr<Materials::Material2DArray> _value;
|
||||
|
||||
QAction _deleteAction;
|
||||
|
||||
void setupDefault();
|
||||
void setHeaders(QStandardItemModel* model);
|
||||
void setColumnWidths(QTableView* table);
|
||||
void setColumnDelegates(QTableView* table);
|
||||
void setupArray();
|
||||
|
||||
bool newRow(const QModelIndex& index);
|
||||
int confirmDelete();
|
||||
void deleteSelected();
|
||||
};
|
||||
|
||||
} // namespace MatGui
|
||||
|
||||
@@ -25,9 +25,12 @@
|
||||
#include <QPushButton>
|
||||
#endif
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
#include <Gui/MainWindow.h>
|
||||
|
||||
#include <Mod/Material/App/Exceptions.h>
|
||||
#include <Mod/Material/App/Materials.h>
|
||||
|
||||
#include "Array3D.h"
|
||||
#include "ArrayDelegate.h"
|
||||
@@ -37,19 +40,23 @@
|
||||
|
||||
using namespace MatGui;
|
||||
|
||||
Array3D::Array3D(const QString& propertyName, Materials::Material* material, QWidget* parent)
|
||||
Array3D::Array3D(const QString& propertyName,
|
||||
std::shared_ptr<Materials::Material> material,
|
||||
QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui_Array3D)
|
||||
, _material(material)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
if (material->hasPhysicalProperty(propertyName)) {
|
||||
_property = &(material->getPhysicalProperty(propertyName));
|
||||
_property = material->getPhysicalProperty(propertyName);
|
||||
}
|
||||
else if (material->hasAppearanceProperty(propertyName)) {
|
||||
_property = &(material->getAppearanceProperty(propertyName));
|
||||
_property = material->getAppearanceProperty(propertyName);
|
||||
}
|
||||
else {
|
||||
Base::Console().Log("Property '%s' not found\n", propertyName.toStdString().c_str());
|
||||
_property = nullptr;
|
||||
}
|
||||
if (_property) {
|
||||
@@ -57,6 +64,7 @@ Array3D::Array3D(const QString& propertyName, Materials::Material* material, QWi
|
||||
std::static_pointer_cast<Materials::Material3DArray>(_property->getMaterialValue());
|
||||
}
|
||||
else {
|
||||
Base::Console().Log("No value loaded\n");
|
||||
_value = nullptr;
|
||||
}
|
||||
|
||||
@@ -64,6 +72,22 @@ Array3D::Array3D(const QString& propertyName, Materials::Material* material, QWi
|
||||
setupDepthArray();
|
||||
setupArray();
|
||||
|
||||
ui->table3D->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->table3D, &QWidget::customContextMenuRequested, this, &Array3D::onDepthContextMenu);
|
||||
|
||||
ui->table2D->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->table2D, &QWidget::customContextMenuRequested, this, &Array3D::on2DContextMenu);
|
||||
|
||||
_deleteDepthAction.setText(tr("Delete row"));
|
||||
// _deleteDepthAction.setShortcut(Qt::Key_Delete);
|
||||
connect(&_deleteDepthAction, &QAction::triggered, this, &Array3D::onDepthDelete);
|
||||
ui->table3D->addAction(&_deleteDepthAction);
|
||||
|
||||
_delete2DAction.setText(tr("Delete row"));
|
||||
// _delete2DAction.setShortcut(Qt::Key_Delete);
|
||||
connect(&_delete2DAction, &QAction::triggered, this, &Array3D::on2DDelete);
|
||||
ui->table2D->addAction(&_delete2DAction);
|
||||
|
||||
Base::Console().Log("Material '%s'\n", material->getName().toStdString().c_str());
|
||||
Base::Console().Log("\tproperty '%s'\n", propertyName.toStdString().c_str());
|
||||
|
||||
@@ -78,6 +102,10 @@ Array3D::Array3D(const QString& propertyName, Materials::Material* material, QWi
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&Array3D::onCancel);
|
||||
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->table3D->selectionModel();
|
||||
connect(selectionModel, &QItemSelectionModel::selectionChanged, this, &Array3D::onSelectDepth);
|
||||
}
|
||||
|
||||
bool Array3D::onSplitter(QEvent* e)
|
||||
@@ -95,13 +123,16 @@ void Array3D::setupDefault()
|
||||
|
||||
try {
|
||||
auto& column1 = _property->getColumn(0);
|
||||
QString label = QString::fromStdString("Default ") + column1.getName();
|
||||
QString label = tr("Default ") + column1.getName();
|
||||
ui->labelDefault->setText(label);
|
||||
if (column1.getPropertyType() == QString::fromStdString("Quantity")) {
|
||||
ui->editDefault->setMinimum(std::numeric_limits<double>::min());
|
||||
ui->editDefault->setMaximum(std::numeric_limits<double>::max());
|
||||
ui->editDefault->setUnitText(_property->getColumnUnits(0));
|
||||
ui->editDefault->setValue(_value->getDefault().getValue().value<Base::Quantity>());
|
||||
if (!_value->defaultSet()) {
|
||||
_value->setDefault(_property->getColumnNull(0).value<Base::Quantity>());
|
||||
}
|
||||
ui->editDefault->setValue(_value->getDefault().value<Base::Quantity>());
|
||||
|
||||
connect(ui->editDefault,
|
||||
qOverload<const Base::Quantity&>(&Gui::QuantitySpinBox::valueChanged),
|
||||
@@ -117,6 +148,7 @@ void Array3D::setupDefault()
|
||||
void Array3D::defaultValueChanged(const Base::Quantity& value)
|
||||
{
|
||||
_value->setDefault(QVariant::fromValue(value));
|
||||
_material->setEditStateAlter();
|
||||
}
|
||||
|
||||
void Array3D::setDepthColumnDelegate(QTableView* table)
|
||||
@@ -140,10 +172,43 @@ void Array3D::setupDepthArray()
|
||||
auto table = ui->table3D;
|
||||
auto model = new Array3DDepthModel(_property, _value, this);
|
||||
table->setModel(model);
|
||||
table->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
// table->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
table->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
setDepthColumnWidth(table);
|
||||
setDepthColumnDelegate(table);
|
||||
connect(model, &QAbstractItemModel::rowsInserted, this, &Array3D::onRowsInserted);
|
||||
connect(model, &QAbstractItemModel::rowsRemoved, this, &Array3D::onRowsRemoved);
|
||||
connect(model, &QAbstractItemModel::dataChanged, this, &Array3D::onDataChanged);
|
||||
}
|
||||
|
||||
void Array3D::onRowsInserted(const QModelIndex& parent, int first, int last)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(first)
|
||||
Q_UNUSED(last)
|
||||
|
||||
update2DArray();
|
||||
}
|
||||
|
||||
void Array3D::onRowsRemoved(const QModelIndex& parent, int first, int last)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(first)
|
||||
Q_UNUSED(last)
|
||||
|
||||
update2DArray();
|
||||
}
|
||||
|
||||
void Array3D::onDataChanged(const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight,
|
||||
const QVector<int>& roles)
|
||||
{
|
||||
Q_UNUSED(topLeft)
|
||||
Q_UNUSED(bottomRight)
|
||||
Q_UNUSED(roles)
|
||||
|
||||
_material->setEditStateAlter();
|
||||
}
|
||||
|
||||
void Array3D::setColumnWidths(QTableView* table)
|
||||
@@ -174,10 +239,190 @@ void Array3D::setupArray()
|
||||
auto table = ui->table2D;
|
||||
auto model = new Array3DModel(_property, _value, this);
|
||||
table->setModel(model);
|
||||
table->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
// table->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
table->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
setColumnWidths(table);
|
||||
setColumnDelegates(table);
|
||||
|
||||
if (_value->depth() == 0) {
|
||||
table->setEnabled(false);
|
||||
}
|
||||
connect(model, &QAbstractItemModel::dataChanged, this, &Array3D::onDataChanged);
|
||||
}
|
||||
|
||||
void Array3D::onSelectDepth(const QItemSelection& selected, const QItemSelection& deselected)
|
||||
{
|
||||
Q_UNUSED(deselected);
|
||||
|
||||
QModelIndexList indexes = selected.indexes();
|
||||
|
||||
// This should be a list of length 1
|
||||
for (auto it = indexes.begin(); it != indexes.end(); it++) {
|
||||
_value->setCurrentDepth(it->row());
|
||||
break;
|
||||
}
|
||||
|
||||
update2DArray();
|
||||
}
|
||||
|
||||
void Array3D::update2DArray()
|
||||
{
|
||||
auto table = ui->table2D;
|
||||
auto model = static_cast<Array3DModel*>(table->model());
|
||||
model->updateData();
|
||||
table->setEnabled(_value->depth() > 0);
|
||||
}
|
||||
|
||||
void Array3D::onDepthContextMenu(const QPoint& pos)
|
||||
{
|
||||
Base::Console().Log("Array3D::onDepthContextMenu(%d,%d)\n", pos.x(), pos.y());
|
||||
QModelIndex index = ui->table3D->indexAt(pos);
|
||||
Base::Console().Log("\tindex at (%d,%d)\n", index.row(), index.column());
|
||||
|
||||
|
||||
QMenu contextMenu(tr("Context menu"), this);
|
||||
|
||||
contextMenu.addAction(&_deleteDepthAction);
|
||||
|
||||
contextMenu.exec(ui->table3D->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
bool Array3D::newDepthRow(const QModelIndex& index)
|
||||
{
|
||||
Array3DDepthModel* model = static_cast<Array3DDepthModel*>(ui->table3D->model());
|
||||
return model->newRow(index);
|
||||
}
|
||||
|
||||
void Array3D::onDepthDelete(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("Array3D::onDepthDelete()\n");
|
||||
QItemSelectionModel* selectionModel = ui->table3D->selectionModel();
|
||||
if (!selectionModel->hasSelection() || newDepthRow(selectionModel->currentIndex())) {
|
||||
Base::Console().Log("\tNothing selected\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int res = confirmDepthDelete();
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int Array3D::confirmDepthDelete()
|
||||
{
|
||||
QMessageBox box(this);
|
||||
box.setIcon(QMessageBox::Question);
|
||||
box.setWindowTitle(tr("Confirm Delete"));
|
||||
|
||||
QString prompt = tr("Are you sure you want to delete the row?");
|
||||
box.setText(prompt);
|
||||
box.setInformativeText(tr("Removing this will also remove all 2D contents."));
|
||||
|
||||
box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
box.setDefaultButton(QMessageBox::Cancel);
|
||||
box.setEscapeButton(QMessageBox::Cancel);
|
||||
|
||||
int res = QMessageBox::Cancel;
|
||||
box.adjustSize(); // Silence warnings from Qt on Windows
|
||||
switch (box.exec()) {
|
||||
case QMessageBox::Ok:
|
||||
deleteDepthSelected();
|
||||
res = QMessageBox::Ok;
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Array3D::deleteDepthSelected()
|
||||
{
|
||||
Array3DDepthModel* model = static_cast<Array3DDepthModel*>(ui->table3D->model());
|
||||
QItemSelectionModel* selectionModel = ui->table3D->selectionModel();
|
||||
auto index = selectionModel->currentIndex();
|
||||
model->deleteRow(index);
|
||||
|
||||
auto depth = _value->currentDepth();
|
||||
if (depth >= _value->depth()) {
|
||||
depth = depth - 1;
|
||||
}
|
||||
_value->setCurrentDepth(depth);
|
||||
update2DArray();
|
||||
}
|
||||
|
||||
void Array3D::on2DContextMenu(const QPoint& pos)
|
||||
{
|
||||
Base::Console().Log("Array3D::onDepthContextMenu(%d,%d)\n", pos.x(), pos.y());
|
||||
QModelIndex index = ui->table2D->indexAt(pos);
|
||||
Base::Console().Log("\tindex at (%d,%d)\n", index.row(), index.column());
|
||||
|
||||
|
||||
QMenu contextMenu(tr("Context menu"), this);
|
||||
|
||||
contextMenu.addAction(&_delete2DAction);
|
||||
|
||||
// contextMenu.exec(mapToGlobal(pos));
|
||||
contextMenu.exec(ui->table2D->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
bool Array3D::new2DRow(const QModelIndex& index)
|
||||
{
|
||||
Array3DModel* model = static_cast<Array3DModel*>(ui->table2D->model());
|
||||
return model->newRow(index);
|
||||
}
|
||||
|
||||
void Array3D::on2DDelete(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("Array3D::on2DDelete()\n");
|
||||
QItemSelectionModel* selectionModel = ui->table2D->selectionModel();
|
||||
if (!selectionModel->hasSelection() || new2DRow(selectionModel->currentIndex())) {
|
||||
Base::Console().Log("\tNothing selected\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int res = confirm2dDelete();
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int Array3D::confirm2dDelete()
|
||||
{
|
||||
QMessageBox box(this);
|
||||
box.setIcon(QMessageBox::Question);
|
||||
box.setWindowTitle(tr("Confirm Delete"));
|
||||
|
||||
QString prompt = tr("Are you sure you want to delete the row?");
|
||||
box.setText(prompt);
|
||||
|
||||
box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
box.setDefaultButton(QMessageBox::Cancel);
|
||||
box.setEscapeButton(QMessageBox::Cancel);
|
||||
|
||||
int res = QMessageBox::Cancel;
|
||||
box.adjustSize(); // Silence warnings from Qt on Windows
|
||||
switch (box.exec()) {
|
||||
case QMessageBox::Ok:
|
||||
delete2DSelected();
|
||||
res = QMessageBox::Ok;
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Array3D::delete2DSelected()
|
||||
{
|
||||
Array3DModel* model = static_cast<Array3DModel*>(ui->table2D->model());
|
||||
QItemSelectionModel* selectionModel = ui->table2D->selectionModel();
|
||||
auto index = selectionModel->currentIndex();
|
||||
model->deleteRow(index);
|
||||
|
||||
update2DArray();
|
||||
}
|
||||
|
||||
void Array3D::onOk(bool checked)
|
||||
|
||||
@@ -22,11 +22,10 @@
|
||||
#ifndef MATGUI_ARRAY3D_H
|
||||
#define MATGUI_ARRAY3D_H
|
||||
|
||||
#include <QAction>
|
||||
#include <QDialog>
|
||||
#include <QStandardItem>
|
||||
#include <QTableView>
|
||||
#include <Mod/Material/App/Materials.h>
|
||||
|
||||
namespace MatGui
|
||||
{
|
||||
|
||||
@@ -37,22 +36,42 @@ class Array3D: public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Array3D(const QString& propertyName,
|
||||
Materials::Material* material,
|
||||
QWidget* parent = nullptr);
|
||||
Array3D(const QString& propertyName,
|
||||
std::shared_ptr<Materials::Material> material,
|
||||
QWidget* parent = nullptr);
|
||||
~Array3D() override = default;
|
||||
|
||||
void defaultValueChanged(const Base::Quantity& value);
|
||||
void onRowsInserted(const QModelIndex& parent, int first, int last);
|
||||
void onRowsRemoved(const QModelIndex& parent, int first, int last);
|
||||
void onDataChanged(const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight,
|
||||
const QVector<int>& roles = QVector<int>());
|
||||
void onSelectDepth(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
bool onSplitter(QEvent* e);
|
||||
void onDepthDelete(bool checked);
|
||||
int confirmDepthDelete();
|
||||
void deleteDepthSelected();
|
||||
void on2DDelete(bool checked);
|
||||
int confirm2dDelete();
|
||||
void delete2DSelected();
|
||||
void onDepthContextMenu(const QPoint& pos);
|
||||
void on2DContextMenu(const QPoint& pos);
|
||||
|
||||
void onOk(bool checked);
|
||||
void onCancel(bool checked);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui_Array3D> ui;
|
||||
const Materials::MaterialProperty* _property;
|
||||
std::shared_ptr<Materials::Material> _material;
|
||||
std::shared_ptr<Materials::MaterialProperty> _property;
|
||||
std::shared_ptr<Materials::Material3DArray> _value;
|
||||
|
||||
QAction _deleteDepthAction;
|
||||
QAction _delete2DAction;
|
||||
|
||||
bool newDepthRow(const QModelIndex& index);
|
||||
bool new2DRow(const QModelIndex& index);
|
||||
void setupDefault();
|
||||
void setDepthColumnWidth(QTableView* table);
|
||||
void setDepthColumnDelegate(QTableView* table);
|
||||
@@ -60,6 +79,7 @@ private:
|
||||
void setColumnWidths(QTableView* table);
|
||||
void setColumnDelegates(QTableView* table);
|
||||
void setupArray();
|
||||
void update2DArray();
|
||||
};
|
||||
|
||||
} // namespace MatGui
|
||||
|
||||
@@ -156,8 +156,8 @@ QWidget* ArrayDelegate::createWidget(QWidget* parent, const QVariant& item) cons
|
||||
else if (_type == Materials::MaterialValue::Boolean) {
|
||||
Gui::PrefComboBox* combo = new Gui::PrefComboBox(parent);
|
||||
combo->insertItem(0, QString::fromStdString(""));
|
||||
combo->insertItem(1, QString::fromStdString("False"));
|
||||
combo->insertItem(2, QString::fromStdString("True"));
|
||||
combo->insertItem(1, tr("False"));
|
||||
combo->insertItem(2, tr("True"));
|
||||
combo->setCurrentText(item.toString());
|
||||
widget = combo;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
#ifndef MATGUI_ArrayDelegate_H
|
||||
#define MATGUI_ArrayDelegate_H
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDir>
|
||||
#include <QStandardItem>
|
||||
@@ -35,8 +33,6 @@
|
||||
#include <Mod/Material/App/Materials.h>
|
||||
#include <Mod/Material/App/ModelManager.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace MatGui
|
||||
{
|
||||
|
||||
@@ -44,10 +40,9 @@ class ArrayDelegate: public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ArrayDelegate(
|
||||
Materials::MaterialValue::ValueType type = Materials::MaterialValue::None,
|
||||
QString units = QString(),
|
||||
QObject* parent = nullptr);
|
||||
ArrayDelegate(Materials::MaterialValue::ValueType type = Materials::MaterialValue::None,
|
||||
QString units = QString(),
|
||||
QObject* parent = nullptr);
|
||||
virtual ~ArrayDelegate() = default;
|
||||
|
||||
void paint(QPainter* painter,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/MetaTypes.h>
|
||||
|
||||
@@ -46,7 +47,7 @@ AbstractArrayModel::AbstractArrayModel(QObject* parent)
|
||||
//===
|
||||
|
||||
|
||||
Array2DModel::Array2DModel(const Materials::MaterialProperty* property,
|
||||
Array2DModel::Array2DModel(std::shared_ptr<Materials::MaterialProperty> property,
|
||||
std::shared_ptr<Materials::Material2DArray> value,
|
||||
QObject* parent)
|
||||
: AbstractArrayModel(parent)
|
||||
@@ -68,6 +69,12 @@ bool Array2DModel::newRow(const QModelIndex& index) const
|
||||
return (index.row() == _value->rows());
|
||||
}
|
||||
|
||||
void Array2DModel::deleteRow(const QModelIndex& index)
|
||||
{
|
||||
removeRows(index.row(), 1);
|
||||
Q_EMIT dataChanged(index, index);
|
||||
}
|
||||
|
||||
int Array2DModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
@@ -145,7 +152,7 @@ bool Array2DModel::insertRows(int row, int count, const QModelIndex& parent)
|
||||
|
||||
int columns = columnCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
std::vector<QVariant>* rowPtr = new std::vector<QVariant>();
|
||||
auto rowPtr = std::make_shared<std::vector<QVariant>>();
|
||||
for (int j = 0; j < columns; j++) {
|
||||
rowPtr->push_back(_property->getColumnNull(j));
|
||||
}
|
||||
@@ -162,6 +169,10 @@ bool Array2DModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||
{
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
_value->deleteRow(row);
|
||||
}
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
return false;
|
||||
@@ -187,7 +198,7 @@ bool Array2DModel::removeColumns(int column, int count, const QModelIndex& paren
|
||||
|
||||
//===
|
||||
|
||||
Array3DDepthModel::Array3DDepthModel(const Materials::MaterialProperty* property,
|
||||
Array3DDepthModel::Array3DDepthModel(std::shared_ptr<Materials::MaterialProperty> property,
|
||||
std::shared_ptr<Materials::Material3DArray> value,
|
||||
QObject* parent)
|
||||
: AbstractArrayModel(parent)
|
||||
@@ -209,26 +220,34 @@ bool Array3DDepthModel::newRow(const QModelIndex& index) const
|
||||
return (index.row() == _value->depth());
|
||||
}
|
||||
|
||||
void Array3DDepthModel::deleteRow(const QModelIndex& index)
|
||||
{
|
||||
removeRows(index.row(), 1);
|
||||
Q_EMIT dataChanged(index, index);
|
||||
}
|
||||
|
||||
QVariant Array3DDepthModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole) {
|
||||
try {
|
||||
return _value->getValue(index.row(), index.column());
|
||||
Base::Quantity q = _value->getDepthValue(index.row());
|
||||
return QVariant::fromValue(q);
|
||||
}
|
||||
catch (const Materials::InvalidDepth&) {
|
||||
}
|
||||
catch (const Materials::InvalidRow&) {
|
||||
}
|
||||
catch (const Materials::InvalidColumn&) {
|
||||
}
|
||||
catch (const Materials::InvalidIndex&) {
|
||||
}
|
||||
|
||||
try {
|
||||
auto column = _property->getColumnType(index.column());
|
||||
if (column == Materials::MaterialValue::Quantity) {
|
||||
Base::Quantity q = Base::Quantity(0, _property->getColumnUnits(index.column()));
|
||||
return QVariant::fromValue(q);
|
||||
}
|
||||
Base::Quantity q = Base::Quantity(0, _property->getColumnUnits(0));
|
||||
return QVariant::fromValue(q);
|
||||
}
|
||||
catch (const Materials::InvalidColumn&) {
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -259,8 +278,9 @@ bool Array3DDepthModel::setData(const QModelIndex& index, const QVariant& value,
|
||||
|
||||
if (index.row() == _value->depth()) {
|
||||
insertRows(index.row(), 1);
|
||||
_value->setCurrentDepth(index.row());
|
||||
}
|
||||
_value->setValue(index.row(), index.column(), value);
|
||||
_value->setDepthValue(index.row(), value.value<Base::Quantity>());
|
||||
|
||||
Q_EMIT dataChanged(index, index);
|
||||
return true;
|
||||
@@ -277,14 +297,8 @@ bool Array3DDepthModel::insertRows(int row, int count, const QModelIndex& parent
|
||||
{
|
||||
beginInsertRows(parent, row, row + count - 1);
|
||||
|
||||
int columns = columnCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
std::vector<QVariant>* rowPtr = new std::vector<QVariant>();
|
||||
for (int j = 0; j < columns; j++) {
|
||||
rowPtr->push_back(_property->getColumnNull(j));
|
||||
}
|
||||
|
||||
// _value->insertRow(row, rowPtr);
|
||||
_value->addDepth(row, Base::Quantity(0, _property->getColumnUnits(0)));
|
||||
}
|
||||
|
||||
endInsertRows();
|
||||
@@ -296,6 +310,10 @@ bool Array3DDepthModel::removeRows(int row, int count, const QModelIndex& parent
|
||||
{
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
_value->deleteDepth(row);
|
||||
}
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
return false;
|
||||
@@ -321,7 +339,7 @@ bool Array3DDepthModel::removeColumns(int column, int count, const QModelIndex&
|
||||
|
||||
//===
|
||||
|
||||
Array3DModel::Array3DModel(const Materials::MaterialProperty* property,
|
||||
Array3DModel::Array3DModel(std::shared_ptr<Materials::MaterialProperty> property,
|
||||
std::shared_ptr<Materials::Material3DArray> value,
|
||||
QObject* parent)
|
||||
: AbstractArrayModel(parent)
|
||||
@@ -335,7 +353,15 @@ int Array3DModel::rowCount(const QModelIndex& parent) const
|
||||
return 0; // No children
|
||||
}
|
||||
|
||||
return _value->depth() + 1; // Will always have 1 empty row
|
||||
try {
|
||||
return _value->rows() + 1; // Will always have 1 empty row
|
||||
}
|
||||
catch (const Materials::InvalidDepth&) {
|
||||
return 1;
|
||||
}
|
||||
catch (const Materials::InvalidRow&) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int Array3DModel::columnCount(const QModelIndex& parent) const
|
||||
@@ -347,15 +373,36 @@ int Array3DModel::columnCount(const QModelIndex& parent) const
|
||||
|
||||
bool Array3DModel::newRow(const QModelIndex& index) const
|
||||
{
|
||||
return (index.row() == _value->depth());
|
||||
try {
|
||||
return (index.row() == _value->rows());
|
||||
}
|
||||
catch (const Materials::InvalidDepth&) {
|
||||
return true;
|
||||
}
|
||||
catch (const Materials::InvalidRow&) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Array3DModel::deleteRow(const QModelIndex& index)
|
||||
{
|
||||
removeRows(index.row(), 1);
|
||||
Q_EMIT dataChanged(index, index);
|
||||
}
|
||||
|
||||
QVariant Array3DModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole) {
|
||||
Base::Console().Error("Row %d, column %d\n", index.row(), index.column());
|
||||
// Base::Console().Log("Row %d, column %d\n", index.row(), index.column());
|
||||
try {
|
||||
return _value->getValue(index.row(), index.column() + 1);
|
||||
Base::Quantity q = _value->getValue(index.row(), index.column());
|
||||
return QVariant::fromValue(q);
|
||||
}
|
||||
catch (const Materials::InvalidDepth&) {
|
||||
}
|
||||
catch (const Materials::InvalidRow&) {
|
||||
}
|
||||
catch (const Materials::InvalidColumn&) {
|
||||
}
|
||||
catch (const Materials::InvalidIndex&) {
|
||||
}
|
||||
@@ -364,16 +411,11 @@ QVariant Array3DModel::data(const QModelIndex& index, int role) const
|
||||
}
|
||||
|
||||
try {
|
||||
auto column = _property->getColumnType(index.column() + 1);
|
||||
if (column == Materials::MaterialValue::Quantity) {
|
||||
Base::Quantity q = Base::Quantity(0, _property->getColumnUnits(index.column() - 1));
|
||||
return QVariant::fromValue(q);
|
||||
}
|
||||
Base::Quantity q = Base::Quantity(0, _property->getColumnUnits(index.column() + 1));
|
||||
return QVariant::fromValue(q);
|
||||
}
|
||||
catch (const Materials::InvalidColumn&) {
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -402,10 +444,32 @@ bool Array3DModel::setData(const QModelIndex& index, const QVariant& value, int
|
||||
{
|
||||
Q_UNUSED(role);
|
||||
|
||||
if (index.row() == _value->depth()) {
|
||||
Base::Console().Log("Array3DModel::setData at (%d, %d, %d)\n",
|
||||
_value->currentDepth(),
|
||||
index.row(),
|
||||
index.column());
|
||||
|
||||
if (_value->depth() == 0) {
|
||||
// Create the first row
|
||||
// _value->addDepth(Base::Quantity(0, _property->getColumnUnits(0)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index.row() == _value->rows()) {
|
||||
insertRows(index.row(), 1);
|
||||
}
|
||||
_value->setValue(index.row(), index.column(), value);
|
||||
try {
|
||||
_value->setValue(index.row(), index.column(), value.value<Base::Quantity>());
|
||||
}
|
||||
catch (const Materials::InvalidDepth&) {
|
||||
Base::Console().Error("Array3DModel::setData - InvalidDepth");
|
||||
}
|
||||
catch (const Materials::InvalidRow&) {
|
||||
Base::Console().Error("Array3DModel::setData - invalidRow");
|
||||
}
|
||||
catch (const Materials::InvalidColumn&) {
|
||||
Base::Console().Error("Array3DModel::setData - InvalidColumn");
|
||||
}
|
||||
|
||||
Q_EMIT dataChanged(index, index);
|
||||
return true;
|
||||
@@ -424,12 +488,12 @@ bool Array3DModel::insertRows(int row, int count, const QModelIndex& parent)
|
||||
|
||||
int columns = columnCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
std::vector<QVariant>* rowPtr = new std::vector<QVariant>();
|
||||
auto rowPtr = std::make_shared<std::vector<Base::Quantity>>();
|
||||
for (int j = 0; j < columns; j++) {
|
||||
rowPtr->push_back(_property->getColumnNull(j));
|
||||
rowPtr->push_back(_property->getColumnNull(j).value<Base::Quantity>());
|
||||
}
|
||||
|
||||
// _value->insertRow(row, rowPtr);
|
||||
_value->insertRow(row, rowPtr);
|
||||
}
|
||||
|
||||
endInsertRows();
|
||||
@@ -441,6 +505,10 @@ bool Array3DModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||
{
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
_value->deleteRow(row);
|
||||
}
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
return false;
|
||||
@@ -463,3 +531,13 @@ bool Array3DModel::removeColumns(int column, int count, const QModelIndex& paren
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Array3DModel::updateData()
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
// The table has changed at this point, typically by setting the current depth.
|
||||
// The existing structure needs to be cleared and the table redrawn.
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#ifndef MATGUI_ARRAYMODEL_H
|
||||
#define MATGUI_ARRAYMODEL_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QDialog>
|
||||
#include <QStandardItem>
|
||||
@@ -36,7 +38,7 @@ namespace MatGui
|
||||
class AbstractArrayModel: public QAbstractTableModel
|
||||
{
|
||||
public:
|
||||
explicit AbstractArrayModel(QObject* parent = nullptr);
|
||||
AbstractArrayModel(QObject* parent = nullptr);
|
||||
~AbstractArrayModel() override = default;
|
||||
|
||||
virtual bool newRow(const QModelIndex& index) const = 0;
|
||||
@@ -45,14 +47,15 @@ public:
|
||||
class Array2DModel: public AbstractArrayModel
|
||||
{
|
||||
public:
|
||||
explicit Array2DModel(const Materials::MaterialProperty* property = nullptr,
|
||||
std::shared_ptr<Materials::Material2DArray> value = nullptr,
|
||||
QObject* parent = nullptr);
|
||||
Array2DModel(std::shared_ptr<Materials::MaterialProperty> property = nullptr,
|
||||
std::shared_ptr<Materials::Material2DArray> value = nullptr,
|
||||
QObject* parent = nullptr);
|
||||
~Array2DModel() override = default;
|
||||
|
||||
// Overridden virtual functions
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
bool newRow(const QModelIndex& index) const override;
|
||||
void deleteRow(const QModelIndex& index);
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant
|
||||
@@ -67,21 +70,22 @@ public:
|
||||
bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex()) override;
|
||||
|
||||
private:
|
||||
const Materials::MaterialProperty* _property;
|
||||
std::shared_ptr<Materials::MaterialProperty> _property;
|
||||
std::shared_ptr<Materials::Material2DArray> _value;
|
||||
};
|
||||
|
||||
class Array3DDepthModel: public AbstractArrayModel
|
||||
{
|
||||
public:
|
||||
explicit Array3DDepthModel(const Materials::MaterialProperty* property = nullptr,
|
||||
std::shared_ptr<Materials::Material3DArray> value = nullptr,
|
||||
QObject* parent = nullptr);
|
||||
Array3DDepthModel(std::shared_ptr<Materials::MaterialProperty> property = nullptr,
|
||||
std::shared_ptr<Materials::Material3DArray> value = nullptr,
|
||||
QObject* parent = nullptr);
|
||||
~Array3DDepthModel() override = default;
|
||||
|
||||
// Overridden virtual functions
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
bool newRow(const QModelIndex& index) const override;
|
||||
void deleteRow(const QModelIndex& index);
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
@@ -100,21 +104,22 @@ public:
|
||||
bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex()) override;
|
||||
|
||||
private:
|
||||
const Materials::MaterialProperty* _property;
|
||||
std::shared_ptr<Materials::MaterialProperty> _property;
|
||||
std::shared_ptr<Materials::Material3DArray> _value;
|
||||
};
|
||||
|
||||
class Array3DModel: public AbstractArrayModel
|
||||
{
|
||||
public:
|
||||
explicit Array3DModel(const Materials::MaterialProperty* property = nullptr,
|
||||
std::shared_ptr<Materials::Material3DArray> value = nullptr,
|
||||
QObject* parent = nullptr);
|
||||
Array3DModel(std::shared_ptr<Materials::MaterialProperty> property = nullptr,
|
||||
std::shared_ptr<Materials::Material3DArray> value = nullptr,
|
||||
QObject* parent = nullptr);
|
||||
~Array3DModel() override = default;
|
||||
|
||||
// Overridden virtual functions
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
bool newRow(const QModelIndex& index) const override;
|
||||
void deleteRow(const QModelIndex& index);
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant
|
||||
@@ -128,8 +133,10 @@ public:
|
||||
bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex()) override;
|
||||
bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex()) override;
|
||||
|
||||
void updateData();
|
||||
|
||||
private:
|
||||
const Materials::MaterialProperty* _property;
|
||||
std::shared_ptr<Materials::MaterialProperty> _property;
|
||||
std::shared_ptr<Materials::Material3DArray> _value;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class DlgSettingsMaterial: public Gui::Dialog::PreferencePage
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DlgSettingsMaterial(QWidget* parent = nullptr);
|
||||
DlgSettingsMaterial(QWidget* parent = nullptr);
|
||||
~DlgSettingsMaterial() override = default;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -88,7 +88,7 @@ bool MaterialDelegate::editorEvent(QEvent* event,
|
||||
std::string type = propertyType.toStdString();
|
||||
if (type == "Color") {
|
||||
Base::Console().Log("Edit color\n");
|
||||
showColorModal(item);
|
||||
showColorModal(item, propertyName);
|
||||
// Mark as handled
|
||||
return true;
|
||||
}
|
||||
@@ -109,7 +109,7 @@ bool MaterialDelegate::editorEvent(QEvent* event,
|
||||
return QStyledItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
||||
|
||||
void MaterialDelegate::showColorModal(QStandardItem* item)
|
||||
void MaterialDelegate::showColorModal(QStandardItem* item, QString propertyName)
|
||||
{
|
||||
QColor currentColor; // = d->col;
|
||||
currentColor.setRgba(parseColor(item->text()));
|
||||
@@ -126,14 +126,18 @@ void MaterialDelegate::showColorModal(QStandardItem* item)
|
||||
|
||||
connect(dlg, &QColorDialog::finished, this, [&](int result) {
|
||||
if (result == QDialog::Accepted) {
|
||||
Base::Console().Log("Accepted\n");
|
||||
QColor color = dlg->selectedColor();
|
||||
if (color.isValid()) {
|
||||
Base::Console().Log("isValid\n");
|
||||
QString colorText = QString(QString::fromStdString("(%1,%2,%3,%4)"))
|
||||
.arg(color.red() / 255.0)
|
||||
.arg(color.green() / 255.0)
|
||||
.arg(color.blue() / 255.0)
|
||||
.arg(color.alpha() / 255.0);
|
||||
item->setText(colorText);
|
||||
Q_EMIT const_cast<MaterialDelegate*>(this)->propertyChange(propertyName,
|
||||
item->text());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -143,7 +147,7 @@ void MaterialDelegate::showColorModal(QStandardItem* item)
|
||||
|
||||
void MaterialDelegate::showArray2DModal(const QString& propertyName, QStandardItem* item)
|
||||
{
|
||||
Materials::Material* material = item->data().value<Materials::Material*>();
|
||||
auto material = item->data().value<std::shared_ptr<Materials::Material>>();
|
||||
Array2D* dlg = new Array2D(propertyName, material);
|
||||
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
@@ -161,7 +165,7 @@ void MaterialDelegate::showArray2DModal(const QString& propertyName, QStandardIt
|
||||
|
||||
void MaterialDelegate::showArray3DModal(const QString& propertyName, QStandardItem* item)
|
||||
{
|
||||
Materials::Material* material = item->data().value<Materials::Material*>();
|
||||
auto material = item->data().value<std::shared_ptr<Materials::Material>>();
|
||||
Array3D* dlg = new Array3D(propertyName, material);
|
||||
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
@@ -411,8 +415,8 @@ QWidget* MaterialDelegate::createWidget(QWidget* parent,
|
||||
else if (type == "Boolean") {
|
||||
Gui::PrefComboBox* combo = new Gui::PrefComboBox(parent);
|
||||
combo->insertItem(0, QString::fromStdString(""));
|
||||
combo->insertItem(1, QString::fromStdString("False"));
|
||||
combo->insertItem(2, QString::fromStdString("True"));
|
||||
combo->insertItem(1, tr("False"));
|
||||
combo->insertItem(2, tr("True"));
|
||||
combo->setCurrentText(propertyValue);
|
||||
widget = combo;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
#ifndef MATGUI_MATERIALDELEGATE_H
|
||||
#define MATGUI_MATERIALDELEGATE_H
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDir>
|
||||
#include <QStandardItem>
|
||||
@@ -35,8 +33,6 @@
|
||||
#include <Mod/Material/App/Materials.h>
|
||||
#include <Mod/Material/App/ModelManager.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace MatGui
|
||||
{
|
||||
|
||||
@@ -44,7 +40,7 @@ class MaterialDelegate: public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MaterialDelegate(QObject* parent = nullptr);
|
||||
MaterialDelegate(QObject* parent = nullptr);
|
||||
~MaterialDelegate() override = default;
|
||||
|
||||
QWidget* createEditor(QWidget* parent,
|
||||
@@ -76,7 +72,7 @@ private:
|
||||
const QString& propertyValue,
|
||||
const QString& propertyUnits) const;
|
||||
QRgb parseColor(const QString& color) const;
|
||||
void showColorModal(QStandardItem* item);
|
||||
void showColorModal(QStandardItem* item, QString propertyName);
|
||||
void showArray2DModal(const QString& propertyName, QStandardItem* item);
|
||||
void showArray3DModal(const QString& propertyName, QStandardItem* item);
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QTreeView>
|
||||
#endif
|
||||
@@ -36,12 +37,15 @@ using namespace MatGui;
|
||||
|
||||
/* TRANSLATOR MatGui::MaterialsEditor */
|
||||
|
||||
MaterialSave::MaterialSave(Materials::Material* material, QWidget* parent)
|
||||
MaterialSave::MaterialSave(std::shared_ptr<Materials::Material> material, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui_MaterialSave)
|
||||
, _material(material)
|
||||
, _saveInherited(true)
|
||||
, _selectedPath(QString::fromStdString("/"))
|
||||
, _selectedFull(QString::fromStdString("/"))
|
||||
, _selectedUUID(QString())
|
||||
, _deleteAction(this)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@@ -57,6 +61,9 @@ MaterialSave::MaterialSave(Materials::Material* material, QWidget* parent)
|
||||
}
|
||||
_filename = QString(ui->editFilename->text()); // No filename by default
|
||||
|
||||
ui->checkDerived->setChecked(_saveInherited);
|
||||
connect(ui->checkDerived, &QCheckBox::stateChanged, this, &MaterialSave::onInherited);
|
||||
|
||||
connect(ui->standardButtons->button(QDialogButtonBox::Ok),
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
@@ -73,11 +80,25 @@ MaterialSave::MaterialSave(Materials::Material* material, QWidget* parent)
|
||||
connect(ui->buttonNewFolder, &QPushButton::clicked, this, &MaterialSave::onNewFolder);
|
||||
connect(ui->editFilename, &QLineEdit::textEdited, this, &MaterialSave::onFilename);
|
||||
|
||||
ui->treeMaterials->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->treeMaterials,
|
||||
&QWidget::customContextMenuRequested,
|
||||
this,
|
||||
&MaterialSave::onContextMenu);
|
||||
|
||||
_deleteAction.setText(tr("Delete"));
|
||||
_deleteAction.setShortcut(Qt::Key_Delete);
|
||||
connect(&_deleteAction, &QAction::triggered, this, &MaterialSave::onDelete);
|
||||
ui->treeMaterials->addAction(&_deleteAction);
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
connect(selectionModel,
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
this,
|
||||
&MaterialSave::onSelectModel);
|
||||
|
||||
auto model = static_cast<QStandardItemModel*>(ui->treeMaterials->model());
|
||||
connect(model, &QStandardItemModel::itemChanged, this, &MaterialSave::onItemChanged);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -88,6 +109,13 @@ MaterialSave::~MaterialSave()
|
||||
// no need to delete child widgets, Qt does it all for us
|
||||
}
|
||||
|
||||
void MaterialSave::onInherited(int state)
|
||||
{
|
||||
Q_UNUSED(state)
|
||||
|
||||
_saveInherited = ui->checkDerived->isChecked();
|
||||
}
|
||||
|
||||
void MaterialSave::onOk(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
@@ -100,18 +128,145 @@ void MaterialSave::onOk(bool checked)
|
||||
}
|
||||
|
||||
auto variant = ui->comboLibrary->currentData();
|
||||
auto library = variant.value<Materials::MaterialLibrary>();
|
||||
auto library = variant.value<std::shared_ptr<Materials::MaterialLibrary>>();
|
||||
QFileInfo filepath(_selectedPath + QString::fromStdString("/") + name
|
||||
+ QString::fromStdString(".FCMat"));
|
||||
Base::Console().Log("saveMaterial(library(%s), material(%s), path(%s))\n",
|
||||
library.getName().toStdString().c_str(),
|
||||
library->getName().toStdString().c_str(),
|
||||
_material->getName().toStdString().c_str(),
|
||||
filepath.filePath().toStdString().c_str());
|
||||
_manager.saveMaterial(&library, *_material, filepath.filePath());
|
||||
|
||||
if (library->fileExists(filepath.filePath())) {
|
||||
// confirm overwrite
|
||||
auto res = confirmOverwrite(_filename);
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
|
||||
_manager.saveMaterial(library, _material, filepath.filePath(), true, false, _saveInherited);
|
||||
accept();
|
||||
return;
|
||||
}
|
||||
|
||||
bool saveAsCopy = false;
|
||||
if (_manager.exists(_material->getUUID())) {
|
||||
// Does it already exist in this library?
|
||||
if (_manager.exists(library, _material->getUUID())) {
|
||||
// Confirm saving a new material
|
||||
auto res = confirmNewMaterial();
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
// saveAsCopy = false = already done
|
||||
}
|
||||
else {
|
||||
// Copy or new
|
||||
auto res = confirmCopy();
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
else if (res == QMessageBox::Save) {
|
||||
// QMessageBox::Save saves as normal, a duplicate
|
||||
saveAsCopy = true;
|
||||
}
|
||||
// QMessageBox::Ok saves a new material
|
||||
}
|
||||
}
|
||||
|
||||
_manager
|
||||
.saveMaterial(library, _material, filepath.filePath(), false, saveAsCopy, _saveInherited);
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
int MaterialSave::confirmOverwrite(const QString& filename)
|
||||
{
|
||||
QMessageBox box(this);
|
||||
box.setIcon(QMessageBox::Question);
|
||||
box.setWindowTitle(QObject::tr("Confirm Overwrite"));
|
||||
|
||||
QFileInfo info(_selectedFull);
|
||||
QString prompt = tr("Are you sure you want to save over '%1'?").arg(filename);
|
||||
box.setText(prompt);
|
||||
|
||||
box.setInformativeText(tr("Saving over the original file may cause other documents to break. "
|
||||
"This is not recommended."));
|
||||
|
||||
box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
box.setDefaultButton(QMessageBox::Cancel);
|
||||
box.setEscapeButton(QMessageBox::Cancel);
|
||||
|
||||
int res = QMessageBox::Cancel;
|
||||
box.adjustSize(); // Silence warnings from Qt on Windows
|
||||
switch (box.exec()) {
|
||||
case QMessageBox::Ok:
|
||||
res = QMessageBox::Ok;
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int MaterialSave::confirmNewMaterial()
|
||||
{
|
||||
QMessageBox box(this);
|
||||
box.setIcon(QMessageBox::Question);
|
||||
box.setWindowTitle(tr("Confirm Save As New Material"));
|
||||
|
||||
QString prompt = tr("Save as new material");
|
||||
box.setText(prompt);
|
||||
|
||||
box.setInformativeText(tr(
|
||||
"This material already exists in this library. Would you like to save as a new material?"));
|
||||
|
||||
box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
box.setDefaultButton(QMessageBox::Cancel);
|
||||
box.setEscapeButton(QMessageBox::Cancel);
|
||||
|
||||
int res = QMessageBox::Cancel;
|
||||
box.adjustSize(); // Silence warnings from Qt on Windows
|
||||
switch (box.exec()) {
|
||||
case QMessageBox::Ok:
|
||||
res = QMessageBox::Ok;
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int MaterialSave::confirmCopy()
|
||||
{
|
||||
QMessageBox box(this);
|
||||
box.setIcon(QMessageBox::Question);
|
||||
box.setWindowTitle(tr("Confirm Save As Copy"));
|
||||
|
||||
QString prompt = tr("Save as Copy");
|
||||
box.setText(prompt);
|
||||
|
||||
box.setInformativeText(tr("Saving a copy is not recommended as it can break other documents. "
|
||||
"We recommend you save as a new material."));
|
||||
|
||||
QPushButton* duplicateButton = box.addButton(tr("Save Copy"), QMessageBox::AcceptRole);
|
||||
QPushButton* newButton = box.addButton(tr("Save As New"), QMessageBox::ActionRole);
|
||||
QPushButton* cancelButton = box.addButton(QMessageBox::Cancel);
|
||||
|
||||
box.setDefaultButton(cancelButton);
|
||||
box.setEscapeButton(cancelButton);
|
||||
|
||||
box.adjustSize(); // Silence warnings from Qt on Windows
|
||||
box.exec();
|
||||
|
||||
int res = QMessageBox::Cancel;
|
||||
if (box.clickedButton() == duplicateButton) {
|
||||
res = QMessageBox::Save;
|
||||
}
|
||||
else if (box.clickedButton() == newButton) {
|
||||
res = QMessageBox::Ok;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void MaterialSave::onCancel(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
@@ -135,7 +290,7 @@ void MaterialSave::setLibraries()
|
||||
for (auto library : *libraries) {
|
||||
if (!library->isReadOnly()) {
|
||||
QVariant libraryVariant;
|
||||
libraryVariant.setValue(*library);
|
||||
libraryVariant.setValue(library);
|
||||
ui->comboLibrary->addItem(library->getName(), libraryVariant);
|
||||
}
|
||||
}
|
||||
@@ -163,31 +318,34 @@ void MaterialSave::addExpanded(QTreeView* tree, QStandardItemModel* parent, QSta
|
||||
|
||||
void MaterialSave::addMaterials(
|
||||
QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, Materials::MaterialTreeNode*>> modelTree,
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::MaterialTreeNode>>>
|
||||
modelTree,
|
||||
const QIcon& folderIcon,
|
||||
const QIcon& icon)
|
||||
{
|
||||
auto tree = ui->treeMaterials;
|
||||
for (auto& mat : *modelTree) {
|
||||
Materials::MaterialTreeNode* nodePtr = mat.second;
|
||||
std::shared_ptr<Materials::MaterialTreeNode> nodePtr = mat.second;
|
||||
if (nodePtr->getType() == Materials::MaterialTreeNode::DataNode) {
|
||||
const Materials::Material* material = nodePtr->getData();
|
||||
std::shared_ptr<Materials::Material> material = nodePtr->getData();
|
||||
QString uuid = material->getUUID();
|
||||
Base::Console().Log("Material path '%s'\n",
|
||||
material->getDirectory().toStdString().c_str());
|
||||
|
||||
// auto card = new QStandardItem(icon, material->getName());
|
||||
auto card = new QStandardItem(icon, mat.first);
|
||||
// card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
// | Qt::ItemIsDropEnabled);
|
||||
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
card->setData(QVariant(uuid), Qt::UserRole);
|
||||
|
||||
addExpanded(tree, &parent, card);
|
||||
}
|
||||
else {
|
||||
Base::Console().Log("Material folder path '%s'\n", mat.first.toStdString().c_str());
|
||||
auto node = new QStandardItem(folderIcon, mat.first);
|
||||
node->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled | Qt::ItemIsEditable);
|
||||
addExpanded(tree, &parent, node);
|
||||
// node->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
|
||||
auto treeMap = nodePtr->getFolder();
|
||||
addMaterials(*node, treeMap, folderIcon, icon);
|
||||
}
|
||||
@@ -202,13 +360,14 @@ void MaterialSave::showSelectedTree()
|
||||
|
||||
if (ui->comboLibrary->count() > 0) {
|
||||
auto variant = ui->comboLibrary->currentData();
|
||||
auto library = variant.value<Materials::MaterialLibrary>();
|
||||
QIcon icon(library.getIconPath());
|
||||
auto library = variant.value<std::shared_ptr<Materials::MaterialLibrary>>();
|
||||
QIcon icon(library->getIconPath());
|
||||
QIcon folderIcon(QString::fromStdString(":/icons/folder.svg"));
|
||||
_libraryName = library.getName();
|
||||
_libraryName = library->getName();
|
||||
_selectedPath = QString::fromStdString("/") + _libraryName;
|
||||
_selectedFull = _selectedPath;
|
||||
|
||||
auto lib = new QStandardItem(library.getName());
|
||||
auto lib = new QStandardItem(library->getName());
|
||||
lib->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, model, lib);
|
||||
|
||||
@@ -246,6 +405,7 @@ void MaterialSave::onSelectModel(const QItemSelection& selected, const QItemSele
|
||||
if (indexes.count() == 0) {
|
||||
Base::Console().Log("Nothing selected\n");
|
||||
_selectedPath = QString::fromStdString("/") + _libraryName;
|
||||
_selectedFull = _selectedPath;
|
||||
_selectedUUID = QString();
|
||||
Base::Console().Log("\tSelected path '%s'\n", _selectedPath.toStdString().c_str());
|
||||
return;
|
||||
@@ -258,11 +418,13 @@ void MaterialSave::onSelectModel(const QItemSelection& selected, const QItemSele
|
||||
if (_selected.isValid()) {
|
||||
Base::Console().Log("\tuuid %s\n", _selected.toString().toStdString().c_str());
|
||||
_selectedPath = getPath(item->parent());
|
||||
_selectedFull = getPath(item);
|
||||
_selectedUUID = _selected.toString();
|
||||
_filename = item->text();
|
||||
}
|
||||
else {
|
||||
_selectedPath = getPath(item);
|
||||
_selectedFull = _selectedPath;
|
||||
_selectedUUID = QString();
|
||||
}
|
||||
}
|
||||
@@ -282,6 +444,34 @@ void MaterialSave::currentTextChanged(const QString& value)
|
||||
showSelectedTree();
|
||||
}
|
||||
|
||||
std::shared_ptr<Materials::MaterialLibrary> MaterialSave::currentLibrary()
|
||||
{
|
||||
auto variant = ui->comboLibrary->currentData();
|
||||
return variant.value<std::shared_ptr<Materials::MaterialLibrary>>();
|
||||
}
|
||||
|
||||
void MaterialSave::createFolder(const QString& path)
|
||||
{
|
||||
auto library = currentLibrary();
|
||||
|
||||
_manager.createFolder(library, path);
|
||||
}
|
||||
|
||||
void MaterialSave::renameFolder(const QString& oldPath, const QString& newPath)
|
||||
{
|
||||
auto library = currentLibrary();
|
||||
|
||||
_manager.renameFolder(library, oldPath, newPath);
|
||||
}
|
||||
|
||||
void MaterialSave::deleteRecursive(const QString& path)
|
||||
{
|
||||
// This will delete files, folders, and any children
|
||||
auto library = currentLibrary();
|
||||
|
||||
_manager.deleteRecursive(library, path);
|
||||
}
|
||||
|
||||
void MaterialSave::onNewFolder(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
@@ -293,16 +483,53 @@ void MaterialSave::onNewFolder(bool checked)
|
||||
current = model->index(0, 0);
|
||||
}
|
||||
auto item = model->itemFromIndex(current);
|
||||
|
||||
// Check for existing folders starting "New Folder" to prevent duplicates
|
||||
int newCount = 0;
|
||||
if (item->hasChildren()) {
|
||||
for (auto i = 0; i < item->rowCount(); i++) {
|
||||
auto child = item->child(i);
|
||||
if (child->text().startsWith(tr("New Folder"))) {
|
||||
newCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Folders have no associated data
|
||||
if (item->data(Qt::UserRole).isNull()) {
|
||||
Base::Console().Log("Add new folder to '%s'\n", item->text().toStdString().c_str());
|
||||
QIcon folderIcon(QString::fromStdString(":/icons/folder.svg"));
|
||||
|
||||
auto node = new QStandardItem(folderIcon, QString::fromStdString("New Folder"));
|
||||
QString folderName = tr("New Folder");
|
||||
if (newCount > 0) {
|
||||
folderName += QString::number(newCount);
|
||||
}
|
||||
auto node = new QStandardItem(folderIcon, folderName);
|
||||
node->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled | Qt::ItemIsEditable);
|
||||
addExpanded(tree, item, node);
|
||||
// node->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
|
||||
Base::Console().Log("New folder index valid: %s\n",
|
||||
node->index().isValid() ? "true" : "false");
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
selectionModel->select(node->index(),
|
||||
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Current);
|
||||
|
||||
createFolder(getPath(node));
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialSave::onItemChanged(QStandardItem* item)
|
||||
{
|
||||
Base::Console().Log("MaterialSave::onItemChanged('%s')\n", item->text().toStdString().c_str());
|
||||
QString oldPath = _selectedPath;
|
||||
_selectedPath = getPath(item);
|
||||
_selectedFull = _selectedPath;
|
||||
Base::Console().Log("\tSelected path '%s'\n", _selectedPath.toStdString().c_str());
|
||||
renameFolder(oldPath, _selectedPath);
|
||||
}
|
||||
|
||||
void MaterialSave::onFilename(const QString& text)
|
||||
{
|
||||
Base::Console().Log("MaterialSave::onFilename('%s')\n", text.toStdString().c_str());
|
||||
@@ -310,4 +537,135 @@ void MaterialSave::onFilename(const QString& text)
|
||||
_filename = text;
|
||||
}
|
||||
|
||||
QString MaterialSave::pathFromIndex(const QModelIndex& index) const
|
||||
{
|
||||
auto model = static_cast<const QStandardItemModel*>(index.model());
|
||||
auto item = model->itemFromIndex(index);
|
||||
return getPath(item);
|
||||
}
|
||||
|
||||
void MaterialSave::onContextMenu(const QPoint& pos)
|
||||
{
|
||||
Base::Console().Log("MaterialSave::onContextMenu(%d,%d)\n", pos.x(), pos.y());
|
||||
QModelIndex index = ui->treeMaterials->indexAt(pos);
|
||||
QString path = pathFromIndex(index);
|
||||
Base::Console().Log("\tindex at (%d,%d)->'%s'\n",
|
||||
index.row(),
|
||||
index.column(),
|
||||
path.toStdString().c_str());
|
||||
|
||||
|
||||
QMenu contextMenu(tr("Context menu"), this);
|
||||
|
||||
// QAction action1(tr("Delete"), this);
|
||||
// action1.setShortcut(Qt::Key_Delete);
|
||||
// connect(&action1, &QAction::triggered, this, &MaterialSave::onDelete);
|
||||
contextMenu.addAction(&_deleteAction);
|
||||
|
||||
contextMenu.exec(ui->treeMaterials->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void MaterialSave::onDelete(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("MaterialSave::onDelete()\n");
|
||||
QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
if (!selectionModel->hasSelection()) {
|
||||
Base::Console().Log("\tNothing selected\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Base::Console().Log("\tSelected path '%s'\n", _selectedFull.toStdString().c_str());
|
||||
int res = confirmDelete(this);
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int MaterialSave::confirmDelete(QWidget* parent)
|
||||
{
|
||||
auto library = currentLibrary();
|
||||
|
||||
if (library->isRoot(_selectedFull)) {
|
||||
return QMessageBox::Cancel;
|
||||
}
|
||||
|
||||
QMessageBox box(parent ? parent : this);
|
||||
box.setIcon(QMessageBox::Question);
|
||||
box.setWindowTitle(QObject::tr("Confirm Delete"));
|
||||
|
||||
QFileInfo info(_selectedFull);
|
||||
QString prompt = QObject::tr("Are you sure you want to delete '%1'?").arg(info.fileName());
|
||||
box.setText(prompt);
|
||||
|
||||
if (selectedHasChildren()) {
|
||||
box.setInformativeText(QObject::tr("Removing this will also remove all contents."));
|
||||
}
|
||||
box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
box.setDefaultButton(QMessageBox::Cancel);
|
||||
box.setEscapeButton(QMessageBox::Cancel);
|
||||
|
||||
int res = QMessageBox::Cancel;
|
||||
box.adjustSize(); // Silence warnings from Qt on Windows
|
||||
switch (box.exec()) {
|
||||
case QMessageBox::Ok:
|
||||
deleteSelected();
|
||||
res = QMessageBox::Ok;
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool MaterialSave::selectedHasChildren()
|
||||
{
|
||||
auto tree = ui->treeMaterials;
|
||||
auto model = static_cast<QStandardItemModel*>(tree->model());
|
||||
auto current = tree->currentIndex();
|
||||
if (!current.isValid()) {
|
||||
current = model->index(0, 0);
|
||||
}
|
||||
auto item = model->itemFromIndex(current);
|
||||
|
||||
return item->hasChildren();
|
||||
}
|
||||
|
||||
void MaterialSave::deleteSelected()
|
||||
{
|
||||
Base::Console().Log("\tDelete selected path '%s'\n", _selectedFull.toStdString().c_str());
|
||||
auto library = currentLibrary();
|
||||
|
||||
if (!library->isRoot(_selectedFull)) {
|
||||
_manager.deleteRecursive(library, _selectedFull);
|
||||
removeSelectedFromTree();
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialSave::removeChildren(QStandardItem* item)
|
||||
{
|
||||
while (item->rowCount() > 0) {
|
||||
auto child = item->child(0);
|
||||
removeChildren(child);
|
||||
item->removeRow(0);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialSave::removeSelectedFromTree()
|
||||
{
|
||||
auto tree = ui->treeMaterials;
|
||||
auto model = static_cast<QStandardItemModel*>(tree->model());
|
||||
auto current = tree->currentIndex();
|
||||
if (current.row() >= 0) {
|
||||
auto item = model->itemFromIndex(current);
|
||||
|
||||
// Remove the children
|
||||
removeChildren(item);
|
||||
item->parent()->removeRow(item->row());
|
||||
}
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
selectionModel->clear();
|
||||
}
|
||||
|
||||
#include "moc_MaterialSave.cpp"
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
#ifndef MATGUI_MATERIALSAVE_H
|
||||
#define MATGUI_MATERIALSAVE_H
|
||||
|
||||
// #include <boost/filesystem.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include <QAction>
|
||||
#include <QDialog>
|
||||
#include <QItemSelection>
|
||||
#include <QStandardItem>
|
||||
@@ -41,39 +42,61 @@ class MaterialSave: public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MaterialSave(Materials::Material* material, QWidget* parent = nullptr);
|
||||
MaterialSave(std::shared_ptr<Materials::Material> material, QWidget* parent = nullptr);
|
||||
~MaterialSave() override;
|
||||
|
||||
void setLibraries();
|
||||
void createModelTree();
|
||||
void addExpanded(QTreeView* tree, QStandardItem* parent, QStandardItem* child);
|
||||
void addExpanded(QTreeView* tree, QStandardItemModel* parent, QStandardItem* child);
|
||||
void
|
||||
addMaterials(QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, Materials::MaterialTreeNode*>> modelTree,
|
||||
const QIcon& folderIcon,
|
||||
const QIcon& icon);
|
||||
void addMaterials(
|
||||
QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::MaterialTreeNode>>>
|
||||
modelTree,
|
||||
const QIcon& folderIcon,
|
||||
const QIcon& icon);
|
||||
void showSelectedTree();
|
||||
|
||||
void onSelectModel(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
void currentTextChanged(const QString& value);
|
||||
void onNewFolder(bool checked);
|
||||
void onItemChanged(QStandardItem* item);
|
||||
void onFilename(const QString& text);
|
||||
void onContextMenu(const QPoint& pos);
|
||||
void onDelete(bool checked);
|
||||
void onInherited(int state);
|
||||
void onOk(bool checked);
|
||||
void onCancel(bool checked);
|
||||
int confirmOverwrite(const QString& filename);
|
||||
int confirmNewMaterial();
|
||||
int confirmCopy();
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui_MaterialSave> ui;
|
||||
Materials::MaterialManager _manager;
|
||||
Materials::Material* _material;
|
||||
std::shared_ptr<Materials::Material> _material;
|
||||
bool _saveInherited;
|
||||
QString _selectedPath;
|
||||
QString _selectedFull;
|
||||
QString _selectedUUID;
|
||||
QString _libraryName;
|
||||
QString _filename;
|
||||
|
||||
QAction _deleteAction;
|
||||
|
||||
QString getPath(const QStandardItem* item) const;
|
||||
std::shared_ptr<Materials::MaterialLibrary> currentLibrary();
|
||||
void createFolder(const QString& path);
|
||||
void renameFolder(const QString& oldPath, const QString& newPath);
|
||||
void deleteRecursive(const QString& path);
|
||||
QString pathFromIndex(const QModelIndex& index) const;
|
||||
int confirmDelete(QWidget* parent);
|
||||
bool selectedHasChildren();
|
||||
void deleteSelected();
|
||||
void removeChildren(QStandardItem* item);
|
||||
void removeSelectedFromTree();
|
||||
};
|
||||
|
||||
} // namespace MatGui
|
||||
|
||||
@@ -83,6 +83,30 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkDerived">
|
||||
<property name="text">
|
||||
<string>Save as Inherited</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="standardButtons">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <QDesktopServices>
|
||||
#include <QIODevice>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
@@ -35,6 +36,7 @@
|
||||
#include <limits>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/License.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/Quantity.h>
|
||||
#include <Gui/Application.h>
|
||||
@@ -61,6 +63,7 @@ using namespace MatGui;
|
||||
MaterialsEditor::MaterialsEditor(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui_MaterialsEditor)
|
||||
, _material(std::make_shared<Materials::Material>())
|
||||
, _edited(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@@ -72,6 +75,7 @@ MaterialsEditor::MaterialsEditor(QWidget* parent)
|
||||
createPhysicalTree();
|
||||
createAppearanceTree();
|
||||
createPreviews();
|
||||
setMaterialDefaults();
|
||||
|
||||
ui->buttonURL->setIcon(QIcon(QString::fromStdString(":/icons/internet-web-browser.svg")));
|
||||
|
||||
@@ -88,12 +92,35 @@ MaterialsEditor::MaterialsEditor(QWidget* parent)
|
||||
this,
|
||||
&MaterialsEditor::onSave);
|
||||
|
||||
connect(ui->editName, &QLineEdit::textEdited, this, &MaterialsEditor::onName);
|
||||
connect(ui->editAuthor, &QLineEdit::textEdited, this, &MaterialsEditor::onAuthor);
|
||||
connect(ui->editLicense, &QLineEdit::textEdited, this, &MaterialsEditor::onLicense);
|
||||
connect(ui->editSourceURL, &QLineEdit::textEdited, this, &MaterialsEditor::onSourceURL);
|
||||
connect(ui->editSourceReference,
|
||||
&QLineEdit::textEdited,
|
||||
this,
|
||||
&MaterialsEditor::onSourceReference);
|
||||
connect(ui->editDescription, &QTextEdit::textChanged, this, &MaterialsEditor::onDescription);
|
||||
|
||||
connect(ui->buttonURL, &QPushButton::clicked, this, &MaterialsEditor::onURL);
|
||||
connect(ui->buttonPhysicalAdd, &QPushButton::clicked, this, &MaterialsEditor::onPhysicalAdd);
|
||||
connect(ui->buttonPhysicalRemove,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&MaterialsEditor::onPhysicalRemove);
|
||||
connect(ui->buttonAppearanceAdd,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&MaterialsEditor::onAppearanceAdd);
|
||||
connect(ui->buttonAppearanceRemove,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&MaterialsEditor::onAppearanceRemove);
|
||||
connect(ui->buttonInheritNew,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&MaterialsEditor::onInheritNewMaterial);
|
||||
connect(ui->buttonNew, &QPushButton::clicked, this, &MaterialsEditor::onNewMaterial);
|
||||
connect(ui->buttonFavorite, &QPushButton::clicked, this, &MaterialsEditor::onFavourite);
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
@@ -101,6 +128,13 @@ MaterialsEditor::MaterialsEditor(QWidget* parent)
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
this,
|
||||
&MaterialsEditor::onSelectMaterial);
|
||||
connect(ui->treeMaterials, &QTreeView::doubleClicked, this, &MaterialsEditor::onDoubleClick);
|
||||
|
||||
ui->treeMaterials->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->treeMaterials,
|
||||
&QWidget::customContextMenuRequested,
|
||||
this,
|
||||
&MaterialsEditor::onContextMenu);
|
||||
}
|
||||
|
||||
void MaterialsEditor::getFavorites()
|
||||
@@ -144,7 +178,7 @@ void MaterialsEditor::addFavorite(const QString& uuid)
|
||||
{
|
||||
// Ensure it is a material. New, unsaved materials will not be
|
||||
try {
|
||||
const Materials::Material& material = _materialManager.getMaterial(uuid);
|
||||
auto material = _materialManager.getMaterial(uuid);
|
||||
Q_UNUSED(material)
|
||||
}
|
||||
catch (const Materials::MaterialNotFound&) {
|
||||
@@ -227,7 +261,7 @@ void MaterialsEditor::addRecent(const QString& uuid)
|
||||
{
|
||||
// Ensure it is a material. New, unsaved materials will not be
|
||||
try {
|
||||
const Materials::Material& material = _materialManager.getMaterial(uuid);
|
||||
auto material = _materialManager.getMaterial(uuid);
|
||||
Q_UNUSED(material)
|
||||
}
|
||||
catch (const Materials::MaterialNotFound&) {
|
||||
@@ -257,16 +291,46 @@ bool MaterialsEditor::isRecent(const QString& uuid) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void MaterialsEditor::onName(const QString& text)
|
||||
{
|
||||
_material->setName(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onAuthor(const QString& text)
|
||||
{
|
||||
_material->setAuthor(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onLicense(const QString& text)
|
||||
{
|
||||
_material->setLicense(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onSourceURL(const QString& text)
|
||||
{
|
||||
_material->setURL(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onSourceReference(const QString& text)
|
||||
{
|
||||
_material->setReference(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onDescription()
|
||||
{
|
||||
_material->setDescription(ui->editDescription->toPlainText());
|
||||
}
|
||||
|
||||
void MaterialsEditor::propertyChange(const QString& property, const QString value)
|
||||
{
|
||||
Base::Console().Log("MaterialsEditor::propertyChange(%s) = '%s'\n",
|
||||
property.toStdString().c_str(),
|
||||
value.toStdString().c_str());
|
||||
if (_material.hasPhysicalProperty(property)) {
|
||||
_material.setPhysicalValue(property, value);
|
||||
if (_material->hasPhysicalProperty(property)) {
|
||||
_material->setPhysicalValue(property, value);
|
||||
}
|
||||
else if (_material.hasAppearanceProperty(property)) {
|
||||
_material.setAppearanceValue(property, value);
|
||||
else if (_material->hasAppearanceProperty(property)) {
|
||||
_material->setAppearanceValue(property, value);
|
||||
updatePreview();
|
||||
}
|
||||
_edited = true;
|
||||
@@ -287,12 +351,12 @@ void MaterialsEditor::onPhysicalAdd(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
ModelSelect dialog(this, Materials::ModelManager::ModelFilter_Physical);
|
||||
ModelSelect dialog(this, Materials::ModelFilter_Physical);
|
||||
dialog.setModal(true);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
QString selected = dialog.selectedModel();
|
||||
Base::Console().Log("Selected model '%s'\n", selected.toStdString().c_str());
|
||||
_material.addPhysical(selected);
|
||||
_material->addPhysical(selected);
|
||||
updateMaterial();
|
||||
}
|
||||
else {
|
||||
@@ -300,16 +364,39 @@ void MaterialsEditor::onPhysicalAdd(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::onPhysicalRemove(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->treePhysicalProperties->selectionModel();
|
||||
if (selectionModel->hasSelection()) {
|
||||
const QModelIndex index = selectionModel->currentIndex().siblingAtColumn(0);
|
||||
|
||||
const QStandardItemModel* treeModel = static_cast<const QStandardItemModel*>(index.model());
|
||||
|
||||
// Check we're the material model root.
|
||||
auto item = treeModel->itemFromIndex(index);
|
||||
auto group = item->parent();
|
||||
if (!group) {
|
||||
QString propertyName = index.data().toString();
|
||||
|
||||
QString uuid = _material->getModelByName(propertyName);
|
||||
_material->removePhysical(uuid);
|
||||
updateMaterial();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::onAppearanceAdd(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
ModelSelect dialog(this, Materials::ModelManager::ModelFilter_Appearance);
|
||||
ModelSelect dialog(this, Materials::ModelFilter_Appearance);
|
||||
dialog.setModal(true);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
QString selected = dialog.selectedModel();
|
||||
Base::Console().Log("Selected model '%s'\n", selected.toStdString().c_str());
|
||||
_material.addAppearance(selected);
|
||||
_material->addAppearance(selected);
|
||||
updateMaterial();
|
||||
}
|
||||
else {
|
||||
@@ -317,12 +404,35 @@ void MaterialsEditor::onAppearanceAdd(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::onAppearanceRemove(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->treeAppearance->selectionModel();
|
||||
if (selectionModel->hasSelection()) {
|
||||
const QModelIndex index = selectionModel->currentIndex().siblingAtColumn(0);
|
||||
|
||||
const QStandardItemModel* treeModel = static_cast<const QStandardItemModel*>(index.model());
|
||||
|
||||
// Check we're the material model root.
|
||||
auto item = treeModel->itemFromIndex(index);
|
||||
auto group = item->parent();
|
||||
if (!group) {
|
||||
QString propertyName = index.data().toString();
|
||||
|
||||
QString uuid = _material->getModelByName(propertyName);
|
||||
_material->removeAppearance(uuid);
|
||||
updateMaterial();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::onFavourite(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("Favorite\n");
|
||||
auto selected = _material.getUUID();
|
||||
auto selected = _material->getUUID();
|
||||
if (isFavorite(selected)) {
|
||||
removeFavorite(selected);
|
||||
}
|
||||
@@ -331,6 +441,76 @@ void MaterialsEditor::onFavourite(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::setMaterialDefaults()
|
||||
{
|
||||
_material->setName(tr("Unnamed"));
|
||||
std::string Author = App::GetApplication()
|
||||
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document")
|
||||
->GetASCII("prefAuthor", "");
|
||||
_material->setAuthor(QString::fromStdString(Author));
|
||||
|
||||
// license stuff
|
||||
auto paramGrp {App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Document")};
|
||||
auto index = static_cast<int>(paramGrp->GetInt("prefLicenseType", 0));
|
||||
const char* name = App::licenseItems.at(index).at(App::posnOfFullName);
|
||||
// const char* url = App::licenseItems.at(index).at(App::posnOfUrl);
|
||||
// std::string licenseUrl = (paramGrp->GetASCII("prefLicenseUrl", url));
|
||||
_material->setLicense(QString::fromStdString(name));
|
||||
|
||||
// Empty materials will have no parent
|
||||
_materialManager.dereference(_material);
|
||||
|
||||
updateMaterial();
|
||||
_material->resetEditState();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onNewMaterial(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("New Material\n");
|
||||
|
||||
// Ensure data is saved (or discarded) before changing materials
|
||||
if (_material->getEditState() != Materials::Material::ModelEdit_None) {
|
||||
// Prompt the user to save or discard changes
|
||||
Base::Console().Log("*** Material edited!!!\n");
|
||||
int res = confirmSave(this);
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new material
|
||||
_material = std::make_shared<Materials::Material>();
|
||||
setMaterialDefaults();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onInheritNewMaterial(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("Inherit New Material\n");
|
||||
|
||||
// Save the current UUID to use as out parent
|
||||
auto parent = _material->getUUID();
|
||||
|
||||
// Ensure data is saved (or discarded) before changing materials
|
||||
if (_material->getEditState() != Materials::Material::ModelEdit_None) {
|
||||
// Prompt the user to save or discard changes
|
||||
Base::Console().Log("*** Material edited!!!\n");
|
||||
int res = confirmSave(this);
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new material
|
||||
_material = std::make_shared<Materials::Material>();
|
||||
_material->setParentUUID(parent);
|
||||
setMaterialDefaults();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onOk(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
@@ -354,17 +534,18 @@ void MaterialsEditor::onSave(bool checked)
|
||||
|
||||
void MaterialsEditor::saveMaterial()
|
||||
{
|
||||
MaterialSave dialog(&_material, this);
|
||||
MaterialSave dialog(_material, this);
|
||||
dialog.setModal(true);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
_material.resetEditState();
|
||||
updateMaterialGeneral();
|
||||
_material->resetEditState();
|
||||
refreshMaterialTree();
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::accept()
|
||||
{
|
||||
addRecent(_material.getUUID());
|
||||
addRecent(_material->getUUID());
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
@@ -379,15 +560,16 @@ void MaterialsEditor::reject()
|
||||
|
||||
void MaterialsEditor::addMaterials(
|
||||
QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, Materials::MaterialTreeNode*>> modelTree,
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::MaterialTreeNode>>>
|
||||
modelTree,
|
||||
const QIcon& folderIcon,
|
||||
const QIcon& icon)
|
||||
{
|
||||
auto tree = ui->treeMaterials;
|
||||
for (auto& mat : *modelTree) {
|
||||
Materials::MaterialTreeNode* nodePtr = mat.second;
|
||||
std::shared_ptr<Materials::MaterialTreeNode> nodePtr = mat.second;
|
||||
if (nodePtr->getType() == Materials::MaterialTreeNode::DataNode) {
|
||||
const Materials::Material* material = nodePtr->getData();
|
||||
auto material = nodePtr->getData();
|
||||
QString uuid = material->getUUID();
|
||||
// Base::Console().Log("Material path '%s'\n",
|
||||
// material->getDirectory().toStdString().c_str());
|
||||
@@ -429,9 +611,9 @@ void MaterialsEditor::createPhysicalTree()
|
||||
tree->setModel(model);
|
||||
|
||||
QStringList headers;
|
||||
headers.append(QString::fromStdString("Property"));
|
||||
headers.append(QString::fromStdString("Value"));
|
||||
headers.append(QString::fromStdString("Type"));
|
||||
headers.append(tr("Property"));
|
||||
headers.append(tr("Value"));
|
||||
headers.append(tr("Type"));
|
||||
model->setHorizontalHeaderLabels(headers);
|
||||
|
||||
tree->setColumnWidth(0, 250);
|
||||
@@ -444,6 +626,12 @@ void MaterialsEditor::createPhysicalTree()
|
||||
tree->setItemDelegateForColumn(1, delegate);
|
||||
|
||||
connect(delegate, &MaterialDelegate::propertyChange, this, &MaterialsEditor::propertyChange);
|
||||
|
||||
// QItemSelectionModel* selectionModel = ui->treePhysicalProperties->selectionModel();
|
||||
// connect(selectionModel,
|
||||
// &QItemSelectionModel::selectionChanged,
|
||||
// this,
|
||||
// &MaterialsEditor::onSelectPhysicalProperty);
|
||||
}
|
||||
|
||||
void MaterialsEditor::createPreviews()
|
||||
@@ -468,9 +656,9 @@ void MaterialsEditor::createAppearanceTree()
|
||||
tree->setModel(model);
|
||||
|
||||
QStringList headers;
|
||||
headers.append(QString::fromStdString("Property"));
|
||||
headers.append(QString::fromStdString("Value"));
|
||||
headers.append(QString::fromStdString("Type"));
|
||||
headers.append(tr("Property"));
|
||||
headers.append(tr("Value"));
|
||||
headers.append(tr("Type"));
|
||||
model->setHorizontalHeaderLabels(headers);
|
||||
|
||||
tree->setColumnWidth(0, 250);
|
||||
@@ -490,10 +678,10 @@ void MaterialsEditor::addRecents(QStandardItem* parent)
|
||||
auto tree = ui->treeMaterials;
|
||||
for (auto& uuid : _recents) {
|
||||
try {
|
||||
const Materials::Material& material = getMaterialManager().getMaterial(uuid);
|
||||
auto material = getMaterialManager().getMaterial(uuid);
|
||||
|
||||
QIcon icon = QIcon(material.getLibrary().getIconPath());
|
||||
auto card = new QStandardItem(icon, material.getName());
|
||||
QIcon icon = QIcon(material->getLibrary()->getIconPath());
|
||||
auto card = new QStandardItem(icon, libraryPath(material));
|
||||
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
card->setData(QVariant(uuid), Qt::UserRole);
|
||||
@@ -510,10 +698,10 @@ void MaterialsEditor::addFavorites(QStandardItem* parent)
|
||||
auto tree = ui->treeMaterials;
|
||||
for (auto& uuid : _favorites) {
|
||||
try {
|
||||
const Materials::Material& material = getMaterialManager().getMaterial(uuid);
|
||||
auto material = getMaterialManager().getMaterial(uuid);
|
||||
|
||||
QIcon icon = QIcon(material.getLibrary().getIconPath());
|
||||
auto card = new QStandardItem(icon, material.getName());
|
||||
QIcon icon = QIcon(material->getLibrary()->getIconPath());
|
||||
auto card = new QStandardItem(icon, libraryPath(material));
|
||||
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
card->setData(QVariant(uuid), Qt::UserRole);
|
||||
@@ -530,12 +718,12 @@ void MaterialsEditor::fillMaterialTree()
|
||||
auto tree = ui->treeMaterials;
|
||||
auto model = static_cast<QStandardItemModel*>(tree->model());
|
||||
|
||||
auto lib = new QStandardItem(QString::fromStdString("Favorites"));
|
||||
auto lib = new QStandardItem(tr("Favorites"));
|
||||
lib->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, model, lib);
|
||||
addFavorites(lib);
|
||||
|
||||
lib = new QStandardItem(QString::fromStdString("Recent"));
|
||||
lib = new QStandardItem(tr("Recent"));
|
||||
lib->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, model, lib);
|
||||
addRecents(lib);
|
||||
@@ -549,7 +737,7 @@ void MaterialsEditor::fillMaterialTree()
|
||||
QIcon icon(library->getIconPath());
|
||||
QIcon folderIcon(QString::fromStdString(":/icons/folder.svg"));
|
||||
|
||||
auto modelTree = _materialManager.getMaterialTree(*library);
|
||||
auto modelTree = _materialManager.getMaterialTree(library);
|
||||
addMaterials(*lib, modelTree, folderIcon, icon);
|
||||
}
|
||||
}
|
||||
@@ -582,23 +770,23 @@ void MaterialsEditor::updatePreview() const
|
||||
QString highlightColor;
|
||||
QString sectionColor;
|
||||
|
||||
if (_material.hasAppearanceProperty(QString::fromStdString("DiffuseColor"))) {
|
||||
diffuseColor = _material.getAppearanceValueString(QString::fromStdString("DiffuseColor"));
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("DiffuseColor"))) {
|
||||
diffuseColor = _material->getAppearanceValueString(QString::fromStdString("DiffuseColor"));
|
||||
}
|
||||
else if (_material.hasAppearanceProperty(QString::fromStdString("ViewColor"))) {
|
||||
diffuseColor = _material.getAppearanceValueString(QString::fromStdString("ViewColor"));
|
||||
else if (_material->hasAppearanceProperty(QString::fromStdString("ViewColor"))) {
|
||||
diffuseColor = _material->getAppearanceValueString(QString::fromStdString("ViewColor"));
|
||||
}
|
||||
else if (_material.hasAppearanceProperty(QString::fromStdString("Color"))) {
|
||||
diffuseColor = _material.getAppearanceValueString(QString::fromStdString("Color"));
|
||||
else if (_material->hasAppearanceProperty(QString::fromStdString("Color"))) {
|
||||
diffuseColor = _material->getAppearanceValueString(QString::fromStdString("Color"));
|
||||
}
|
||||
|
||||
if (_material.hasAppearanceProperty(QString::fromStdString("SpecularColor"))) {
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("SpecularColor"))) {
|
||||
highlightColor =
|
||||
_material.getAppearanceValueString(QString::fromStdString("SpecularColor"));
|
||||
_material->getAppearanceValueString(QString::fromStdString("SpecularColor"));
|
||||
}
|
||||
|
||||
if (_material.hasAppearanceProperty(QString::fromStdString("SectionColor"))) {
|
||||
sectionColor = _material.getAppearanceValueString(QString::fromStdString("SectionColor"));
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("SectionColor"))) {
|
||||
sectionColor = _material->getAppearanceValueString(QString::fromStdString("SectionColor"));
|
||||
}
|
||||
|
||||
if ((diffuseColor.length() + highlightColor.length()) > 0) {
|
||||
@@ -678,28 +866,28 @@ void MaterialsEditor::updateMaterialAppearance()
|
||||
treeModel->clear();
|
||||
|
||||
QStringList headers;
|
||||
headers.append(QString::fromStdString("Property"));
|
||||
headers.append(QString::fromStdString("Value"));
|
||||
headers.append(QString::fromStdString("Type"));
|
||||
headers.append(tr("Property"));
|
||||
headers.append(tr("Value"));
|
||||
headers.append(tr("Type"));
|
||||
treeModel->setHorizontalHeaderLabels(headers);
|
||||
|
||||
tree->setColumnWidth(0, 250);
|
||||
tree->setColumnWidth(1, 250);
|
||||
tree->setColumnHidden(2, true);
|
||||
|
||||
const std::vector<QString>* models = _material.getAppearanceModels();
|
||||
auto models = _material->getAppearanceModels();
|
||||
if (models) {
|
||||
for (auto it = models->begin(); it != models->end(); it++) {
|
||||
QString uuid = *it;
|
||||
try {
|
||||
const Materials::Model& model = getModelManager().getModel(uuid);
|
||||
QString name = model.getName();
|
||||
auto model = getModelManager().getModel(uuid);
|
||||
QString name = model->getName();
|
||||
|
||||
auto modelRoot = new QStandardItem(name);
|
||||
modelRoot->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, treeModel, modelRoot);
|
||||
for (auto itp = model.begin(); itp != model.end(); itp++) {
|
||||
for (auto itp = model->begin(); itp != model->end(); itp++) {
|
||||
QList<QStandardItem*> items;
|
||||
|
||||
QString key = itp->first;
|
||||
@@ -707,10 +895,10 @@ void MaterialsEditor::updateMaterialAppearance()
|
||||
propertyItem->setToolTip(itp->second.getDescription());
|
||||
items.append(propertyItem);
|
||||
|
||||
auto valueItem = new QStandardItem(_material.getAppearanceValueString(key));
|
||||
auto valueItem = new QStandardItem(_material->getAppearanceValueString(key));
|
||||
valueItem->setToolTip(itp->second.getDescription());
|
||||
QVariant variant;
|
||||
variant.setValue(&_material);
|
||||
variant.setValue(_material);
|
||||
valueItem->setData(variant);
|
||||
items.append(valueItem);
|
||||
|
||||
@@ -737,10 +925,10 @@ void MaterialsEditor::updateMaterialProperties()
|
||||
treeModel->clear();
|
||||
|
||||
QStringList headers;
|
||||
headers.append(QString::fromStdString("Property"));
|
||||
headers.append(QString::fromStdString("Value"));
|
||||
headers.append(QString::fromStdString("Type"));
|
||||
headers.append(QString::fromStdString("Units"));
|
||||
headers.append(tr("Property"));
|
||||
headers.append(tr("Value"));
|
||||
headers.append(tr("Type"));
|
||||
headers.append(tr("Units"));
|
||||
treeModel->setHorizontalHeaderLabels(headers);
|
||||
|
||||
tree->setColumnWidth(0, 250);
|
||||
@@ -748,19 +936,19 @@ void MaterialsEditor::updateMaterialProperties()
|
||||
tree->setColumnHidden(2, true);
|
||||
tree->setColumnHidden(3, true);
|
||||
|
||||
const std::vector<QString>* models = _material.getPhysicalModels();
|
||||
auto models = _material->getPhysicalModels();
|
||||
if (models) {
|
||||
for (auto it = models->begin(); it != models->end(); it++) {
|
||||
QString uuid = *it;
|
||||
try {
|
||||
const Materials::Model& model = getModelManager().getModel(uuid);
|
||||
QString name = model.getName();
|
||||
auto model = getModelManager().getModel(uuid);
|
||||
QString name = model->getName();
|
||||
|
||||
auto modelRoot = new QStandardItem(name);
|
||||
modelRoot->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, treeModel, modelRoot);
|
||||
for (auto itp = model.begin(); itp != model.end(); itp++) {
|
||||
for (auto itp = model->begin(); itp != model->end(); itp++) {
|
||||
QList<QStandardItem*> items;
|
||||
|
||||
QString key = itp->first;
|
||||
@@ -770,10 +958,10 @@ void MaterialsEditor::updateMaterialProperties()
|
||||
propertyItem->setToolTip(modelProperty.getDescription());
|
||||
items.append(propertyItem);
|
||||
|
||||
auto valueItem = new QStandardItem(_material.getPhysicalValueString(key));
|
||||
auto valueItem = new QStandardItem(_material->getPhysicalValueString(key));
|
||||
valueItem->setToolTip(modelProperty.getDescription());
|
||||
QVariant variant;
|
||||
variant.setValue(&_material);
|
||||
variant.setValue(_material);
|
||||
valueItem->setData(variant);
|
||||
items.append(valueItem);
|
||||
|
||||
@@ -794,17 +982,47 @@ void MaterialsEditor::updateMaterialProperties()
|
||||
}
|
||||
}
|
||||
|
||||
QString MaterialsEditor::libraryPath(std::shared_ptr<Materials::Material> material) const
|
||||
{
|
||||
QString path;
|
||||
auto library = material->getLibrary();
|
||||
if (library) {
|
||||
path = QString::fromStdString("/%1/%2")
|
||||
.arg(material->getLibrary()->getName())
|
||||
.arg(material->getDirectory());
|
||||
}
|
||||
else {
|
||||
path = QString::fromStdString("%1").arg(material->getDirectory());
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void MaterialsEditor::updateMaterialGeneral()
|
||||
{
|
||||
QString parentString;
|
||||
try {
|
||||
auto parent = _materialManager.getParent(_material);
|
||||
parentString = libraryPath(parent);
|
||||
}
|
||||
catch (const Materials::MaterialNotFound&) {
|
||||
}
|
||||
|
||||
// Update the general information
|
||||
ui->editName->setText(_material->getName());
|
||||
ui->editAuthor->setText(_material->getAuthor());
|
||||
ui->editLicense->setText(_material->getLicense());
|
||||
ui->editParent->setText(parentString);
|
||||
ui->editParent->setReadOnly(true);
|
||||
ui->editSourceURL->setText(_material->getURL());
|
||||
ui->editSourceReference->setText(_material->getReference());
|
||||
// ui->editTags->setText(_material->getName());
|
||||
ui->editDescription->setText(_material->getDescription());
|
||||
}
|
||||
|
||||
void MaterialsEditor::updateMaterial()
|
||||
{
|
||||
// Update the general information
|
||||
ui->editName->setText(_material.getName());
|
||||
ui->editAuthorLicense->setText(_material.getAuthorAndLicense());
|
||||
// ui->editParent->setText(_material.getName());
|
||||
ui->editSourceURL->setText(_material.getURL());
|
||||
ui->editSourceReference->setText(_material.getReference());
|
||||
// ui->editTags->setText(_material.getName());
|
||||
ui->editDescription->setText(_material.getDescription());
|
||||
|
||||
updateMaterialGeneral();
|
||||
updateMaterialProperties();
|
||||
updateMaterialAppearance();
|
||||
|
||||
@@ -830,13 +1048,13 @@ void MaterialsEditor::onSelectMaterial(const QItemSelection& selected,
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid.isEmpty() || uuid == _material.getUUID()) {
|
||||
if (uuid.isEmpty() || uuid == _material->getUUID()) {
|
||||
Base::Console().Log("*** Unchanged material '%s'\n", uuid.toStdString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure data is saved (or discarded) before changing materials
|
||||
if (_material.getEditState() != Materials::Material::ModelEdit_None) {
|
||||
if (_material->getEditState() != Materials::Material::ModelEdit_None) {
|
||||
// Prompt the user to save or discard changes
|
||||
Base::Console().Log("*** Material edited!!!\n");
|
||||
int res = confirmSave(this);
|
||||
@@ -847,16 +1065,85 @@ void MaterialsEditor::onSelectMaterial(const QItemSelection& selected,
|
||||
|
||||
// Get the selected material
|
||||
try {
|
||||
_material = getMaterialManager().getMaterial(uuid);
|
||||
_material = std::make_shared<Materials::Material>(*getMaterialManager().getMaterial(uuid));
|
||||
}
|
||||
catch (Materials::ModelNotFound const&) {
|
||||
Base::Console().Log("*** Unable to load material '%s'\n", uuid.toStdString().c_str());
|
||||
Materials::Material empty;
|
||||
_material = empty;
|
||||
_material = std::make_shared<Materials::Material>();
|
||||
}
|
||||
|
||||
updateMaterial();
|
||||
_material.resetEditState();
|
||||
_material->resetEditState();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onDoubleClick(const QModelIndex& index)
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
Base::Console().Log("MaterialsEditor::onDoubleClick()\n");
|
||||
accept();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onContextMenu(const QPoint& pos)
|
||||
{
|
||||
Base::Console().Log("MaterialsEditor::onContextMenu(%d,%d)\n", pos.x(), pos.y());
|
||||
// QModelIndex index = ui->treeMaterials->indexAt(pos);
|
||||
// QString path = pathFromIndex(index);
|
||||
// Base::Console().Log("\tindex at (%d,%d)->'%s'\n",
|
||||
// index.row(),
|
||||
// index.column(),
|
||||
// path.toStdString().c_str());
|
||||
|
||||
|
||||
QMenu contextMenu(tr("Context menu"), this);
|
||||
|
||||
QAction action1(tr("Inherit from"), this);
|
||||
// action1.setShortcut(Qt::Key_Delete);
|
||||
connect(&action1, &QAction::triggered, this, &MaterialsEditor::onInherit);
|
||||
contextMenu.addAction(&action1);
|
||||
|
||||
QAction action2(tr("Inherit new material"), this);
|
||||
// action1.setShortcut(Qt::Key_Delete);
|
||||
connect(&action2, &QAction::triggered, this, &MaterialsEditor::onInheritNew);
|
||||
contextMenu.addAction(&action2);
|
||||
|
||||
contextMenu.exec(ui->treeMaterials->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void MaterialsEditor::onInherit(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("MaterialsEditor::onInherit()\n");
|
||||
// QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
// if (!selectionModel->hasSelection()) {
|
||||
// Base::Console().Log("\tNothing selected\n");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Base::Console().Log("\tSelected path '%s'\n", _selectedFull.toStdString().c_str());
|
||||
// int res = confirmDelete(this);
|
||||
// if (res == QMessageBox::Cancel) {
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
void MaterialsEditor::onInheritNew(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("MaterialsEditor::onInherit()\n");
|
||||
// QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
// if (!selectionModel->hasSelection()) {
|
||||
// Base::Console().Log("\tNothing selected\n");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Base::Console().Log("\tSelected path '%s'\n", _selectedFull.toStdString().c_str());
|
||||
// int res = confirmDelete(this);
|
||||
// if (res == QMessageBox::Cancel) {
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
int MaterialsEditor::confirmSave(QWidget* parent)
|
||||
|
||||
@@ -22,10 +22,11 @@
|
||||
#ifndef MATGUI_MATERIALSEDITOR_H
|
||||
#define MATGUI_MATERIALSEDITOR_H
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDir>
|
||||
#include <QPoint>
|
||||
#include <QStandardItem>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QSvgWidget>
|
||||
@@ -35,8 +36,6 @@
|
||||
#include <Mod/Material/App/Materials.h>
|
||||
#include <Mod/Material/App/ModelManager.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace MatGui
|
||||
{
|
||||
|
||||
@@ -47,14 +46,25 @@ class MaterialsEditor: public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MaterialsEditor(QWidget* parent = nullptr);
|
||||
MaterialsEditor(QWidget* parent = nullptr);
|
||||
~MaterialsEditor() override = default;
|
||||
|
||||
void onName(const QString& text);
|
||||
void onAuthor(const QString& text);
|
||||
void onLicense(const QString& text);
|
||||
void onSourceURL(const QString& text);
|
||||
void onSourceReference(const QString& text);
|
||||
void onDescription();
|
||||
|
||||
void propertyChange(const QString& property, const QString value);
|
||||
void onInheritNewMaterial(bool checked);
|
||||
void onNewMaterial(bool checked);
|
||||
void onFavourite(bool checked);
|
||||
void onURL(bool checked);
|
||||
void onPhysicalAdd(bool checked);
|
||||
void onPhysicalRemove(bool checked);
|
||||
void onAppearanceAdd(bool checked);
|
||||
void onAppearanceRemove(bool checked);
|
||||
void onOk(bool checked);
|
||||
void onCancel(bool checked);
|
||||
void onSave(bool checked);
|
||||
@@ -70,10 +80,15 @@ public:
|
||||
return _modelManager;
|
||||
}
|
||||
|
||||
QString libraryPath(std::shared_ptr<Materials::Material> material) const;
|
||||
|
||||
void updateMaterialAppearance();
|
||||
void updateMaterialProperties();
|
||||
void updateMaterialGeneral();
|
||||
void updateMaterial();
|
||||
void onSelectMaterial(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
void onDoubleClick(const QModelIndex& index);
|
||||
void onContextMenu(const QPoint& pos);
|
||||
|
||||
protected:
|
||||
int confirmSave(QWidget* parent);
|
||||
@@ -83,7 +98,7 @@ private:
|
||||
std::unique_ptr<Ui_MaterialsEditor> ui;
|
||||
Materials::MaterialManager _materialManager;
|
||||
Materials::ModelManager _modelManager;
|
||||
Materials::Material _material;
|
||||
std::shared_ptr<Materials::Material> _material;
|
||||
QSvgWidget* _rendered;
|
||||
QSvgWidget* _vectored;
|
||||
bool _edited;
|
||||
@@ -102,6 +117,10 @@ private:
|
||||
void addRecent(const QString& uuid);
|
||||
bool isRecent(const QString& uuid) const;
|
||||
|
||||
void onInherit(bool checked);
|
||||
void onInheritNew(bool checked);
|
||||
|
||||
void setMaterialDefaults();
|
||||
void updatePreview() const;
|
||||
QString getColorHash(const QString& colorString, int colorRange = 255) const;
|
||||
|
||||
@@ -115,15 +134,12 @@ private:
|
||||
void createMaterialTree();
|
||||
void fillMaterialTree();
|
||||
void refreshMaterialTree();
|
||||
void
|
||||
addMaterials(QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, Materials::MaterialTreeNode*>> modelTree,
|
||||
const QIcon& folderIcon,
|
||||
const QIcon& icon);
|
||||
bool isMaterial(const fs::path& p) const
|
||||
{
|
||||
return Materials::MaterialManager::isMaterial(p);
|
||||
}
|
||||
void addMaterials(
|
||||
QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::MaterialTreeNode>>>
|
||||
modelTree,
|
||||
const QIcon& folderIcon,
|
||||
const QIcon& icon);
|
||||
};
|
||||
|
||||
} // namespace MatGui
|
||||
|
||||
@@ -68,19 +68,40 @@
|
||||
<property name="bottomMargin">
|
||||
<number>7</number>
|
||||
</property>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelParent">
|
||||
<property name="text">
|
||||
<string>Parent</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QTextEdit" name="editDescription"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Tags</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelSourceURL">
|
||||
<property name="text">
|
||||
<string>Source URL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="editName"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="labelDescription">
|
||||
<property name="text">
|
||||
<string>Description</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="editAuthorLicense"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelName">
|
||||
<property name="text">
|
||||
@@ -88,54 +109,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelSourceReference">
|
||||
<property name="text">
|
||||
<string>Source Reference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelParent">
|
||||
<property name="text">
|
||||
<string>Parent</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QTextEdit" name="editDescription"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelAuthorLicense">
|
||||
<property name="text">
|
||||
<string>Author and License</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="editParent"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Tags</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelSourceURL">
|
||||
<property name="text">
|
||||
<string>Source URL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<item row="6" column="2">
|
||||
<widget class="QLineEdit" name="editTags"/>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLineEdit" name="editSourceReference"/>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="editSourceURL"/>
|
||||
@@ -155,6 +132,39 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="editAuthor"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelAuthor">
|
||||
<property name="text">
|
||||
<string>Author</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLineEdit" name="editParent"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="labelSourceReference">
|
||||
<property name="text">
|
||||
<string>Source Reference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLineEdit" name="editSourceReference"/>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="editLicense"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelLicense">
|
||||
<property name="text">
|
||||
<string>License</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -172,6 +182,20 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonNew">
|
||||
<property name="text">
|
||||
<string>&New</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonInheritNew">
|
||||
<property name="text">
|
||||
<string>Inherit New</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonFavorite">
|
||||
<property name="text">
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
|
||||
#include <Mod/Material/App/ModelManager.h>
|
||||
|
||||
#include "ModelSelect.h"
|
||||
#include "ui_ModelSelect.h"
|
||||
|
||||
@@ -41,7 +43,7 @@ using namespace MatGui;
|
||||
|
||||
/* TRANSLATOR MatGui::ModelSelect */
|
||||
|
||||
ModelSelect::ModelSelect(QWidget* parent, Materials::ModelManager::ModelFilter filter)
|
||||
ModelSelect::ModelSelect(QWidget* parent, Materials::ModelFilter filter)
|
||||
: QDialog(parent)
|
||||
, _filter(filter)
|
||||
, ui(new Ui_ModelSelect)
|
||||
@@ -69,6 +71,7 @@ ModelSelect::ModelSelect(QWidget* parent, Materials::ModelManager::ModelFilter f
|
||||
connect(ui->buttonURL, &QPushButton::clicked, this, &ModelSelect::onURL);
|
||||
connect(ui->buttonDOI, &QPushButton::clicked, this, &ModelSelect::onDOI);
|
||||
connect(ui->buttonFavorite, &QPushButton::clicked, this, &ModelSelect::onFavourite);
|
||||
connect(ui->treeModels, &QTreeView::doubleClicked, this, &ModelSelect::onDoubleClick);
|
||||
|
||||
ui->standardButtons->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
ui->buttonFavorite->setEnabled(false);
|
||||
@@ -232,14 +235,14 @@ void ModelSelect::addExpanded(QTreeView* tree, QStandardItemModel* parent, QStan
|
||||
|
||||
void ModelSelect::addModels(
|
||||
QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, Materials::ModelTreeNode*>> modelTree,
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::ModelTreeNode>>> modelTree,
|
||||
const QIcon& icon)
|
||||
{
|
||||
auto tree = ui->treeModels;
|
||||
for (auto& mod : *modelTree) {
|
||||
Materials::ModelTreeNode* nodePtr = mod.second;
|
||||
std::shared_ptr<Materials::ModelTreeNode> nodePtr = mod.second;
|
||||
if (nodePtr->getType() == Materials::ModelTreeNode::DataNode) {
|
||||
const Materials::Model* model = nodePtr->getData();
|
||||
auto model = nodePtr->getData();
|
||||
QString uuid = model->getUUID();
|
||||
|
||||
auto card = new QStandardItem(icon, model->getName());
|
||||
@@ -264,11 +267,11 @@ void ModelSelect::addRecents(QStandardItem* parent)
|
||||
auto tree = ui->treeModels;
|
||||
for (auto& uuid : _recents) {
|
||||
try {
|
||||
const Materials::Model& model = getModelManager().getModel(uuid);
|
||||
auto model = getModelManager().getModel(uuid);
|
||||
|
||||
if (getModelManager().passFilter(_filter, model.getType())) {
|
||||
QIcon icon = QIcon(model.getLibrary().getIconPath());
|
||||
auto card = new QStandardItem(icon, model.getName());
|
||||
if (getModelManager().passFilter(_filter, model->getType())) {
|
||||
QIcon icon = QIcon(model->getLibrary()->getIconPath());
|
||||
auto card = new QStandardItem(icon, model->getName());
|
||||
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
card->setData(QVariant(uuid), Qt::UserRole);
|
||||
@@ -286,11 +289,11 @@ void ModelSelect::addFavorites(QStandardItem* parent)
|
||||
auto tree = ui->treeModels;
|
||||
for (auto& uuid : _favorites) {
|
||||
try {
|
||||
const Materials::Model& model = getModelManager().getModel(uuid);
|
||||
auto model = getModelManager().getModel(uuid);
|
||||
|
||||
if (getModelManager().passFilter(_filter, model.getType())) {
|
||||
QIcon icon = QIcon(model.getLibrary().getIconPath());
|
||||
auto card = new QStandardItem(icon, model.getName());
|
||||
if (getModelManager().passFilter(_filter, model->getType())) {
|
||||
QIcon icon = QIcon(model->getLibrary()->getIconPath());
|
||||
auto card = new QStandardItem(icon, model->getName());
|
||||
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
card->setData(QVariant(uuid), Qt::UserRole);
|
||||
@@ -305,8 +308,6 @@ void ModelSelect::addFavorites(QStandardItem* parent)
|
||||
|
||||
void ModelSelect::createModelTree()
|
||||
{
|
||||
// Materials::ModelManager modelManager;
|
||||
|
||||
auto tree = ui->treeModels;
|
||||
auto model = new QStandardItemModel();
|
||||
tree->setModel(model);
|
||||
@@ -326,17 +327,16 @@ void ModelSelect::refreshModelTree()
|
||||
|
||||
void ModelSelect::fillTree()
|
||||
{
|
||||
// Materials::ModelManager modelManager;
|
||||
|
||||
auto tree = ui->treeModels;
|
||||
auto model = static_cast<QStandardItemModel*>(tree->model());
|
||||
model->clear();
|
||||
|
||||
auto lib = new QStandardItem(QString::fromStdString("Favorites"));
|
||||
auto lib = new QStandardItem(tr("Favorites"));
|
||||
lib->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, model, lib);
|
||||
addFavorites(lib);
|
||||
|
||||
lib = new QStandardItem(QString::fromStdString("Recent"));
|
||||
lib = new QStandardItem(tr("Recent"));
|
||||
lib->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, model, lib);
|
||||
addRecents(lib);
|
||||
@@ -347,7 +347,7 @@ void ModelSelect::fillTree()
|
||||
lib->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, model, lib);
|
||||
|
||||
auto modelTree = getModelManager().getModelTree(*library, _filter);
|
||||
auto modelTree = getModelManager().getModelTree(library, _filter);
|
||||
addModels(*lib, modelTree, QIcon(library->getIconPath()));
|
||||
}
|
||||
}
|
||||
@@ -355,11 +355,11 @@ void ModelSelect::fillTree()
|
||||
void ModelSelect::setHeaders(QStandardItemModel* model)
|
||||
{
|
||||
QStringList headers;
|
||||
headers.append(QString::fromStdString("Inherited"));
|
||||
headers.append(QString::fromStdString("Property"));
|
||||
headers.append(QString::fromStdString("Units"));
|
||||
headers.append(QString::fromStdString("Description"));
|
||||
headers.append(QString::fromStdString("URL"));
|
||||
headers.append(tr("Inherited"));
|
||||
headers.append(tr("Property"));
|
||||
headers.append(tr("Units"));
|
||||
headers.append(tr("Description"));
|
||||
headers.append(tr("URL"));
|
||||
|
||||
model->setHorizontalHeaderLabels(headers);
|
||||
}
|
||||
@@ -388,7 +388,7 @@ void ModelSelect::createModelProperties()
|
||||
// table->setItemDelegate(new MaterialDelegate(this));
|
||||
}
|
||||
|
||||
void ModelSelect::updateModelProperties(const Materials::Model& model)
|
||||
void ModelSelect::updateModelProperties(std::shared_ptr<Materials::Model> model)
|
||||
{
|
||||
QTableView* table = ui->tableProperties;
|
||||
QStandardItemModel* tableModel = static_cast<QStandardItemModel*>(table->model());
|
||||
@@ -397,7 +397,7 @@ void ModelSelect::updateModelProperties(const Materials::Model& model)
|
||||
setHeaders(tableModel);
|
||||
setColumnWidths(table);
|
||||
|
||||
for (auto itp = model.begin(); itp != model.end(); itp++) {
|
||||
for (auto itp = model->begin(); itp != model->end(); itp++) {
|
||||
QList<QStandardItem*> items;
|
||||
|
||||
QString key = itp->first;
|
||||
@@ -428,19 +428,19 @@ void ModelSelect::updateModelProperties(const Materials::Model& model)
|
||||
|
||||
void ModelSelect::updateMaterialModel(const QString& uuid)
|
||||
{
|
||||
Materials::Model model = getModelManager().getModel(uuid);
|
||||
auto model = getModelManager().getModel(uuid);
|
||||
|
||||
// Update the general information
|
||||
ui->editName->setText(model.getName());
|
||||
ui->editURL->setText(model.getURL());
|
||||
ui->editDOI->setText(model.getDOI());
|
||||
ui->editDescription->setText(model.getDescription());
|
||||
ui->editName->setText(model->getName());
|
||||
ui->editURL->setText(model->getURL());
|
||||
ui->editDOI->setText(model->getDOI());
|
||||
ui->editDescription->setText(model->getDescription());
|
||||
|
||||
if (model.getType() == Materials::Model::ModelType_Physical) {
|
||||
ui->tabWidget->setTabText(1, QString::fromStdString("Properties"));
|
||||
if (model->getType() == Materials::Model::ModelType_Physical) {
|
||||
ui->tabWidget->setTabText(1, tr("Properties"));
|
||||
}
|
||||
else {
|
||||
ui->tabWidget->setTabText(1, QString::fromStdString("Appearance"));
|
||||
ui->tabWidget->setTabText(1, tr("Appearance"));
|
||||
}
|
||||
updateModelProperties(model);
|
||||
}
|
||||
@@ -453,7 +453,7 @@ void ModelSelect::clearMaterialModel()
|
||||
ui->editDOI->setText(QString::fromStdString(""));
|
||||
ui->editDescription->setText(QString::fromStdString(""));
|
||||
|
||||
ui->tabWidget->setTabText(1, QString::fromStdString("Properties"));
|
||||
ui->tabWidget->setTabText(1, tr("Properties"));
|
||||
|
||||
QTableView* table = ui->tableProperties;
|
||||
QStandardItemModel* tableModel = static_cast<QStandardItemModel*>(table->model());
|
||||
@@ -467,6 +467,7 @@ void ModelSelect::onSelectModel(const QItemSelection& selected, const QItemSelec
|
||||
{
|
||||
Q_UNUSED(deselected);
|
||||
|
||||
Base::Console().Log("ModelSelect::onSelectModel()\n");
|
||||
QStandardItemModel* model = static_cast<QStandardItemModel*>(ui->treeModels->model());
|
||||
QModelIndexList indexes = selected.indexes();
|
||||
for (auto it = indexes.begin(); it != indexes.end(); it++) {
|
||||
@@ -491,6 +492,14 @@ void ModelSelect::onSelectModel(const QItemSelection& selected, const QItemSelec
|
||||
}
|
||||
}
|
||||
|
||||
void ModelSelect::onDoubleClick(const QModelIndex& index)
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
Base::Console().Log("ModelSelect::onDoubleClick()\n");
|
||||
accept();
|
||||
}
|
||||
|
||||
void ModelSelect::onURL(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#ifndef MATGUI_MODELSELECT_H
|
||||
#define MATGUI_MODELSELECT_H
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDir>
|
||||
@@ -31,9 +31,7 @@
|
||||
#include <QTreeView>
|
||||
|
||||
#include <Mod/Material/App/Materials.h>
|
||||
#include <Mod/Material/App/ModelManager.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
#include <Mod/Material/App/Model.h>
|
||||
|
||||
namespace MatGui
|
||||
{
|
||||
@@ -45,15 +43,15 @@ class ModelSelect: public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ModelSelect(
|
||||
QWidget* parent = nullptr,
|
||||
Materials::ModelManager::ModelFilter filter = Materials::ModelManager::ModelFilter_None);
|
||||
ModelSelect(QWidget* parent = nullptr,
|
||||
Materials::ModelFilter filter = Materials::ModelFilter_None);
|
||||
~ModelSelect() override;
|
||||
|
||||
void onURL(bool checked);
|
||||
void onDOI(bool checked);
|
||||
void onFavourite(bool checked);
|
||||
void onSelectModel(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
void onDoubleClick(const QModelIndex& index);
|
||||
const QString& selectedModel() const
|
||||
{
|
||||
return _selected;
|
||||
@@ -77,9 +75,11 @@ private:
|
||||
void addExpanded(QTreeView* tree, QStandardItemModel* parent, QStandardItem* child);
|
||||
void addRecents(QStandardItem* parent);
|
||||
void addFavorites(QStandardItem* parent);
|
||||
void addModels(QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, Materials::ModelTreeNode*>> modelTree,
|
||||
const QIcon& icon);
|
||||
void
|
||||
addModels(QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::ModelTreeNode>>>
|
||||
modelTree,
|
||||
const QIcon& icon);
|
||||
void updateMaterialModel(const QString& uuid);
|
||||
void clearMaterialModel();
|
||||
void createModelTree();
|
||||
@@ -88,14 +88,14 @@ private:
|
||||
|
||||
void setHeaders(QStandardItemModel* model);
|
||||
void setColumnWidths(QTableView* table);
|
||||
void updateModelProperties(const Materials::Model& model);
|
||||
void updateModelProperties(std::shared_ptr<Materials::Model> model);
|
||||
void createModelProperties();
|
||||
Materials::ModelManager& getModelManager()
|
||||
{
|
||||
return _modelManager;
|
||||
}
|
||||
|
||||
Materials::ModelManager::ModelFilter _filter;
|
||||
Materials::ModelFilter _filter;
|
||||
std::unique_ptr<Ui_ModelSelect> ui;
|
||||
Materials::ModelManager _modelManager;
|
||||
QString _selected;
|
||||
|
||||
@@ -55,10 +55,6 @@
|
||||
// OpenCasCade
|
||||
// #include <Mod/Part/App/OpenCascadeAll.h>
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
// Qt Toolkit
|
||||
#ifndef __QtAll__
|
||||
#include <Gui/QtAll.h>
|
||||
|
||||
@@ -22,13 +22,53 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Gui/MenuManager.h>
|
||||
#include <Gui/ToolBarManager.h>
|
||||
|
||||
#include "Workbench.h"
|
||||
|
||||
using namespace MatGui;
|
||||
|
||||
|
||||
#if 0 // needed for Qt's lupdate utility
|
||||
qApp->translate("Workbench", "&Materials");
|
||||
qApp->translate("Workbench", "Materials");
|
||||
#endif
|
||||
|
||||
/// @namespace MatGui @class Workbench
|
||||
TYPESYSTEM_SOURCE(MatGui::Workbench, Gui::StdWorkbench)
|
||||
|
||||
Workbench::Workbench() = default;
|
||||
|
||||
Workbench::~Workbench() = default;
|
||||
|
||||
Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
{
|
||||
Gui::MenuItem* root = StdWorkbench::setupMenuBar();
|
||||
Gui::MenuItem* item = root->findItem("&Windows");
|
||||
|
||||
Gui::MenuItem* part = new Gui::MenuItem;
|
||||
root->insertItem(item, part);
|
||||
part->setCommand("&Materials");
|
||||
*part << "Materials_Edit";
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
{
|
||||
Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
|
||||
|
||||
Gui::ToolBarItem* solids = new Gui::ToolBarItem(root);
|
||||
solids->setCommand("Materials");
|
||||
*solids << "Materials_Edit";
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
Gui::ToolBarItem* Workbench::setupCommandBars() const
|
||||
{
|
||||
// Part tools
|
||||
Gui::ToolBarItem* root = new Gui::ToolBarItem;
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,11 @@ class MatGuiExport Workbench: public Gui::StdWorkbench
|
||||
public:
|
||||
Workbench();
|
||||
~Workbench() override;
|
||||
|
||||
protected:
|
||||
Gui::MenuItem* setupMenuBar() const override;
|
||||
Gui::ToolBarItem* setupToolBars() const override;
|
||||
Gui::ToolBarItem* setupCommandBars() const override;
|
||||
};
|
||||
|
||||
} // namespace MatGui
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "d1f317f0-5ffa-4798-8ab3-af2ff0b5182c"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Aluminum"
|
||||
Description: "Defines the Aluminum appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "4151e19c-fd6a-4ca4-83d4-d5e17d76cb9c"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Brass"
|
||||
Description: "Defines the Brass appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "ae194589-02d4-4e9b-98a7-f523f660d510"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Bronze"
|
||||
Description: "Defines the Bronze appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "a9544b88-dde7-4d05-9bdb-c008a4e88dc1"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Chrome"
|
||||
Description: "Defines the Chrome appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "524cad9b-b841-4037-9851-badeca7dcee2"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Copper"
|
||||
Description: "Defines the Copper appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "5dbb7be6-8b63-479b-ab4c-87be02ead973"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Default Appearance"
|
||||
Description: "Defines the default appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "54def35f-a6bf-472e-8410-dc9fb4b143cf"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Emerald"
|
||||
Description: "Defines the Emerald appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "85257e2c-be3f-40a1-b03f-0bd4ba58ca08"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Gold"
|
||||
Description: "Defines the Gold appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "cddfa21f-0715-49dd-b35b-951c076fa52c"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Jade"
|
||||
Description: "Defines the Jade appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "d149a177-07f1-4e53-9bad-0b5bf0663600"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Metalized"
|
||||
Description: "Defines the Metalized appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "c0341eef-0897-4fcf-a7f7-eddf1a2600a5"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Neon GNC"
|
||||
Description: "Defines the Neon GNC appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "add2d6b2-c8fb-4777-a80a-52bae97300ae"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Neon PHC"
|
||||
Description: "Defines the Neon PHC appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "a004c270-7d2c-4898-bec6-b1120edacea9"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Obsidian"
|
||||
Description: "Defines the Obsidian appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "a61853b9-ec9f-403e-9726-0a938731aecd"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Pewter"
|
||||
Description: "Defines the Pewter appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "569dccb6-c64b-4dd0-9d3c-1b78f40ad1a5"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Plaster"
|
||||
Description: "Defines the Plaster appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "a74622cd-0e2d-4a96-b8c4-fefcc82ac694"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Plastic"
|
||||
Description: "Defines the Plastic appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "953261a0-cc48-41f8-a3f9-7b20ae3f9b56"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Ruby"
|
||||
Description: "Defines the Ruby appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "951b54ae-86b6-46d2-b452-60bd6a3ba1bb"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Satin"
|
||||
Description: "Defines the Satin appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "591c4c4a-22ba-4a9a-869d-e5610107d69a"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Shiny Plastic"
|
||||
Description: "Defines the Shiny Plastic appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "62839fb0-d854-4b44-92df-b7249213de49"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Silver"
|
||||
Description: "Defines the Silver appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "4b849c55-6b3a-4f75-a055-40c0d0324596"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Steel"
|
||||
Description: "Defines the Steel appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "a9f54d61-cc98-46df-8734-b0543ceb4e45"
|
||||
AuthorAndLicense: "(c) 2023 David Carter"
|
||||
Author: "David Carter"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Stone"
|
||||
Description: "Defines the Stone appearance properties"
|
||||
AppearanceModels:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "94370b96-c97e-4a3f-83b2-11d7461f7da7"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Air"
|
||||
Description: "Dry air properties at 20 Degrees Celsius and 1 atm"
|
||||
Models:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "e359c5b5-eae2-42b1-9ef6-edde21d706ee"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Argon"
|
||||
Description: "Argon properties at 20 Degrees Celsius and 1 atm"
|
||||
Models:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "ef0e4040-a498-48c3-a87b-e996bfd89195"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Carbon dioxide"
|
||||
Description: "Carbon dioxide properties at 20 Degrees Celsius and 1 atm"
|
||||
Models:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "8d02a797-5e0a-4e40-803a-75fc66de8de6"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Nitrogen"
|
||||
Description: "Nitrogen properties at 20 Degrees Celsius and 1 atm"
|
||||
Models:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "944a8018-09bf-48f6-a7b3-aa8f6a00a310"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "None"
|
||||
Description: "None"
|
||||
Models:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "7e5559d5-be15-4571-a72f-20c39edd41cf"
|
||||
License: "GPL-2.0-or-later"
|
||||
Name: "Water"
|
||||
Description: "Standard distilled water properties at 20 Degrees Celsius and 1 atm"
|
||||
ReferenceSource: "''"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "dba76940-a910-4a3b-ab73-a9f412ac69d9"
|
||||
AuthorAndLicense: "(c) 2019 Bernd Hahnebach (CC-BY 3.0)"
|
||||
Author: "Bernd Hahnebach"
|
||||
License: "CC-BY-3.0"
|
||||
Name: "Concrete-EN-C35/45"
|
||||
Description: "Concrete matrix for reinforcement material examples, 0.6 x 0.75 x 35 MPa = 15.75 MPa (https://forum.freecad.org/viewtopic.php?f=18&t=33106&start=200#p311075)"
|
||||
Inherits:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "26042aa5-56e6-4d99-8b63-dd8b9ea5a37a"
|
||||
AuthorAndLicense: "(c) 2013 Yorik van Havre (CC-BY 3.0)"
|
||||
Author: "Yorik van Havre"
|
||||
License: "CC-BY-3.0"
|
||||
Name: "Concrete"
|
||||
Description: "A standard C-25 construction concrete"
|
||||
Inherits:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "57507cd4-d22f-4d86-9794-fdb1ec8cd098"
|
||||
AuthorAndLicense: "(c) 2019 Bernd Hahnebach (CC-BY 3.0)"
|
||||
Author: "Bernd Hahnebach"
|
||||
License: "CC-BY-3.0"
|
||||
Name: "Reinforcement-Harry"
|
||||
Description: "Reinforcement inside concrete for reinforcement material examples, from fib examples, 0.84 x 0.75 x 500 MPa = 315 MPa (https://forum.freecad.org/viewtopic.php?f=18&t=33106&start=200#p311705)"
|
||||
Inherits:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "5c67b675-69a2-4782-902a-bb90c3952f07"
|
||||
AuthorAndLicense: "Uwe Stöhr, LGPL"
|
||||
Author: "Uwe Stöhr"
|
||||
License: "LGPL-2.0-or-later"
|
||||
Name: "Graphite"
|
||||
Description: "Typical material properties for pure graphite"
|
||||
ReferenceSource: "Properties and characteristics of graphite"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "a02bf9d7-6e3e-4e36-881b-10779ee9f706"
|
||||
AuthorAndLicense: "(c) 2015 DaviKaur (CC-BY 3.0)"
|
||||
Author: "DaviKaur"
|
||||
License: "CC-BY-3.0"
|
||||
Name: "Glass-E"
|
||||
Description: "Glass Fibre"
|
||||
Models:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "3e3a3e13-04a4-410e-8e36-bbd83ca66847"
|
||||
AuthorAndLicense: "(c) 2015 Przemo Firszt (CC-BY 3.0)"
|
||||
Author: "Przemo Firszt"
|
||||
License: "CC-BY-3.0"
|
||||
Name: "Glass"
|
||||
Description: "Generic soda-lime glass"
|
||||
Models:
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "0c4943e0-248b-4df9-88d9-3b4dd84dfc68"
|
||||
AuthorAndLicense: "(c) 2015 DaviKaur (CC-BY 3.0)"
|
||||
Author: "DaviKaur"
|
||||
License: "CC-BY-3.0"
|
||||
Name: "Glass-S2"
|
||||
Description: "Glass Fibre"
|
||||
Models:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# File created by ConvertFCMat.py
|
||||
General:
|
||||
UUID: "27745e16-2a10-4c8e-bd22-59971806909c"
|
||||
AuthorAndLicense: "Uwe Stöhr"
|
||||
Author: "Uwe Stöhr"
|
||||
Name: "Invar Generic"
|
||||
Models:
|
||||
Father:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user