Skip to content

Commit

Permalink
Merge pull request #371 from howetuft/materialx
Browse files Browse the repository at this point in the history
Materialx: 1st merge (experimental)
  • Loading branch information
howetuft authored Apr 8, 2024
2 parents 8afe0f2 + dd4738e commit f52defd
Show file tree
Hide file tree
Showing 31 changed files with 4,607 additions and 442 deletions.
32 changes: 20 additions & 12 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ init-hook='import sys; sys.path.append("/usr/lib/freecad/lib"); sys.path.append(
ignore=CVS

# Python version
# 2022-04-30: we target 3.6, same as FreeCAD 0.20
py-version=3.6
# 2024-02-15: we target 3.8, same as FreeCAD 0.21
py-version=3.8

# Pickle collected data for later comparisons.
persistent=yes
Expand All @@ -24,7 +24,9 @@ persistent=yes
# usually to register additional checkers.
load-plugins=
pylint.extensions.check_elif,
pylint.extensions.no_self_use
pylint.extensions.no_self_use,
pylint.extensions.typing,
pylint.extensions.code_style

# Use multiple processes to speed up Pylint.
jobs=2
Expand All @@ -36,15 +38,21 @@ unsafe-load-any-extension=no
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=PySide2,
PySide,
FreeCAD,
FreeCADGui,
Part,
Draft,
ImageGui,
MeshPart,
Mesh
extension-pkg-allow-list=PySide2,
PySide,
FreeCAD,
FreeCADGui,
Part,
Draft,
ImageGui,
MeshPart,
Mesh,
MaterialX.PyMaterialXCore,
MaterialX.PyMaterialXGenShader,
MaterialX.PyMaterialXGenGlsl,
MaterialX.PyMaterialXFormat,
MaterialX.PyMaterialXRender,
MaterialX.PyMaterialXRenderGlsl


[MESSAGES CONTROL]
Expand Down
1 change: 1 addition & 0 deletions Render/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,4 @@
)
from Render.commands import RENDER_COMMANDS # noqa: F401
from Render.prefpage import PreferencesPage # noqa: F401
from Render.materialx import import_materialx # noqa: F401
183 changes: 162 additions & 21 deletions Render/commands.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ***************************************************************************
# * *
# * Copyright (c) 2017 Yorik van Havre <[email protected]> *
# * Copyright (c) 2021 Howetuft <[email protected]> *
# * Copyright (c) 2024 Howetuft <[email protected]> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
Expand All @@ -27,14 +27,20 @@
import os
import itertools as it

from PySide.QtCore import QT_TRANSLATE_NOOP, Qt
from PySide.QtGui import QMessageBox, QInputDialog, QApplication, QCursor
from PySide.QtCore import QT_TRANSLATE_NOOP, Qt, QUrl
from PySide.QtGui import (
QMessageBox,
QInputDialog,
QApplication,
QCursor,
QFileDialog,
)

import FreeCAD as App
import FreeCADGui as Gui
from ArchMaterial import _CommandArchMaterial

from Render.constants import ICONDIR, VALID_RENDERERS
from Render.constants import ICONDIR, VALID_RENDERERS, PARAMS
from Render.utils import translate
from Render.rdrhandler import RendererHandler
from Render.taskpanels import MaterialSettingsTaskPanel
Expand All @@ -49,6 +55,10 @@
)
from Render.rendermaterial import is_multimat
from Render.help import open_help
from Render.materialx import (
import_materialx,
open_mxdownloader,
)


class RenderProjectCommand:
Expand Down Expand Up @@ -336,15 +346,23 @@ class MaterialCreatorCommand(_CommandArchMaterial):
This class is partially based on Arch 'ArchMaterial' command.
"""

def __init__(self, newname=False):
"""Init command."""
self._newname = bool(newname)

def GetResources(self):
"""Get command's resources (callback)."""
res = super().GetResources()
res["MenuText"] = QT_TRANSLATE_NOOP(
"MaterialCreatorCommand", "Create Material"
res["MenuText"] = (
QT_TRANSLATE_NOOP(
"MaterialCreatorCommand", "Internal Material Library"
)
if self._newname
else QT_TRANSLATE_NOOP("MaterialCreatorCommand", "Create Material")
)
res["ToolTip"] = QT_TRANSLATE_NOOP(
"MaterialCreatorCommand",
"Create a new Material in current document",
"Create a new Material in current document from internal library",
)
return res

Expand All @@ -365,6 +383,101 @@ def Activated(self):
App.ActiveDocument.commitTransaction()


class MaterialMaterialXImportCommand:
"""GUI command to import a MaterialX material."""

def GetResources(self): # pylint: disable=no-self-use
"""Get command's resources (callback)."""
return {
"Pixmap": os.path.join(ICONDIR, "materialx-stacked-black.svg"),
"MenuText": QT_TRANSLATE_NOOP(
"MaterialMaterialXImportCommand",
"Import MaterialX file",
),
"ToolTip": QT_TRANSLATE_NOOP(
"MaterialMaterialXImportCommand",
"Import a material from MaterialX file",
),
}

def Activated(self): # pylint: disable=no-self-use
"""Respond to Activated event (callback).
This code is executed when the command is run in FreeCAD.
It opens a dialog to set the rendering parameters of the selected
material.
"""
filefilter = "MaterialX (*.mtlx *.zip);;All files (*.*)"
caption = translate("Render", "Select MaterialX")
openfilename = QFileDialog.getOpenFileName(
Gui.getMainWindow(), caption, "", filefilter
)
materialx_file = openfilename[0]
if not materialx_file:
return
App.ActiveDocument.openTransaction("MaterialXImport")
import_materialx(materialx_file, Gui.ActiveDocument.Document)
App.ActiveDocument.commitTransaction()


class MaterialMaterialXLibrary:
"""GUI command to open MaterialX online library."""

def GetResources(self): # pylint: disable=no-self-use
"""Get command's resources (callback)."""
return {
"Pixmap": os.path.join(ICONDIR, "amdgpuopen.png"),
"MenuText": QT_TRANSLATE_NOOP(
"MaterialMaterialXImportCommand",
"GPUOpen Material Library",
),
"ToolTip": QT_TRANSLATE_NOOP(
"MaterialMaterialXImportCommand",
"Open AMD GPUOpen Material Library",
),
}

def Activated(self): # pylint: disable=no-self-use
"""Respond to Activated event (callback).
This code is executed when the command is run in FreeCAD.
It opens a dialog to set the rendering parameters of the selected
material.
"""
doc = App.ActiveDocument
url = QUrl("https://matlib.gpuopen.com/")
open_mxdownloader(url, doc)


class MaterialAmbientCGLibrary:
"""GUI command to open AmbientCG online library."""

def GetResources(self): # pylint: disable=no-self-use
"""Get command's resources (callback)."""
return {
"Pixmap": os.path.join(ICONDIR, "ambientcg.png"),
"MenuText": QT_TRANSLATE_NOOP(
"MaterialMaterialXImportCommand",
"AmbientCG Material Library",
),
"ToolTip": QT_TRANSLATE_NOOP(
"MaterialMaterialXImportCommand",
"Open AmbientCG Material Library",
),
}

def Activated(self): # pylint: disable=no-self-use
"""Respond to Activated event (callback).
This code is executed when the command is run in FreeCAD.
It opens a dialog to set the rendering parameters of the selected
material.
"""
doc = App.ActiveDocument
url = QUrl("https://ambientcg.com/")
open_mxdownloader(url, doc, disp2bump=True)


class MaterialRenderSettingsCommand:
"""GUI command to set render settings of a material object."""

Expand Down Expand Up @@ -613,25 +726,53 @@ def add_command(name, action):
lights_group = CommandGroup(lights_cmd, "Lights", "Create a Light")

mats_cmd = [
("MaterialCreator", MaterialCreatorCommand()),
("MaterialRenderSettings", MaterialRenderSettingsCommand()),
("MaterialApplier", MaterialApplierCommand()),
("MaterialRenderSettings", MaterialRenderSettingsCommand()),
]
materials_group = CommandGroup(mats_cmd, "Materials", "Manage Materials")

render_commands = [
("Projects", projects_group),
separator,
("Camera", CameraCommand()),
("Lights", lights_group),
("View", RenderViewCommand()),
("Materials", materials_group),
separator,
("Render", RenderCommand()),
separator,
("Settings", SettingsCommand()),
("Help", HelpCommand()),
libs_cmd = [
("MaterialMaterialXLibrary", MaterialMaterialXLibrary()),
("MaterialAmbientCGLibrary", MaterialAmbientCGLibrary()),
("MaterialCreator", MaterialCreatorCommand()),
("MaterialMaterialXImporter", MaterialMaterialXImportCommand()),
]
libraries_group = CommandGroup(
libs_cmd, "Libraries", "Download from material libraries"
)

if PARAMS.GetBool("MaterialX"):
render_commands = [
("Projects", projects_group),
separator,
("Camera", CameraCommand()),
("Lights", lights_group),
("View", RenderViewCommand()),
separator,
("Libraries", libraries_group),
("Materials", materials_group),
separator,
("Render", RenderCommand()),
separator,
("Settings", SettingsCommand()),
("Help", HelpCommand()),
]
else:
mats_cmd.insert(0, ("MaterialCreator", MaterialCreatorCommand()))
render_commands = [
("Projects", projects_group),
separator,
("Camera", CameraCommand()),
("Lights", lights_group),
("View", RenderViewCommand()),
separator,
("Materials", materials_group),
separator,
("Render", RenderCommand()),
separator,
("Settings", SettingsCommand()),
("Help", HelpCommand()),
]

result = []

Expand Down
2 changes: 2 additions & 0 deletions Render/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
# Paths
PKGDIR = os.path.dirname(__file__) # Package directory (=this file directory)
WBDIR = os.path.dirname(PKGDIR) # Workbench root directory
USERAPPDIR = App.getUserAppDataDir()
RDRDIR = os.path.join(PKGDIR, "renderers")
ICONDIR = os.path.join(PKGDIR, "resources", "icons")
TEMPLATEDIR = os.path.join(WBDIR, "templates")
Expand All @@ -41,6 +42,7 @@
TRANSDIR = os.path.join(PKGDIR, "resources", "translations")
PREFPAGE = os.path.join(PKGDIR, "resources", "ui", "RenderSettings.ui")
TASKPAGE = os.path.join(PKGDIR, "resources", "ui", "RenderMaterial.ui")
VENVDIR = os.path.join(USERAPPDIR, ".render_venv") # Virtual environment

# Renderers lists
RENDERERS = {
Expand Down
6 changes: 3 additions & 3 deletions Render/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@

import os.path

from PySide2.QtWebEngineWidgets import (
from PySide.QtWebEngineWidgets import (
QWebEngineView,
QWebEngineScript,
QWebEnginePage,
)
from PySide2.QtCore import QUrl
from PySide2.QtWidgets import QWidget, QToolBar, QVBoxLayout
from PySide.QtCore import QUrl
from PySide.QtGui import QWidget, QToolBar, QVBoxLayout

import FreeCADGui as Gui
import FreeCAD as App
Expand Down
7 changes: 4 additions & 3 deletions Render/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@
from Render.utils import translate, warn


def make_material(name="Material", color=None, transparency=None):
def make_material(name="Material", color=None, transparency=None, doc=None):
"""Make an Material object."""
if not App.ActiveDocument:
doc = doc or App.ActiveDocument
if not doc and not App.ActiveDocument:
App.Console.PrintError("No active document. Aborting\n")
return None
obj = App.ActiveDocument.addObject("App::MaterialObjectPython", "Material")
obj = doc.addObject("App::MaterialObjectPython", "Material")
obj.Label = name
Material(obj)
if App.GuiUp:
Expand Down
27 changes: 27 additions & 0 deletions Render/materialx/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ***************************************************************************
# * *
# * Copyright (c) 2024 Howetuft <[email protected]> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************

"""This module gathers public MaterialX handling features."""

from .materialx_importer import MaterialXImporter, import_materialx
from .materialx_downloader import MaterialXDownloader, open_mxdownloader
from .materialx_installer import RENDERVENV
Loading

0 comments on commit f52defd

Please sign in to comment.