Merge branch 'master' into xr-dev

This commit is contained in:
Peter Kim 2022-05-28 17:29:32 +09:00
commit 22270a72d6
18 changed files with 162 additions and 118 deletions

View File

@ -40,7 +40,7 @@ class AMTH_NODE_OT_show_active_node_image(bpy.types.Operator):
def invoke(self, context, event):
mlocx = event.mouse_region_x
mlocy = event.mouse_region_y
select_node = bpy.ops.node.select(mouse_x=mlocx, mouse_y=mlocy, extend=False)
select_node = bpy.ops.node.select(location=(mlocx, mlocy), extend=False)
if 'FINISHED' in select_node: # Only run if we're clicking on a node
get_addon = "amaranth" in context.preferences.addons.keys()

View File

@ -36,7 +36,6 @@ def create_and_link_mesh(name, faces, face_nors, points, global_matrix):
mesh.normals_split_custom_set(tuple(zip(*(iter(clnors),) * 3)))
mesh.use_auto_smooth = True
mesh.show_edge_sharp = True
mesh.free_normals_split()
mesh.update()

View File

@ -4,8 +4,8 @@
bl_info = {
'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
"version": (3, 3, 0),
'blender': (3, 1, 0),
"version": (3, 3, 3),
'blender': (3, 3, 0),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',
'warning': '',

View File

@ -526,18 +526,11 @@ def __get_uvs(blender_mesh, uv_i):
def __get_colors(blender_mesh, color_i):
layer = blender_mesh.vertex_colors[color_i]
colors = np.empty(len(blender_mesh.loops) * 4, dtype=np.float32)
layer.data.foreach_get('color', colors)
layer = blender_mesh.vertex_colors[color_i]
blender_mesh.color_attributes[layer.name].data.foreach_get('color', colors)
colors = colors.reshape(len(blender_mesh.loops), 4)
# sRGB -> Linear
rgb = colors[:, :-1]
not_small = rgb >= 0.04045
small_result = np.where(rgb < 0.0, 0.0, rgb * (1.0 / 12.92))
large_result = np.power((rgb + 0.055) * (1.0 / 1.055), 2.4, where=not_small)
rgb[:] = np.where(not_small, large_result, small_result)
# colors are already linear, no need to switch color space
return colors

View File

@ -193,11 +193,11 @@ def __get_image_data(sockets, export_settings) -> ExportImage:
# rudimentarily try follow the node tree to find the correct image data.
src_chan = Channel.R
for elem in result.path:
if isinstance(elem.from_node, bpy.types.ShaderNodeSeparateRGB):
if isinstance(elem.from_node, bpy.types.ShaderNodeSeparateColor):
src_chan = {
'R': Channel.R,
'G': Channel.G,
'B': Channel.B,
'Red': Channel.R,
'Green': Channel.G,
'Blue': Channel.B,
}[elem.from_socket.name]
if elem.from_socket.name == 'Alpha':
src_chan = Channel.A

View File

@ -39,10 +39,10 @@ def clearcoat(mh, location, clearcoat_socket):
x -= 200
# Separate RGB
node = mh.node_tree.nodes.new('ShaderNodeSeparateRGB')
node = mh.node_tree.nodes.new('ShaderNodeSeparateColor')
node.location = x - 150, y - 75
# Outputs
mh.node_tree.links.new(clearcoat_socket, node.outputs['R'])
mh.node_tree.links.new(clearcoat_socket, node.outputs['Red'])
# Inputs
clearcoat_socket = node.inputs[0]
@ -92,10 +92,10 @@ def clearcoat_roughness(mh, location, roughness_socket):
x -= 200
# Separate RGB (roughness is in G)
node = mh.node_tree.nodes.new('ShaderNodeSeparateRGB')
node = mh.node_tree.nodes.new('ShaderNodeSeparateColor')
node.location = x - 150, y - 75
# Outputs
mh.node_tree.links.new(roughness_socket, node.outputs['G'])
mh.node_tree.links.new(roughness_socket, node.outputs['Green'])
# Inputs
color_socket = node.inputs[0]

View File

@ -5,7 +5,7 @@ from .gltf2_blender_animation_node import BlenderNodeAnim
from .gltf2_blender_animation_weight import BlenderWeightAnim
from .gltf2_blender_animation_utils import simulate_stash, restore_animation_on_object
from .gltf2_blender_vnode import VNode
from io_scene_gltf2.io.imp.gltf2_io_user_extensions import import_user_extensions
class BlenderAnimation():
"""Dispatch Animation to node or morph weights animation."""
@ -20,6 +20,8 @@ class BlenderAnimation():
# Things we need to stash when we're done.
gltf.needs_stash = []
import_user_extensions('gather_import_animation_before_hook', gltf, anim_idx)
for vnode_id in gltf.vnodes:
if isinstance(vnode_id, int):
BlenderNodeAnim.anim(gltf, anim_idx, vnode_id)
@ -30,6 +32,8 @@ class BlenderAnimation():
for (obj, action) in gltf.needs_stash:
simulate_stash(obj, track_name, action)
import_user_extensions('gather_import_animation_after_hook', gltf, anim_idx, track_name)
@staticmethod
def restore_animation(gltf, animation_name):
"""Restores the actions for an animation by its track name."""

View File

@ -20,6 +20,7 @@ class BlenderNodeAnim():
"""Manage animation targeting a node's TRS."""
animation = gltf.data.animations[anim_idx]
node = gltf.data.nodes[node_idx]
if anim_idx not in node.animations.keys():
return

View File

@ -58,6 +58,16 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
"""Put all primitive data into the mesh."""
pymesh = gltf.data.meshes[mesh_idx]
# Use a class here, to be able to pass data by reference to hook (to be able to change them inside hook)
class IMPORT_mesh_options:
def __init__(self, skinning: bool = True, skin_into_bind_pose: bool = True, use_auto_smooth: bool = True):
self.skinning = skinning
self.skin_into_bind_pose = skin_into_bind_pose
self.use_auto_smooth = use_auto_smooth
mesh_options = IMPORT_mesh_options()
import_user_extensions('gather_import_mesh_options', gltf, mesh_options, pymesh, skin_idx)
# Scan the primitives to find out what we need to create
has_normals = False
@ -135,6 +145,8 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
print_console('INFO', 'Draco Decoder: Decode primitive {}'.format(pymesh.name or '[unnamed]'))
decode_primitive(gltf, prim)
import_user_extensions('gather_import_decode_primitive', gltf, pymesh, prim, skin_idx)
if prim.indices is not None:
indices = BinaryData.decode_accessor(gltf, prim.indices)
indices = indices.reshape(len(indices))
@ -240,7 +252,7 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
for sk_locs in sk_vert_locs:
gltf.locs_batch_gltf_to_blender(sk_locs)
if num_joint_sets:
if num_joint_sets and mesh_options.skin_into_bind_pose:
skin_into_bind_pose(
gltf, skin_idx, vert_joints, vert_weights,
locs=[vert_locs] + sk_vert_locs,
@ -250,9 +262,6 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
for uvs in loop_uvs:
uvs_gltf_to_blender(uvs)
for cols in loop_cols:
colors_linear_to_srgb(cols[:, :-1])
# ---------------
# Start creating things
@ -289,14 +298,14 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
if layer is None:
print("WARNING: Vertex colors are ignored because the maximum number of vertex color layers has been "
"reached.")
"reached.")
break
layer.data.foreach_set('color', squish(loop_cols[col_i]))
mesh.color_attributes[layer.name].data.foreach_set('color', squish(loop_cols[col_i]))
# Skinning
# TODO: this is slow :/
if num_joint_sets:
if num_joint_sets and mesh_options.skinning:
pyskin = gltf.data.skins[skin_idx]
for i, node_idx in enumerate(pyskin.joints):
bone = gltf.vnodes[node_idx]
@ -343,7 +352,7 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
if prim.material is not None:
# Get the material
pymaterial = gltf.data.materials[prim.material]
vertex_color = 'COLOR_0' if 'COLOR_0' in prim.attributes else None
vertex_color = 'COLOR_0' if ('COLOR_0' in prim.attributes) else None
if vertex_color not in pymaterial.blender_material:
BlenderMaterial.create(gltf, prim.material, vertex_color)
material_name = pymaterial.blender_material[vertex_color]
@ -377,7 +386,7 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
if has_normals:
mesh.create_normals_split()
mesh.normals_split_custom_set_from_vertices(vert_normals)
mesh.use_auto_smooth = True
mesh.use_auto_smooth = mesh_options.use_auto_smooth
def points_edges_tris(mode, indices):
@ -468,16 +477,6 @@ def colors_rgb_to_rgba(rgb):
rgba[:, :3] = rgb
return rgba
def colors_linear_to_srgb(color):
assert color.shape[1] == 3 # only change RGB, not A
not_small = color >= 0.0031308
small_result = np.where(color < 0.0, 0.0, color * 12.92)
large_result = 1.055 * np.power(color, 1.0 / 2.4, where=not_small) - 0.055
color[:] = np.where(not_small, large_result, small_result)
def uvs_gltf_to_blender(uvs):
# u,v -> u,1-v
uvs[:, 1] *= -1

View File

@ -363,11 +363,11 @@ def metallic_roughness(mh: MaterialHelper, location, metallic_socket, roughness_
x -= 200
# Separate RGB
node = mh.node_tree.nodes.new('ShaderNodeSeparateRGB')
node = mh.node_tree.nodes.new('ShaderNodeSeparateColor')
node.location = x - 150, y - 75
# Outputs
mh.node_tree.links.new(metallic_socket, node.outputs['B'])
mh.node_tree.links.new(roughness_socket, node.outputs['G'])
mh.node_tree.links.new(metallic_socket, node.outputs['Blue'])
mh.node_tree.links.new(roughness_socket, node.outputs['Green'])
# Inputs
color_socket = node.inputs[0]
@ -447,10 +447,10 @@ def occlusion(mh: MaterialHelper, location, occlusion_socket):
x -= 200
# Separate RGB
node = mh.node_tree.nodes.new('ShaderNodeSeparateRGB')
node = mh.node_tree.nodes.new('ShaderNodeSeparateColor')
node.location = x - 150, y - 75
# Outputs
mh.node_tree.links.new(occlusion_socket, node.outputs['R'])
mh.node_tree.links.new(occlusion_socket, node.outputs['Red'])
# Inputs
color_socket = node.inputs[0]

View File

@ -57,6 +57,15 @@ class BlenderScene():
@staticmethod
def create_animations(gltf):
"""Create animations."""
# Use a class here, to be able to pass data by reference to hook (to be able to change them inside hook)
class IMPORT_animation_options:
def __init__(self, restore_first_anim: bool = True):
self.restore_first_anim = restore_first_anim
animation_options = IMPORT_animation_options()
import_user_extensions('gather_import_animations', gltf, gltf.data.animations, animation_options)
if gltf.data.animations:
# NLA tracks are added bottom to top, so create animations in
# reverse so the first winds up on top
@ -64,8 +73,9 @@ class BlenderScene():
BlenderAnimation.anim(gltf, anim_idx)
# Restore first animation
anim_name = gltf.data.animations[0].track_name
BlenderAnimation.restore_animation(gltf, anim_name)
if animation_options.restore_first_anim:
anim_name = gltf.data.animations[0].track_name
BlenderAnimation.restore_animation(gltf, anim_name)
@staticmethod
def select_imported_objects(gltf):

View File

@ -6,7 +6,7 @@
bl_info = {
"name": "Snap_Utilities_Line",
"author": "Germano Cavalcante",
"version": (6, 9, 9),
"version": (6, 7, 0),
"blender": (3, 2, 0),
"location": "View3D > TOOLS > Line Tool",
"description": "Extends Blender Snap controls",

View File

@ -2,16 +2,10 @@
import gpu
import bmesh
import ctypes
from mathutils import Matrix
def load_shader(shadername):
from os import path
with open(path.join(path.dirname(__file__), "shaders", shadername), "r") as f:
return f.read()
def get_mesh_vert_co_array(me):
tot_vco = len(me.vertices)
if tot_vco:
@ -183,10 +177,14 @@ class GPU_Indices_Mesh:
_Hash = {}
shader = None
UBO_data = None
UBO = None
@classmethod
def end_opengl(cls):
del cls.shader
del cls.UBO
del cls.UBO_data
del cls
@ -203,14 +201,79 @@ class GPU_Indices_Mesh:
atexit.unregister(cls.end_opengl)
atexit.register(cls.end_opengl)
cls.shader = gpu.types.GPUShader(
load_shader("ID_color_vert.glsl"),
load_shader("ID_color_frag.glsl"),
defines="#define USE_CLIP_PLANES\n",
shader_info = gpu.types.GPUShaderCreateInfo()
shader_info.define("USE_CLIP_PLANES")
shader_info.typedef_source(
"struct Data {\n"
"#ifdef USE_CLIP_PLANES\n"
" mat4 ModelMatrix;"
" vec4 WorldClipPlanes[4];\n"
"#endif\n"
" int offset;\n"
"#ifdef USE_CLIP_PLANES\n"
" bool use_clip_planes;\n"
"#endif\n"
"};\n"
)
shader_info.push_constant("MAT4", "ModelViewProjectionMatrix")
shader_info.uniform_buf(0, "Data", "g_data")
shader_info.vertex_in(0, "VEC3", "pos")
shader_info.vertex_source(
# #define USE_CLIP_PLANES
# uniform mat4 ModelViewProjectionMatrix;
# layout(binding = 1, std140) uniform _g_data { Data g_data; };;
# in vec3 pos;
"void main()"
"{\n"
"#ifdef USE_CLIP_PLANES\n"
" if (g_data.use_clip_planes) {"
" vec4 wpos = g_data.ModelMatrix * vec4(pos, 1.0);"
" gl_ClipDistance[0] = dot(g_data.WorldClipPlanes[0], wpos);"
" gl_ClipDistance[1] = dot(g_data.WorldClipPlanes[1], wpos);"
" gl_ClipDistance[2] = dot(g_data.WorldClipPlanes[2], wpos);"
" gl_ClipDistance[3] = dot(g_data.WorldClipPlanes[3], wpos);"
" }\n"
"#endif\n"
" gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);"
"}"
)
cls.unif_offset = cls.shader.uniform_from_name("offset")
cls.use_clip_planes = False
shader_info.fragment_out(0, "UINT", "fragColor")
shader_info.fragment_source(
# out uint fragColor;
"void main() {fragColor = uint(gl_PrimitiveID + g_data.offset);}"
)
cls.shader = gpu.shader.create_from_info(shader_info)
class _UBO_struct(ctypes.Structure):
_pack_ = 16
_fields_ = [
("ModelMatrix", 4 * (4 * ctypes.c_float)),
("WorldClipPlanes", 4 * (4 * ctypes.c_float)),
("offset", ctypes.c_int),
("use_clip_planes", ctypes.c_int),
("_pad", ctypes.c_int * 2),
]
cls.UBO_data = _UBO_struct()
cls.UBO = gpu.types.GPUUniformBuf(
gpu.types.Buffer("UBYTE", ctypes.sizeof(cls.UBO_data), cls.UBO_data)
)
@staticmethod
def update_UBO():
cls = GPU_Indices_Mesh
cls.UBO.update(
gpu.types.Buffer(
"UBYTE",
ctypes.sizeof(cls.UBO_data),
cls.UBO_data,
)
)
cls.shader.bind()
cls.shader.uniform_block("g_data", cls.UBO)
def __init__(self, depsgraph, obj, draw_tris, draw_edges, draw_verts):
self.ob_data = obj.original.data
@ -326,12 +389,17 @@ class GPU_Indices_Mesh:
gpu.matrix.multiply_matrix(ob_mat)
self.shader.bind()
if GPU_Indices_Mesh.use_clip_planes:
if GPU_Indices_Mesh.UBO_data.use_clip_planes:
gpu.state.clip_distances_set(4)
self.shader.uniform_float("ModelMatrix", ob_mat)
self.UBO_data.ModelMatrix[0] = ob_mat[0][:]
self.UBO_data.ModelMatrix[1] = ob_mat[1][:]
self.UBO_data.ModelMatrix[2] = ob_mat[2][:]
self.UBO_data.ModelMatrix[3] = ob_mat[3][:]
if self.draw_tris:
self.shader.uniform_int("offset", (index_offset,))
self.UBO_data.offset = index_offset
self.update_UBO()
self.batch_tris.draw(self.shader)
index_offset += len(self.tri_verts)
@ -356,17 +424,21 @@ class GPU_Indices_Mesh:
gpu.matrix.load_projection_matrix(winmat)
if self.draw_edges:
self.shader.uniform_int("offset", (index_offset,))
self.UBO_data.offset = index_offset
self.update_UBO()
# bgl.glLineWidth(3.0)
self.batch_edges.draw(self.shader)
# bgl.glLineWidth(1.0)
index_offset += len(self.edge_verts)
if self.draw_verts:
self.shader.uniform_int("offset", (index_offset,))
self.UBO_data.offset = index_offset
self.update_UBO()
self.batch_lverts.draw(self.shader)
if GPU_Indices_Mesh.use_clip_planes:
if GPU_Indices_Mesh.UBO_data.use_clip_planes:
gpu.state.clip_distances_set(0)
gpu.matrix.pop()
@ -384,7 +456,7 @@ class GPU_Indices_Mesh:
def get_loop_tri_co_by_bmface(self, bm, bmface):
l_tri_layer = bm.faces.layers.int["l_tri"]
tri = bmface[l_tri_layer]
return self.verts_co[self.tri_verts[tri : tri + len(bmface.verts) - 2]]
return self.verts_co[self.tri_verts[tri: tri + len(bmface.verts) - 2]]
def get_tri_verts(self, index):
return self.tri_verts[index]
@ -426,18 +498,16 @@ def gpu_Indices_restore_state():
def gpu_Indices_use_clip_planes(rv3d, value):
GPU_Indices_Mesh.init_opengl()
shader = GPU_Indices_Mesh.shader
shader.bind()
if value and rv3d.use_clip_planes:
GPU_Indices_Mesh.use_clip_planes = True
planes = gpu.types.Buffer("FLOAT", (6, 4), rv3d.clip_planes)
shader.uniform_vector_float(
shader.uniform_from_name("WorldClipPlanes"), planes, 4, 4
)
GPU_Indices_Mesh.UBO_data.use_clip_planes = True
GPU_Indices_Mesh.UBO_data.WorldClipPlanes[0] = rv3d.clip_planes[0][:]
GPU_Indices_Mesh.UBO_data.WorldClipPlanes[1] = rv3d.clip_planes[1][:]
GPU_Indices_Mesh.UBO_data.WorldClipPlanes[2] = rv3d.clip_planes[2][:]
GPU_Indices_Mesh.UBO_data.WorldClipPlanes[3] = rv3d.clip_planes[3][:]
else:
GPU_Indices_Mesh.use_clip_planes = False
GPU_Indices_Mesh.UBO_data.use_clip_planes = False
shader.uniform_bool("use_clip_planes", (GPU_Indices_Mesh.use_clip_planes,))
GPU_Indices_Mesh.update_UBO()
def gpu_Indices_mesh_cache_clear():

View File

@ -1,7 +0,0 @@
uniform int offset;
out uint FragColor;
void main()
{
FragColor = uint(gl_PrimitiveID + offset);
}

View File

@ -1,25 +0,0 @@
uniform mat4 ModelViewProjectionMatrix;
#ifdef USE_CLIP_PLANES
uniform mat4 ModelMatrix;
uniform bool use_clip_planes;
uniform vec4 WorldClipPlanes[4];
#endif
in vec3 pos;
void main()
{
#ifdef USE_CLIP_PLANES
if (use_clip_planes) {
vec4 g_pos = ModelMatrix * vec4(pos, 1.0);
gl_ClipDistance[0] = dot(WorldClipPlanes[0], g_pos);
gl_ClipDistance[1] = dot(WorldClipPlanes[1], g_pos);
gl_ClipDistance[2] = dot(WorldClipPlanes[2], g_pos);
gl_ClipDistance[3] = dot(WorldClipPlanes[3], g_pos);
}
#endif
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
}

View File

@ -158,7 +158,7 @@ shaders_texture_nodes_props = (
shaders_color_nodes_props = (
('ShaderNodeBrightContrast', 'BRIGHTCONTRAST', 'Bright Contrast'),
('ShaderNodeGamma', 'GAMMA', 'Gamma'),
('ShaderNodeHueSaturation', 'HUE_SAT', 'Hue/Saturation'),
('ShaderNodeHueSaturation', 'HUE_SAT', 'Hue Saturation Value'),
('ShaderNodeInvert', 'INVERT', 'Invert'),
('ShaderNodeLightFalloff', 'LIGHT_FALLOFF', 'Light Falloff'),
('ShaderNodeMixRGB', 'MIX_RGB', 'MixRGB'),
@ -366,7 +366,7 @@ blender_mat_color_nodes_props = (
('ShaderNodeMixRGB', 'MIX_RGB', 'MixRGB'),
('ShaderNodeRGBCurve', 'CURVE_RGB', 'RGB Curves'),
('ShaderNodeInvert', 'INVERT', 'Invert'),
('ShaderNodeHueSaturation', 'HUE_SAT', 'Hue/Saturation'),
('ShaderNodeHueSaturation', 'HUE_SAT', 'Hue Saturation Value'),
)
# (rna_type.identifier, type, rna_type.name)
@ -420,7 +420,7 @@ texture_color_nodes_props = (
('TextureNodeMixRGB', 'MIX_RGB', 'Mix RGB'),
('TextureNodeCurveRGB', 'CURVE_RGB', 'RGB Curves'),
('TextureNodeInvert', 'INVERT', 'Invert'),
('TextureNodeHueSaturation', 'HUE_SAT', 'Hue/Saturation'),
('TextureNodeHueSaturation', 'HUE_SAT', 'Hue Saturation Value'),
('TextureNodeCompose', 'COMPOSE', 'Combine RGBA'),
('TextureNodeDecompose', 'DECOMPOSE', 'Separate RGBA'),
)
@ -1856,7 +1856,7 @@ class NWPreviewNode(Operator, NWBase):
shader_types = [x[1] for x in shaders_shader_nodes_props]
mlocx = event.mouse_region_x
mlocy = event.mouse_region_y
select_node = bpy.ops.node.select(mouse_x=mlocx, mouse_y=mlocy, extend=False)
select_node = bpy.ops.node.select(location=(mlocx, mlocy), extend=False)
if 'FINISHED' in select_node: # only run if mouse click is on a node
active_tree, path_to_tree = get_active_tree(context)
nodes, links = active_tree.nodes, active_tree.links
@ -4026,7 +4026,7 @@ class NWViewerFocus(bpy.types.Operator):
if viewers:
mlocx = event.mouse_region_x
mlocy = event.mouse_region_y
select_node = bpy.ops.node.select(mouse_x=mlocx, mouse_y=mlocy, extend=False)
select_node = bpy.ops.node.select(location=(mlocx, mlocy), extend=False)
if not 'FINISHED' in select_node: # only run if we're not clicking on a node
region_x = context.region.width

View File

@ -91,7 +91,7 @@ class POV(StoredView):
view3d.lock_cursor = stored_view.lock_cursor
if stored_view.lock_cursor is True:
# update cursor only if view is locked to cursor
view3d.cursor_location = stored_view.cursor_location
self.scene.cursor.location = stored_view.cursor_location
if stored_view.perspective == "CAMERA":

View File

@ -148,7 +148,7 @@ class POV(StoredView):
view3d.lock_cursor = stored_view.lock_cursor
if stored_view.lock_cursor is True:
# update cursor only if view is locked to cursor
view3d.cursor_location = stored_view.cursor_location
self.scene.cursor.location = stored_view.cursor_location
if stored_view.perspective == "CAMERA":