Skip to content

Commit b06043c

Browse files
authored
Weekly Update (#3)
* restructure to support additional file formats * update for dim3 template * rename simloader to bseq * minor fix * add notes
1 parent 1c8dfc4 commit b06043c

17 files changed

+276
-251
lines changed

__init__.py

+28-28
Original file line numberDiff line numberDiff line change
@@ -20,53 +20,53 @@
2020
if bpy.context.preferences.filepaths.use_relative_paths == True:
2121
bpy.context.preferences.filepaths.use_relative_paths = False
2222

23-
from simloader import *
23+
from bseq import *
2424

2525
classes = [
26-
SIMLOADER_obj_property,
27-
SIMLOADER_scene_property,
28-
SIMLOADER_mesh_property,
29-
SIMLOADER_OT_load,
30-
SIMLOADER_OT_edit,
31-
SIMLOADER_OT_resetpt,
32-
SIMLOADER_OT_resetins,
33-
SIMLOADER_OT_resetmesh,
34-
SIMLOADER_Import,
35-
SIMLOADER_List_Panel,
36-
SIMLOADER_UL_Obj_List,
37-
SIMLOADER_Settings,
38-
SIMLOADER_Templates,
39-
SIMLOADER_UL_Att_List,
40-
SIMLOADER_OT_set_as_split_norm,
41-
SIMLOADER_OT_remove_split_norm,
42-
SIMLOADER_OT_disable_selected,
43-
SIMLOADER_OT_enable_selected,
44-
SIMLOADER_OT_refresh_seq,
26+
BSEQ_obj_property,
27+
BSEQ_scene_property,
28+
BSEQ_mesh_property,
29+
BSEQ_OT_load,
30+
BSEQ_OT_edit,
31+
BSEQ_OT_resetpt,
32+
BSEQ_OT_resetins,
33+
BSEQ_OT_resetmesh,
34+
BSEQ_Import,
35+
BSEQ_List_Panel,
36+
BSEQ_UL_Obj_List,
37+
BSEQ_Settings,
38+
BSEQ_Templates,
39+
BSEQ_UL_Att_List,
40+
BSEQ_OT_set_as_split_norm,
41+
BSEQ_OT_remove_split_norm,
42+
BSEQ_OT_disable_selected,
43+
BSEQ_OT_enable_selected,
44+
BSEQ_OT_refresh_seq,
4545
]
4646

4747

4848
def register():
49-
bpy.app.handlers.load_post.append(SIMLOADER_initialize)
49+
bpy.app.handlers.load_post.append(BSEQ_initialize)
5050
for cls in classes:
5151
bpy.utils.register_class(cls)
5252
bpy.types.TEXT_MT_templates.append(draw_template)
53-
bpy.types.Scene.SIMLOADER = bpy.props.PointerProperty(type=SIMLOADER_scene_property)
54-
bpy.types.Object.SIMLOADER = bpy.props.PointerProperty(type=SIMLOADER_obj_property)
55-
bpy.types.Mesh.SIMLOADER = bpy.props.PointerProperty(type=SIMLOADER_mesh_property)
53+
bpy.types.Scene.BSEQ = bpy.props.PointerProperty(type=BSEQ_scene_property)
54+
bpy.types.Object.BSEQ = bpy.props.PointerProperty(type=BSEQ_obj_property)
55+
bpy.types.Mesh.BSEQ = bpy.props.PointerProperty(type=BSEQ_mesh_property)
5656

5757

5858
# manually call this function once
5959
# so when addon being installed, it can run correctly
6060
# because scene is not used, so pass None into it
61-
SIMLOADER_initialize(None)
61+
BSEQ_initialize(None)
6262

6363
def unregister():
6464
for cls in classes:
6565
bpy.utils.unregister_class(cls)
6666
bpy.types.TEXT_MT_templates.remove(draw_template)
67-
del bpy.types.Scene.SIMLOADER
68-
del bpy.types.Object.SIMLOADER
69-
bpy.app.handlers.load_post.remove(SIMLOADER_initialize)
67+
del bpy.types.Scene.BSEQ
68+
del bpy.types.Object.BSEQ
69+
bpy.app.handlers.load_post.remove(BSEQ_initialize)
7070
unsubscribe_to_selected()
7171

7272

additional_file_formats/README.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Here you can find an example if you want to import customized file formats.
2+
3+
1. create an `example.py`
4+
2. implement a function as following
5+
```python
6+
def read_func(filepath):
7+
# open the filepath linked file
8+
# construct the meshio object
9+
return meshio.Mesh
10+
```
11+
3. call `meshio.register_format("name", [".extenstion"], read_func, {".extenstion": None})`in global environment
12+
4. add `from . import example` in `__init__.py`
13+
14+
You can check `bgeo.py` as an example, which reads the partiles-only [.bgeo](https://github.com/wdas/partio) file.
15+
16+
For more details how to construct the `meshio.Mesh` object, you can check [here](https://github.com/nschloe/meshio/wiki/meshio-Mesh()-data-structure) for the details about the data strucutre, and [here](https://github.com/nschloe/meshio/wiki/Node-ordering-in-cells) more details about the vertex ordering.

additional_file_formats/__init__.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,2 @@
1-
from .mzd import readMZD_to_bpymesh, readMZD_to_meshio
2-
from .bgeo import readbgeo_to_meshio
3-
4-
additional_format_loader = {'bgeo': readbgeo_to_meshio, 'mzd': readMZD_to_meshio}
5-
6-
__all__ = [
7-
readMZD_to_bpymesh, readMZD_to_meshio, readbgeo_to_meshio, additional_format_loader
8-
]
1+
from . import bgeo
2+
from . import mzd

additional_file_formats/bgeo.py

+3
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,6 @@ def readbgeo_to_meshio(filepath):
105105
raise Exception("file didn't end")
106106
return meshio.Mesh(position, [('vertex', [])], point_data=point_attributes)
107107

108+
109+
# no need for write function
110+
meshio.register_format("bgeo", [".bgeo"], readbgeo_to_meshio, {".bgeo": None})

additional_file_formats/mzd.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ def readMZD_to_meshio(filepath):
159159
pass
160160
return meshio.Mesh(out_vertPositions.reshape((out_numVertices, 3)), cells, point_data)
161161

162+
162163
def readMZD_to_bpymesh(filepath, mesh):
163164
shade_scheme = False
164165
if mesh.polygons:
@@ -308,4 +309,8 @@ def readMZD_to_bpymesh(filepath, mesh):
308309
else:
309310
# print(name)
310311
file.seek(size, 1)
311-
pass
312+
pass
313+
314+
315+
# no need for write function
316+
meshio.register_format("mzd", [".mzd"], readMZD_to_meshio, {".mzd": None})

bseq/__init__.py

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from .operators import BSEQ_OT_load, BSEQ_OT_edit, BSEQ_OT_resetpt, BSEQ_OT_resetmesh, BSEQ_OT_resetins,BSEQ_OT_set_as_split_norm,BSEQ_OT_remove_split_norm,BSEQ_OT_disable_selected,BSEQ_OT_enable_selected,BSEQ_OT_refresh_seq
2+
from .properties import BSEQ_scene_property, BSEQ_obj_property,BSEQ_mesh_property
3+
from .panels import BSEQ_UL_Obj_List, BSEQ_List_Panel, BSEQ_Settings, BSEQ_Import, BSEQ_Templates, BSEQ_UL_Att_List, draw_template
4+
from .messenger import subscribe_to_selected, unsubscribe_to_selected
5+
import bpy
6+
from bpy.app.handlers import persistent
7+
from .importer import update_obj
8+
from datetime import datetime
9+
10+
11+
def print_information(scene):
12+
if not bpy.context.scene.BSEQ.print:
13+
return
14+
now = datetime.now()
15+
path = bpy.context.scene.render.filepath
16+
path = bpy.path.abspath(path)
17+
filepath = path + '/bseq_' + now.strftime("%Y-%m-%d_%H-%M")
18+
with open(filepath, 'w') as file:
19+
file.write("Render Time: {}\n".format(now.strftime("%Y-%m-%d_%H-%M")))
20+
file.write("bseq Objects in the scene:\n\n")
21+
for obj in bpy.data.objects:
22+
bseq_prop = obj.BSEQ
23+
if bseq_prop.init:
24+
file.write("Object name: {}\n".format(obj.name))
25+
file.write("Is it being animated: {}\n".format(bseq_prop.enabled))
26+
file.write("Filepath: {}\n".format(bseq_prop.pattern))
27+
file.write("Is it relative path: {}\n".format(bseq_prop.use_relative))
28+
file.write("\n\n")
29+
30+
31+
@persistent
32+
def BSEQ_initialize(scene):
33+
if update_obj not in bpy.app.handlers.frame_change_post:
34+
bpy.app.handlers.frame_change_post.append(update_obj)
35+
subscribe_to_selected()
36+
if print_information not in bpy.app.handlers.render_init:
37+
bpy.app.handlers.render_init.append(print_information)
38+
39+
40+
__all__ = [
41+
"BSEQ_OT_edit",
42+
"BSEQ_OT_load",
43+
"BSEQ_obj_property",
44+
"BSEQ_initialize",
45+
"BSEQ_Import",
46+
"BSEQ_List_Panel",
47+
"BSEQ_UL_Obj_List",
48+
"BSEQ_scene_property",
49+
"BSEQ_Templates",
50+
"BSEQ_Settings",
51+
"BSEQ_UL_Att_List",
52+
"subscribe_to_selected",
53+
"BSEQ_OT_resetpt",
54+
"BSEQ_OT_resetmesh",
55+
"BSEQ_OT_resetins",
56+
"draw_template",
57+
"unsubscribe_to_selected",
58+
"BSEQ_OT_set_as_split_norm",
59+
"BSEQ_mesh_property",
60+
"BSEQ_OT_remove_split_norm",
61+
"BSEQ_OT_disable_selected",
62+
"BSEQ_OT_enable_selected",
63+
"BSEQ_OT_refresh_seq",
64+
]

simloader/callback.py renamed to bseq/callback.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66

77
def update_path(self, context):
88
# When the path has been changed, reset the selected sequence to None
9-
context.scene.SIMLOADER['fileseq'] = 1
10-
context.scene.SIMLOADER.use_pattern = False
11-
context.scene.SIMLOADER.pattern = ""
9+
context.scene.BSEQ['fileseq'] = 1
10+
context.scene.BSEQ.use_pattern = False
11+
context.scene.BSEQ.pattern = ""
1212

1313

1414
def item_fileseq(self, context):
1515
'''
1616
Detects all the file sequences in the directory
1717
'''
1818

19-
p = context.scene.SIMLOADER.path
19+
p = context.scene.BSEQ.path
2020
try:
2121
f = fileseq.findSequencesOnDisk(p)
2222
except:
@@ -38,10 +38,10 @@ def item_fileseq(self, context):
3838
def update_selected_obj_num(self, context):
3939

4040
# Here is when select sequences, then change the corresponding object to active object
41-
index = context.scene.SIMLOADER.selected_obj_num
41+
index = context.scene.BSEQ.selected_obj_num
4242
obj = bpy.data.objects[index]
4343

44-
if context.scene.SIMLOADER.selected_obj_deselectall_flag:
44+
if context.scene.BSEQ.selected_obj_deselectall_flag:
4545
bpy.ops.object.select_all(action="DESELECT")
4646
obj.select_set(True)
4747
context.view_layer.objects.active = obj

simloader/importer.py renamed to bseq/importer.py

+16-23
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from .utils import show_message_box
66
import numpy as np
77
from mathutils import Matrix
8+
# this import is not useless
89
import additional_file_formats
910

1011

@@ -131,7 +132,7 @@ def update_mesh(meshio_mesh, mesh):
131132
attribute.data.foreach_set(name_string, v.ravel())
132133

133134
# set as split norm
134-
if mesh.SIMLOADER.split_norm_att_name and mesh.SIMLOADER.split_norm_att_name == k:
135+
if mesh.BSEQ.split_norm_att_name and mesh.BSEQ.split_norm_att_name == k:
135136
mesh.use_auto_smooth = True
136137
mesh.normals_split_custom_set_from_vertices(v)
137138

@@ -144,11 +145,7 @@ def create_obj(fileseq, use_relaitve, transform_matrix=Matrix([[1, 0, 0, 0], [0,
144145
meshio_mesh = None
145146
enabled = True
146147
try:
147-
ext = fileseq.extension().split('.')[-1]
148-
if ext in additional_file_formats.additional_format_loader:
149-
meshio_mesh = additional_file_formats.additional_format_loader[ext](filepath)
150-
else:
151-
meshio_mesh = meshio.read(filepath)
148+
meshio_mesh = meshio.read(filepath)
152149
except Exception as e:
153150
show_message_box("Error when reading: " + filepath + ",\n" + traceback.format_exc(),
154151
"Meshio Loading Error" + str(e),
@@ -159,13 +156,13 @@ def create_obj(fileseq, use_relaitve, transform_matrix=Matrix([[1, 0, 0, 0], [0,
159156
name = fileseq.basename() + "@" + fileseq.extension()
160157
mesh = bpy.data.meshes.new(name)
161158
object = bpy.data.objects.new(name, mesh)
162-
object.SIMLOADER.use_relative = use_relaitve
159+
object.BSEQ.use_relative = use_relaitve
163160
if use_relaitve:
164-
object.SIMLOADER.pattern = bpy.path.relpath(str(fileseq))
161+
object.BSEQ.pattern = bpy.path.relpath(str(fileseq))
165162
else:
166-
object.SIMLOADER.pattern = str(fileseq)
167-
object.SIMLOADER.init = True
168-
object.SIMLOADER.enabled = enabled
163+
object.BSEQ.pattern = str(fileseq)
164+
object.BSEQ.init = True
165+
object.BSEQ.enabled = enabled
169166
object.matrix_world = transform_matrix
170167
if enabled:
171168
update_mesh(meshio_mesh, object.data)
@@ -180,25 +177,25 @@ def update_obj(scene, depsgraph=None):
180177
current_frame = bpy.context.scene.frame_current
181178

182179
for obj in bpy.data.objects:
183-
if obj.SIMLOADER.init == False:
180+
if obj.BSEQ.init == False:
184181
continue
185-
if obj.SIMLOADER.enabled == False:
182+
if obj.BSEQ.enabled == False:
186183
continue
187184

188185
meshio_mesh = None
189-
pattern = obj.SIMLOADER.pattern
190-
if obj.SIMLOADER.use_relative:
186+
pattern = obj.BSEQ.pattern
187+
if obj.BSEQ.use_relative:
191188
pattern = bpy.path.abspath(pattern)
192189
# in case the blender file was created on windows system, but opened in linux system
193190
pattern = bpy.path.native_pathsep(pattern)
194191
fs = fileseq.FileSequence(pattern)
195192

196-
if obj.SIMLOADER.use_advance and obj.SIMLOADER.script_name:
197-
script = bpy.data.texts[obj.SIMLOADER.script_name]
193+
if obj.BSEQ.use_advance and obj.BSEQ.script_name:
194+
script = bpy.data.texts[obj.BSEQ.script_name]
198195
try:
199196
exec(script.as_string())
200197
except Exception as e:
201-
show_message_box(traceback.format_exc(), "running script: " + obj.SIMLOADER.script_name + " failed: " + str(e),
198+
show_message_box(traceback.format_exc(), "running script: " + obj.BSEQ.script_name + " failed: " + str(e),
202199
"ERROR")
203200
continue
204201

@@ -225,11 +222,7 @@ def update_obj(scene, depsgraph=None):
225222
else:
226223
filepath = fs[current_frame % len(fs)]
227224
try:
228-
ext = fs.extension().split('.')[-1]
229-
if ext in additional_file_formats.additional_format_loader:
230-
meshio_mesh = additional_file_formats.additional_format_loader[ext](filepath)
231-
else:
232-
meshio_mesh = meshio.read(filepath)
225+
meshio_mesh = meshio.read(filepath)
233226
except Exception as e:
234227
show_message_box("Error when reading: " + filepath + ",\n" + traceback.format_exc(),
235228
"Meshio Loading Error" + str(e),

simloader/messenger.py renamed to bseq/messenger.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,28 @@ def selected_callback():
77
name = bpy.context.active_object.name
88
idx = bpy.data.objects.find(name)
99
if idx >= 0:
10-
bpy.context.scene.SIMLOADER.selected_obj_deselectall_flag = False
11-
bpy.context.scene.SIMLOADER.selected_obj_num = idx
12-
bpy.context.scene.SIMLOADER.selected_obj_deselectall_flag = True
10+
bpy.context.scene.BSEQ.selected_obj_deselectall_flag = False
11+
bpy.context.scene.BSEQ.selected_obj_num = idx
12+
bpy.context.scene.BSEQ.selected_obj_deselectall_flag = True
1313

1414

1515
def subscribe_to_selected():
16-
import simloader
16+
import bseq
1717

1818
# because current implementation may subscribe twice
1919
# so clear once to avoid duplication
20-
bpy.msgbus.clear_by_owner(simloader)
20+
bpy.msgbus.clear_by_owner(bseq)
2121

2222
bpy.msgbus.subscribe_rna(
2323
key=(bpy.types.LayerObjects, 'active'),
24-
# don't know why it needs this owner, so I set owner to this module `simloader`
25-
owner=simloader,
24+
# don't know why it needs this owner, so I set owner to this module `bseq`
25+
owner=bseq,
2626
# no args
2727
args=(()),
2828
notify=selected_callback,
2929
)
3030

3131

3232
def unsubscribe_to_selected():
33-
import simloader
34-
bpy.msgbus.clear_by_owner(simloader)
33+
import bseq
34+
bpy.msgbus.clear_by_owner(bseq)

0 commit comments

Comments
 (0)