Material: Material editor enhancements (#11764)
Continues the work of the material subsystem improvements. Add support for embedded SVG files. These are not the same as image files so need to be handled differently. Add the ability to filter materials in the editor when called from code. This allows programs to select objects supporting specific models, complete models, older models, etc. Updated tests, and refactored code. New models and materials supporting patterns such as used by the TechDraw workbench. fixes #11686 - checks for the presense of a model property before assinging a value. This can happen when a required model definition is not available. --------- Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
This commit is contained in:
@@ -148,60 +148,23 @@ void MaterialProperty::setPropertyType(const QString& type)
|
||||
|
||||
void MaterialProperty::setType(const QString& type)
|
||||
{
|
||||
if (type == QString::fromStdString("String")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::String);
|
||||
auto mappedType = MaterialValue::mapType(type);
|
||||
if (mappedType == MaterialValue::None) {
|
||||
throw UnknownValueType();
|
||||
}
|
||||
else if (type == QString::fromStdString("Boolean")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::Boolean);
|
||||
}
|
||||
else if (type == QString::fromStdString("Integer")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::Integer);
|
||||
}
|
||||
else if (type == QString::fromStdString("Float")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::Float);
|
||||
}
|
||||
else if (type == QString::fromStdString("URL")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::URL);
|
||||
}
|
||||
else if (type == QString::fromStdString("Quantity")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::Quantity);
|
||||
}
|
||||
else if (type == QString::fromStdString("Color")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::Color);
|
||||
}
|
||||
else if (type == QString::fromStdString("File")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::File);
|
||||
}
|
||||
else if (type == QString::fromStdString("Image")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::Image);
|
||||
}
|
||||
else if (type == QString::fromStdString("List")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::List);
|
||||
}
|
||||
else if (type == QString::fromStdString("FileList")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::FileList);
|
||||
}
|
||||
else if (type == QString::fromStdString("ImageList")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::ImageList);
|
||||
}
|
||||
else if (type == QString::fromStdString("MultiLineString")) {
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::MultiLineString);
|
||||
}
|
||||
else if (type == QString::fromStdString("2DArray")) {
|
||||
if (mappedType == MaterialValue::Array2D) {
|
||||
auto arrayPtr = std::make_shared<Material2DArray>();
|
||||
arrayPtr->setColumns(columns());
|
||||
_valuePtr = arrayPtr;
|
||||
}
|
||||
else if (type == QString::fromStdString("3DArray")) {
|
||||
else if (mappedType == MaterialValue::Array3D) {
|
||||
auto arrayPtr = std::make_shared<Material3DArray>();
|
||||
// First column is third dimension
|
||||
arrayPtr->setColumns(columns() - 1);
|
||||
_valuePtr = arrayPtr;
|
||||
}
|
||||
else {
|
||||
// Error. Throw something
|
||||
_valuePtr = std::make_shared<MaterialValue>(MaterialValue::None);
|
||||
throw UnknownValueType();
|
||||
_valuePtr = std::make_shared<MaterialValue>(mappedType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,16 +420,16 @@ Material::Material(const Material& other)
|
||||
, _editState(other._editState)
|
||||
{
|
||||
for (auto& it : other._tags) {
|
||||
_tags.push_back(it);
|
||||
_tags.insert(it);
|
||||
}
|
||||
for (auto& it : other._physicalUuids) {
|
||||
_physicalUuids.push_back(it);
|
||||
_physicalUuids.insert(it);
|
||||
}
|
||||
for (auto& it : other._appearanceUuids) {
|
||||
_appearanceUuids.push_back(it);
|
||||
_appearanceUuids.insert(it);
|
||||
}
|
||||
for (auto& it : other._allUuids) {
|
||||
_allUuids.push_back(it);
|
||||
_allUuids.insert(it);
|
||||
}
|
||||
for (auto& it : other._physical) {
|
||||
MaterialProperty prop(it.second);
|
||||
@@ -498,7 +461,7 @@ QString Material::getAuthorAndLicense() const
|
||||
|
||||
void Material::addModel(const QString& uuid)
|
||||
{
|
||||
for (QString& modelUUID : _allUuids) {
|
||||
for (const auto& modelUUID : qAsConst(_allUuids)) {
|
||||
if (modelUUID == uuid) {
|
||||
return;
|
||||
}
|
||||
@@ -582,9 +545,9 @@ void Material::setEditState(ModelEdit newState)
|
||||
}
|
||||
}
|
||||
|
||||
void Material::removeUUID(QStringList& uuidList, const QString& uuid)
|
||||
void Material::removeUUID(QSet<QString>& uuidList, const QString& uuid)
|
||||
{
|
||||
uuidList.removeAll(uuid);
|
||||
uuidList.remove(uuid);
|
||||
}
|
||||
|
||||
void Material::addPhysical(const QString& uuid)
|
||||
@@ -605,7 +568,7 @@ void Material::addPhysical(const QString& uuid)
|
||||
removeUUID(_physicalUuids, it);
|
||||
}
|
||||
|
||||
_physicalUuids.push_back(uuid);
|
||||
_physicalUuids.insert(uuid);
|
||||
addModel(uuid);
|
||||
setEditStateExtend();
|
||||
|
||||
@@ -637,7 +600,7 @@ void Material::removePhysical(const QString& uuid)
|
||||
|
||||
// If it's an inherited model, do nothing
|
||||
bool inherited = true;
|
||||
for (auto& it : _physicalUuids) {
|
||||
for (const auto& it : qAsConst(_physicalUuids)) {
|
||||
if (it == uuid) {
|
||||
inherited = false;
|
||||
break;
|
||||
@@ -689,7 +652,7 @@ void Material::addAppearance(const QString& uuid)
|
||||
removeUUID(_appearanceUuids, it);
|
||||
}
|
||||
|
||||
_appearanceUuids.push_back(uuid);
|
||||
_appearanceUuids.insert(uuid);
|
||||
addModel(uuid);
|
||||
setEditStateExtend();
|
||||
|
||||
@@ -715,7 +678,7 @@ void Material::removeAppearance(const QString& uuid)
|
||||
|
||||
// If it's an inherited model, do nothing
|
||||
bool inherited = true;
|
||||
for (auto& it : _appearanceUuids) {
|
||||
for (const auto& it : qAsConst(_appearanceUuids)) {
|
||||
if (it == uuid) {
|
||||
inherited = false;
|
||||
break;
|
||||
@@ -790,56 +753,72 @@ void Material::setPhysicalValue(const QString& name, const QString& value)
|
||||
{
|
||||
setPhysicalEditState(name);
|
||||
|
||||
_physical[name]->setValue(value); // may not be a string type, conversion may be required
|
||||
if (hasPhysicalProperty(name)) {
|
||||
_physical[name]->setValue(value); // may not be a string type, conversion may be required
|
||||
}
|
||||
}
|
||||
|
||||
void Material::setPhysicalValue(const QString& name, int value)
|
||||
{
|
||||
setPhysicalEditState(name);
|
||||
|
||||
_physical[name]->setInt(value);
|
||||
if (hasPhysicalProperty(name)) {
|
||||
_physical[name]->setInt(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Material::setPhysicalValue(const QString& name, double value)
|
||||
{
|
||||
setPhysicalEditState(name);
|
||||
|
||||
_physical[name]->setFloat(value);
|
||||
if (hasPhysicalProperty(name)) {
|
||||
_physical[name]->setFloat(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Material::setPhysicalValue(const QString& name, const Base::Quantity& value)
|
||||
{
|
||||
setPhysicalEditState(name);
|
||||
|
||||
_physical[name]->setQuantity(value);
|
||||
if (hasPhysicalProperty(name)) {
|
||||
_physical[name]->setQuantity(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Material::setPhysicalValue(const QString& name, const std::shared_ptr<MaterialValue>& value)
|
||||
{
|
||||
setPhysicalEditState(name);
|
||||
|
||||
_physical[name]->setValue(value);
|
||||
if (hasPhysicalProperty(name)) {
|
||||
_physical[name]->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Material::setPhysicalValue(const QString& name, const std::shared_ptr<QList<QVariant>>& value)
|
||||
{
|
||||
setPhysicalEditState(name);
|
||||
|
||||
_physical[name]->setList(*value);
|
||||
if (hasPhysicalProperty(name)) {
|
||||
_physical[name]->setList(*value);
|
||||
}
|
||||
}
|
||||
|
||||
void Material::setAppearanceValue(const QString& name, const QString& value)
|
||||
{
|
||||
setAppearanceEditState(name);
|
||||
|
||||
_appearance[name]->setValue(value); // may not be a string type, conversion may be required
|
||||
if (hasAppearanceProperty(name)) {
|
||||
_appearance[name]->setValue(value); // may not be a string type, conversion may be required
|
||||
}
|
||||
}
|
||||
|
||||
void Material::setAppearanceValue(const QString& name, const std::shared_ptr<MaterialValue>& value)
|
||||
{
|
||||
setAppearanceEditState(name);
|
||||
|
||||
_appearance[name]->setValue(value);
|
||||
if (hasAppearanceProperty(name)) {
|
||||
_appearance[name]->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Material::setAppearanceValue(const QString& name,
|
||||
@@ -847,7 +826,9 @@ void Material::setAppearanceValue(const QString& name,
|
||||
{
|
||||
setAppearanceEditState(name);
|
||||
|
||||
_appearance[name]->setList(*value);
|
||||
if (hasAppearanceProperty(name)) {
|
||||
_appearance[name]->setList(*value);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<MaterialProperty> Material::getPhysicalProperty(const QString& name)
|
||||
@@ -890,6 +871,28 @@ std::shared_ptr<MaterialProperty> Material::getAppearanceProperty(const QString&
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<MaterialProperty> Material::getProperty(const QString& name)
|
||||
{
|
||||
if (hasPhysicalProperty(name)) {
|
||||
return getPhysicalProperty(name);
|
||||
}
|
||||
if (hasAppearanceProperty(name)) {
|
||||
return getAppearanceProperty(name);
|
||||
}
|
||||
throw PropertyNotFound();
|
||||
}
|
||||
|
||||
std::shared_ptr<MaterialProperty> Material::getProperty(const QString& name) const
|
||||
{
|
||||
if (hasPhysicalProperty(name)) {
|
||||
return getPhysicalProperty(name);
|
||||
}
|
||||
if (hasAppearanceProperty(name)) {
|
||||
return getAppearanceProperty(name);
|
||||
}
|
||||
throw PropertyNotFound();
|
||||
}
|
||||
|
||||
QVariant
|
||||
Material::getValue(const std::map<QString, std::shared_ptr<MaterialProperty>>& propertyList,
|
||||
const QString& name)
|
||||
@@ -1295,7 +1298,8 @@ QString Material::getModelByName(const QString& name) const
|
||||
void Material::save(QTextStream& stream, bool overwrite, bool saveAsCopy, bool saveInherited)
|
||||
{
|
||||
if (saveInherited && !saveAsCopy) {
|
||||
// Check to see if we're an original or if we're already in the list of models
|
||||
// Check to see if we're an original or if we're already in the list of
|
||||
// models
|
||||
MaterialManager materialManager;
|
||||
if (materialManager.exists(_uuid) && !overwrite) {
|
||||
// Make a new version based on the current
|
||||
@@ -1304,6 +1308,11 @@ void Material::save(QTextStream& stream, bool overwrite, bool saveAsCopy, bool s
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent self inheritance
|
||||
if (_parentUuid == _uuid) {
|
||||
_parentUuid = QString();
|
||||
}
|
||||
|
||||
if (saveAsCopy) {
|
||||
// Save it in the same format as the parent
|
||||
if (_parentUuid.isEmpty()) {
|
||||
@@ -1315,8 +1324,8 @@ void Material::save(QTextStream& stream, bool overwrite, bool saveAsCopy, bool s
|
||||
}
|
||||
else {
|
||||
if (!overwrite) {
|
||||
// Creating a new derived model when overwriting sets itself as a parent,
|
||||
// that will no longer exist because it's been overwritten
|
||||
// Creating a new derived model when overwriting sets itself as a
|
||||
// parent, that will no longer exist because it's been overwritten
|
||||
newUuid();
|
||||
}
|
||||
}
|
||||
@@ -1358,19 +1367,19 @@ Material& Material::operator=(const Material& other)
|
||||
|
||||
_tags.clear();
|
||||
for (auto& it : other._tags) {
|
||||
_tags.push_back(it);
|
||||
_tags.insert(it);
|
||||
}
|
||||
_physicalUuids.clear();
|
||||
for (auto& it : other._physicalUuids) {
|
||||
_physicalUuids.push_back(it);
|
||||
_physicalUuids.insert(it);
|
||||
}
|
||||
_appearanceUuids.clear();
|
||||
for (auto& it : other._appearanceUuids) {
|
||||
_appearanceUuids.push_back(it);
|
||||
_appearanceUuids.insert(it);
|
||||
}
|
||||
_allUuids.clear();
|
||||
for (auto& it : other._allUuids) {
|
||||
_allUuids.push_back(it);
|
||||
_allUuids.insert(it);
|
||||
}
|
||||
|
||||
// Create copies of the properties rather than modify the originals
|
||||
@@ -1420,14 +1429,15 @@ QStringList Material::normalizeModels(const QStringList& models)
|
||||
}
|
||||
|
||||
/*
|
||||
* Set or change the base material for the current material, updating the properties as
|
||||
* required.
|
||||
* Set or change the base material for the current material, updating the
|
||||
* properties as required.
|
||||
*/
|
||||
void Material::updateInheritance([[maybe_unused]] const QString& parent)
|
||||
{}
|
||||
|
||||
/*
|
||||
* Return a list of models that are defined in the parent material but not in this one
|
||||
* Return a list of models that are defined in the parent material but not in
|
||||
* this one
|
||||
*/
|
||||
QStringList Material::inheritedMissingModels(const Material& parent) const
|
||||
{
|
||||
@@ -1457,7 +1467,8 @@ QStringList Material::inheritedAddedModels(const Material& parent) const
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a list of properties that have different values from the parent material
|
||||
* Return a list of properties that have different values from the parent
|
||||
* material
|
||||
*/
|
||||
void Material::inheritedPropertyDiff([[maybe_unused]] const QString& parent)
|
||||
{}
|
||||
|
||||
Reference in New Issue
Block a user