Skip to content

Commit

Permalink
Merge pull request #337 from howetuft/a2plus
Browse files Browse the repository at this point in the history
Passthrough: enable access to material textures
  • Loading branch information
howetuft authored Dec 17, 2023
2 parents 4463b6c + 41b0d92 commit b686ac1
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 23 deletions.
6 changes: 5 additions & 1 deletion Render/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@
VALID_RENDERERS = sorted(RENDERERS - DEPRECATED_RENDERERS)

# FreeCAD version
FCDVERSION = int(App.Version()[0]), int(App.Version()[1]), int(App.Version()[2])
FCDVERSION = (
int(App.Version()[0]),
int(App.Version()[1]),
int(App.Version()[2]),
)

# Workbench parameters
PARAMS = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Render")
Expand Down
5 changes: 4 additions & 1 deletion Render/renderers/Appleseed.py
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,10 @@ def _write_material_pbr(name, matval):
def _write_material_passthrough(name, matval):
"""Compute a string in the renderer SDL for a passthrough material."""
snippet = indent(matval["string"], " ")
return snippet.format(n=name, c=matval.default_color.to_linear())
texture = matval.passthrough_texture
return snippet.format(
n=name, c=matval.default_color.to_linear(), tex=texture
)


def _write_material_fallback(name, matval):
Expand Down
9 changes: 6 additions & 3 deletions Render/renderers/Cycles.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,9 +475,11 @@ def _write_material(name, matval):

def _write_material_passthrough(name, matval):
"""Compute a string in the renderer SDL for a passthrough material."""
# snippet = indent(material.passthrough.string, " ")
texture = matval.passthrough_texture
snippet = matval["string"]
return snippet.format(n=name, c=matval.default_color.to_linear())
return snippet.format(
n=name, c=matval.default_color.to_linear(), tex=texture
)


def _write_material_glass(name, matval, connect_to="output surface"):
Expand Down Expand Up @@ -675,7 +677,8 @@ def _write_texture(**kwargs):
# as the input file
filename = pathlib.Path(propvalue.file).name

scale, rotation = float(propvalue.scale), float(propvalue.rotation)
scale = float(propvalue.scale)
rotation = -radians(float(propvalue.rotation))
translation_u = float(propvalue.translation_u)
translation_v = float(propvalue.translation_v)

Expand Down
11 changes: 9 additions & 2 deletions Render/renderers/Luxcore.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import os
from textwrap import dedent
import configparser
import math

import FreeCAD as App

Expand Down Expand Up @@ -326,9 +327,15 @@ def _write_material(name, matval):

def _write_material_passthrough(name, matval):
"""Compute a string in the renderer SDL for a passthrough material."""
# snippet = indent(matval["string"], " ")
snippet = matval["string"]
return snippet.format(n=name, c=matval.default_color.to_linear())
texture = matval.passthrough_texture
try:
texture["Rotation"] = math.degrees(texture["Rotation"])
except KeyError:
pass
return snippet.format(
n=name, c=matval.default_color.to_linear(), tex=texture
)


def _write_material_glass(name, matval):
Expand Down
5 changes: 4 additions & 1 deletion Render/renderers/Ospray.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,11 @@ def _write_material(name, matval):

def _write_material_passthrough(name, matval):
"""Compute a string in the renderer SDL for a passthrough material."""
texture = matval.passthrough_texture
snippet = "\n# Passthrough\n" + matval["string"]
return snippet.format(n=name, c=matval.default_color.to_linear())
return snippet.format(
n=name, c=matval.default_color.to_linear(), tex=texture
)


def _write_material_glass(name, matval): # pylint: disable=unused-argument
Expand Down
3 changes: 2 additions & 1 deletion Render/renderers/Pbrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,9 @@ def _write_material(name, matval):
def _write_material_passthrough(name, matval):
"""Compute a string in the renderer SDL for a passthrough material."""
snippet = "# Passthrough\n" + matval["string"] + "\n"
texture = matval.passthrough_texture
return snippet.format(
n=name, c=matval.default_color.to_linear(precise=True)
n=name, c=matval.default_color.to_linear(precise=True), tex=texture
)


Expand Down
3 changes: 2 additions & 1 deletion Render/renderers/Povray.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,8 @@ def _write_material(name, matval):
def _write_material_passthrough(name, matval):
"""Compute a string in the renderer SDL for a passthrough material."""
snippet = matval["string"]
return snippet.format(n=name, c=matval.default_color)
texture = matval.passthrough_texture
return snippet.format(n=name, c=matval.default_color, tex=texture)


def _write_material_glass(name, matval): # pylint: disable=unused-argument
Expand Down
73 changes: 60 additions & 13 deletions Render/rendermaterial.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import types
import functools
import uuid
import re
import os.path

import FreeCAD as App

Expand Down Expand Up @@ -210,7 +212,7 @@ def get_rendering_material(meshname, material, renderer, default_color):
lines = tuple(mat[k] for k in sorted(common_keys))
debug("Found valid Passthrough - returning")
return RenderMaterial.build_passthrough(
lines, renderer, default_color, doc
lines, renderer, default_color, doc, material.Proxy.get_textures()
)

# Try standard materials
Expand Down Expand Up @@ -315,16 +317,54 @@ def build_standard(shadertype, values, doc):
return res

@staticmethod
def build_passthrough(lines, renderer, default_color, doc):
def build_passthrough(lines, renderer, default_color, doc, textures):
"""Build passthrough material."""
res = RenderMaterial("Passthrough", doc)
res.shader.string = _convert_passthru("\n".join(lines))
res.shader.renderer = renderer
res.default_color = default_color

# pylint: disable=protected-access

# The main parameter is the string containing the passthrough
res.shader.string = _convert_passthru("\n".join(lines))
res._partypes["string"] = "str"

res.shader.renderer = renderer
res._partypes["renderer"] = "str"

res.default_color = default_color
res._partypes["default_color"] = "RGBA"

# We also need to register textures
# in case they would be referenced by the material
# We just take the first texture
def _tex_get_value(propname, tex):
"""Get value of a property in a texture."""
prop = tex.getPropertyByName(propname)

# Angle?
if propname == "Rotation":
return prop.getValueAs("rad")

# Distance?
if propname in ["TranslationU", "TranslationV"]:
return prop.getValueAs("m")

# Image File?
if propname.startswith("Image"):
return os.path.basename(prop)

# Default
return prop

try:
texture = textures[0]
except IndexError:
res.passthrough_texture = {}
else:
res.passthrough_texture = {
propname: _tex_get_value(propname, texture)
for propname in texture.PropertiesList
}

return res

@staticmethod
Expand Down Expand Up @@ -618,6 +658,11 @@ def __init__(
# Store resulting value
self._values[propkey] = value

# Special case: passthrough. We store all the textures in a
# dedicated field, to make them available for the material
if material.shadertype == "Passthrough":
self.passthrough_texture = material.passthrough_texture

@property
def textures(self):
"""Get a list of material's textures in renderer SDL."""
Expand Down Expand Up @@ -922,12 +967,13 @@ def _casttexscalar(*args):


_PASSTHRU_REPLACED_TOKENS = (
("{", "{{"),
("}", "}}"),
("%NAME%", "{n}"),
("%RED%", "{c[0]}"),
("%GREEN%", "{c[1]}"),
("%BLUE%", "{c[2]}"),
(r"{", r"{{"),
(r"}", r"}}"),
(r"%NAME%", r"{n}"),
(r"%RED%", r"{c[0]}"),
(r"%GREEN%", r"{c[1]}"),
(r"%BLUE%", r"{c[2]}"),
(r"%TEXTURE\((.*)\)%", r"{tex[\1]}"),
)


Expand All @@ -936,8 +982,9 @@ def _convert_passthru(passthru):
(FSML stands for Format Specification Mini-Language)
"""
for token in _PASSTHRU_REPLACED_TOKENS:
passthru = passthru.replace(*token)
for pattern, replace in _PASSTHRU_REPLACED_TOKENS:
passthru = re.sub(pattern, replace, passthru)

return passthru


Expand Down

0 comments on commit b686ac1

Please sign in to comment.