Compare commits
No commits in common. "58e6816e392d4a840c947541da75d7ed1c05461b" and "c8763f5ca4ea63b736635365ef96963f0d405b6d" have entirely different histories.
58e6816e39
...
c8763f5ca4
|
@ -373,6 +373,10 @@ def add_multiple_strokes(stroke_list, layer=None, use_current_frame=True, select
|
||||||
|
|
||||||
for s in stroke_list:
|
for s in stroke_list:
|
||||||
add_stroke(s, target_frame, layer, obj, select=select)
|
add_stroke(s, target_frame, layer, obj, select=select)
|
||||||
|
'''
|
||||||
|
for s in stroke_data:
|
||||||
|
add_stroke(s, target_frame)
|
||||||
|
'''
|
||||||
|
|
||||||
# print(len(stroke_list), 'strokes pasted')
|
# print(len(stroke_list), 'strokes pasted')
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import numpy as np
|
||||||
from time import time
|
from time import time
|
||||||
from .utils import (location_to_region, region_to_location)
|
from .utils import (location_to_region, region_to_location)
|
||||||
|
|
||||||
## DISABLED (in init, also in menu append, see register below)
|
|
||||||
"""
|
"""
|
||||||
## Do not work on multiple object
|
## Do not work on multiple object
|
||||||
def batch_flat_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False):
|
def batch_flat_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False):
|
||||||
|
|
|
@ -21,7 +21,6 @@ from .utils import get_addon_prefs, is_vector_close
|
||||||
# PATTERN = r'^(?P<grp>-\s)?(?P<tag>[A-Z]{2}_)?(?P<tag2>[A-Z]{1,6}_)?(?P<name>.*?)(?P<sfix>_[A-Z]{2})?(?P<inc>\.\d{3})?$' # numering
|
# PATTERN = r'^(?P<grp>-\s)?(?P<tag>[A-Z]{2}_)?(?P<tag2>[A-Z]{1,6}_)?(?P<name>.*?)(?P<sfix>_[A-Z]{2})?(?P<inc>\.\d{3})?$' # numering
|
||||||
PATTERN = r'^(?P<grp>-\s)?(?P<tag>[A-Z]{2}_)?(?P<name>.*?)(?P<sfix>_[A-Z]{2})?(?P<inc>\.\d{3})?$' # numering
|
PATTERN = r'^(?P<grp>-\s)?(?P<tag>[A-Z]{2}_)?(?P<name>.*?)(?P<sfix>_[A-Z]{2})?(?P<inc>\.\d{3})?$' # numering
|
||||||
|
|
||||||
# TODO: allow a more flexible prefix pattern
|
|
||||||
|
|
||||||
def layer_name_build(layer, prefix='', desc='', suffix=''):
|
def layer_name_build(layer, prefix='', desc='', suffix=''):
|
||||||
'''GET a layer and argument to build and assign name
|
'''GET a layer and argument to build and assign name
|
||||||
|
@ -156,16 +155,13 @@ class GPTB_OT_layer_name_build(Operator):
|
||||||
gpl = ob.data.layers
|
gpl = ob.data.layers
|
||||||
act = gpl.active
|
act = gpl.active
|
||||||
if not act:
|
if not act:
|
||||||
act = ob.data.layer_groups.active
|
self.report({'ERROR'}, 'no layer active')
|
||||||
|
|
||||||
if not act:
|
|
||||||
self.report({'ERROR'}, 'No layer active')
|
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
layer_name_build(act, prefix=self.prefix, desc=self.desc, suffix=self.suffix)
|
layer_name_build(act, prefix=self.prefix, desc=self.desc, suffix=self.suffix)
|
||||||
|
|
||||||
## /!\ Deactivate multi-selection on layer !
|
## Deactivate multi-selection on layer !
|
||||||
## Somethimes it affect a random layer that is still considered selected
|
## somethimes it affect a random layer that is still considered selected
|
||||||
# for l in gpl:
|
# for l in gpl:
|
||||||
# if l.select or l == act:
|
# if l.select or l == act:
|
||||||
# layer_name_build(l, prefix=self.prefix, desc=self.desc, suffix=self.suffix)
|
# layer_name_build(l, prefix=self.prefix, desc=self.desc, suffix=self.suffix)
|
||||||
|
@ -173,6 +169,79 @@ class GPTB_OT_layer_name_build(Operator):
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
def grp_toggle(l, mode='TOGGLE'):
|
||||||
|
'''take mode in (TOGGLE, GROUP, UNGROUP) '''
|
||||||
|
grp_item_id = ' - '
|
||||||
|
res = re.search(r'^(\s{1,3}-\s{0,3})(.*)', l.name)
|
||||||
|
if not res and mode in ('TOGGLE', 'GROUP'):
|
||||||
|
# No gpr : add group prefix after stripping all space and dash
|
||||||
|
l.name = grp_item_id + l.name.lstrip(' -')
|
||||||
|
|
||||||
|
elif res and mode in ('TOGGLE', 'UNGROUP'):
|
||||||
|
# found : delete group prefix
|
||||||
|
l.name = res.group(2)
|
||||||
|
|
||||||
|
|
||||||
|
class GPTB_OT_layer_group_toggle(Operator):
|
||||||
|
bl_idname = "gp.layer_group_toggle"
|
||||||
|
bl_label = "Group Toggle"
|
||||||
|
bl_description = "Group or ungroup a layer"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# group : StringProperty(default='', options={'SKIP_SAVE'})
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
ob = context.object
|
||||||
|
gpl = ob.data.layers
|
||||||
|
act = gpl.active
|
||||||
|
if not act:
|
||||||
|
self.report({'ERROR'}, 'no layer active')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
for l in gpl:
|
||||||
|
if l.select or l == act:
|
||||||
|
grp_toggle(l)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
class GPTB_OT_layer_new_group(Operator):
|
||||||
|
bl_idname = "gp.layer_new_group"
|
||||||
|
bl_label = "New Group"
|
||||||
|
bl_description = "Create a group from active layer"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
ob = context.object
|
||||||
|
gpl = ob.data.layers
|
||||||
|
act = gpl.active
|
||||||
|
if not act:
|
||||||
|
self.report({'ERROR'}, 'no layer active')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
res = re.search(PATTERN, act.name)
|
||||||
|
if not res:
|
||||||
|
self.report({'ERROR'}, 'Could not create a group name, create a layer manually')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
name = res.group('name').strip(' -')
|
||||||
|
if not name:
|
||||||
|
self.report({'ERROR'}, f'No name found in {act.name}')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
if name in [l.name.strip(' -') for l in gpl]:
|
||||||
|
self.report({'WARNING'}, f'Name already exists: {act.name}')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
grp_toggle(act, mode='GROUP')
|
||||||
|
n = gpl.new(name, set_active=False)
|
||||||
|
n.use_onion_skinning = n.use_lights = False
|
||||||
|
n.hide = True
|
||||||
|
n.opacity = 0
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
#-## SELECTION MANAGEMENT ##-#
|
#-## SELECTION MANAGEMENT ##-#
|
||||||
|
|
||||||
def activate_channel_group_color(context):
|
def activate_channel_group_color(context):
|
||||||
|
@ -749,6 +818,8 @@ def unregister_keymaps():
|
||||||
classes=(
|
classes=(
|
||||||
GPTB_OT_rename_gp_layer,
|
GPTB_OT_rename_gp_layer,
|
||||||
GPTB_OT_layer_name_build,
|
GPTB_OT_layer_name_build,
|
||||||
|
GPTB_OT_layer_group_toggle,
|
||||||
|
GPTB_OT_layer_new_group,
|
||||||
GPTB_OT_select_set_same_prefix,
|
GPTB_OT_select_set_same_prefix,
|
||||||
GPTB_OT_select_set_same_color,
|
GPTB_OT_select_set_same_color,
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,6 @@ class GPTB_OT_move_material_to_layer(Operator) :
|
||||||
# t = time.time() # Dbg
|
# t = time.time() # Dbg
|
||||||
total = 0
|
total = 0
|
||||||
oct = 0
|
oct = 0
|
||||||
|
|
||||||
for ob in pool:
|
for ob in pool:
|
||||||
mat_index = next((i for i, ms in enumerate(ob.material_slots) if ms.material and ms.material == mat), None)
|
mat_index = next((i for i, ms in enumerate(ob.material_slots) if ms.material and ms.material == mat), None)
|
||||||
if mat_index is None:
|
if mat_index is None:
|
||||||
|
@ -111,26 +110,26 @@ class GPTB_OT_move_material_to_layer(Operator) :
|
||||||
### Move Strokes to a new key (or existing key if comming for yet another layer)
|
### Move Strokes to a new key (or existing key if comming for yet another layer)
|
||||||
fct = 0
|
fct = 0
|
||||||
sct = 0
|
sct = 0
|
||||||
for layer in gpl:
|
for l in gpl:
|
||||||
if layer == target_layer:
|
if l == target_layer:
|
||||||
## ! infinite loop if target layer is included
|
## ! infinite loop if target layer is included
|
||||||
continue
|
continue
|
||||||
for fr in layer.frames:
|
for f in l.frames:
|
||||||
## skip if no stroke has active material
|
## skip if no stroke has active material
|
||||||
if not next((s for s in fr.drawing.strokes if s.material_index == mat_index), None):
|
if not next((s for s in f.drawing.strokes if s.material_index == mat_index), None):
|
||||||
continue
|
continue
|
||||||
## Get/Create a destination frame and keep a reference to it
|
## Get/Create a destination frame and keep a reference to it
|
||||||
if not (dest_key := key_dict.get(fr.frame_number)):
|
if not (dest_key := key_dict.get(f.frame_number)):
|
||||||
dest_key = target_layer.frames.new(fr.frame_number)
|
dest_key = target_layer.frames.new(f.frame_number)
|
||||||
key_dict[dest_key.frame_number] = dest_key
|
key_dict[dest_key.frame_number] = dest_key
|
||||||
|
|
||||||
print(f'{ob.name} : frame {fr.frame_number}')
|
print(f'{ob.name} : frame {f.frame_number}')
|
||||||
## Replicate strokes in dest_keys
|
## Replicate strokes in dest_keys
|
||||||
stroke_to_delete = []
|
stroke_to_delete = []
|
||||||
for s_idx, s in enumerate(fr.drawing.strokes):
|
for s in f.drawing.strokes:
|
||||||
if s.material_index == mat_index:
|
if s.material_index == mat_index:
|
||||||
utils.copy_stroke_to_frame(s, dest_key)
|
utils.copy_stroke_to_frame(s, dest_key)
|
||||||
stroke_to_delete.append(s_idx)
|
stroke_to_delete.append(s)
|
||||||
|
|
||||||
## Debug
|
## Debug
|
||||||
# if time.time() - t > 10:
|
# if time.time() - t > 10:
|
||||||
|
@ -139,15 +138,16 @@ class GPTB_OT_move_material_to_layer(Operator) :
|
||||||
|
|
||||||
sct += len(stroke_to_delete)
|
sct += len(stroke_to_delete)
|
||||||
|
|
||||||
## Remove from source frame (fr)
|
# print('Removing frames') # Dbg
|
||||||
|
## Remove from source frame (f)
|
||||||
if not self.copy:
|
if not self.copy:
|
||||||
# print('Removing frames') # Dbg
|
for s in reversed(stroke_to_delete):
|
||||||
if stroke_to_delete:
|
f.drawing.strokes.remove(s)
|
||||||
fr.drawing.remove_strokes(indices=stroke_to_delete)
|
|
||||||
|
|
||||||
## ? Remove frame if layer is empty ? -> probably not, otherwise will show previous frame
|
## ? Remove frame if layer is empty ? -> probably not, will show previous frame
|
||||||
|
|
||||||
fct += 1
|
fct += 1
|
||||||
|
l.frames.update()
|
||||||
|
|
||||||
|
|
||||||
if fct:
|
if fct:
|
||||||
|
|
|
@ -4,7 +4,7 @@ bl_info = {
|
||||||
"name": "GP toolbox",
|
"name": "GP toolbox",
|
||||||
"description": "Tool set for Grease Pencil in animation production",
|
"description": "Tool set for Grease Pencil in animation production",
|
||||||
"author": "Samuel Bernou, Christophe Seux",
|
"author": "Samuel Bernou, Christophe Seux",
|
||||||
"version": (4, 0, 2),
|
"version": (4, 0, 1),
|
||||||
"blender": (4, 3, 0),
|
"blender": (4, 3, 0),
|
||||||
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
@ -35,7 +35,7 @@ from . import OP_brushes
|
||||||
from . import OP_file_checker
|
from . import OP_file_checker
|
||||||
from . import OP_copy_paste
|
from . import OP_copy_paste
|
||||||
from . import OP_realign
|
from . import OP_realign
|
||||||
# from . import OP_flat_reproject # Disabled
|
from . import OP_flat_reproject
|
||||||
from . import OP_depth_move
|
from . import OP_depth_move
|
||||||
from . import OP_key_duplicate_send
|
from . import OP_key_duplicate_send
|
||||||
from . import OP_layer_manager
|
from . import OP_layer_manager
|
||||||
|
@ -793,7 +793,7 @@ addon_modules = (
|
||||||
OP_brushes,
|
OP_brushes,
|
||||||
OP_cursor_snap_canvas,
|
OP_cursor_snap_canvas,
|
||||||
OP_copy_paste,
|
OP_copy_paste,
|
||||||
# OP_flat_reproject # Disabled,
|
OP_flat_reproject,
|
||||||
OP_realign,
|
OP_realign,
|
||||||
OP_depth_move,
|
OP_depth_move,
|
||||||
OP_key_duplicate_send,
|
OP_key_duplicate_send,
|
||||||
|
|
194
utils.py
194
utils.py
|
@ -10,80 +10,14 @@ from math import sqrt
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
from sys import platform
|
from sys import platform
|
||||||
|
|
||||||
## constants values
|
|
||||||
|
|
||||||
|
|
||||||
## Default stroke and points attributes
|
""" def get_gp_parent(layer) :
|
||||||
stroke_attr = [
|
if layer.parent_type == "BONE" and layer.parent_bone :
|
||||||
'start_cap',
|
return layer.parent.pose.bones.get(layer.parent_bone)
|
||||||
'end_cap',
|
else :
|
||||||
'softness',
|
return layer.parent
|
||||||
'material_index',
|
"""
|
||||||
'fill_opacity',
|
|
||||||
'fill_color',
|
|
||||||
'cyclic',
|
|
||||||
'aspect_ratio',
|
|
||||||
'time_start',
|
|
||||||
# 'curve_type', # read-only
|
|
||||||
]
|
|
||||||
|
|
||||||
point_attr = [
|
|
||||||
'position',
|
|
||||||
'radius',
|
|
||||||
'rotation',
|
|
||||||
'opacity',
|
|
||||||
'vertex_color',
|
|
||||||
'delta_time',
|
|
||||||
# 'select',
|
|
||||||
]
|
|
||||||
|
|
||||||
### Attribute value, types and shape
|
|
||||||
|
|
||||||
attribute_value_string = {
|
|
||||||
'FLOAT': "value",
|
|
||||||
'INT': "value",
|
|
||||||
'FLOAT_VECTOR': "vector",
|
|
||||||
'FLOAT_COLOR': "color",
|
|
||||||
'BYTE_COLOR': "color",
|
|
||||||
'STRING': "value",
|
|
||||||
'BOOLEAN': "value",
|
|
||||||
'FLOAT2': "value",
|
|
||||||
'INT8': "value",
|
|
||||||
'INT32_2D': "value",
|
|
||||||
'QUATERNION': "value",
|
|
||||||
'FLOAT4X4': "value",
|
|
||||||
}
|
|
||||||
|
|
||||||
attribute_value_dtype = {
|
|
||||||
'FLOAT': np.float32,
|
|
||||||
'INT': np.dtype('int'),
|
|
||||||
'FLOAT_VECTOR': np.float32,
|
|
||||||
'FLOAT_COLOR': np.float32,
|
|
||||||
'BYTE_COLOR': np.int8,
|
|
||||||
'STRING': np.dtype('str'),
|
|
||||||
'BOOLEAN': np.dtype('bool'),
|
|
||||||
'FLOAT2': np.float32,
|
|
||||||
'INT8': np.int8,
|
|
||||||
'INT32_2D': np.dtype('int'),
|
|
||||||
'QUATERNION': np.float32,
|
|
||||||
'FLOAT4X4': np.float32,
|
|
||||||
}
|
|
||||||
|
|
||||||
attribute_value_shape = {
|
|
||||||
'FLOAT': (),
|
|
||||||
'INT': (),
|
|
||||||
'FLOAT_VECTOR': (3,),
|
|
||||||
'FLOAT_COLOR': (4,),
|
|
||||||
'BYTE_COLOR': (4,),
|
|
||||||
'STRING': (),
|
|
||||||
'BOOLEAN': (),
|
|
||||||
'FLOAT2':(2,),
|
|
||||||
'INT8': (),
|
|
||||||
'INT32_2D': (2,),
|
|
||||||
'QUATERNION': (4,),
|
|
||||||
'FLOAT4X4': (4,4),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def translate_range(OldValue, OldMin, OldMax, NewMax, NewMin):
|
def translate_range(OldValue, OldMin, OldMax, NewMax, NewMin):
|
||||||
return (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
|
return (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
|
||||||
|
@ -623,30 +557,64 @@ def copy_stroke_to_frame(s, frame, select=True):
|
||||||
return created stroke
|
return created stroke
|
||||||
'''
|
'''
|
||||||
|
|
||||||
frame.drawing.add_strokes([len(s.points)])
|
ns = frame.drawing.strokes.new()
|
||||||
ns = frame.drawing.strokes[-1]
|
|
||||||
# print(len(s.points), 'new:', len(ns.points))
|
## Set strokes attr
|
||||||
#ns.material_index
|
stroke_attr = [
|
||||||
|
'line_width',
|
||||||
|
'material_index',
|
||||||
|
'draw_cyclic',
|
||||||
|
'use_cyclic',
|
||||||
|
'uv_scale',
|
||||||
|
'uv_rotation',
|
||||||
|
'hardness',
|
||||||
|
'uv_translation',
|
||||||
|
'vertex_color_fill',
|
||||||
|
]
|
||||||
|
|
||||||
## replicate attributes (simple loop)
|
|
||||||
## TODO : might need to create atribute domain if does not exists in destination
|
|
||||||
for attr in stroke_attr:
|
for attr in stroke_attr:
|
||||||
|
if not hasattr(s, attr):
|
||||||
|
continue
|
||||||
|
# print(f'transfer stroke {attr}') # Dbg
|
||||||
setattr(ns, attr, getattr(s, attr))
|
setattr(ns, attr, getattr(s, attr))
|
||||||
|
|
||||||
for src_p, dest_p in zip(s.points, ns.points):
|
## create points
|
||||||
for attr in point_attr:
|
point_count = len(s.points)
|
||||||
setattr(dest_p, attr, getattr(src_p, attr))
|
ns.points.add(len(s.points))
|
||||||
## Define selection
|
|
||||||
dest_p.select=select
|
|
||||||
|
|
||||||
## Direcly iterate over attribute ?
|
## Set points attr
|
||||||
# src_start = src_dr.curve_offsets[0].value
|
# for p, np in zip(s.points, ns.points):
|
||||||
# src_end = src_start + data_size
|
flat_list = [0.0] * point_count
|
||||||
# dst_start = dst_dr.curve_offsets[0].value
|
flat_uv_fill_list = [0.0, 0.0] * point_count
|
||||||
# dst_end = dst_start + data_size
|
flat_vector_list = [0.0, 0.0, 0.0] * point_count
|
||||||
# for src_idx, dest_idx in zip(range(src_start, src_end),range(dst_start, dst_end)):
|
flat_color_list = [0.0, 0.0, 0.0, 0.0] * point_count
|
||||||
# setattr(dest_attr.data[dest_idx], val_type, getattr(source_attr.data[src_idx], val_type))
|
|
||||||
|
|
||||||
|
single_attr = [
|
||||||
|
'pressure',
|
||||||
|
'strength',
|
||||||
|
'uv_factor',
|
||||||
|
'uv_rotation',
|
||||||
|
]
|
||||||
|
|
||||||
|
for attr in single_attr:
|
||||||
|
# print(f'transfer point {attr}') # Dbg
|
||||||
|
s.points.foreach_get(attr, flat_list)
|
||||||
|
ns.points.foreach_set(attr, flat_list)
|
||||||
|
|
||||||
|
# print(f'transfer point co') # Dbg
|
||||||
|
s.points.foreach_get('co', flat_vector_list)
|
||||||
|
ns.points.foreach_set('co', flat_vector_list)
|
||||||
|
|
||||||
|
# print(f'transfer point uv_fill') # Dbg
|
||||||
|
s.points.foreach_get('uv_fill', flat_uv_fill_list)
|
||||||
|
ns.points.foreach_set('uv_fill', flat_uv_fill_list)
|
||||||
|
|
||||||
|
# print(f'transfer point vertex_color') # Dbg
|
||||||
|
s.points.foreach_get('vertex_color', flat_color_list)
|
||||||
|
ns.points.foreach_set('vertex_color', flat_color_list)
|
||||||
|
|
||||||
|
ns.select = select
|
||||||
|
ns.points.update()
|
||||||
return ns
|
return ns
|
||||||
|
|
||||||
"""## Works, but do not copy all attributes type (probably ok for GP though)
|
"""## Works, but do not copy all attributes type (probably ok for GP though)
|
||||||
|
@ -689,6 +657,52 @@ def bulk_frame_copy_attributes(source_attr, target_attr):
|
||||||
# setattr(dest_attr.data[dest_idx], val_type, getattr(source_attr.data[src_idx], val_type))
|
# setattr(dest_attr.data[dest_idx], val_type, getattr(source_attr.data[src_idx], val_type))
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
attribute_value_string = {
|
||||||
|
'FLOAT': "value",
|
||||||
|
'INT': "value",
|
||||||
|
'FLOAT_VECTOR': "vector",
|
||||||
|
'FLOAT_COLOR': "color",
|
||||||
|
'BYTE_COLOR': "color",
|
||||||
|
'STRING': "value",
|
||||||
|
'BOOLEAN': "value",
|
||||||
|
'FLOAT2': "value",
|
||||||
|
'INT8': "value",
|
||||||
|
'INT32_2D': "value",
|
||||||
|
'QUATERNION': "value",
|
||||||
|
'FLOAT4X4': "value",
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute_value_dtype = {
|
||||||
|
'FLOAT': np.float32,
|
||||||
|
'INT': np.dtype('int'),
|
||||||
|
'FLOAT_VECTOR': np.float32,
|
||||||
|
'FLOAT_COLOR': np.float32,
|
||||||
|
'BYTE_COLOR': np.int8,
|
||||||
|
'STRING': np.dtype('str'),
|
||||||
|
'BOOLEAN': np.dtype('bool'),
|
||||||
|
'FLOAT2': np.float32,
|
||||||
|
'INT8': np.int8,
|
||||||
|
'INT32_2D': np.dtype('int'),
|
||||||
|
'QUATERNION': np.float32,
|
||||||
|
'FLOAT4X4': np.float32,
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute_value_shape = {
|
||||||
|
'FLOAT': (),
|
||||||
|
'INT': (),
|
||||||
|
'FLOAT_VECTOR': (3,),
|
||||||
|
'FLOAT_COLOR': (4,),
|
||||||
|
'BYTE_COLOR': (4,),
|
||||||
|
'STRING': (),
|
||||||
|
'BOOLEAN': (),
|
||||||
|
'FLOAT2':(2,),
|
||||||
|
'INT8': (),
|
||||||
|
'INT32_2D': (2,),
|
||||||
|
'QUATERNION': (4,),
|
||||||
|
'FLOAT4X4': (4,4),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def bulk_copy_attributes(source_attr, target_attr):
|
def bulk_copy_attributes(source_attr, target_attr):
|
||||||
'''Get and apply data as flat numpy array based on attribute type'''
|
'''Get and apply data as flat numpy array based on attribute type'''
|
||||||
value_string = attribute_value_string[source_attr.data_type]
|
value_string = attribute_value_string[source_attr.data_type]
|
||||||
|
|
Loading…
Reference in New Issue