Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
12d5f8c236 | |||
6fe856fa8e | |||
c2a85a2d86 |
@ -9,7 +9,7 @@ The latest commit may not be stable to use, please use the latest commit with gi
|
|||||||
This plugin contain various aspect of Ballance mapping. However, if some features can be easily gotten from other Blender plugin, this plugin will not provide them duplicatedly. We highly recommend that use this plugin with following plugins.
|
This plugin contain various aspect of Ballance mapping. However, if some features can be easily gotten from other Blender plugin, this plugin will not provide them duplicatedly. We highly recommend that use this plugin with following plugins.
|
||||||
|
|
||||||
* [BenjaminSauder/SimpleLattice](https://github.com/BenjaminSauder/SimpleLattice): Create lattice quickly to transform object.
|
* [BenjaminSauder/SimpleLattice](https://github.com/BenjaminSauder/SimpleLattice): Create lattice quickly to transform object.
|
||||||
* [egtwobits/Mesh Align Plus](https://github.com/egtwobits/mesh_mesh_align_plus): Provide powerful align functions which far beyond vanilla Blender align function.
|
* [JulienHeijmans/quicksnap](https://github.com/JulienHeijmans/quicksnap): Provide powerful align functions which far beyond vanilla Blender align function.
|
||||||
|
|
||||||
## Technical Infomation
|
## Technical Infomation
|
||||||
|
|
||||||
@ -17,11 +17,14 @@ Used BM file spec can be found in [there](https://github.com/yyc12345/gist/blob/
|
|||||||
Used tools chain principle and the file format located in `meshes` can be found in [there](https://github.com/yyc12345/gist/blob/master/BMFileSpec/YYCToolsChainSpec_ZH.md) (Chinese only).
|
Used tools chain principle and the file format located in `meshes` can be found in [there](https://github.com/yyc12345/gist/blob/master/BMFileSpec/YYCToolsChainSpec_ZH.md) (Chinese only).
|
||||||
The format of the files which are under the `jsons` folder and belong to the BMERevenge section, can be found in [here](https://github.com/yyc12345/gist/blob/master/BMERevenge/DevDocument_ZH.md) (Chinese only).
|
The format of the files which are under the `jsons` folder and belong to the BMERevenge section, can be found in [here](https://github.com/yyc12345/gist/blob/master/BMERevenge/DevDocument_ZH.md) (Chinese only).
|
||||||
|
|
||||||
This plugin will continuously support Blender lastest **LTS** version. This plugin will migrate to new version when the new LTS version released. Currently, it based on Blender **3.3.x**.
|
This plugin will continuously support Blender lastest **LTS** version. This plugin will migrate to new version when the new LTS version released. Currently, it based on Blender **3.6.x**.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Put `ballance_blender_plugin` into Blender's plugin folder, `scripts/addons_contrib`. Then enable this plugin in Blender's preferences (DO NOT forget to configure this plugin's settings after first installation or updating plugin.).
|
Put `ballance_blender_plugin` into Blender's plugin folder, `scripts/addons`. Then enable this plugin in Blender's preferences (DO NOT forget to configure this plugin's settings after first installation or updating plugin.).
|
||||||
|
|
||||||
|
> **Note**
|
||||||
|
After the version 3.3 supporting Blender 3.6 LTS, you should install this plugin in `scripts/addons`, not `scripts/addons_contrib` due to Blender do not support testing plugin anymore. If you still have old version in `scripts/addons_contrib`, please **DELETE** it **BEFORE** install the new version.
|
||||||
|
|
||||||
## Feature Introduction
|
## Feature Introduction
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
本插件囊括了Ballance制图中可能会用到的各种功能。对于一些其它插件可以提供的功能,本插件不再重复提供。建议与下列插件合用以取得更好制图效果:
|
本插件囊括了Ballance制图中可能会用到的各种功能。对于一些其它插件可以提供的功能,本插件不再重复提供。建议与下列插件合用以取得更好制图效果:
|
||||||
|
|
||||||
* [BenjaminSauder/SimpleLattice](https://github.com/BenjaminSauder/SimpleLattice):快速创建晶格以便变形物体。
|
* [BenjaminSauder/SimpleLattice](https://github.com/BenjaminSauder/SimpleLattice):快速创建晶格以便变形物体。
|
||||||
* [egtwobits/Mesh Align Plus](https://github.com/egtwobits/mesh_mesh_align_plus):提供远超Blender原生的对齐功能。
|
* [JulienHeijmans/quicksnap](https://github.com/JulienHeijmans/quicksnap):提供远超Blender原生的对齐功能。
|
||||||
|
|
||||||
## 技术信息
|
## 技术信息
|
||||||
|
|
||||||
@ -17,11 +17,14 @@
|
|||||||
使用的制图链标准以及`meshes`文件夹下的文件的格式可以在[这里](https://github.com/yyc12345/gist/blob/master/BMFileSpec/YYCToolsChainSpec_ZH.md)查找
|
使用的制图链标准以及`meshes`文件夹下的文件的格式可以在[这里](https://github.com/yyc12345/gist/blob/master/BMFileSpec/YYCToolsChainSpec_ZH.md)查找
|
||||||
`jsons`文件夹下的,隶属于BMERevenge部分的文件的格式可以在[这里](https://github.com/yyc12345/gist/blob/master/BMERevenge/DevDocument_ZH.md)查找
|
`jsons`文件夹下的,隶属于BMERevenge部分的文件的格式可以在[这里](https://github.com/yyc12345/gist/blob/master/BMERevenge/DevDocument_ZH.md)查找
|
||||||
|
|
||||||
支持Blender的原则是支持当前最新的 **LTS** 版本,在最新的LTS版本释出之后会花一些时间迁移插件。当前插件基于**3.3.x**版本
|
支持Blender的原则是支持当前最新的 **LTS** 版本,在最新的LTS版本释出之后会花一些时间迁移插件。当前插件基于**3.6.x**版本
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
将`ballance_blender_plugin`直接复制到Blender插件目录`scripts/addons_contrib`内即可。然后在Blender偏好设置中启用即可(请在第一次安装后或更新插件后配置插件设置)。
|
将`ballance_blender_plugin`直接复制到Blender插件目录`scripts/addons`内即可。然后在Blender偏好设置中启用即可(请在第一次安装后或更新插件后配置插件设置)。
|
||||||
|
|
||||||
|
> **Note**
|
||||||
|
在对标Blender 3.6 LTS的3.3版本之后,您应该将此插件安装在`scripts/addons`中,而不是`scripts/addons_contrib`中,因为Blender不再支持Testing类型插件。 如果您在`scripts/addons_contrib`中仍有旧版本,请在安装新版本**之前删除**它。
|
||||||
|
|
||||||
## 功能介绍
|
## 功能介绍
|
||||||
|
|
||||||
|
@ -173,14 +173,14 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
|
|||||||
mesh_faceIndexPairs = [(face, index) for index, face in enumerate(mesh.polygons)]
|
mesh_faceIndexPairs = [(face, index) for index, face in enumerate(mesh.polygons)]
|
||||||
UTILS_file_io.write_uint32(fmesh, len(mesh_faceIndexPairs) * 3)
|
UTILS_file_io.write_uint32(fmesh, len(mesh_faceIndexPairs) * 3)
|
||||||
if mesh.uv_layers.active is not None:
|
if mesh.uv_layers.active is not None:
|
||||||
uv_layer = mesh.uv_layers.active.data[:]
|
uv_layer = mesh.uv_layers.active.uv
|
||||||
for f, f_index in mesh_faceIndexPairs:
|
for f, f_index in mesh_faceIndexPairs:
|
||||||
# it should be triangle face, otherwise throw a error
|
# it should be triangle face, otherwise throw a error
|
||||||
if (f.loop_total != 3):
|
if (f.loop_total != 3):
|
||||||
raise Exception("Not a triangle", f.poly.loop_total)
|
raise Exception("Not a triangle", f.poly.loop_total)
|
||||||
|
|
||||||
for loop_index in range(f.loop_start, f.loop_start + f.loop_total):
|
for loop_index in range(f.loop_start, f.loop_start + f.loop_total):
|
||||||
uv = uv_layer[loop_index].uv
|
uv = uv_layer[loop_index].vector
|
||||||
# reverse v
|
# reverse v
|
||||||
UTILS_file_io.write_2vector(fmesh, uv[0], -uv[1])
|
UTILS_file_io.write_2vector(fmesh, uv[0], -uv[1])
|
||||||
else:
|
else:
|
||||||
@ -202,6 +202,10 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
|
|||||||
mesh_usedBlenderMtl = mesh.materials[:]
|
mesh_usedBlenderMtl = mesh.materials[:]
|
||||||
mesh_noMaterial = len(mesh_usedBlenderMtl) == 0
|
mesh_noMaterial = len(mesh_usedBlenderMtl) == 0
|
||||||
for mat in mesh_usedBlenderMtl:
|
for mat in mesh_usedBlenderMtl:
|
||||||
|
# skip empty mtl slot
|
||||||
|
if mat is None:
|
||||||
|
continue
|
||||||
|
# add into mtl set
|
||||||
if mat not in materialSet:
|
if mat not in materialSet:
|
||||||
materialSet.add(mat)
|
materialSet.add(mat)
|
||||||
materialList.append(mat)
|
materialList.append(mat)
|
||||||
@ -212,7 +216,10 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
|
|||||||
mesh_vIndex = []
|
mesh_vIndex = []
|
||||||
for f, f_index in mesh_faceIndexPairs:
|
for f, f_index in mesh_faceIndexPairs:
|
||||||
# confirm material use
|
# confirm material use
|
||||||
if mesh_noMaterial:
|
# a face without mtl have 2 situations. first is the whole object do not have mtl
|
||||||
|
# another is this face use an empty mtl slot.
|
||||||
|
mesh_faceNoMtl = mesh_noMaterial or (mesh_usedBlenderMtl[f.material_index] is None)
|
||||||
|
if mesh_faceNoMtl:
|
||||||
mesh_materialIndex = 0
|
mesh_materialIndex = 0
|
||||||
else:
|
else:
|
||||||
mesh_materialIndex = materialList.index(mesh_usedBlenderMtl[f.material_index])
|
mesh_materialIndex = materialList.index(mesh_usedBlenderMtl[f.material_index])
|
||||||
@ -235,7 +242,7 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
|
|||||||
mesh_vIndex[0], mesh_vtIndex[0], mesh_vnIndex[0])
|
mesh_vIndex[0], mesh_vtIndex[0], mesh_vnIndex[0])
|
||||||
|
|
||||||
# set used material
|
# set used material
|
||||||
UTILS_file_io.write_bool(fmesh, not mesh_noMaterial)
|
UTILS_file_io.write_bool(fmesh, not mesh_faceNoMtl)
|
||||||
UTILS_file_io.write_uint32(fmesh, mesh_materialIndex)
|
UTILS_file_io.write_uint32(fmesh, mesh_materialIndex)
|
||||||
|
|
||||||
# free splited normals
|
# free splited normals
|
||||||
@ -311,6 +318,8 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
|
|||||||
# get absolute texture path
|
# get absolute texture path
|
||||||
texture_filepath = io_utils.path_reference(texture.filepath, texture_blenderFilePath, utils_tempTextureFolder,
|
texture_filepath = io_utils.path_reference(texture.filepath, texture_blenderFilePath, utils_tempTextureFolder,
|
||||||
'ABSOLUTE', "", None, texture.library)
|
'ABSOLUTE', "", None, texture.library)
|
||||||
|
# texture_filepath = bpy.path.abspath(texture.filepath, start=texture_blenderFilePath, library=texture.library)
|
||||||
|
|
||||||
# get file name and write it
|
# get file name and write it
|
||||||
texture_filename = os.path.basename(texture_filepath)
|
texture_filename = os.path.basename(texture_filepath)
|
||||||
UTILS_file_io.write_string(ftexture, texture_filename)
|
UTILS_file_io.write_string(ftexture, texture_filename)
|
||||||
|
@ -260,10 +260,10 @@ def import_bm(context, bmx_filepath, prefs_fncg, prefs_externalTexture, prefs_te
|
|||||||
mesh_target.vertices.foreach_set("co", unpack_list(mesh_vList))
|
mesh_target.vertices.foreach_set("co", unpack_list(mesh_vList))
|
||||||
mesh_target.loops.foreach_set("vertex_index", unpack_list(_flat_vertices_index(mesh_faceList)))
|
mesh_target.loops.foreach_set("vertex_index", unpack_list(_flat_vertices_index(mesh_faceList)))
|
||||||
mesh_target.loops.foreach_set("normal", unpack_list(_flat_vertices_normal(mesh_faceList, mesh_vnList)))
|
mesh_target.loops.foreach_set("normal", unpack_list(_flat_vertices_normal(mesh_faceList, mesh_vnList)))
|
||||||
mesh_target.uv_layers[0].data.foreach_set("uv", unpack_list(_flat_vertices_uv(mesh_faceList, mesh_vtList)))
|
mesh_target.uv_layers[0].uv.foreach_set("vector", unpack_list(_flat_vertices_uv(mesh_faceList, mesh_vtList))) # Blender 3.5 CHANGED
|
||||||
for i in range(len(mesh_faceList)):
|
for i in range(len(mesh_faceList)):
|
||||||
mesh_target.polygons[i].loop_start = i * 3
|
mesh_target.polygons[i].loop_start = i * 3
|
||||||
mesh_target.polygons[i].loop_total = 3
|
# mesh_target.polygons[i].loop_total = 3 # Blender 3.6 CHANGED
|
||||||
if mesh_faceList[i][9] != -1:
|
if mesh_faceList[i][9] != -1:
|
||||||
mesh_target.polygons[i].material_index = mesh_faceList[i][9]
|
mesh_target.polygons[i].material_index = mesh_faceList[i][9]
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ def _real_flatten_uv(mesh, reference_edge, scale_data: ScaleDataUnion):
|
|||||||
mesh.uv_layers.new(do_init=False)
|
mesh.uv_layers.new(do_init=False)
|
||||||
|
|
||||||
bm = bmesh.from_edit_mesh(mesh)
|
bm = bmesh.from_edit_mesh(mesh)
|
||||||
uv_lay = bm.loops.layers.uv.active
|
uv_lay = bm.loops.layers.uv.active # NOTE: this is a part of bmesh. not affected by Blender 3.5 CHANGED.
|
||||||
for face in bm.faces:
|
for face in bm.faces:
|
||||||
# ========== only process selected face ==========
|
# ========== only process selected face ==========
|
||||||
if not face.select:
|
if not face.select:
|
||||||
|
@ -141,15 +141,17 @@ def _create_rail_uv(rail_type, material_pointer, scale_size, projection_axis):
|
|||||||
)
|
)
|
||||||
real_scale = 1.0 / maxLength
|
real_scale = 1.0 / maxLength
|
||||||
|
|
||||||
uv_layer = mesh.uv_layers.active.data
|
# Blender 3.5 CHANGED: mesh.uv_layers.active.data -> mesh.uv_layers.active.uv
|
||||||
|
# .uv -> .vector
|
||||||
|
uv_layer = mesh.uv_layers.active.uv
|
||||||
for poly in mesh.polygons:
|
for poly in mesh.polygons:
|
||||||
for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
|
for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
|
||||||
# get correspond vec index
|
# get correspond vec index
|
||||||
index = mesh.loops[loop_index].vertex_index
|
index = mesh.loops[loop_index].vertex_index
|
||||||
if rail_type == 'POINT':
|
if rail_type == 'POINT':
|
||||||
# set to 1 point
|
# set to 1 point
|
||||||
uv_layer[loop_index].uv[0] = 0
|
uv_layer[loop_index].vector[0] = 0
|
||||||
uv_layer[loop_index].uv[1] = 1
|
uv_layer[loop_index].vector[1] = 1
|
||||||
elif rail_type == 'SCALE' or rail_type == 'UNIFORM':
|
elif rail_type == 'SCALE' or rail_type == 'UNIFORM':
|
||||||
# following xy -> uv scale
|
# following xy -> uv scale
|
||||||
#
|
#
|
||||||
@ -157,16 +159,16 @@ def _create_rail_uv(rail_type, material_pointer, scale_size, projection_axis):
|
|||||||
# use X axis: Y->U Z->V
|
# use X axis: Y->U Z->V
|
||||||
# use Y axis: X->U Z->V
|
# use Y axis: X->U Z->V
|
||||||
if projection_axis == 'X':
|
if projection_axis == 'X':
|
||||||
uv_layer[loop_index].uv[0] = vecList[index].co[1] * real_scale
|
uv_layer[loop_index].vector[0] = vecList[index].co[1] * real_scale
|
||||||
uv_layer[loop_index].uv[1] = vecList[index].co[2] * real_scale
|
uv_layer[loop_index].vector[1] = vecList[index].co[2] * real_scale
|
||||||
elif projection_axis == 'Y':
|
elif projection_axis == 'Y':
|
||||||
uv_layer[loop_index].uv[0] = vecList[index].co[0] * real_scale
|
uv_layer[loop_index].vector[0] = vecList[index].co[0] * real_scale
|
||||||
uv_layer[loop_index].uv[1] = vecList[index].co[2] * real_scale
|
uv_layer[loop_index].vector[1] = vecList[index].co[2] * real_scale
|
||||||
elif projection_axis == 'Z':
|
elif projection_axis == 'Z':
|
||||||
uv_layer[loop_index].uv[0] = vecList[index].co[0] * real_scale
|
uv_layer[loop_index].vector[0] = vecList[index].co[0] * real_scale
|
||||||
uv_layer[loop_index].uv[1] = vecList[index].co[1] * real_scale
|
uv_layer[loop_index].vector[1] = vecList[index].co[1] * real_scale
|
||||||
elif rail_type == 'TT':
|
elif rail_type == 'TT':
|
||||||
(uv_layer[loop_index].uv[0], uv_layer[loop_index].uv[1]) = _tt_reflection_mapping_compute(
|
(uv_layer[loop_index].vector[0], uv_layer[loop_index].vector[1]) = _tt_reflection_mapping_compute(
|
||||||
vecList[index].co,
|
vecList[index].co,
|
||||||
mesh.loops[loop_index].normal,
|
mesh.loops[loop_index].normal,
|
||||||
(0.0, 0.0, 0.0)
|
(0.0, 0.0, 0.0)
|
||||||
|
@ -469,13 +469,18 @@ def _load_basic_floor(mesh, floor_type, rotation, height_multiplier, d1, d2, sid
|
|||||||
_virtual_foreach_set(mesh.vertices, "co", global_offset_vec, vecList)
|
_virtual_foreach_set(mesh.vertices, "co", global_offset_vec, vecList)
|
||||||
_virtual_foreach_set(mesh.loops, "vertex_index", global_offset_loops, faceList)
|
_virtual_foreach_set(mesh.loops, "vertex_index", global_offset_loops, faceList)
|
||||||
_virtual_foreach_set(mesh.loops, "normal", global_offset_loops, normalList)
|
_virtual_foreach_set(mesh.loops, "normal", global_offset_loops, normalList)
|
||||||
_virtual_foreach_set(mesh.uv_layers[0].data, "uv", global_offset_loops, uvList)
|
# Blender 3.5 CHANGED. MeshUVLoop is deprecated and removed in 4.0
|
||||||
|
# See https://wiki.blender.org/wiki/Reference/Release_Notes/3.5/Python_API
|
||||||
|
# use MeshUVLoopLayer.uv[i].vector instead. MeshUVLoopLayer can be fetched from `mesh.uv_layers[i]` or `mesh.uv_layers.active`
|
||||||
|
_virtual_foreach_set(mesh.uv_layers[0].uv, "vector", global_offset_loops, uvList)
|
||||||
|
|
||||||
cache_counter = 0
|
cache_counter = 0
|
||||||
for i in range(len(faceMatList)):
|
for i in range(len(faceMatList)):
|
||||||
indCount = faceIndList[i]
|
indCount = faceIndList[i]
|
||||||
mesh.polygons[i + global_offset_polygons].loop_start = global_offset_loops + cache_counter
|
mesh.polygons[i + global_offset_polygons].loop_start = global_offset_loops + cache_counter
|
||||||
mesh.polygons[i + global_offset_polygons].loop_total = indCount
|
# Blender 3.6 CHANGED. loop_total is readonly now. the count of consumed vertices is decided by next loop's loop_start
|
||||||
|
# See: https://wiki.blender.org/wiki/Reference/Release_Notes/3.6/Python_API
|
||||||
|
# mesh.polygons[i + global_offset_polygons].loop_total = indCount
|
||||||
mesh.polygons[i + global_offset_polygons].material_index = faceMatList[i]
|
mesh.polygons[i + global_offset_polygons].material_index = faceMatList[i]
|
||||||
mesh.polygons[i + global_offset_polygons].use_smooth = True
|
mesh.polygons[i + global_offset_polygons].use_smooth = True
|
||||||
cache_counter += indCount
|
cache_counter += indCount
|
||||||
|
@ -178,8 +178,7 @@ def load_component(component_id):
|
|||||||
mesh.loops.foreach_set("normal", unpack_list(_flat_component_vertices_normal(faceList, vnList)))
|
mesh.loops.foreach_set("normal", unpack_list(_flat_component_vertices_normal(faceList, vnList)))
|
||||||
for i in range(len(faceList)):
|
for i in range(len(faceList)):
|
||||||
mesh.polygons[i].loop_start = i * 3
|
mesh.polygons[i].loop_start = i * 3
|
||||||
mesh.polygons[i].loop_total = 3
|
# mesh.polygons[i].loop_total = 3 # Blender 3.6 CHANGED
|
||||||
|
|
||||||
mesh.polygons[i].use_smooth = True
|
mesh.polygons[i].use_smooth = True
|
||||||
|
|
||||||
mesh.validate(clean_customdata=False)
|
mesh.validate(clean_customdata=False)
|
||||||
|
@ -2,10 +2,10 @@ bl_info={
|
|||||||
"name":"Ballance Blender Plugin",
|
"name":"Ballance Blender Plugin",
|
||||||
"description":"Ballance mapping tools for Blender",
|
"description":"Ballance mapping tools for Blender",
|
||||||
"author":"yyc12345",
|
"author":"yyc12345",
|
||||||
"version":(3,2),
|
"version":(3,3),
|
||||||
"blender":(3,3,0),
|
"blender":(3,6,0),
|
||||||
"category":"Object",
|
"category":"Object",
|
||||||
"support":"TESTING",
|
"support":"COMMUNITY",
|
||||||
"warning": "Please read document before using this plugin.",
|
"warning": "Please read document before using this plugin.",
|
||||||
"wiki_url": "https://github.com/yyc12345/BallanceBlenderHelper",
|
"wiki_url": "https://github.com/yyc12345/BallanceBlenderHelper",
|
||||||
"tracker_url": "https://github.com/yyc12345/BallanceBlenderHelper/issues"
|
"tracker_url": "https://github.com/yyc12345/BallanceBlenderHelper/issues"
|
||||||
|
Reference in New Issue
Block a user