Merge branch 'master' into asset-browser-poselib

This commit is contained in:
Julian Eisel 2021-04-23 12:21:17 +02:00
commit af63561396
12 changed files with 187 additions and 26 deletions

View File

@ -24,7 +24,7 @@ bl_info = {
"location": "View3D > Properties > BlenderKit",
"description": "Online BlenderKit library (materials, models, brushes and more). Connects to the internet.",
"warning": "",
"doc_url": "{BLENDER_MANUAL_URL}/addons/add_mesh/blenderkit.html",
"doc_url": "{BLENDER_MANUAL_URL}/addons/3d_view/blenderkit.html",
"category": "3D View",
}

View File

@ -21,7 +21,7 @@ bl_info = {
"name": "Grease Pencil Tools",
"description": "Extra tools for Grease Pencil",
"author": "Samuel Bernou, Antonio Vazquez, Daniel Martinez Lara, Matias Mendiola",
"version": (1, 4, 2),
"version": (1, 4, 3),
"blender": (2, 91, 0),
"location": "Sidebar > Grease Pencil > Grease Pencil Tools",
"warning": "",

View File

@ -262,8 +262,22 @@ def delete_cage(cage):
def apply_cage(gp_obj, cage):
mod = gp_obj.grease_pencil_modifiers.get('tmp_lattice')
multi_user = None
if mod:
if gp_obj.data.users > 1:
old = gp_obj.data
multi_user = old.name
other_user = [o for o in bpy.data.objects if o is not gp_obj and o.data is old]
gp_obj.data = gp_obj.data.copy()
bpy.ops.object.gpencil_modifier_apply(apply_as='DATA', modifier=mod.name)
if multi_user:
for o in other_user: # relink
o.data = gp_obj.data
bpy.data.grease_pencils.remove(old)
gp_obj.data.name = multi_user
else:
print('tmp_lattice modifier not found to apply...')

View File

@ -173,7 +173,7 @@ def SVGParseTransform(transform):
"""
m = Matrix()
r = re.compile('\s*([A-z]+)\s*\((.*?)\)')
r = re.compile(r'\s*([A-z]+)\s*\((.*?)\)')
for match in r.finditer(transform):
func = match.group(1)
@ -195,7 +195,7 @@ def SVGGetMaterial(color, context):
"""
materials = context['materials']
rgb_re = re.compile('^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,(\d+)\s*\)\s*$')
rgb_re = re.compile(r'^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,(\d+)\s*\)\s*$')
if color in materials:
return materials[color]
@ -405,6 +405,7 @@ class SVGPathData:
spaces = ' ,\t'
commands = {'m', 'l', 'h', 'v', 'c', 's', 'q', '', 't', 'a', 'z'}
current_command = ''
tokens = []
i = 0
@ -416,8 +417,22 @@ class SVGPathData:
pass
elif c.lower() in commands:
tokens.append(c)
current_command = c
arg_index = 1
elif c in ['-', '.'] or c.isdigit():
token, last_char = read_float(d, i)
# Special case for 'a/A' commands.
# Arguments 4 and 5 are either 0 or 1 and might not
# be separated from the next argument with space or comma.
if current_command.lower() == 'a':
if arg_index % 7 in [4,5]:
token = d[i]
last_char = i + 1
else:
token, last_char = read_float(d, i)
else:
token, last_char = read_float(d, i)
arg_index += 1
tokens.append(token)
# in most cases len(token) and (last_char - i) are the same

View File

@ -15,7 +15,7 @@
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": (1, 6, 9),
"version": (1, 7, 5),
'blender': (2, 91, 0),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',

View File

@ -89,5 +89,9 @@ def set_extras(blender_element, extras, exclude=[]):
try:
blender_element[custom_property] = value
except TypeError:
print('Error setting property %s to value of type %s' % (custom_property, type(value)))
except Exception:
# Try to convert to string
try:
blender_element[custom_property] = str(value)
except Exception:
print('Error setting property %s to value of type %s' % (custom_property, type(value)))

View File

@ -374,7 +374,8 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert
def __get_positions(blender_mesh, key_blocks, armature, blender_object, export_settings):
locs = np.empty(len(blender_mesh.vertices) * 3, dtype=np.float32)
blender_mesh.vertices.foreach_get('co', locs)
source = key_blocks[0].relative_key.data if key_blocks else blender_mesh.vertices
source.foreach_get('co', locs)
locs = locs.reshape(len(blender_mesh.vertices), 3)
morph_locs = []
@ -408,10 +409,14 @@ def __get_positions(blender_mesh, key_blocks, armature, blender_object, export_s
def __get_normals(blender_mesh, key_blocks, armature, blender_object, export_settings):
"""Get normal for each loop."""
blender_mesh.calc_normals_split()
if key_blocks:
normals = key_blocks[0].relative_key.normals_split_get()
normals = np.array(normals, dtype=np.float32)
else:
normals = np.empty(len(blender_mesh.loops) * 3, dtype=np.float32)
blender_mesh.calc_normals_split()
blender_mesh.loops.foreach_get('normal', normals)
normals = np.empty(len(blender_mesh.loops) * 3, dtype=np.float32)
blender_mesh.loops.foreach_get('normal', normals)
normals = normals.reshape(len(blender_mesh.loops), 3)
morph_normals = []

View File

@ -83,3 +83,10 @@ class BlenderWeightAnim():
group_name="ShapeKeys",
interpolation=animation.samplers[channel.sampler].interpolation,
)
# Expand weight range if needed
kb = obj.data.shape_keys.key_blocks[kb_name]
min_weight = min(coords[1:2])
max_weight = max(coords[1:2])
if min_weight < kb.slider_min: kb.slider_min = min_weight
if max_weight > kb.slider_max: kb.slider_max = max_weight

View File

@ -165,7 +165,7 @@ class BlenderGlTF():
# Calculate names for each mesh's shapekeys
for mesh in gltf.data.meshes or []:
mesh.shapekey_names = []
used_names = set()
used_names = set(['Basis']) #Be sure to not use 'Basis' name at import, this is a reserved name
# Some invalid glTF files has empty primitive tab
if len(mesh.primitives) > 0:

View File

@ -225,7 +225,11 @@ class BlenderNode():
weights = pynode.weights or pymesh.weights or []
for i, weight in enumerate(weights):
if pymesh.shapekey_names[i] is not None:
obj.data.shape_keys.key_blocks[pymesh.shapekey_names[i]].value = weight
kb = obj.data.shape_keys.key_blocks[pymesh.shapekey_names[i]]
# extend range if needed
if weight < kb.slider_min: kb.slider_min = weight
if weight > kb.slider_max: kb.slider_max = weight
kb.value = weight
@staticmethod
def setup_skinning(gltf, pynode, obj):

View File

@ -62,29 +62,61 @@ def encode_scene_primitives(scenes, export_settings):
dll.encoderCopy.restype = None
dll.encoderCopy.argtypes = [c_void_p, c_void_p]
# Don't encode the same primitive multiple times.
encoded_primitives_cache = {}
# Compress meshes into Draco buffers.
for scene in scenes:
for node in scene.nodes:
__traverse_node(node, lambda node: __encode_node(node, dll, export_settings))
__traverse_node(node, lambda node: __encode_node(node, dll, export_settings, encoded_primitives_cache))
# Release uncompressed index and attribute buffers.
# Since those buffers may be shared across nodes, this step must happen after all meshes have been compressed.
for scene in scenes:
for node in scene.nodes:
__traverse_node(node, lambda node: __cleanup_node(node))
def __cleanup_node(node):
if node.mesh is None:
return
for primitive in node.mesh.primitives:
if primitive.extensions is None or primitive.extensions['KHR_draco_mesh_compression'] is None:
continue
primitive.indices.buffer_view = None
for attr_name in primitive.attributes:
attr = primitive.attributes[attr_name]
attr.buffer_view = None
def __traverse_node(node, f):
f(node)
if not (node.children is None):
if node.children is not None:
for child in node.children:
__traverse_node(child, f)
def __encode_node(node, dll, export_settings):
if not (node.mesh is None):
def __encode_node(node, dll, export_settings, encoded_primitives_cache):
if node.mesh is not None:
print_console('INFO', 'Draco encoder: Encoding mesh {}.'.format(node.name))
for primitive in node.mesh.primitives:
__encode_primitive(primitive, dll, export_settings)
__encode_primitive(primitive, dll, export_settings, encoded_primitives_cache)
def __encode_primitive(primitive, dll, export_settings):
def __encode_primitive(primitive, dll, export_settings, encoded_primitives_cache):
attributes = primitive.attributes
indices = primitive.indices
# Check if this primitive has already been encoded.
# This usually happens when nodes are duplicated in Blender, thus their indices/attributes are shared data.
if primitive in encoded_primitives_cache:
if primitive.extensions is None:
primitive.extensions = {}
primitive.extensions['KHR_draco_mesh_compression'] = encoded_primitives_cache[primitive]
return
# Only do TRIANGLES primitives
if primitive.mode not in [None, 4]:
return
@ -106,10 +138,8 @@ def __encode_primitive(primitive, dll, export_settings):
attr = attributes[attr_name]
draco_id = dll.encoderSetAttribute(encoder, attr_name.encode(), attr.component_type, attr.type.encode(), attr.buffer_view.data)
draco_ids[attr_name] = draco_id
attr.buffer_view = None
dll.encoderSetIndices(encoder, indices.component_type, indices.count, indices.buffer_view.data)
indices.buffer_view = None
dll.encoderSetCompressionLevel(encoder, export_settings['gltf_draco_mesh_compression_level'])
dll.encoderSetQuantizationBits(encoder,
@ -119,7 +149,8 @@ def __encode_primitive(primitive, dll, export_settings):
export_settings['gltf_draco_color_quantization'],
export_settings['gltf_draco_generic_quantization'])
if not dll.encoderEncode(encoder, primitive.targets is not None and len(primitive.targets) > 0):
preserve_triangle_order = primitive.targets is not None and len(primitive.targets) > 0
if not dll.encoderEncode(encoder, preserve_triangle_order):
print_console('ERROR', 'Could not encode primitive. Skipping primitive.')
byte_length = dll.encoderGetByteLength(encoder)
@ -129,10 +160,12 @@ def __encode_primitive(primitive, dll, export_settings):
if primitive.extensions is None:
primitive.extensions = {}
primitive.extensions['KHR_draco_mesh_compression'] = {
extension_info = {
'bufferView': BinaryData(encoded_data),
'attributes': draco_ids
}
primitive.extensions['KHR_draco_mesh_compression'] = extension_info
encoded_primitives_cache[primitive] = extension_info
# Set to triangle list mode.
primitive.mode = 4

View File

@ -367,6 +367,7 @@
speaker="#000000"
vertex="#000000"
vertex_select="#00b38a"
vertex_active="#000000"
vertex_size="3"
vertex_bevel="#00a5ff"
vertex_unreferenced="#000000"
@ -476,6 +477,7 @@
preview_range="#a14d0066"
vertex="#000000"
vertex_select="#ff8500"
vertex_active="#ffffff"
vertex_size="6"
vertex_bevel="#000000"
vertex_unreferenced="#000000"
@ -537,8 +539,8 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser
row_alternate="#ffffffff"
selected_file="#76afff"
row_alternate="#ffffffff"
>
<space>
<ThemeSpaceGeneric
@ -719,6 +721,7 @@
grid="#a4a4a4ff"
vertex="#000000"
vertex_select="#00b38a"
vertex_active="#000000"
vertex_size="3"
vertex_bevel="#000000"
vertex_unreferenced="#000000"
@ -815,6 +818,7 @@
metadatabg="#000000"
metadatatext="#ffffff"
preview_range="#a14d0066"
row_alternate="#ffffff0d"
>
<space>
<ThemeSpaceGeneric
@ -849,7 +853,10 @@
</ThemeSequenceEditor>
</sequence_editor>
<properties>
<ThemeProperties>
<ThemeProperties
match="#5680c2"
active_modifier="#5680c2ff"
>
<space>
<ThemeSpaceGeneric
back="#ffffff"
@ -957,6 +964,8 @@
script_node="#6c696f"
pattern_node="#6c696f"
layout_node="#6c696f"
geometry_node="#00d7a4"
attribute_node="#3f5980"
>
<space>
<ThemeSpaceGeneric
@ -1307,6 +1316,42 @@
</space>
</ThemeStatusBar>
</statusbar>
<spreadsheet>
<ThemeSpreadsheet
row_alternate="#ffffffff"
>
<space>
<ThemeSpaceGeneric
back="#d8d8d8"
title="#000000"
text="#000000"
text_hi="#ffffff"
header="#d8d8d8ff"
header_text="#000000"
header_text_hi="#ffffff"
button="#ffffffff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff"
navigation_bar="#00000000"
execution_buts="#00000000"
tab_active="#76afff"
tab_inactive="#ffffff"
tab_back="#d8d8d8ff"
tab_outline="#000000"
>
<panelcolors>
<ThemePanelColors
header="#424242cc"
back="#333333b3"
sub_back="#0000003e"
>
</ThemePanelColors>
</panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSpreadsheet>
</spreadsheet>
<bone_color_sets>
<ThemeBoneColorSet
normal="#9a0000"
@ -1449,6 +1494,40 @@
>
</ThemeBoneColorSet>
</bone_color_sets>
<collection_color>
<ThemeCollectionColor
color="#e2605b"
>
</ThemeCollectionColor>
<ThemeCollectionColor
color="#f1a355"
>
</ThemeCollectionColor>
<ThemeCollectionColor
color="#f1dc55"
>
</ThemeCollectionColor>
<ThemeCollectionColor
color="#7bcc7b"
>
</ThemeCollectionColor>
<ThemeCollectionColor
color="#5db6ea"
>
</ThemeCollectionColor>
<ThemeCollectionColor
color="#8d59da"
>
</ThemeCollectionColor>
<ThemeCollectionColor
color="#c673b8"
>
</ThemeCollectionColor>
<ThemeCollectionColor
color="#7a5441"
>
</ThemeCollectionColor>
</collection_color>
</Theme>
<ThemeStyle>
<panel_title>