Blender Addon: entity manager
This commit is contained in:
parent
db3e0d1273
commit
e02bab244d
2 changed files with 171 additions and 14 deletions
|
@ -42,6 +42,7 @@ from bpy.props import (
|
||||||
|
|
||||||
from .io_scene_json import export_json
|
from .io_scene_json import export_json
|
||||||
from .io_anim_ros2bag import set_animation_data
|
from .io_anim_ros2bag import set_animation_data
|
||||||
|
from .io_entity_manager import switch_3d_entities
|
||||||
|
|
||||||
bl_info = {
|
bl_info = {
|
||||||
'name': 'Robossembler Tools',
|
'name': 'Robossembler Tools',
|
||||||
|
@ -60,7 +61,7 @@ bl_info = {
|
||||||
class addon_Properties(PropertyGroup):
|
class addon_Properties(PropertyGroup):
|
||||||
|
|
||||||
engine: EnumProperty(
|
engine: EnumProperty(
|
||||||
name='Physics Engine',
|
name='Engine',
|
||||||
description='Selest Target Engine',
|
description='Selest Target Engine',
|
||||||
items=[('BULLET', 'Bullet', ''),
|
items=[('BULLET', 'Bullet', ''),
|
||||||
('ODE', 'O D E', ''),
|
('ODE', 'O D E', ''),
|
||||||
|
@ -69,14 +70,39 @@ class addon_Properties(PropertyGroup):
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
conf_file_path: StringProperty(
|
entity: EnumProperty(
|
||||||
name='Config File Path',
|
name='Entity',
|
||||||
description='Input/output config file path',
|
description='Selest 3d Entity',
|
||||||
|
items=[('hp', 'Highpoly', ''),
|
||||||
|
('mp', 'Modpoly', ''),
|
||||||
|
('lp', 'Lowpoly', '')
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
json_file_path: StringProperty(
|
||||||
|
name='File Path',
|
||||||
|
description='Input/output Json file path',
|
||||||
default='',
|
default='',
|
||||||
maxlen=1023,
|
maxlen=1023,
|
||||||
subtype='FILE_PATH'
|
subtype='FILE_PATH'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ros2bag_file_path: StringProperty(
|
||||||
|
name='File Path',
|
||||||
|
description='Input Ros2Bag file path',
|
||||||
|
default='',
|
||||||
|
maxlen=1023,
|
||||||
|
subtype='FILE_PATH'
|
||||||
|
)
|
||||||
|
|
||||||
|
refs_file_path: StringProperty(
|
||||||
|
name='Dir Path',
|
||||||
|
description='References library file path',
|
||||||
|
default='',
|
||||||
|
maxlen=1023,
|
||||||
|
subtype='DIR_PATH'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class RobossemblerPanel1(Panel):
|
class RobossemblerPanel1(Panel):
|
||||||
''' Robossembler UI'''
|
''' Robossembler UI'''
|
||||||
|
@ -90,13 +116,13 @@ class RobossemblerPanel1(Panel):
|
||||||
prop = context.scene.robossembler_properties
|
prop = context.scene.robossembler_properties
|
||||||
|
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.prop(prop, 'conf_file_path')
|
layout.prop(prop, 'json_file_path')
|
||||||
layout.prop(prop, 'engine')
|
layout.prop(prop, 'engine')
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.alert = True
|
col.alert = True
|
||||||
col.scale_y = 2.0
|
col.scale_y = 2.0
|
||||||
col.operator('export.scene_config',
|
col.operator('scene.export_json',
|
||||||
icon='WORLD_DATA',
|
icon='WORLD_DATA',
|
||||||
text='Export Scene')
|
text='Export Scene')
|
||||||
|
|
||||||
|
@ -113,27 +139,50 @@ class RobossemblerPanel2(Panel):
|
||||||
prop = context.scene.robossembler_properties
|
prop = context.scene.robossembler_properties
|
||||||
|
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.prop(prop, 'conf_file_path')
|
layout.prop(prop, 'ros2bag_file_path')
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.alert = True
|
col.alert = True
|
||||||
col.scale_y = 2.0
|
col.scale_y = 2.0
|
||||||
col.operator('export.scene_config',
|
col.operator('scene.import_ros2bag',
|
||||||
icon='ACTION',
|
icon='ACTION',
|
||||||
text='Import Animation')
|
text='Import Animation')
|
||||||
|
|
||||||
|
|
||||||
|
class RobossemblerPanel3(Panel):
|
||||||
|
''' Robossembler UI'''
|
||||||
|
bl_idname = 'ROBOSSEMBLER_PT_ENTITY_MANAGER'
|
||||||
|
bl_label = 'Switch 3d Entities'
|
||||||
|
bl_space_type = 'VIEW_3D'
|
||||||
|
bl_region_type = 'UI'
|
||||||
|
bl_category = 'Robossembler'
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
prop = context.scene.robossembler_properties
|
||||||
|
|
||||||
|
layout = self.layout
|
||||||
|
layout.prop(prop, 'refs_file_path')
|
||||||
|
layout.prop(prop, 'entity')
|
||||||
|
|
||||||
|
col = layout.column()
|
||||||
|
col.alert = True
|
||||||
|
col.scale_y = 2.0
|
||||||
|
col.operator('scene.manage_entities',
|
||||||
|
icon='ASSET_MANAGER',
|
||||||
|
text='Switch Entities')
|
||||||
|
|
||||||
|
|
||||||
class RobossemblerOperator1(Operator):
|
class RobossemblerOperator1(Operator):
|
||||||
'''Tooltip'''
|
'''Tooltip'''
|
||||||
bl_idname = 'export.scene_config'
|
bl_idname = 'scene.export_json'
|
||||||
bl_label = ''
|
bl_label = ''
|
||||||
bl_description = 'Export scene liks to json config.'
|
bl_description = 'Export scene liks to json config operator.'
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
prop = context.scene.robossembler_properties
|
prop = context.scene.robossembler_properties
|
||||||
|
|
||||||
file_path = os.path.realpath(bpy.path.abspath((prop.conf_file_path)))
|
file_path = os.path.realpath(bpy.path.abspath((prop.json_file_path)))
|
||||||
physics_engine = prop.engine
|
physics_engine = prop.engine
|
||||||
export_json(context, file_path, physics_engine)
|
export_json(context, file_path, physics_engine)
|
||||||
|
|
||||||
|
@ -142,25 +191,45 @@ class RobossemblerOperator1(Operator):
|
||||||
|
|
||||||
class RobossemblerOperator2(Operator):
|
class RobossemblerOperator2(Operator):
|
||||||
'''Tooltip'''
|
'''Tooltip'''
|
||||||
bl_idname = 'export.scene_config'
|
bl_idname = 'scene.import_ros2bag'
|
||||||
bl_label = ''
|
bl_label = ''
|
||||||
bl_description = 'Export scene liks to json config.'
|
bl_description = 'Import Ros2Bag animation to scene and apply it to liks.'
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
prop = context.scene.robossembler_properties
|
prop = context.scene.robossembler_properties
|
||||||
|
|
||||||
file_path = os.path.realpath(bpy.path.abspath((prop.conf_file_path)))
|
file_path = os.path.realpath(bpy.path.abspath((prop.ros2bag_file_path)))
|
||||||
set_animation_data(context, file_path)
|
set_animation_data(context, file_path)
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class RobossemblerOperator3(Operator):
|
||||||
|
'''Tooltip'''
|
||||||
|
bl_idname = 'scene.manage_entities'
|
||||||
|
bl_label = ''
|
||||||
|
bl_description = 'Switch visual 3d entities.'
|
||||||
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
prop = context.scene.robossembler_properties
|
||||||
|
|
||||||
|
file_path = os.path.realpath(bpy.path.abspath((prop.refs_file_path)))
|
||||||
|
print('1'*10, file_path)
|
||||||
|
entity = prop.entity
|
||||||
|
switch_3d_entities(context, file_path)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
RobossemblerPanel1,
|
RobossemblerPanel1,
|
||||||
RobossemblerPanel2,
|
RobossemblerPanel2,
|
||||||
|
RobossemblerPanel3,
|
||||||
RobossemblerOperator1,
|
RobossemblerOperator1,
|
||||||
RobossemblerOperator2,
|
RobossemblerOperator2,
|
||||||
|
RobossemblerOperator3,
|
||||||
addon_Properties)
|
addon_Properties)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
# coding: utf-8
|
||||||
|
'''
|
||||||
|
Copyright (C) 2024 brothermechanic@yandex.com
|
||||||
|
|
||||||
|
Created by brothermechanic
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def unlink_from_collections(context, obj):
|
||||||
|
''' Unlinking object from all collections. '''
|
||||||
|
for col in list(bpy.data.collections) + [context.scene.collection]:
|
||||||
|
if obj.name in col.objects:
|
||||||
|
col.objects.unlink(obj)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def link_library(lib_path, lib_type, lib_name):
|
||||||
|
''' '''
|
||||||
|
bpy.ops.wm.link(
|
||||||
|
filepath=lib_path,
|
||||||
|
directory=os.path.join(lib_path, lib_type),
|
||||||
|
filename=lib_name,
|
||||||
|
relative_path=True,
|
||||||
|
do_reuse_local_id=True,
|
||||||
|
autoselect=True,
|
||||||
|
instance_collections=True,
|
||||||
|
instance_object_data=True
|
||||||
|
)
|
||||||
|
return bpy.data.objects[lib_name]
|
||||||
|
|
||||||
|
|
||||||
|
def switch_3d_entities(context, lib_dir):
|
||||||
|
''' '''
|
||||||
|
assert bpy.data.collections.get('visual'), 'No visual collection!'
|
||||||
|
entities_from = bpy.data.collections['visual'].objects
|
||||||
|
assert os.path.isdir(lib_dir), 'No libs dir {}!'.format(lib_dir)
|
||||||
|
lib_files = os.listdir(lib_dir)
|
||||||
|
|
||||||
|
hp_col = bpy.data.collections.new('Parts')
|
||||||
|
context.scene.collection.children.link(hp_col)
|
||||||
|
for entity_from in entities_from:
|
||||||
|
for lib_file in lib_files:
|
||||||
|
if '{}_hp.blend'.format(entity_from.name) != lib_file:
|
||||||
|
continue
|
||||||
|
|
||||||
|
entity_to = link_library(
|
||||||
|
lib_path=os.path.join(lib_dir, lib_file),
|
||||||
|
lib_type='Collection',
|
||||||
|
lib_name='{}_hp'.format(entity_from.name))
|
||||||
|
|
||||||
|
entity_to.empty_display_type = 'ARROWS'
|
||||||
|
entity_to.empty_display_size = 0.5
|
||||||
|
|
||||||
|
unlink_from_collections(context, entity_to)
|
||||||
|
hp_col.objects.link(entity_to)
|
||||||
|
|
||||||
|
entity_to.location = entity_from.location
|
||||||
|
entity_from.rotation_mode = entity_to.rotation_mode = 'QUATERNION'
|
||||||
|
entity_to.rotation_quaternion = entity_from.rotation_quaternion
|
||||||
|
entity_to.scale = entity_from.scale
|
||||||
|
|
||||||
|
entity_to.parent = entity_from.parent
|
||||||
|
|
||||||
|
logger.info('Entity %s changed to %s!', entity_from.name, entity_to.name)
|
||||||
|
|
||||||
|
bpy.data.collections['visual'].hide_render = True
|
||||||
|
bpy.data.collections['visual'].hide_viewport = True
|
||||||
|
|
||||||
|
return True
|
Loading…
Add table
Add a link
Reference in a new issue