Storm Hydra render addon #104597

Merged
Brecht Van Lommel merged 22 commits from BogdanNagirniak/blender-addons:storm-hydra-addon into main 2023-08-04 17:02:11 +02:00
26 changed files with 166 additions and 104 deletions
Showing only changes of commit 15b3c6c993 - Show all commits

View File

@ -1,7 +0,0 @@
{
"project_id" : "Blender Addons",
"conduit_uri" : "https://developer.blender.org/",
"phabricator.uri" : "https://developer.blender.org/",
"git.default-relative-commit" : "origin/master",
"arc.land.update.default" : "rebase"
}

View File

@ -1,5 +1,4 @@
This repository is only used as a mirror of git.blender.org. Blender development happens on This repository is only used as a mirror. Blender development happens on projects.blender.org.
https://developer.blender.org.
To get started with contributing code, please see: To get started with contributing code, please see:
https://wiki.blender.org/wiki/Process/Contributing_Code https://wiki.blender.org/wiki/Process/Contributing_Code

3
.github/stale.yml vendored
View File

@ -15,8 +15,7 @@ staleLabel: stale
# Comment to post when closing a stale Issue or Pull Request. # Comment to post when closing a stale Issue or Pull Request.
closeComment: > closeComment: >
This issue has been automatically closed, because this repository is only This issue has been automatically closed, because this repository is only
used as a mirror of git.blender.org. Blender development happens on used as a mirror. Blender development happens on projects.blender.org.
developer.blender.org.
To get started contributing code, please read: To get started contributing code, please read:
https://wiki.blender.org/wiki/Process/Contributing_Code https://wiki.blender.org/wiki/Process/Contributing_Code

View File

@ -2,8 +2,8 @@
bl_info = { bl_info = {
"name": "Import Palettes", "name": "Import Palettes",
"author": "Antonio Vazquez", "author": "Antonio Vazquez, Kevin C. Burke (@blastframe)",
"version": (1, 0, 0), "version": (1, 0, 1),
"blender": (2, 81, 6), "blender": (2, 81, 6),
"location": "File > Import", "location": "File > Import",
"description": "Import Palettes", "description": "Import Palettes",

View File

@ -99,16 +99,9 @@ def parse(filename):
return [c for c in parse_chunk(data)] return [c for c in parse_chunk(data)]
def load(context, filepath): def create_color(data):
output = parse(filepath)
(path, filename) = os.path.split(filepath)
pal = None
for elm in output:
valid = False valid = False
data = elm['data']
color = [0, 0, 0] color = [0, 0, 0]
val = data['values'] val = data['values']
@ -128,12 +121,31 @@ def load(context, filepath):
color[1] = (1.0 - val[1]) * (1.0 - val[3]) color[1] = (1.0 - val[1]) * (1.0 - val[3])
color[2] = (1.0 - val[2]) * (1.0 - val[3]) color[2] = (1.0 - val[2]) * (1.0 - val[3])
# Create palette color
if valid: if valid:
return color
def load(context, filepath):
output = parse(filepath)
(path, filename) = os.path.split(filepath)
pal = None
for elm in output:
colors = []
if "data" in elm:
colors.append(create_color(elm['data']))
if "swatches" in elm:
for swatch in elm['swatches']:
colors.append(create_color(swatch["data"]))
# Create Palette # Create Palette
if pal is None: if pal is None:
pal = bpy.data.palettes.new(name=filename) pal = bpy.data.palettes.new(name=filename)
for color in colors:
# Create Color # Create Color
col = pal.colors.new() col = pal.colors.new()
col.color[0] = color[0] col.color[0] = color[0]

View File

@ -43,7 +43,7 @@ bl_info = {
"name": "Atomic Blender PDB/XYZ", "name": "Atomic Blender PDB/XYZ",
"description": "Importing atoms listed in PDB or XYZ files as balls into Blender", "description": "Importing atoms listed in PDB or XYZ files as balls into Blender",
"author": "Clemens Barth", "author": "Clemens Barth",
"version": (1, 8), "version": (1, 8, 1),
"blender": (2, 80, 0), "blender": (2, 80, 0),
"location": "File -> Import -> PDB (.pdb) and File -> Import -> XYZ (.xyz)", "location": "File -> Import -> PDB (.pdb) and File -> Import -> XYZ (.xyz)",
"warning": "", "warning": "",

View File

@ -755,7 +755,8 @@ def draw_sticks_dupliverts(all_atoms,
if use_sticks_color == False: if use_sticks_color == False:
stick_material = bpy.data.materials.new(ELEMENTS[-1].name) stick_material = bpy.data.materials.new(ELEMENTS[-1].name)
stick_material.use_nodes = True stick_material.use_nodes = True
mat_P_BSDF = stick_material.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in stick_material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = ELEMENTS[-1].color mat_P_BSDF.inputs['Base Color'].default_value = ELEMENTS[-1].color
# Sort the sticks and put them into a new list such that ... # Sort the sticks and put them into a new list such that ...
@ -1048,7 +1049,8 @@ def draw_sticks_skin(all_atoms,
stick_material = bpy.data.materials.new(ELEMENTS[-1].name) stick_material = bpy.data.materials.new(ELEMENTS[-1].name)
stick_material.use_nodes = True stick_material.use_nodes = True
mat_P_BSDF = stick_material.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in stick_material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = ELEMENTS[-1].color mat_P_BSDF.inputs['Base Color'].default_value = ELEMENTS[-1].color
new_stick_mesh.active_material = stick_material new_stick_mesh.active_material = stick_material
@ -1105,7 +1107,8 @@ def draw_sticks_normal(all_atoms,
stick_material = bpy.data.materials.new(ELEMENTS[-1].name) stick_material = bpy.data.materials.new(ELEMENTS[-1].name)
stick_material.use_nodes = True stick_material.use_nodes = True
mat_P_BSDF = stick_material.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in stick_material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = ELEMENTS[-1].color mat_P_BSDF.inputs['Base Color'].default_value = ELEMENTS[-1].color
up_axis = Vector([0.0, 0.0, 1.0]) up_axis = Vector([0.0, 0.0, 1.0])
@ -1332,7 +1335,8 @@ def import_pdb(Ball_type,
material = bpy.data.materials.new(atom_type[1]) material = bpy.data.materials.new(atom_type[1])
material.diffuse_color = atom_type[2] material.diffuse_color = atom_type[2]
material.use_nodes = True material.use_nodes = True
mat_P_BSDF = material.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = atom_type[2] mat_P_BSDF.inputs['Base Color'].default_value = atom_type[2]
material.name = atom_type[0] material.name = atom_type[0]
atom_material_list.append(material) atom_material_list.append(material)
@ -1350,7 +1354,8 @@ def import_pdb(Ball_type,
if atom.name == "Vacancy": if atom.name == "Vacancy":
# For cycles and eevee. # For cycles and eevee.
material.use_nodes = True material.use_nodes = True
mat_P_BSDF = material.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Metallic'].default_value = 0.1 mat_P_BSDF.inputs['Metallic'].default_value = 0.1
mat_P_BSDF.inputs['Specular'].default_value = 0.15 mat_P_BSDF.inputs['Specular'].default_value = 0.15
mat_P_BSDF.inputs['Roughness'].default_value = 0.05 mat_P_BSDF.inputs['Roughness'].default_value = 0.05

View File

@ -493,7 +493,8 @@ def modify_objects(action_type,
else: else:
new_material = draw_obj_material('1', atom.active_material) new_material = draw_obj_material('1', atom.active_material)
# Assign now the correct color. # Assign now the correct color.
mat_P_BSDF = new_material.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in new_material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = element.color mat_P_BSDF.inputs['Base Color'].default_value = element.color
new_material.name = element.name + "_normal" new_material.name = element.name + "_normal"
@ -580,7 +581,8 @@ def separate_atoms(scn):
# Prepare a new material # Prepare a new material
def draw_obj_material(material_type, material): def draw_obj_material(material_type, material):
mat_P_BSDF_default = material.node_tree.nodes['Principled BSDF'] mat_P_BSDF_default = next(n for n in material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
default_color = mat_P_BSDF_default.inputs['Base Color'].default_value default_color = mat_P_BSDF_default.inputs['Base Color'].default_value
if material_type == '0': # Unchanged if material_type == '0': # Unchanged
@ -591,7 +593,8 @@ def draw_obj_material(material_type, material):
# user's work in Blender ... . # user's work in Blender ... .
material_new = bpy.data.materials.new(material.name + "_normal") material_new = bpy.data.materials.new(material.name + "_normal")
material_new.use_nodes = True material_new.use_nodes = True
mat_P_BSDF = material_new.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material_new.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = default_color mat_P_BSDF.inputs['Base Color'].default_value = default_color
mat_P_BSDF.inputs['Metallic'].default_value = 0.0 mat_P_BSDF.inputs['Metallic'].default_value = 0.0
mat_P_BSDF.inputs['Specular'].default_value = 0.5 mat_P_BSDF.inputs['Specular'].default_value = 0.5
@ -607,7 +610,8 @@ def draw_obj_material(material_type, material):
if material_type == '2': # Transparent if material_type == '2': # Transparent
material_new = bpy.data.materials.new(material.name + "_transparent") material_new = bpy.data.materials.new(material.name + "_transparent")
material_new.use_nodes = True material_new.use_nodes = True
mat_P_BSDF = material_new.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material_new.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = default_color mat_P_BSDF.inputs['Base Color'].default_value = default_color
mat_P_BSDF.inputs['Metallic'].default_value = 0.0 mat_P_BSDF.inputs['Metallic'].default_value = 0.0
mat_P_BSDF.inputs['Specular'].default_value = 0.15 mat_P_BSDF.inputs['Specular'].default_value = 0.15
@ -624,7 +628,8 @@ def draw_obj_material(material_type, material):
if material_type == '3': # Reflecting if material_type == '3': # Reflecting
material_new = bpy.data.materials.new(material.name + "_reflecting") material_new = bpy.data.materials.new(material.name + "_reflecting")
material_new.use_nodes = True material_new.use_nodes = True
mat_P_BSDF = material_new.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material_new.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = default_color mat_P_BSDF.inputs['Base Color'].default_value = default_color
mat_P_BSDF.inputs['Metallic'].default_value = 0.7 mat_P_BSDF.inputs['Metallic'].default_value = 0.7
mat_P_BSDF.inputs['Specular'].default_value = 0.15 mat_P_BSDF.inputs['Specular'].default_value = 0.15
@ -640,7 +645,8 @@ def draw_obj_material(material_type, material):
if material_type == '4': # Transparent + reflecting if material_type == '4': # Transparent + reflecting
material_new = bpy.data.materials.new(material.name + "_trans+refl") material_new = bpy.data.materials.new(material.name + "_trans+refl")
material_new.use_nodes = True material_new.use_nodes = True
mat_P_BSDF = material_new.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material_new.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = default_color mat_P_BSDF.inputs['Base Color'].default_value = default_color
mat_P_BSDF.inputs['Metallic'].default_value = 0.5 mat_P_BSDF.inputs['Metallic'].default_value = 0.5
mat_P_BSDF.inputs['Specular'].default_value = 0.15 mat_P_BSDF.inputs['Specular'].default_value = 0.15
@ -933,7 +939,8 @@ def draw_obj_special(atom_shape, atom):
# Get the color of the selected atom. # Get the color of the selected atom.
material = atom.active_material material = atom.active_material
mat_P_BSDF_default = material.node_tree.nodes['Principled BSDF'] mat_P_BSDF_default = next(n for n in material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
default_color = mat_P_BSDF_default.inputs['Base Color'].default_value default_color = mat_P_BSDF_default.inputs['Base Color'].default_value
# Create first a cube # Create first a cube
@ -952,7 +959,8 @@ def draw_obj_special(atom_shape, atom):
# New material for this cube # New material for this cube
material_new = bpy.data.materials.new(atom.name + "_F2+_vac") material_new = bpy.data.materials.new(atom.name + "_F2+_vac")
material_new.use_nodes = True material_new.use_nodes = True
mat_P_BSDF = material_new.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material_new.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = default_color mat_P_BSDF.inputs['Base Color'].default_value = default_color
mat_P_BSDF.inputs['Metallic'].default_value = 0.7 mat_P_BSDF.inputs['Metallic'].default_value = 0.7
mat_P_BSDF.inputs['Specular'].default_value = 0.0 mat_P_BSDF.inputs['Specular'].default_value = 0.0
@ -1008,7 +1016,8 @@ def draw_obj_special(atom_shape, atom):
# New material for this cube # New material for this cube
material_new = bpy.data.materials.new(atom.name + "_F2+_vac") material_new = bpy.data.materials.new(atom.name + "_F2+_vac")
material_new.use_nodes = True material_new.use_nodes = True
mat_P_BSDF = material_new.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material_new.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = [0.0, 0.0, 0.8, 1.0] mat_P_BSDF.inputs['Base Color'].default_value = [0.0, 0.0, 0.8, 1.0]
mat_P_BSDF.inputs['Metallic'].default_value = 0.7 mat_P_BSDF.inputs['Metallic'].default_value = 0.7
mat_P_BSDF.inputs['Specular'].default_value = 0.0 mat_P_BSDF.inputs['Specular'].default_value = 0.0
@ -1038,7 +1047,8 @@ def draw_obj_special(atom_shape, atom):
# New material for the electron # New material for the electron
material_electron = bpy.data.materials.new(atom.name + "_F+-center") material_electron = bpy.data.materials.new(atom.name + "_F+-center")
material_electron.use_nodes = True material_electron.use_nodes = True
mat_P_BSDF = material_electron.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material_electron.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = [0.0, 0.0, 0.8, 1.0] mat_P_BSDF.inputs['Base Color'].default_value = [0.0, 0.0, 0.8, 1.0]
mat_P_BSDF.inputs['Metallic'].default_value = 0.8 mat_P_BSDF.inputs['Metallic'].default_value = 0.8
mat_P_BSDF.inputs['Specular'].default_value = 0.0 mat_P_BSDF.inputs['Specular'].default_value = 0.0
@ -1097,7 +1107,8 @@ def draw_obj_special(atom_shape, atom):
# New material for this cube # New material for this cube
material_new = bpy.data.materials.new(atom.name + "_F2+_vac") material_new = bpy.data.materials.new(atom.name + "_F2+_vac")
material_new.use_nodes = True material_new.use_nodes = True
mat_P_BSDF = material_new.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material_new.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = [0.8, 0.0, 0.0, 1.0] mat_P_BSDF.inputs['Base Color'].default_value = [0.8, 0.0, 0.0, 1.0]
mat_P_BSDF.inputs['Metallic'].default_value = 0.7 mat_P_BSDF.inputs['Metallic'].default_value = 0.7
mat_P_BSDF.inputs['Specular'].default_value = 0.0 mat_P_BSDF.inputs['Specular'].default_value = 0.0
@ -1136,7 +1147,8 @@ def draw_obj_special(atom_shape, atom):
# Create a new material for the two electrons. # Create a new material for the two electrons.
material_electron = bpy.data.materials.new(atom.name + "_F0-center") material_electron = bpy.data.materials.new(atom.name + "_F0-center")
material_electron.use_nodes = True material_electron.use_nodes = True
mat_P_BSDF = material_electron.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material_electron.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = [0.0, 0.0, 0.8, 1.0] mat_P_BSDF.inputs['Base Color'].default_value = [0.0, 0.0, 0.8, 1.0]
mat_P_BSDF.inputs['Metallic'].default_value = 0.8 mat_P_BSDF.inputs['Metallic'].default_value = 0.8
mat_P_BSDF.inputs['Specular'].default_value = 0.0 mat_P_BSDF.inputs['Specular'].default_value = 0.0
@ -1263,7 +1275,8 @@ def custom_datafile_change_atom_props():
if FLAG: if FLAG:
obj.scale = (e.radii[0],) * 3 obj.scale = (e.radii[0],) * 3
mat = obj.active_material mat = obj.active_material
mat_P_BSDF = mat.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in mat.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = e.color mat_P_BSDF.inputs['Base Color'].default_value = e.color
mat_P_BSDF.subsurface_method = e.mat_P_BSDF.Subsurface_method mat_P_BSDF.subsurface_method = e.mat_P_BSDF.Subsurface_method

View File

@ -472,7 +472,8 @@ def import_xyz(Ball_type,
material = bpy.data.materials.new(atom.name) material = bpy.data.materials.new(atom.name)
material.diffuse_color = atom.color material.diffuse_color = atom.color
material.use_nodes = True material.use_nodes = True
mat_P_BSDF = material.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Base Color'].default_value = atom.color mat_P_BSDF.inputs['Base Color'].default_value = atom.color
material.name = atom.name material.name = atom.name
atom_material_list.append(material) atom_material_list.append(material)
@ -491,7 +492,8 @@ def import_xyz(Ball_type,
if atom.name == "Vacancy": if atom.name == "Vacancy":
# For cycles and eevee. # For cycles and eevee.
material.use_nodes = True material.use_nodes = True
mat_P_BSDF = material.node_tree.nodes['Principled BSDF'] mat_P_BSDF = next(n for n in material.node_tree.nodes
if n.type == "BSDF_PRINCIPLED")
mat_P_BSDF.inputs['Metallic'].default_value = 0.1 mat_P_BSDF.inputs['Metallic'].default_value = 0.1
mat_P_BSDF.inputs['Specular'].default_value = 0.15 mat_P_BSDF.inputs['Specular'].default_value = 0.15
mat_P_BSDF.inputs['Roughness'].default_value = 0.05 mat_P_BSDF.inputs['Roughness'].default_value = 0.05

View File

@ -3,7 +3,7 @@
bl_info = { bl_info = {
"name": "FBX format", "name": "FBX format",
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier", "author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
"version": (4, 37, 4), "version": (4, 37, 5),
"blender": (3, 4, 0), "blender": (3, 4, 0),
"location": "File > Import-Export", "location": "File > Import-Export",
"description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions", "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
@ -80,7 +80,7 @@ class ImportFBX(bpy.types.Operator, ImportHelper):
name="Apply Transform", name="Apply Transform",
description="Bake space transform into object data, avoids getting unwanted rotations to objects when " description="Bake space transform into object data, avoids getting unwanted rotations to objects when "
"target space is not aligned with Blender's space " "target space is not aligned with Blender's space "
"(WARNING! experimental option, use at own risks, known broken with armatures/animations)", "(WARNING! experimental option, use at own risk, known to be broken with armatures/animations)",
default=False, default=False,
) )
@ -434,7 +434,7 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
name="Apply Transform", name="Apply Transform",
description="Bake space transform into object data, avoids getting unwanted rotations to objects when " description="Bake space transform into object data, avoids getting unwanted rotations to objects when "
"target space is not aligned with Blender's space " "target space is not aligned with Blender's space "
"(WARNING! experimental option, use at own risks, known broken with armatures/animations)", "(WARNING! experimental option, use at own risk, known to be broken with armatures/animations)",
default=False, default=False,
) )
@ -549,8 +549,8 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
('LIMBNODE', "LimbNode", "'LimbNode' FBX node, a regular joint between two bones..."), ('LIMBNODE', "LimbNode", "'LimbNode' FBX node, a regular joint between two bones..."),
), ),
description="FBX type of node (object) used to represent Blender's armatures " description="FBX type of node (object) used to represent Blender's armatures "
"(use Null one unless you experience issues with other app, other choices may no import back " "(use the Null type unless you experience issues with the other app, "
"perfectly in Blender...)", "as other choices may not import back perfectly into Blender...)",
default='NULL', default='NULL',
) )
bake_anim: BoolProperty( bake_anim: BoolProperty(

View File

@ -3154,7 +3154,7 @@ def load(operator, context, filepath="",
# Intensity actually, not color... # Intensity actually, not color...
ma_wrap.metallic_texture.image = image ma_wrap.metallic_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.metallic_texture) texture_mapping_set(fbx_lnk, ma_wrap.metallic_texture)
elif lnk_type in {b'TransparentColor', b'TransparentFactor'}: elif lnk_type in {b'TransparentColor', b'TransparencyFactor'}:
ma_wrap.alpha_texture.image = image ma_wrap.alpha_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.alpha_texture) texture_mapping_set(fbx_lnk, ma_wrap.alpha_texture)
if use_alpha_decals: if use_alpha_decals:

View File

@ -4,8 +4,8 @@
bl_info = { bl_info = {
'name': 'glTF 2.0 format', 'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors', 'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
"version": (3, 5, 21), "version": (3, 6, 0),
'blender': (3, 4, 0), 'blender': (3, 5, 0),
'location': 'File > Import-Export', 'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0', 'description': 'Import-Export as glTF 2.0',
'warning': '', 'warning': '',
@ -97,6 +97,11 @@ def on_export_format_changed(self, context):
self.export_format, self.export_format,
) )
# Also change the filter
sfile.params.filter_glob = '*.glb' if self.export_format == 'GLB' else '*.gltf'
# Force update of file list, has update the filter does not update the real file list
bpy.ops.file.refresh()
class ConvertGLTF2_Base: class ConvertGLTF2_Base:
"""Base class containing options that should be exposed during both import and export.""" """Base class containing options that should be exposed during both import and export."""
@ -146,7 +151,7 @@ class ExportGLTF2_Base(ConvertGLTF2_Base):
'Output format and embedding options. Binary is most efficient, ' 'Output format and embedding options. Binary is most efficient, '
'but JSON (embedded or separate) may be easier to edit later' 'but JSON (embedded or separate) may be easier to edit later'
), ),
default='GLB', default='GLB', #Warning => If you change the default, need to change the default filter too
update=on_export_format_changed, update=on_export_format_changed,
) )
@ -441,7 +446,7 @@ class ExportGLTF2_Base(ConvertGLTF2_Base):
export_optimize_animation_size: BoolProperty( export_optimize_animation_size: BoolProperty(
name='Optimize Animation Size', name='Optimize Animation Size',
description=( description=(
"Reduce exported file-size by removing duplicate keyframes" "Reduce exported file size by removing duplicate keyframes "
"(can cause problems with stepped animation)" "(can cause problems with stepped animation)"
), ),
default=False default=False
@ -1158,7 +1163,7 @@ class ExportGLTF2(bpy.types.Operator, ExportGLTF2_Base, ExportHelper):
filename_ext = '' filename_ext = ''
filter_glob: StringProperty(default='*.glb;*.gltf', options={'HIDDEN'}) filter_glob: StringProperty(default='*.glb', options={'HIDDEN'})
def menu_func_export(self, context): def menu_func_export(self, context):

View File

@ -6,6 +6,7 @@ from mathutils import Vector
from . import gltf2_blender_export_keys from . import gltf2_blender_export_keys
from ...io.com.gltf2_io_debug import print_console from ...io.com.gltf2_io_debug import print_console
from ...io.com.gltf2_io_constants import NORMALS_ROUNDING_DIGIT
from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins
from io_scene_gltf2.io.com import gltf2_io_constants from io_scene_gltf2.io.com import gltf2_io_constants
from io_scene_gltf2.blender.com import gltf2_blender_conversion from io_scene_gltf2.blender.com import gltf2_blender_conversion
@ -699,10 +700,13 @@ class PrimitiveCreator:
self.normals = self.normals.reshape(len(self.blender_mesh.loops), 3) self.normals = self.normals.reshape(len(self.blender_mesh.loops), 3)
self.normals = np.round(self.normals, NORMALS_ROUNDING_DIGIT)
self.morph_normals = [] self.morph_normals = []
for key_block in key_blocks: for key_block in key_blocks:
ns = np.array(key_block.normals_split_get(), dtype=np.float32) ns = np.array(key_block.normals_split_get(), dtype=np.float32)
ns = ns.reshape(len(self.blender_mesh.loops), 3) ns = ns.reshape(len(self.blender_mesh.loops), 3)
ns = np.round(ns, NORMALS_ROUNDING_DIGIT)
self.morph_normals.append(ns) self.morph_normals.append(ns)
# Transform for skinning # Transform for skinning

View File

@ -86,10 +86,16 @@ def __gather_wrap(blender_shader_node, export_settings):
elif blender_shader_node.extension == 'CLIP': elif blender_shader_node.extension == 'CLIP':
# Not possible in glTF, but ClampToEdge is closest # Not possible in glTF, but ClampToEdge is closest
wrap_s = TextureWrap.ClampToEdge wrap_s = TextureWrap.ClampToEdge
elif blender_shader_node.extension == 'MIRROR':
wrap_s = TextureWrap.MirroredRepeat
else: else:
wrap_s = TextureWrap.Repeat wrap_s = TextureWrap.Repeat
wrap_t = wrap_s wrap_t = wrap_s
# Starting Blender 3.5, MIRROR is now an extension of image node
# So this manual uv wrapping trick is no more usefull for MIRROR x MIRROR
# But still works for old files
# Still needed for heterogen heterogeneous sampler, like MIRROR x REPEAT, for example
# Take manual wrapping into account # Take manual wrapping into account
result = detect_manual_uv_wrapping(blender_shader_node) result = detect_manual_uv_wrapping(blender_shader_node)
if result: if result:

View File

@ -169,7 +169,7 @@ def __gather_texture_transform_and_tex_coord(primary_socket, export_settings):
node_tree = node.id_data node_tree = node.id_data
for mesh in bpy.data.meshes: for mesh in bpy.data.meshes:
for material in mesh.materials: for material in mesh.materials:
if material.node_tree == node_tree: if material and material.node_tree == node_tree:
i = mesh.uv_layers.find(node.uv_map) i = mesh.uv_layers.find(node.uv_map)
if i >= 0: if i >= 0:
texcoord_idx = i texcoord_idx = i

View File

@ -171,8 +171,8 @@ class VExportTree:
# If object is parented to bone, and Rest pose is used, we need to keep the world matrix # If object is parented to bone, and Rest pose is used, we need to keep the world matrix
# Of the rest pose, not the current world matrix # Of the rest pose, not the current world matrix
if parent_uuid and self.nodes[parent_uuid].blender_type == VExportNode.BONE and self.export_settings['gltf_current_frame'] is False: if parent_uuid and self.nodes[parent_uuid].blender_type == VExportNode.BONE and self.export_settings['gltf_current_frame'] is False:
blender_bone = self.nodes[parent_uuid].blender_bone _blender_bone = self.nodes[parent_uuid].blender_bone
node.matrix_world = (blender_bone.matrix @ blender_bone.bone.matrix_local.inverted_safe()).inverted_safe() @ node.matrix_world node.matrix_world = (_blender_bone.matrix @ _blender_bone.bone.matrix_local.inverted_safe()).inverted_safe() @ node.matrix_world
if node.blender_type == VExportNode.CAMERA and self.export_settings[gltf2_blender_export_keys.CAMERAS]: if node.blender_type == VExportNode.CAMERA and self.export_settings[gltf2_blender_export_keys.CAMERAS]:
if self.export_settings[gltf2_blender_export_keys.YUP]: if self.export_settings[gltf2_blender_export_keys.YUP]:

View File

@ -309,7 +309,11 @@ class GlTF2Exporter:
return image return image
# extensions # extensions
if isinstance(node, gltf2_io_extensions.Extension): # I don't know why, but after reloading script, this condition failed
# So using name comparison, instead of isinstance
# if isinstance(node, gltf2_io_extensions.Extension):
if isinstance(node, gltf2_io_extensions.Extension) \
or (node and hasattr(type(node), "extension")):
extension = self.__traverse(node.extension) extension = self.__traverse(node.extension)
self.__append_unique_and_get_index(self.__gltf.extensions_used, node.name) self.__append_unique_and_get_index(self.__gltf.extensions_used, node.name)
if node.required: if node.required:

View File

@ -69,11 +69,13 @@ def texture(
wrap_s = TextureWrap.Repeat wrap_s = TextureWrap.Repeat
if wrap_t is None: if wrap_t is None:
wrap_t = TextureWrap.Repeat wrap_t = TextureWrap.Repeat
# If wrapping is REPEATxREPEAT or CLAMPxCLAMP, just set tex_img.extension # If wrapping is the same in both directions, just set tex_img.extension
if (wrap_s, wrap_t) == (TextureWrap.Repeat, TextureWrap.Repeat): if wrap_s == wrap_t == TextureWrap.Repeat:
tex_img.extension = 'REPEAT' tex_img.extension = 'REPEAT'
elif (wrap_s, wrap_t) == (TextureWrap.ClampToEdge, TextureWrap.ClampToEdge): elif wrap_s == wrap_t == TextureWrap.ClampToEdge:
tex_img.extension = 'EXTEND' tex_img.extension = 'EXTEND'
elif wrap_s == wrap_t == TextureWrap.MirroredRepeat:
tex_img.extension = 'MIRROR'
else: else:
# Otherwise separate the UV components and use math nodes to compute # Otherwise separate the UV components and use math nodes to compute
# the wrapped UV coordinates # the wrapped UV coordinates

View File

@ -150,3 +150,6 @@ GLTF_DATA_TYPE_MAT3 = "MAT3"
GLTF_DATA_TYPE_MAT4 = "MAT4" GLTF_DATA_TYPE_MAT4 = "MAT4"
GLTF_IOR = 1.5 GLTF_IOR = 1.5
# Rounding digit used for normal rounding
NORMALS_ROUNDING_DIGIT = 4

View File

@ -6,6 +6,8 @@ from typing import List, Dict, Any
class Extension: class Extension:
"""Container for extensions. Allows to specify requiredness""" """Container for extensions. Allows to specify requiredness"""
extension = True # class method used to check Extension class at traversal (after reloading script, isinstance is not working)
def __init__(self, name: str, extension: Dict[str, Any], required: bool = True): def __init__(self, name: str, extension: Dict[str, Any], required: bool = True):
self.name = name self.name = name
self.extension = extension self.extension = extension

View File

@ -449,7 +449,8 @@ class MUV_OT_TextureProjection_Project(bpy.types.Operator):
# assign image # assign image
if compat.check_version(2, 80, 0) >= 0: if compat.check_version(2, 80, 0) >= 0:
node_tree = obj.active_material.node_tree node_tree = obj.active_material.node_tree
output_node = node_tree.nodes["Material Output"] output_node = next(n for n in node_tree.nodes
if n.type == "OUTPUT_MATERIAL")
nodes = common.find_texture_nodes_from_material( nodes = common.find_texture_nodes_from_material(
obj.active_material) obj.active_material)

View File

@ -447,7 +447,8 @@ class MUV_OT_UVInspection_PaintUVIsland(bpy.types.Operator):
"MagicUV_PaintUVMaterial_{}".format(i)) "MagicUV_PaintUVMaterial_{}".format(i))
if compat.check_version(2, 80, 0) >= 0: if compat.check_version(2, 80, 0) >= 0:
target_mtrl.use_nodes = True target_mtrl.use_nodes = True
output_node = target_mtrl.node_tree.nodes["Material Output"] output_node = next(n for n in target_mtrl.node_tree.nodes
if n.type == "OUTPUT_MATERIAL")
nodes_to_remove = [n for n in target_mtrl.node_tree.nodes nodes_to_remove = [n for n in target_mtrl.node_tree.nodes
if n != output_node] if n != output_node]
for n in nodes_to_remove: for n in nodes_to_remove:

View File

@ -2,7 +2,7 @@
bl_info = { bl_info = {
"name": "Rigify", "name": "Rigify",
"version": (0, 6, 6), "version": (0, 6, 7),
"author": "Nathan Vegdahl, Lucio Rossi, Ivan Cappiello, Alexander Gavrilov", # noqa "author": "Nathan Vegdahl, Lucio Rossi, Ivan Cappiello, Alexander Gavrilov", # noqa
"blender": (3, 0, 0), "blender": (3, 0, 0),
"description": "Automatic rigging from building-block components", "description": "Automatic rigging from building-block components",

View File

@ -720,17 +720,17 @@ class MESH_MT_CopyFaceSettings(Menu):
layout = self.layout layout = self.layout
op = layout.operator(mesh.copy_face_settings, text="Copy Material") op = layout.operator("mesh.copy_face_settings", text="Copy Material")
op['layer'] = '' op['layer'] = ''
op['mode'] = 'MAT' op['mode'] = 'MAT'
if mesh.uv_layers.active: if mesh.uv_layers.active:
op = layout.operator(mesh.copy_face_settings, text="Copy Active UV Coords") op = layout.operator("mesh.copy_face_settings", text="Copy Active UV Coords")
op['layer'] = '' op['layer'] = ''
op['mode'] = 'UV' op['mode'] = 'UV'
if mesh.vertex_colors.active: if mesh.vertex_colors.active:
op = layout.operator(mesh.copy_face_settings, text="Copy Active Vertex Colors") op = layout.operator("mesh.copy_face_settings", text="Copy Active Vertex Colors")
op['layer'] = '' op['layer'] = ''
op['mode'] = 'VCOL' op['mode'] = 'VCOL'
@ -783,7 +783,7 @@ def _buildmenu(self, mesh, mode, icon):
layers = mesh.uv_layers layers = mesh.uv_layers
for layer in layers: for layer in layers:
if not layer.active: if not layer.active:
op = layout.operator(mesh.copy_face_settings, op = layout.operator("mesh.copy_face_settings",
text=layer.name, icon=icon) text=layer.name, icon=icon)
op['layer'] = layer.name op['layer'] = layer.name
op['mode'] = mode op['mode'] = mode

View File

@ -16,7 +16,7 @@
bl_info = { bl_info = {
"name": "Sun Position", "name": "Sun Position",
"author": "Michael Martin", "author": "Michael Martin",
"version": (3, 2, 0), "version": (3, 2, 2),
"blender": (3, 0, 0), "blender": (3, 0, 0),
"location": "World > Sun Position", "location": "World > Sun Position",
"description": "Show sun position with objects and/or sky texture", "description": "Show sun position with objects and/or sky texture",

View File

@ -11,14 +11,23 @@ if bpy.app.background: # ignore north line in background mode
def north_update(self, context): def north_update(self, context):
pass pass
else: else:
vertex_shader = ''' shader_interface = gpu.types.GPUStageInterfaceInfo("my_interface")
uniform mat4 u_ViewProjectionMatrix; shader_interface.flat('VEC2', "v_StartPos")
shader_interface.smooth('VEC4', "v_VertPos")
in vec3 position; shader_info = gpu.types.GPUShaderCreateInfo()
shader_info.push_constant('MAT4', "u_ViewProjectionMatrix")
flat out vec2 v_StartPos; shader_info.push_constant('VEC4', "u_Color")
out vec4 v_VertPos; shader_info.push_constant('VEC2', "u_Resolution")
shader_info.vertex_in(0, 'VEC3', "position")
shader_info.vertex_out(shader_interface)
shader_info.vertex_source(
# uniform mat4 u_ViewProjectionMatrix;
# in vec3 position;
# flat out vec2 v_StartPos;
# out vec4 v_VertPos;
'''
void main() void main()
{ {
vec4 pos = u_ViewProjectionMatrix * vec4(position, 1.0f); vec4 pos = u_ViewProjectionMatrix * vec4(position, 1.0f);
@ -27,16 +36,16 @@ else:
v_VertPos = pos; v_VertPos = pos;
} }
''' '''
)
fragment_shader = ''' shader_info.fragment_out(0, 'VEC4', "FragColor")
uniform vec4 u_Color; shader_info.fragment_source(
# uniform vec4 u_Color;
flat in vec2 v_StartPos; # uniform vec2 u_Resolution;
in vec4 v_VertPos; # flat in vec2 v_StartPos;
out vec4 FragColor; # in vec4 v_VertPos;
# out vec4 FragColor;
uniform vec2 u_Resolution; '''
void main() void main()
{ {
vec4 vertPos_2d = v_VertPos / v_VertPos.w; vec4 vertPos_2d = v_VertPos / v_VertPos.w;
@ -48,8 +57,11 @@ else:
FragColor = u_Color; FragColor = u_Color;
} }
''' '''
)
shader = gpu.types.GPUShader(vertex_shader, fragment_shader) shader = gpu.shader.create_from_info(shader_info)
del shader_info
del shader_interface
def draw_north_callback(): def draw_north_callback():
""" """
@ -77,7 +89,6 @@ else:
batch.draw(shader) batch.draw(shader)
gpu.state.line_width_set(width) gpu.state.line_width_set(width)
_north_handle = None _north_handle = None
def north_update(self, context): def north_update(self, context):