提交 61f52937 编写于 作者: R Ricardo Cabello

Merge pull request #6536 from tschw/Blender_extra_vertex_groups

Allows export of non-skinning Vertex Groups as BufferGeometry custom …
......@@ -305,6 +305,10 @@ def restore_export_settings(properties, settings):
constants.APPLY_MODIFIERS,
constants.EXPORT_OPTIONS[constants.APPLY_MODIFIERS])
properties.option_extra_vgroups = settings.get(
constants.EXTRA_VGROUPS,
constants.EXPORT_OPTIONS[constants.EXTRA_VGROUPS])
properties.option_geometry_type = settings.get(
constants.GEOMETRY_TYPE,
constants.EXPORT_OPTIONS[constants.GEOMETRY_TYPE])
......@@ -432,6 +436,7 @@ def set_settings(properties):
constants.NORMALS: properties.option_normals,
constants.SKINNING: properties.option_skinning,
constants.BONES: properties.option_bones,
constants.EXTRA_VGROUPS: properties.option_extra_vgroups,
constants.APPLY_MODIFIERS: properties.option_apply_modifiers,
constants.GEOMETRY_TYPE: properties.option_geometry_type,
constants.INDEX_TYPE: properties.option_index_type,
......@@ -565,6 +570,11 @@ class ExportThree(bpy.types.Operator, ExportHelper):
description="Export bones",
default=constants.EXPORT_OPTIONS[constants.BONES])
option_extra_vgroups = StringProperty(
name="Extra Vertex Groups",
description="Non-skinning vertex groups to export (comma-separated, w/ star wildcard, BufferGeometry only).",
default=constants.EXPORT_OPTIONS[constants.EXTRA_VGROUPS])
option_apply_modifiers = BoolProperty(
name="Apply Modifiers",
description="Apply Modifiers to mesh objects",
......@@ -778,6 +788,9 @@ class ExportThree(bpy.types.Operator, ExportHelper):
row.prop(self.properties, 'option_bones')
row.prop(self.properties, 'option_skinning')
row = layout.row()
row.prop(self.properties, 'option_extra_vgroups')
row = layout.row()
row.prop(self.properties, 'option_apply_modifiers')
......
......@@ -47,6 +47,7 @@ UVS = 'uvs'
APPLY_MODIFIERS = 'applyModifiers'
COLORS = 'colors'
MIX_COLORS = 'mixColors'
EXTRA_VGROUPS = 'extraVertexGroups'
INDEX = 'index'
DRAW_CALLS = 'offsets'
DC_START = 'start'
......@@ -108,6 +109,7 @@ EXPORT_OPTIONS = {
UVS: True,
APPLY_MODIFIERS: True,
COLORS: False,
EXTRA_VGROUPS: '',
INDEX_TYPE: UINT_16,
MATERIALS: False,
FACE_MATERIALS: False,
......
......@@ -5,6 +5,7 @@ morph targets) with the geometry nodes.
"""
import operator
import re
from bpy import data, types, context
from . import material, texture, animation
from . import object as object_
......@@ -177,6 +178,97 @@ def buffer_uv(mesh):
return uvs_
@_mesh
def extra_vertex_groups(mesh, patterns_string):
"""
Returns (name,index) tuples for the extra (non-skinning) vertex groups
matching the given patterns.
The patterns are comma-separated where the star character can be used
as a wildcard character sequence.
:param mesh:
:param patterns_string:
:rtype: []
"""
logger.debug("mesh._extra_vertex_groups(%s)", mesh)
pattern_re = None
extra_vgroups = []
if not patterns_string.strip():
return extra_vgroups
armature = _armature(mesh)
obj = object_.objects_using_mesh(mesh)[0]
for vgroup_index, vgroup in enumerate(obj.vertex_groups):
# Skip bone weights:
vgroup_name = vgroup.name
if armature:
is_bone_weight=False
for bone in armature.pose.bones:
if bone.name == vgroup_name:
is_bone_weight=True
break
if (is_bone_weight):
continue
if pattern_re is None:
# Translate user-friendly patterns to a regular expression:
# Join the whitespace-stripped, initially comma-separated
# entries to alternatives. Escape all characters except
# the star and replace that one with '.*?'.
pattern_re = '^(?:' + '|'.join(
map(lambda entry:
'.*?'.join(map(re.escape, entry.strip().split('*'))),
patterns_string.split(',')) ) + ')$'
if not re.match(pattern_re, vgroup_name):
continue
extra_vgroups.append( (vgroup_name, vgroup_index) )
return extra_vgroups
@_mesh
def vertex_group_data(mesh, index):
"""
Return vertex group data for each vertex. Vertices not in the group
get a zero value.
:param mesh:
:param index:
"""
data = []
for vertex in mesh.vertices:
weight = None
for group in vertex.groups:
if group.group == index:
weight = group.weight
data.append(weight or 0.0)
return data
@_mesh
def buffer_vertex_group_data(mesh, index):
"""
Return vertex group data for each deindexed vertex. Vertices not in the
group get a zero value.
:param mesh:
:param index:
"""
data = []
for face in mesh.tessfaces:
for vertex_index in face.vertices:
vertex = mesh.vertices[vertex_index]
weight = None
for group in vertex.groups:
if group.group == index:
weight = group.weight
data.append(weight or 0.0)
return data
@_mesh
def faces(mesh, options, materials=None):
"""
......
......@@ -261,6 +261,12 @@ class Geometry(base_classes.BaseNode):
else:
logger.info("No animation data found for %s", self.node)
option_extra_vgroups = self.options.get(constants.EXTRA_VGROUPS)
for name, index in api.mesh.extra_vertex_groups(self.node,
option_extra_vgroups):
components.append(name);
for component in components:
try:
data[component] = self[component]
......@@ -371,6 +377,7 @@ class Geometry(base_classes.BaseNode):
options_vertices = self.options.get(constants.VERTICES)
option_normals = self.options.get(constants.NORMALS)
option_uvs = self.options.get(constants.UVS)
option_extra_vgroups = self.options.get(constants.EXTRA_VGROUPS)
option_index_type = self.options.get(constants.INDEX_TYPE)
pos_tuple = (constants.POSITION, options_vertices,
......@@ -397,6 +404,22 @@ class Geometry(base_classes.BaseNode):
constants.ARRAY: array
}
for name, index in api.mesh.extra_vertex_groups(self.node,
option_extra_vgroups):
logger.info("Exporting extra vertex group %s", name)
array = api.mesh.buffer_vertex_group_data(self.node, index)
if not array:
logger.warning("No array could be made for %s", name)
continue
self[constants.ATTRIBUTES][name] = {
constants.ITEM_SIZE: 1,
constants.TYPE: constants.FLOAT_32,
constants.ARRAY: array
}
if option_index_type != constants.NONE:
assert(not (self.get(constants.INDEX) or
......@@ -539,3 +562,14 @@ class Geometry(base_classes.BaseNode):
logger.info("Parsing %s", constants.MORPH_TARGETS)
self[constants.MORPH_TARGETS] = api.mesh.morph_targets(
self.node, self.options) or []
# In the moment there is no way to add extra data to a Geomtry in
# Three.js. In case there is some day, here is the code:
#
# option_extra_vgroups = self.options.get(constants.EXTRA_VGROUPS)
#
# for name, index in api.mesh.extra_vertex_groups(self.node,
# option_extra_vgroups):
#
# logger.info("Exporting extra vertex group %s", name)
# self[name] = api.mesh.vertex_group_data(self.node, index)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册