Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
12d5f8c236 | |||
6fe856fa8e | |||
c2a85a2d86 | |||
dafb679780 | |||
f3663a4280 | |||
9c8d365ab6 |
13
README.md
13
README.md
@ -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.
|
||||
|
||||
* [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
|
||||
|
||||
@ -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).
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@ -68,6 +71,10 @@ Note that only convex face is supported. Applying this for a concave face will c
|
||||
In the edit mode, select the surface, click Flatten UV, and then scroll the slider to select an edge as a reference.
|
||||
If the generated UV is not attached correctly, such as the FloorSide's band is pasted to the bottom, you can reselect the reference edge and redo the operation until it is correct.
|
||||
|
||||
For the UV flatten by plugin, it must have a scale property. For example, the UV scale of normal floor is 5. However, the UV scale of sink floor is slightly larger than 5. Because the sink floor is "sink" in the floor block. There are 2 methods provided by plugin to getting this proper scale number. You can choose one from Scale Mode.
|
||||
The first method is that user specify a direct scale number. You just need select Scale Size in Scale Mode and fill with a proper scale number. This option is frequently used for fill a large borderless floor.
|
||||
The second method is reference point mode. You need specify a reference point and corresponding U component of its UV. Plugin will calculate the scale size automatically. This method is used for expanding a path of floor.
|
||||
|
||||
### Quick Struct Adder
|
||||
|
||||
In the add menu, we have added a set of commonly used objects. After adding, the object will move to the 3D cursor.
|
||||
|
13
README_ZH.md
13
README_ZH.md
@ -9,7 +9,7 @@
|
||||
本插件囊括了Ballance制图中可能会用到的各种功能。对于一些其它插件可以提供的功能,本插件不再重复提供。建议与下列插件合用以取得更好制图效果:
|
||||
|
||||
* [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)查找
|
||||
`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`中仍有旧版本,请在安装新版本**之前删除**它。
|
||||
|
||||
## 功能介绍
|
||||
|
||||
@ -68,6 +71,10 @@ Ballance 3D是一套简单的用于制图3D相关的轻型工具集合,可以
|
||||
编辑模式下,选中面,点击Flatten UV,然后选中一个边作为参考。
|
||||
如果最后生成的边贴附不对,比如把路面花纹贴到了下部,可以重新选择参考边再进行操作,直到正确为止。
|
||||
|
||||
对于粘贴的贴图的UV,需要具有一定缩放,比如对于平路面,这个缩放比是5,而对于凹路面,则要比5大一些,因为凹路面由于凹进路面。为了方便确认这个缩放值,我们提供了两种方式,可以在Scale Mode种选择。
|
||||
一种是用户直接指定,选择Scale Mode为Scale Size并填写合适的缩放数值即可。此选项适合平谱无边框路面。
|
||||
另一种即为参考点模式。用户指定一个参考点,并指定此参考点在U轴上的位置,插件会自动计算缩放值应为多少。此选项适合展开路面路径的贴图。
|
||||
|
||||
### 快速添加结构
|
||||
|
||||
在添加菜单中我们添加了一系列较为常用的物体。添加后物体会移动到3D游标处。
|
||||
|
@ -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)]
|
||||
UTILS_file_io.write_uint32(fmesh, len(mesh_faceIndexPairs) * 3)
|
||||
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:
|
||||
# it should be triangle face, otherwise throw a error
|
||||
if (f.loop_total != 3):
|
||||
raise Exception("Not a triangle", f.poly.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
|
||||
UTILS_file_io.write_2vector(fmesh, uv[0], -uv[1])
|
||||
else:
|
||||
@ -202,6 +202,10 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
|
||||
mesh_usedBlenderMtl = mesh.materials[:]
|
||||
mesh_noMaterial = len(mesh_usedBlenderMtl) == 0
|
||||
for mat in mesh_usedBlenderMtl:
|
||||
# skip empty mtl slot
|
||||
if mat is None:
|
||||
continue
|
||||
# add into mtl set
|
||||
if mat not in materialSet:
|
||||
materialSet.add(mat)
|
||||
materialList.append(mat)
|
||||
@ -212,7 +216,10 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
|
||||
mesh_vIndex = []
|
||||
for f, f_index in mesh_faceIndexPairs:
|
||||
# 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
|
||||
else:
|
||||
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])
|
||||
|
||||
# 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)
|
||||
|
||||
# free splited normals
|
||||
@ -311,6 +318,8 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
|
||||
# get absolute texture path
|
||||
texture_filepath = io_utils.path_reference(texture.filepath, texture_blenderFilePath, utils_tempTextureFolder,
|
||||
'ABSOLUTE', "", None, texture.library)
|
||||
# texture_filepath = bpy.path.abspath(texture.filepath, start=texture_blenderFilePath, library=texture.library)
|
||||
|
||||
# get file name and write it
|
||||
texture_filename = os.path.basename(texture_filepath)
|
||||
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.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.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)):
|
||||
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:
|
||||
mesh_target.polygons[i].material_index = mesh_faceList[i][9]
|
||||
|
||||
|
@ -3,32 +3,61 @@ import bmesh
|
||||
import math
|
||||
from . import UTILS_functions
|
||||
|
||||
class ScaleDataUnion(object):
|
||||
def __init__(self):
|
||||
self.UseRefPoint: bool = None
|
||||
def SetAsScale(self, scale_num: float):
|
||||
self.UseRefPoint: bool = False
|
||||
self.ScaleSize: float = scale_num
|
||||
def SetAsRefPoint(self, ref_point: int, ref_point_uv: float):
|
||||
self.UseRefPoint: bool = True
|
||||
self.ReferencePoint: int = ref_point
|
||||
self.ReferenceUV: float = ref_point_uv
|
||||
|
||||
class BALLANCE_OT_flatten_uv(bpy.types.Operator):
|
||||
"""Flatten selected face UV. Only works for convex face"""
|
||||
bl_idname = "ballance.flatten_uv"
|
||||
bl_label = "Flatten UV"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
normal_scale_correction = 5.0
|
||||
sink_scale_correction = 5.0 * (math.sqrt(2.5 ** 2 + 0.7 ** 2) / 2.5)
|
||||
|
||||
scale_correction: bpy.props.EnumProperty(
|
||||
name="Scale Correction",
|
||||
description="Choose your UV scale.",
|
||||
items=(
|
||||
("NORMAL", "Normal Floor", "Normal floor scale, 5.0"),
|
||||
("SINK", "Sink Floor", "Sink floor scale, around 5.19")
|
||||
),
|
||||
default='NORMAL',
|
||||
reference_edge : bpy.props.IntProperty(
|
||||
name="Reference Edge",
|
||||
description="The references edge of UV.\nIt will be placed in V axis.",
|
||||
min=0,
|
||||
soft_min=0, soft_max=3,
|
||||
default=0,
|
||||
)
|
||||
|
||||
reference_edge : bpy.props.IntProperty(
|
||||
name="Reference edge",
|
||||
description="The references edge of UV. It will be placed in V axis.",
|
||||
scale_mode: bpy.props.EnumProperty(
|
||||
name="Scale Mode",
|
||||
items=(('NUM', "Scale Size", "Scale UV with specific number."),
|
||||
('REF', "Ref. Point", "Scale UV with Reference Point feature."),
|
||||
),
|
||||
)
|
||||
|
||||
scale_number : bpy.props.FloatProperty(
|
||||
name="Scale Size",
|
||||
description="The size which will be applied for scale.",
|
||||
min=0,
|
||||
soft_min=0,
|
||||
soft_max=3,
|
||||
default=0,
|
||||
soft_min=0, soft_max=5,
|
||||
default=5.0,
|
||||
step=0.1, precision=1,
|
||||
)
|
||||
|
||||
reference_point : bpy.props.IntProperty(
|
||||
name="Reference Point",
|
||||
description="The references point of UV.\nIt's U component will be set to the number specified by Reference Point UV.\nThis point index is related to the start point of reference edge.",
|
||||
min=2, # 0 and 1 is invalid. we can not order the reference edge to be set on the outside of uv axis
|
||||
soft_min=2, soft_max=3,
|
||||
default=2,
|
||||
)
|
||||
|
||||
reference_uv : bpy.props.FloatProperty(
|
||||
name="Reference Point UV",
|
||||
description="The U component which should be applied to references point in UV.",
|
||||
soft_min=0, soft_max=1,
|
||||
default=0.5,
|
||||
step=0.1, precision=2,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -42,26 +71,38 @@ class BALLANCE_OT_flatten_uv(bpy.types.Operator):
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_scale_correction(self):
|
||||
if self.scale_correction == 'NORMAL':
|
||||
return BALLANCE_OT_flatten_uv.normal_scale_correction
|
||||
elif self.scale_correction == 'SINK':
|
||||
return BALLANCE_OT_flatten_uv.sink_scale_correction
|
||||
else:
|
||||
raise Exception("Unknow scale correction.")
|
||||
|
||||
def execute(self, context):
|
||||
no_processed_count = _real_flatten_uv(bpy.context.active_object.data, self.reference_edge, self.get_scale_correction())
|
||||
# construct scale data
|
||||
scale_data: ScaleDataUnion = ScaleDataUnion()
|
||||
if self.scale_mode == 'NUM':
|
||||
scale_data.SetAsScale(self.scale_number)
|
||||
else:
|
||||
scale_data.SetAsRefPoint(self.reference_point, self.reference_uv)
|
||||
|
||||
# do flatten uv and report
|
||||
no_processed_count = _real_flatten_uv(bpy.context.active_object.data, self.reference_edge, scale_data)
|
||||
if no_processed_count != 0:
|
||||
print("[Flatten UV] {} faces may not be processed correctly because they have problem.".format(no_processed_count))
|
||||
return {'FINISHED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.prop(self, "scale_correction")
|
||||
layout.emboss = 'NORMAL'
|
||||
layout.prop(self, "reference_edge")
|
||||
|
||||
def _real_flatten_uv(mesh, reference_edge, scale_correction):
|
||||
layout.separator()
|
||||
layout.label(text="Scale Mode")
|
||||
layout.prop(self, "scale_mode", expand=True)
|
||||
|
||||
layout.separator()
|
||||
layout.label(text="Scale Config")
|
||||
if self.scale_mode == 'NUM':
|
||||
layout.prop(self, "scale_number")
|
||||
else:
|
||||
layout.prop(self, "reference_point")
|
||||
layout.prop(self, "reference_uv")
|
||||
|
||||
def _real_flatten_uv(mesh, reference_edge, scale_data: ScaleDataUnion):
|
||||
no_processed_count = 0
|
||||
|
||||
if mesh.uv_layers.active is None:
|
||||
@ -69,18 +110,31 @@ def _real_flatten_uv(mesh, reference_edge, scale_correction):
|
||||
mesh.uv_layers.new(do_init=False)
|
||||
|
||||
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:
|
||||
# ========== only process selected face ==========
|
||||
if not face.select:
|
||||
continue
|
||||
|
||||
# check whether ref edge is legal
|
||||
# ========== resolve reference edge and point ==========
|
||||
# check reference validation
|
||||
allPoint = len(face.loops)
|
||||
if allPoint <= reference_edge:
|
||||
no_processed_count+=1
|
||||
if reference_edge >= allPoint: # reference edge overflow
|
||||
no_processed_count += 1
|
||||
continue
|
||||
|
||||
# get correct new corrdinate system
|
||||
# check scale validation
|
||||
if scale_data.UseRefPoint:
|
||||
if ((scale_data.ReferencePoint <= 1) # reference point too low
|
||||
or (scale_data.ReferencePoint >= allPoint)): # reference point overflow
|
||||
no_processed_count += 1
|
||||
continue
|
||||
else:
|
||||
if round(scale_data.ScaleSize, 7) == 0.0: # invalid scale size
|
||||
no_processed_count += 1
|
||||
continue
|
||||
|
||||
# ========== get correct new corrdinate system ==========
|
||||
# yyc mark:
|
||||
# we use 3 points located in this face to calc
|
||||
# the base of this local uv corredinate system.
|
||||
@ -90,7 +144,7 @@ def _real_flatten_uv(mesh, reference_edge, scale_correction):
|
||||
# if z axis is zero vector, we will try using face normal instead
|
||||
# to try getting correct data.
|
||||
#
|
||||
# zero base is not important. because it will not raise any math exceptio
|
||||
# zero base is not important. because it will not raise any math exception
|
||||
# just a weird uv. user will notice this problem.
|
||||
|
||||
# get point
|
||||
@ -102,9 +156,9 @@ def _real_flatten_uv(mesh, reference_edge, scale_correction):
|
||||
if p3Relative >= allPoint:
|
||||
p3Relative -= allPoint
|
||||
|
||||
p1=mathutils.Vector(tuple(face.loops[p1Relative].vert.co[x] for x in range(3)))
|
||||
p2=mathutils.Vector(tuple(face.loops[p2Relative].vert.co[x] for x in range(3)))
|
||||
p3=mathutils.Vector(tuple(face.loops[p3Relative].vert.co[x] for x in range(3)))
|
||||
p1 = mathutils.Vector(tuple(face.loops[p1Relative].vert.co[x] for x in range(3)))
|
||||
p2 = mathutils.Vector(tuple(face.loops[p2Relative].vert.co[x] for x in range(3)))
|
||||
p3 = mathutils.Vector(tuple(face.loops[p3Relative].vert.co[x] for x in range(3)))
|
||||
|
||||
# get y axis
|
||||
new_y_axis = p2 - p1
|
||||
@ -115,7 +169,7 @@ def _real_flatten_uv(mesh, reference_edge, scale_correction):
|
||||
# get z axis
|
||||
new_z_axis = new_y_axis.cross(vec1)
|
||||
new_z_axis.normalize()
|
||||
if not any(round(v, 7) for v in new_z_axis):
|
||||
if not any(round(v, 7) for v in new_z_axis): # if z is a zero vector, use face normal instead
|
||||
new_z_axis = face.normal.normalized()
|
||||
|
||||
# get x axis
|
||||
@ -137,21 +191,50 @@ def _real_flatten_uv(mesh, reference_edge, scale_correction):
|
||||
transition_matrix = origin_base @ new_base
|
||||
transition_matrix.invert_safe()
|
||||
|
||||
# process each face
|
||||
# ========== rescale correction ==========
|
||||
if scale_data.UseRefPoint:
|
||||
# ref point method
|
||||
# get reference point from loop
|
||||
refpRelative = p1Relative + scale_data.ReferencePoint
|
||||
if refpRelative >= allPoint:
|
||||
refpRelative -= allPoint
|
||||
pRef = mathutils.Vector(tuple(face.loops[refpRelative].vert.co[x] for x in range(3))) - p1
|
||||
|
||||
# calc its U component
|
||||
vec_u = abs((transition_matrix @ pRef).x)
|
||||
if round(vec_u, 7) == 0.0:
|
||||
rescale = 1 # fallback. rescale = 1 will not affect anything
|
||||
else:
|
||||
rescale = scale_data.ReferenceUV / vec_u
|
||||
else:
|
||||
# scale size method
|
||||
# apply rescale directly
|
||||
rescale = 1.0 / scale_data.ScaleSize
|
||||
|
||||
# construct matrix
|
||||
# we only rescale U component (X component)
|
||||
# and 5.0 scale for V component (Y component)
|
||||
scale_matrix = mathutils.Matrix((
|
||||
(rescale, 0, 0),
|
||||
(0, 1.0 / 5.0, 0),
|
||||
(0, 0, 1.0)
|
||||
))
|
||||
# order can not be changed. we order do transition first, then scale it.
|
||||
rescale_transition_matrix = scale_matrix @ transition_matrix
|
||||
|
||||
# ========== process each face ==========
|
||||
for loop_index in range(allPoint):
|
||||
pp = mathutils.Vector(tuple(face.loops[loop_index].vert.co[x] for x in range(3)))
|
||||
vec = pp-p1
|
||||
new_vec = transition_matrix @ vec
|
||||
pp = mathutils.Vector(tuple(face.loops[loop_index].vert.co[x] for x in range(3))) - p1
|
||||
ppuv = rescale_transition_matrix @ pp
|
||||
|
||||
# y axis always use 5.0 to scale
|
||||
# however, x need use custom scale correction.
|
||||
# however, x need use custom scale correction which has been calculated by our matrix.
|
||||
face.loops[loop_index][uv_lay].uv = (
|
||||
(new_vec.x if new_vec.x >=0 else -new_vec.x) / scale_correction,
|
||||
(new_vec.y) / 5.0
|
||||
abs(ppuv.x),
|
||||
ppuv.y
|
||||
)
|
||||
|
||||
# Show the updates in the viewport
|
||||
bmesh.update_edit_mesh(mesh)
|
||||
|
||||
return no_processed_count
|
||||
|
||||
|
@ -141,15 +141,17 @@ def _create_rail_uv(rail_type, material_pointer, scale_size, projection_axis):
|
||||
)
|
||||
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 loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total):
|
||||
# get correspond vec index
|
||||
index = mesh.loops[loop_index].vertex_index
|
||||
if rail_type == 'POINT':
|
||||
# set to 1 point
|
||||
uv_layer[loop_index].uv[0] = 0
|
||||
uv_layer[loop_index].uv[1] = 1
|
||||
uv_layer[loop_index].vector[0] = 0
|
||||
uv_layer[loop_index].vector[1] = 1
|
||||
elif rail_type == 'SCALE' or rail_type == 'UNIFORM':
|
||||
# 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 Y axis: X->U Z->V
|
||||
if projection_axis == 'X':
|
||||
uv_layer[loop_index].uv[0] = vecList[index].co[1] * real_scale
|
||||
uv_layer[loop_index].uv[1] = vecList[index].co[2] * real_scale
|
||||
uv_layer[loop_index].vector[0] = vecList[index].co[1] * real_scale
|
||||
uv_layer[loop_index].vector[1] = vecList[index].co[2] * real_scale
|
||||
elif projection_axis == 'Y':
|
||||
uv_layer[loop_index].uv[0] = vecList[index].co[0] * real_scale
|
||||
uv_layer[loop_index].uv[1] = vecList[index].co[2] * real_scale
|
||||
uv_layer[loop_index].vector[0] = vecList[index].co[0] * real_scale
|
||||
uv_layer[loop_index].vector[1] = vecList[index].co[2] * real_scale
|
||||
elif projection_axis == 'Z':
|
||||
uv_layer[loop_index].uv[0] = vecList[index].co[0] * real_scale
|
||||
uv_layer[loop_index].uv[1] = vecList[index].co[1] * real_scale
|
||||
uv_layer[loop_index].vector[0] = vecList[index].co[0] * real_scale
|
||||
uv_layer[loop_index].vector[1] = vecList[index].co[1] * real_scale
|
||||
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,
|
||||
mesh.loops[loop_index].normal,
|
||||
(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.loops, "vertex_index", global_offset_loops, faceList)
|
||||
_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
|
||||
for i in range(len(faceMatList)):
|
||||
indCount = faceIndList[i]
|
||||
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].use_smooth = True
|
||||
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)))
|
||||
for i in range(len(faceList)):
|
||||
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.validate(clean_customdata=False)
|
||||
|
@ -2,10 +2,10 @@ bl_info={
|
||||
"name":"Ballance Blender Plugin",
|
||||
"description":"Ballance mapping tools for Blender",
|
||||
"author":"yyc12345",
|
||||
"version":(3,1),
|
||||
"blender":(3,3,0),
|
||||
"version":(3,3),
|
||||
"blender":(3,6,0),
|
||||
"category":"Object",
|
||||
"support":"TESTING",
|
||||
"support":"COMMUNITY",
|
||||
"warning": "Please read document before using this plugin.",
|
||||
"wiki_url": "https://github.com/yyc12345/BallanceBlenderHelper",
|
||||
"tracker_url": "https://github.com/yyc12345/BallanceBlenderHelper/issues"
|
||||
|
Reference in New Issue
Block a user