finish bme
This commit is contained in:
parent
6bc3933291
commit
35f2c4a389
@ -156,7 +156,30 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
|
|||||||
return self.execute(context)
|
return self.execute(context)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
# todo: call general creator
|
# collect cfgs data
|
||||||
|
cfgs: dict[str, typing.Any] = {}
|
||||||
|
for (cfg, cfg_index) in self.bme_struct_cfg_index_cache:
|
||||||
|
match(cfg.get_type()):
|
||||||
|
case UTIL_bme.PrototypeShowcaseCfgsTypes.Integer:
|
||||||
|
cfgs[cfg.get_field()] = self.bme_struct_cfgs[cfg_index].prop_int
|
||||||
|
case UTIL_bme.PrototypeShowcaseCfgsTypes.Float:
|
||||||
|
cfgs[cfg.get_field()] = self.bme_struct_cfgs[cfg_index].prop_float
|
||||||
|
case UTIL_bme.PrototypeShowcaseCfgsTypes.Boolean:
|
||||||
|
cfgs[cfg.get_field()] = self.bme_struct_cfgs[cfg_index].prop_bool
|
||||||
|
case UTIL_bme.PrototypeShowcaseCfgsTypes.Face:
|
||||||
|
# face is just 6 bool tuple
|
||||||
|
cfgs[cfg.get_field()] = tuple(
|
||||||
|
self.bme_struct_cfgs[cfg_index + i].prop_bool for i in range(6)
|
||||||
|
)
|
||||||
|
|
||||||
|
# call general creator
|
||||||
|
obj: bpy.types.Object = UTIL_bme.create_bme_struct_wrapper(
|
||||||
|
_g_EnumHelper_BmeStructType.get_selection(self.bme_struct_type),
|
||||||
|
cfgs
|
||||||
|
)
|
||||||
|
|
||||||
|
# move to cursor
|
||||||
|
UTIL_functions.add_into_scene_and_move_to_cursor(obj)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
@ -106,6 +106,9 @@ def _load_bme_material_preset(mtl: bpy.types.Material, preset_name: str) -> None
|
|||||||
newrawmtl.mTexture = blctex
|
newrawmtl.mTexture = blctex
|
||||||
PROP_virtools_material.set_raw_virtools_material(mtl, newrawmtl)
|
PROP_virtools_material.set_raw_virtools_material(mtl, newrawmtl)
|
||||||
|
|
||||||
|
# apply vt mtl to blender mtl
|
||||||
|
PROP_virtools_material.apply_to_blender_material(mtl)
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region BME Material Operation Help Class & Functions
|
#region BME Material Operation Help Class & Functions
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import bpy, mathutils
|
import bpy, mathutils
|
||||||
import os, json, enum, typing, math
|
import os, json, enum, typing, math
|
||||||
from . import PROP_virtools_group, PROP_bme_material
|
from . import PROP_virtools_group, PROP_bme_material
|
||||||
from . import UTIL_functions, UTIL_icons_manager, UTIL_blender_mesh
|
from . import UTIL_functions, UTIL_icons_manager, UTIL_blender_mesh, UTIL_virtools_types, UTIL_naming_convension
|
||||||
|
|
||||||
## NOTE: Outside caller should use BME struct's unique indetifier to visit each prototype
|
## NOTE: Outside caller should use BME struct's unique indetifier to visit each prototype
|
||||||
# and drive this class' functions to work.
|
# and drive this class' functions to work.
|
||||||
@ -130,7 +130,7 @@ def _eval_params(strl: str, cfgs_data: dict[str, typing.Any]) -> typing.Any:
|
|||||||
def _eval_vars(strl: str, params_data: dict[str, typing.Any]) -> typing.Any:
|
def _eval_vars(strl: str, params_data: dict[str, typing.Any]) -> typing.Any:
|
||||||
return eval(strl, _g_ProgFieldGlobals, params_data)
|
return eval(strl, _g_ProgFieldGlobals, params_data)
|
||||||
|
|
||||||
def _eval_others(strl, str, params_vars_data: dict[str, typing.Any]) -> typing.Any:
|
def _eval_others(strl: str, params_vars_data: dict[str, typing.Any]) -> typing.Any:
|
||||||
return eval(strl, _g_ProgFieldGlobals, params_vars_data)
|
return eval(strl, _g_ProgFieldGlobals, params_vars_data)
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -216,13 +216,182 @@ class EnumPropHelper(UTIL_functions.EnumPropHelper):
|
|||||||
|
|
||||||
#region Core Creator
|
#region Core Creator
|
||||||
|
|
||||||
def get_bme_struct_cfgs():
|
def create_bme_struct_wrapper(ident: str, cfgs: dict[str, typing.Any]) -> bpy.types.Object:
|
||||||
pass
|
# get prototype first
|
||||||
|
proto: dict[str, typing.Any] = _get_prototype_by_identifier(ident)
|
||||||
|
|
||||||
def create_bme_struct_wrapper():
|
# analyse params by given cfgs
|
||||||
pass
|
params: dict[str, typing.Any] = {}
|
||||||
|
for proto_param in proto[TOKEN_PARAMS]:
|
||||||
|
params[proto_param[TOKEN_PARAMS_FIELD]] = _eval_params(proto_param[TOKEN_PARAMS_DATA], cfgs)
|
||||||
|
|
||||||
def create_bme_struct():
|
# create used mesh
|
||||||
pass
|
mesh: bpy.types.Mesh = bpy.data.meshes.new('BMEStruct')
|
||||||
|
|
||||||
|
# create mesh writer and bme mtl helper
|
||||||
|
# recursively calling underlying creation function
|
||||||
|
with UTIL_blender_mesh.MeshWriter(mesh) as writer:
|
||||||
|
with PROP_bme_material.BMEMaterialsHelper(bpy.context.scene) as bmemtl:
|
||||||
|
create_bme_struct(
|
||||||
|
ident,
|
||||||
|
writer,
|
||||||
|
bmemtl,
|
||||||
|
mathutils.Matrix.Identity(4),
|
||||||
|
params
|
||||||
|
)
|
||||||
|
|
||||||
|
# create object and assign prop
|
||||||
|
# get obj info first
|
||||||
|
obj_info: UTIL_naming_convension.BallanceObjectInfo
|
||||||
|
match(PrototypeShowcaseTypes(proto[TOKEN_SHOWCASE][TOKEN_SHOWCASE_TYPE])):
|
||||||
|
case PrototypeShowcaseTypes.No:
|
||||||
|
obj_info = UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.DECORATION)
|
||||||
|
case PrototypeShowcaseTypes.Floor:
|
||||||
|
obj_info = UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.FLOOR)
|
||||||
|
case PrototypeShowcaseTypes.Rail:
|
||||||
|
obj_info = UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.RAIL)
|
||||||
|
case PrototypeShowcaseTypes.Wood:
|
||||||
|
obj_info = UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.WOOD)
|
||||||
|
# then get object name
|
||||||
|
obj_name: str | None = UTIL_naming_convension.YYCToolchainConvention.set_to_name(obj_info, None)
|
||||||
|
if obj_name is None: raise UTIL_functions.BBPException('impossible null name')
|
||||||
|
# create object by name
|
||||||
|
obj: bpy.types.Object = bpy.data.objects.new(obj_name, mesh)
|
||||||
|
# assign virtools groups
|
||||||
|
UTIL_naming_convension.VirtoolsGroupConvention.set_to_object(obj, obj_info, None)
|
||||||
|
|
||||||
|
# return object
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def create_bme_struct(
|
||||||
|
ident: str,
|
||||||
|
writer: UTIL_blender_mesh.MeshWriter,
|
||||||
|
bmemtl: PROP_bme_material.BMEMaterialsHelper,
|
||||||
|
transform: mathutils.Matrix,
|
||||||
|
params: dict[str, typing.Any]) -> None:
|
||||||
|
# get prototype first
|
||||||
|
proto: dict[str, typing.Any] = _get_prototype_by_identifier(ident)
|
||||||
|
|
||||||
|
# calc vars by given params
|
||||||
|
# please note i will add entries directly into params dict
|
||||||
|
# but the params dict will not used independently later,
|
||||||
|
# all following use is the union of params and vars dict.
|
||||||
|
# so it is safe.
|
||||||
|
for proto_var in proto[TOKEN_VARS]:
|
||||||
|
params[proto_var[TOKEN_VARS_FIELD]] = _eval_vars(proto_var[TOKEN_VARS_DATA], params)
|
||||||
|
|
||||||
|
# collect valid face and vertices data for following using.
|
||||||
|
# if NOT skip, add into valid list
|
||||||
|
valid_vec_idx: list[int] = []
|
||||||
|
for vec_idx, proto_vec in enumerate(proto[TOKEN_VERTICES]):
|
||||||
|
if not _eval_others(proto_vec[TOKEN_VERTICES_SKIP], params):
|
||||||
|
valid_vec_idx.append(vec_idx)
|
||||||
|
valid_face_idx: list[int] = []
|
||||||
|
for face_idx, proto_face in enumerate(proto[TOKEN_FACES]):
|
||||||
|
if not _eval_others(proto_face[TOKEN_FACES_SKIP], params):
|
||||||
|
valid_face_idx.append(face_idx)
|
||||||
|
|
||||||
|
# create mtl slot remap to help following mesh adding
|
||||||
|
# because mesh writer do not accept string format mtl slot visiting,
|
||||||
|
# it only accept int based mtl slot index.
|
||||||
|
# NOTE: since Python 3.6, the item of builtin dict is ordered by inserting order.
|
||||||
|
# we rely on this to implement following features
|
||||||
|
mtl_remap: dict[str, int] = {}
|
||||||
|
for face_idx in valid_face_idx:
|
||||||
|
# eval mtl name
|
||||||
|
mtl_name: str = _eval_others(proto[TOKEN_FACES][face_idx][TOKEN_FACES_TEXTURE], params)
|
||||||
|
# add into remap if not exist
|
||||||
|
if mtl_name not in mtl_remap:
|
||||||
|
mtl_remap[mtl_name] = len(mtl_remap)
|
||||||
|
|
||||||
|
# prepare mesh part data
|
||||||
|
mesh_part: UTIL_blender_mesh.MeshWriterIngredient = UTIL_blender_mesh.MeshWriterIngredient()
|
||||||
|
def vpos_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector3]:
|
||||||
|
v: UTIL_virtools_types.VxVector3 = UTIL_virtools_types.VxVector3()
|
||||||
|
for vec_idx in valid_vec_idx:
|
||||||
|
# BME no need to convert co system
|
||||||
|
v.x, v.y, v.z = _eval_others(proto[TOKEN_VERTICES][vec_idx][TOKEN_VERTICES_DATA], params)
|
||||||
|
yield v
|
||||||
|
mesh_part.mVertexPosition = vpos_iterator()
|
||||||
|
def vnml_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector3]:
|
||||||
|
v: UTIL_virtools_types.VxVector3 = UTIL_virtools_types.VxVector3()
|
||||||
|
for face_idx in valid_face_idx:
|
||||||
|
face_data: dict[str, typing.Any] = proto[TOKEN_FACES][face_idx]
|
||||||
|
for i in range(len(face_data[TOKEN_FACES_INDICES])):
|
||||||
|
v.x, v.y, v.z = _eval_others(face_data[TOKEN_FACES_NORMALS][i], params)
|
||||||
|
# BME normals need normalize
|
||||||
|
UTIL_virtools_types.vxvector3_normalize(v)
|
||||||
|
yield v
|
||||||
|
mesh_part.mVertexNormal = vnml_iterator()
|
||||||
|
def vuv_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector2]:
|
||||||
|
v: UTIL_virtools_types.VxVector2 = UTIL_virtools_types.VxVector2()
|
||||||
|
for face_idx in valid_face_idx:
|
||||||
|
face_data: dict[str, typing.Any] = proto[TOKEN_FACES][face_idx]
|
||||||
|
for i in range(len(face_data[TOKEN_FACES_INDICES])):
|
||||||
|
v.x, v.y = _eval_others(face_data[TOKEN_FACES_UVS][i], params)
|
||||||
|
yield v
|
||||||
|
mesh_part.mVertexUV = vuv_iterator()
|
||||||
|
def mtl_iterator() -> typing.Iterator[bpy.types.Material | None]:
|
||||||
|
for mtl_name in mtl_remap.keys():
|
||||||
|
yield bmemtl.get_material(mtl_name)
|
||||||
|
mesh_part.mMaterial = mtl_iterator()
|
||||||
|
def face_iterator() -> typing.Iterator[UTIL_blender_mesh.FaceData]:
|
||||||
|
# create face data with 3 placeholder
|
||||||
|
f: UTIL_blender_mesh.FaceData = UTIL_blender_mesh.FaceData(
|
||||||
|
[UTIL_blender_mesh.FaceVertexData() for i in range(3)]
|
||||||
|
)
|
||||||
|
|
||||||
|
# create a internal counter to count how many indices has been processed
|
||||||
|
# this counter will be used to calc uv and normal index
|
||||||
|
# because these are based on face, not vertex position index.
|
||||||
|
face_counter: int = 0
|
||||||
|
|
||||||
|
# iterate valid face
|
||||||
|
for face_idx in valid_face_idx:
|
||||||
|
# get face data
|
||||||
|
face_data: dict[str, typing.Any] = proto[TOKEN_FACES][face_idx]
|
||||||
|
|
||||||
|
# calc indices count
|
||||||
|
face_indices: list[int] = face_data[TOKEN_FACES_INDICES]
|
||||||
|
indices_count: int = len(face_indices)
|
||||||
|
# resize face data to fulfill req
|
||||||
|
while len(f.mIndices) > indices_count:
|
||||||
|
f.mIndices.pop()
|
||||||
|
while len(f.mIndices) < indices_count:
|
||||||
|
f.mIndices.append(UTIL_blender_mesh.FaceVertexData())
|
||||||
|
|
||||||
|
# fill the data
|
||||||
|
for i in range(indices_count):
|
||||||
|
# fill vertex position data by indices
|
||||||
|
f.mIndices[i].mPosIdx = face_indices[i]
|
||||||
|
# fill nml and uv based on face index
|
||||||
|
f.mIndices[i].mNmlIdx = face_counter + i
|
||||||
|
f.mIndices[i].mUvIdx = face_counter + i
|
||||||
|
|
||||||
|
# add current face indices count to internal counter
|
||||||
|
face_counter += indices_count
|
||||||
|
|
||||||
|
# return data once
|
||||||
|
yield f
|
||||||
|
mesh_part.mFace = face_iterator()
|
||||||
|
# add part to writer
|
||||||
|
writer.add_ingredient(mesh_part)
|
||||||
|
|
||||||
|
# then we incursively process instance creation
|
||||||
|
for proto_instance in proto[TOKEN_INSTANCES]:
|
||||||
|
# calc instance params
|
||||||
|
instance_params: dict[str, typing.Any] = {}
|
||||||
|
proto_instance_params: dict[str, str] = proto_instance[TOKEN_INSTANCES_PARAMS]
|
||||||
|
for proto_inst_param_field, proto_inst_param_data in proto_instance_params.items():
|
||||||
|
instance_params[proto_inst_param_field] = _eval_others(proto_inst_param_data, params)
|
||||||
|
|
||||||
|
# call recursively
|
||||||
|
create_bme_struct(
|
||||||
|
proto_instance[TOKEN_INSTANCES_IDENTIFIER],
|
||||||
|
writer,
|
||||||
|
bmemtl,
|
||||||
|
_eval_others(proto_instance[TOKEN_INSTANCES_TRANSFORM], params),
|
||||||
|
instance_params
|
||||||
|
)
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -27,6 +27,14 @@ def vxvector3_conv_co(self: VxVector3) -> None:
|
|||||||
"""
|
"""
|
||||||
self.y, self.z = self.z, self.y
|
self.y, self.z = self.z, self.y
|
||||||
|
|
||||||
|
def vxvector3_normalize(self: VxVector3) -> None:
|
||||||
|
"""
|
||||||
|
Normalize given Vector
|
||||||
|
"""
|
||||||
|
cache: mathutils.Vector = mathutils.Vector((self.x, self.y, self.z))
|
||||||
|
cache.normalize()
|
||||||
|
self.x, self.y, self.z = cache.x, cache.y, cache.z
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region VxMatrix Patch
|
#region VxMatrix Patch
|
||||||
|
Loading…
Reference in New Issue
Block a user