Skip to content

Commit

Permalink
Material: Material editor enhancements
Browse files Browse the repository at this point in the history
Continues the work of the material subsystem improvements.

This merge covers the continued development of the material editor. The
primary improvements are the addition of new data types, a new
appearance preview UI, and changes in the array data types.

New data types were added to support more advanced workflows, such as
the Render Workbench.The Image datatype allows the material to embed
the image in the card instead of pointing to an image in an external
file. Multi-buyte strings span multiple lines as the name implies.
It preserves formatting accross those lines. Also several list types
are now supported, with the primary difference being the editors.
List is a list of strings, FileList is a list of file path names, and
ImageList is a list of embedded images.

For the appearance preview, the UI now uses the same Coin library as
is used in the documents, meaning the preview will look exactly the
same as the material will be shown in the documents.

The array data types are now more complete. The default value wasn't
being used as originially envisioned and was tehrefore removed. For
3D arrays, the Python API was implemented.

There were a lot of code clean ups. This involved removing logging
statements used for debugging during development, reduction of lint
warnings, and code refactoring.

The editor can automatically convert from previous format files to the
current format. This has been extended to material files generated by
the Render WB. Old format files are displayed in the editor with a
warning icon. Selecting one will require saving the file in the new
format before it can be used.
  • Loading branch information
davesrocketshop authored and chennes committed Dec 6, 2023
1 parent 008fc32 commit 09f67f2
Show file tree
Hide file tree
Showing 72 changed files with 4,250 additions and 1,336 deletions.
18 changes: 10 additions & 8 deletions src/Gui/View3DSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@
#include <Base/Parameter.h>
#include <QApplication>

namespace Gui {
namespace Gui
{
class View3DInventorViewer;

class View3DSettings : public ParameterGrp::ObserverType
class GuiExport View3DSettings: public ParameterGrp::ObserverType
{
public:
View3DSettings(ParameterGrp::handle hGrp, View3DInventorViewer *);
View3DSettings(ParameterGrp::handle hGrp, const std::vector<View3DInventorViewer *>&);
View3DSettings(ParameterGrp::handle hGrp, View3DInventorViewer*);
View3DSettings(ParameterGrp::handle hGrp, const std::vector<View3DInventorViewer*>&);
~View3DSettings() override;

/// Observer message from the ParameterGrp
void OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason) override;
void OnChange(ParameterGrp::SubjectType& rCaller, ParameterGrp::MessageType Reason) override;
void applySettings();
int stopAnimatingIfDeactivated() const;

Expand All @@ -56,17 +57,18 @@ class NaviCubeSettings
{
Q_DECLARE_TR_FUNCTIONS(NaviCubeSettings)
public:
NaviCubeSettings(ParameterGrp::handle hGrp, View3DInventorViewer *);
NaviCubeSettings(ParameterGrp::handle hGrp, View3DInventorViewer*);
~NaviCubeSettings();

void applySettings();

private:
void parameterChanged(ParameterGrp::MessageType pName);
ParameterGrp::handle hGrp;
View3DInventorViewer * _viewer;
View3DInventorViewer* _viewer;
boost::signals2::connection connectParameterChanged;
};

} // namespace Gui
} // namespace Gui

#endif // GUI_VIEW3DSETTINGS_H
15 changes: 13 additions & 2 deletions src/Mod/Material/App/Array2DPy.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
<Author Licence="LGPL" Name="DavidCarter" EMail="[email protected]" />
<UserDocu>2D Array of material properties.</UserDocu>
</Documentation>
<Attribute Name="Array" ReadOnly="true">
<Documentation>
<UserDocu>The 2 dimensional array.</UserDocu>
</Documentation>
<Parameter Name="Array" Type="List"/>
</Attribute>
<Attribute Name="Rows" ReadOnly="true">
<Documentation>
<UserDocu>The number of rows in the array.</UserDocu>
Expand All @@ -27,9 +33,14 @@
</Documentation>
<Parameter Name="Columns" Type="Int"/>
</Attribute>
<Methode Name="getDefaultValue" ReadOnly="true">
<Methode Name="getRow" ReadOnly="true">
<Documentation>
<UserDocu>Get the row given the first column value</UserDocu>
</Documentation>
</Methode>
<Methode Name="getValue" ReadOnly="true">
<Documentation>
<UserDocu>Get the default value for the first column of the array</UserDocu>
<UserDocu>Get the value at the given row and column</UserDocu>
</Documentation>
</Methode>
</PythonExport>
Expand Down
71 changes: 66 additions & 5 deletions src/Mod/Material/App/Array2DPyImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,16 @@

#include "PreCompiled.h"

#include <QList>
#include <QMetaType>

#include <Base/Quantity.h>
#include <Base/QuantityPy.h>
#include <CXX/Objects.hxx>
#include <Gui/MetaTypes.h>

#include "Array2DPy.h"
#include "Exceptions.h"
#include "Model.h"
#include "ModelLibrary.h"
#include "ModelPropertyPy.h"
Expand Down Expand Up @@ -52,6 +61,25 @@ int Array2DPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
return 0;
}

Py::List Array2DPy::getArray() const
{
Py::List list;
auto array = getMaterial2DArrayPtr()->getArray();

for (auto& row : array) {
Py::List* rowList = new Py::List();
for (auto& column : *row) {
auto quantity =
new Base::QuantityPy(new Base::Quantity(column.value<Base::Quantity>()));
rowList->append(Py::Object(quantity));
}

list.append(*rowList);
}

return list;
}

Py::Int Array2DPy::getRows() const
{
return Py::Int(getMaterial2DArrayPtr()->rows());
Expand All @@ -62,15 +90,48 @@ Py::Int Array2DPy::getColumns() const
return Py::Int(getMaterial2DArrayPtr()->columns());
}

PyObject* Array2DPy::getDefaultValue(PyObject* args)
PyObject* Array2DPy::getRow(PyObject* args)
{
int row;
if (!PyArg_ParseTuple(args, "i", &row)) {
return nullptr;
}

try {
Py::List list;

auto arrayRow = getMaterial2DArrayPtr()->getRow(row);
for (auto& column : *arrayRow) {
auto quantity =
new Base::QuantityPy(new Base::Quantity(column.value<Base::Quantity>()));
list.append(Py::Object(quantity));
}

return Py::new_reference_to(list);
}
catch (const InvalidIndex&) {
}

PyErr_SetString(PyExc_IndexError, "Invalid array index");
return nullptr;
}

PyObject* Array2DPy::getValue(PyObject* args)
{
char* name;
if (!PyArg_ParseTuple(args, "s", &name)) {
int row;
int column;
if (!PyArg_ParseTuple(args, "ii", &row, &column)) {
return nullptr;
}

// QVariant value = getMaterial2DArrayPtr()->getPhysicalValue(QString::fromStdString(name));
// return _pyObjectFromVariant(value);
try {
auto value = getMaterial2DArrayPtr()->getValue(row, column);
return new Base::QuantityPy(new Base::Quantity(value.value<Base::Quantity>()));
}
catch (const InvalidIndex&) {
}

PyErr_SetString(PyExc_IndexError, "Invalid array index");
return nullptr;
}

Expand Down
52 changes: 52 additions & 0 deletions src/Mod/Material/App/Array3DPy.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?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="Array3DPy"
Twin="Material3DArray"
TwinPointer="Material3DArray"
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="[email protected]" />
<UserDocu>3D Array of material properties.</UserDocu>
</Documentation>
<Attribute Name="Array" ReadOnly="true">
<Documentation>
<UserDocu>The 3 dimensional array.</UserDocu>
</Documentation>
<Parameter Name="Array" Type="List"/>
</Attribute>
<Attribute Name="Columns" ReadOnly="true">
<Documentation>
<UserDocu>The number of columns in the array.</UserDocu>
</Documentation>
<Parameter Name="Columns" Type="Int"/>
</Attribute>
<Attribute Name="Depth" ReadOnly="true">
<Documentation>
<UserDocu>The depth of the array (3rd dimension).</UserDocu>
</Documentation>
<Parameter Name="Columns" Type="Int"/>
</Attribute>
<Methode Name="getRows" ReadOnly="true">
<Documentation>
<UserDocu>Get the number of rows in the array at the specified depth.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getValue" ReadOnly="true">
<Documentation>
<UserDocu>Get the value at the given row and column</UserDocu>
</Documentation>
</Methode>
<Methode Name="getDepthValue" ReadOnly="true">
<Documentation>
<UserDocu>Get the column value at the given depth</UserDocu>
</Documentation>
</Methode>
</PythonExport>
</GenerateModel>
152 changes: 152 additions & 0 deletions src/Mod/Material/App/Array3DPyImpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/***************************************************************************
* Copyright (c) 2023 David Carter <[email protected]> *
* *
* 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 <QList>
#include <QMetaType>

#include <Base/Quantity.h>
#include <Base/QuantityPy.h>
#include <CXX/Objects.hxx>
#include <Gui/MetaTypes.h>

#include "Array3DPy.h"
#include "Exceptions.h"
#include "Model.h"
#include "ModelLibrary.h"
#include "ModelPropertyPy.h"
#include "ModelUuids.h"

#include "Array3DPy.cpp"

using namespace Materials;

// returns a string which represents the object e.g. when printed in python
std::string Array3DPy::representation() const
{
std::stringstream str;
str << "<Array3D object at " << getMaterial3DArrayPtr() << ">";

return str.str();
}

PyObject* Array3DPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
{
// never create such objects with the constructor
return new Array3DPy(new Material3DArray());
}

// constructor method
int Array3DPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
{
return 0;
}

Py::List Array3DPy::getArray() const
{
Py::List list;
auto array = getMaterial3DArrayPtr()->getArray();

for (auto& depth : array) {
Py::List* depthList = new Py::List();
for (auto& row : *std::get<1>(depth)) {
Py::List* rowList = new Py::List();
for (auto& column : *row) {
auto quantity = new Base::QuantityPy(new Base::Quantity(column));
rowList->append(Py::Object(quantity));
}

depthList->append(*rowList);
}
list.append(*depthList);
}

return list;
}

Py::Int Array3DPy::getColumns() const
{
return Py::Int(getMaterial3DArrayPtr()->columns());
}

Py::Int Array3DPy::getDepth() const
{
return Py::Int(getMaterial3DArrayPtr()->depth());
}

PyObject* Array3DPy::getRows(PyObject* args)
{
int depth = getMaterial3DArrayPtr()->currentDepth();
if (!PyArg_ParseTuple(args, "|i", &depth)) {
return nullptr;
}

return PyLong_FromLong(getMaterial3DArrayPtr()->rows(depth));
}

PyObject* Array3DPy::getValue(PyObject* args)
{
int depth;
int row;
int column;
if (!PyArg_ParseTuple(args, "iii", &depth, &row, &column)) {
return nullptr;
}

try {
auto value = getMaterial3DArrayPtr()->getValue(depth, row, column);
return new Base::QuantityPy(new Base::Quantity(value));
}
catch (const InvalidIndex&) {
}

PyErr_SetString(PyExc_IndexError, "Invalid array index");
return nullptr;
}

PyObject* Array3DPy::getDepthValue(PyObject* args)
{
int depth;
if (!PyArg_ParseTuple(args, "i", &depth)) {
return nullptr;
}

try {
auto value = getMaterial3DArrayPtr()->getDepthValue(depth);
return new Base::QuantityPy(new Base::Quantity(value));
}
catch (const InvalidIndex&) {
}

PyErr_SetString(PyExc_IndexError, "Invalid array index");
return nullptr;
}

PyObject* Array3DPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}

int Array3DPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}
3 changes: 3 additions & 0 deletions src/Mod/Material/App/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ list(APPEND Material_LIBS
)

generate_from_xml(Array2DPy)
generate_from_xml(Array3DPy)
generate_from_xml(MaterialManagerPy)
generate_from_xml(MaterialPy)
generate_from_xml(ModelManagerPy)
Expand All @@ -45,6 +46,8 @@ SET(Python_SRCS
Exceptions.h
Array2DPy.xml
Array2DPyImpl.cpp
Array3DPy.xml
Array3DPyImpl.cpp
MaterialManagerPy.xml
MaterialManagerPyImpl.cpp
MaterialPy.xml
Expand Down
Loading

0 comments on commit 09f67f2

Please sign in to comment.