1 Commits

Author SHA1 Message Date
f29e4e9478 feat: support macos arm64 arch 2025-08-04 11:17:46 +08:00
149 changed files with 5302 additions and 10365 deletions

11
.gitattributes vendored
View File

@ -1,6 +1,7 @@
# All PNG image are binary # all png are binary
*.png binary *.png binary
# Element placeholder mesh should be save as binary # our generated mesh should be save as binary
*.ph binary *.bin binary
# Raw json data should be binary, although i edit it manually # the raw json data should be binary
assets/jsons/*.json binary # although i edit it manually
bbp_ng/raw_jsons/*.json binary

4
.gitignore vendored
View File

@ -1,3 +1,3 @@
## ===== Personal ===== ## ===== Personal =====
# Disable VSCode # Disable distribution build folder
.vscode/ redist/

13
bbp_ng/.gitignore vendored
View File

@ -1,15 +1,20 @@
## ===== Personal ===== ## ===== Personal =====
# Do not include PyBMap in this repository. # Do not include PyBMap in this repository.
# Order user build and fetch it manually. # Order build fetch it manually.
PyBMap/ PyBMap/
# Disable generated assets but keep the directory hierarchy. # Disable generated icons and jsons but keep the directory hierarchy.
icons/* icons/*
!icons/.gitkeep !icons/.gitkeep
jsons/* jsons/*
!jsons/.gitkeep !jsons/.gitkeep
meshes/*
!meshes/.gitkeep # Do not include intermidiate translation template (POT)
# NOTE: it seems that Python default gitignore (written following) disable POT file in default.
# so, as it wish, I also remove it from git.
i18n/*
!i18n/blender.pot
!i18n/*.po
## ===== Python ===== ## ===== Python =====
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files

View File

@ -1,6 +1,6 @@
import bpy, mathutils import bpy, mathutils
import math, typing import math, typing
from . import UTIL_functions, UTIL_icons_manager, UTIL_naming_convention from . import UTIL_functions, UTIL_icons_manager, UTIL_naming_convension
from . import PROP_ballance_element, PROP_virtools_group, PROP_ballance_map_info from . import PROP_ballance_element, PROP_virtools_group, PROP_ballance_map_info
#region Param Help Classes #region Param Help Classes
@ -41,33 +41,33 @@ class ComponentCountParam():
#region Help Classes & Functions #region Help Classes & Functions
def _get_component_info(comp_type: PROP_ballance_element.BallanceElementType, comp_sector: int) -> UTIL_naming_convention.BallanceObjectInfo: def _get_component_info(comp_type: PROP_ballance_element.BallanceElementType, comp_sector: int) -> UTIL_naming_convension.BallanceObjectInfo:
match(comp_type): match(comp_type):
# process for 2 special unique components # process for 2 special unique components
case PROP_ballance_element.BallanceElementType.PS_FourFlames: case PROP_ballance_element.BallanceElementType.PS_FourFlames:
return UTIL_naming_convention.BallanceObjectInfo.create_from_others(UTIL_naming_convention.BallanceObjectType.LEVEL_START) return UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.LEVEL_START)
case PROP_ballance_element.BallanceElementType.PE_Balloon: case PROP_ballance_element.BallanceElementType.PE_Balloon:
return UTIL_naming_convention.BallanceObjectInfo.create_from_others(UTIL_naming_convention.BallanceObjectType.LEVEL_END) return UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.LEVEL_END)
# process naming convention required special components # process naming convention required special components
case PROP_ballance_element.BallanceElementType.PC_TwoFlames: case PROP_ballance_element.BallanceElementType.PC_TwoFlames:
return UTIL_naming_convention.BallanceObjectInfo.create_from_checkpoint(comp_sector) return UTIL_naming_convension.BallanceObjectInfo.create_from_checkpoint(comp_sector)
case PROP_ballance_element.BallanceElementType.PR_Resetpoint: case PROP_ballance_element.BallanceElementType.PR_Resetpoint:
return UTIL_naming_convention.BallanceObjectInfo.create_from_resetpoint(comp_sector) return UTIL_naming_convension.BallanceObjectInfo.create_from_resetpoint(comp_sector)
# process for other components # process for other components
case _: case _:
return UTIL_naming_convention.BallanceObjectInfo.create_from_component( return UTIL_naming_convension.BallanceObjectInfo.create_from_component(
PROP_ballance_element.get_ballance_element_name(comp_type), PROP_ballance_element.get_ballance_element_name(comp_type),
comp_sector comp_sector
) )
def _set_component_by_info(obj: bpy.types.Object, info: UTIL_naming_convention.BallanceObjectInfo) -> None: def _set_component_by_info(obj: bpy.types.Object, info: UTIL_naming_convension.BallanceObjectInfo) -> None:
# set component name and grouping it into virtools group at the same time # set component name and grouping it into virtools group at the same time
# set name first # set name first
if not UTIL_naming_convention.YYCToolchainConvention.set_to_object(obj, info, None): if not UTIL_naming_convension.YYCToolchainConvention.set_to_object(obj, info, None):
raise UTIL_functions.BBPException('impossible fail to set component name.') raise UTIL_functions.BBPException('impossible fail to set component name.')
# set vt group next # set vt group next
if not UTIL_naming_convention.VirtoolsGroupConvention.set_to_object(obj, info, None): if not UTIL_naming_convension.VirtoolsGroupConvention.set_to_object(obj, info, None):
raise UTIL_functions.BBPException('impossible fail to set component virtools groups.') raise UTIL_functions.BBPException('impossible fail to set component virtools groups.')
def _check_component_existance(comp_type: PROP_ballance_element.BallanceElementType, comp_sector: int) -> str | None: def _check_component_existance(comp_type: PROP_ballance_element.BallanceElementType, comp_sector: int) -> str | None:
@ -85,10 +85,10 @@ def _check_component_existance(comp_type: PROP_ballance_element.BallanceElementT
return None # return, do not check return None # return, do not check
# get info # get info
comp_info: UTIL_naming_convention.BallanceObjectInfo = _get_component_info(comp_type, comp_sector) comp_info: UTIL_naming_convension.BallanceObjectInfo = _get_component_info(comp_type, comp_sector)
# get expected name # get expected name
expect_name: str | None = UTIL_naming_convention.YYCToolchainConvention.set_to_name(comp_info, None) expect_name: str | None = UTIL_naming_convension.YYCToolchainConvention.set_to_name(comp_info, None)
if expect_name is None: if expect_name is None:
raise UTIL_functions.BBPException('impossible fail to get component name.') raise UTIL_functions.BBPException('impossible fail to get component name.')
@ -129,7 +129,7 @@ class _GeneralComponentCreator():
@return The created component instance. @return The created component instance.
""" """
# get element info first # get element info first
ele_info: UTIL_naming_convention.BallanceObjectInfo = _get_component_info(comp_type, comp_sector) ele_info: UTIL_naming_convension.BallanceObjectInfo = _get_component_info(comp_type, comp_sector)
# create blc element context # create blc element context
with PROP_ballance_element.BallanceElementsHelper(bpy.context.scene) as creator: with PROP_ballance_element.BallanceElementsHelper(bpy.context.scene) as creator:
@ -152,12 +152,12 @@ class _GeneralComponentCreator():
enlarged_sector: int enlarged_sector: int
# check component type to get enlarged value # check component type to get enlarged value
match(ele_info.mBasicType): match(ele_info.mBasicType):
case UTIL_naming_convention.BallanceObjectType.COMPONENT: case UTIL_naming_convension.BallanceObjectType.COMPONENT:
enlarged_sector = comp_sector enlarged_sector = comp_sector
case UTIL_naming_convention.BallanceObjectType.CHECKPOINT: case UTIL_naming_convension.BallanceObjectType.CHECKPOINT:
# checkpoint 1 means that there is sector 2, so we plus 1 for it. # checkpoint 1 means that there is sector 2, so we plus 1 for it.
enlarged_sector = comp_sector + 1 enlarged_sector = comp_sector + 1
case UTIL_naming_convention.BallanceObjectType.RESETPOINT: case UTIL_naming_convension.BallanceObjectType.RESETPOINT:
enlarged_sector = comp_sector enlarged_sector = comp_sector
case _: case _:
# this component is not a sector based component # this component is not a sector based component
@ -574,17 +574,14 @@ class BBP_OT_add_sector_component_pair(bpy.types.Operator, ComponentSectorParam)
# get type and sector data first # get type and sector data first
(checkp_ty, checkp_sector) = self.__get_checkpoint() (checkp_ty, checkp_sector) = self.__get_checkpoint()
(resetp_ty, resetp_sector) = self.__get_resetpoint() (resetp_ty, resetp_sector) = self.__get_resetpoint()
# calc resetpoint offset and checkpoint rotation # calc resetpoint offset
# resetpoint need a extra offset between checkpoint but it is different in FourFlams and TwoFlams. # resetpoint need a extra offset between checkpoint
# 4 flames startpoint need a extra 90 degree rotation to correspond with ballance asset library (and the direction of resetpoint). # but it is different in FourFlams and TwoFlams
resetp_offset: float resetp_offset: float
checkp_degree: float
if checkp_ty == PROP_ballance_element.BallanceElementType.PS_FourFlames: if checkp_ty == PROP_ballance_element.BallanceElementType.PS_FourFlames:
resetp_offset = 3.65 resetp_offset = 3.25
checkp_degree = 90
else: else:
resetp_offset = 3.3258 resetp_offset = 2.0
checkp_degree = 0
# add elements # add elements
# create checkpoint # create checkpoint
@ -593,7 +590,7 @@ class BBP_OT_add_sector_component_pair(bpy.types.Operator, ComponentSectorParam)
checkp_ty, checkp_ty,
checkp_sector, checkp_sector,
1, # only create one 1, # only create one
lambda _: mathutils.Matrix.Rotation(math.radians(checkp_degree), 4, 'Z') lambda _: mathutils.Matrix.Identity(4)
) )
# create resetpoint # create resetpoint
creator.create_component( creator.create_component(

View File

@ -1,8 +1,8 @@
import bpy, mathutils import bpy, mathutils
from bpy_extras.wm_utils.progress_report import ProgressReport from bpy_extras.wm_utils.progress_report import ProgressReport
import tempfile, os, typing import tempfile, os, typing
from . import PROP_preferences, UTIL_ioport_shared, UTIL_naming_convention from . import PROP_preferences, UTIL_ioport_shared
from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh, UTIL_ballance_texture from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh, UTIL_ballance_texture, UTIL_naming_convension
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture, PROP_virtools_light from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture, PROP_virtools_light
from .PyBMap import bmap_wrapper as bmap from .PyBMap import bmap_wrapper as bmap
@ -190,7 +190,7 @@ def _export_virtools_groups(
# So we create all needed sector group in here to make sure exported virtools file can be read by Ballancde correctly. # So we create all needed sector group in here to make sure exported virtools file can be read by Ballancde correctly.
if successive_sector: if successive_sector:
for i in range(successive_sector_count): for i in range(successive_sector_count):
gp_name: str = UTIL_naming_convention.build_name_from_sector_index(i + 1) gp_name: str = UTIL_naming_convension.build_name_from_sector_index(i + 1)
vtgroup: bmap.BMGroup | None = group_cret_map.get(gp_name, None) vtgroup: bmap.BMGroup | None = group_cret_map.get(gp_name, None)
if vtgroup is None: if vtgroup is None:
vtgroup = writer.create_group() vtgroup = writer.create_group()

View File

@ -1,8 +1,8 @@
import bpy, mathutils import bpy, mathutils
from bpy_extras.wm_utils.progress_report import ProgressReport from bpy_extras.wm_utils.progress_report import ProgressReport
import tempfile, os, typing import tempfile, os, typing
from . import PROP_preferences, UTIL_ioport_shared, UTIL_naming_convention from . import PROP_preferences, UTIL_ioport_shared
from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh, UTIL_ballance_texture from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh, UTIL_ballance_texture, UTIL_naming_convension
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture, PROP_virtools_light, PROP_ballance_map_info from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture, PROP_virtools_light, PROP_ballance_map_info
from .PyBMap import bmap_wrapper as bmap from .PyBMap import bmap_wrapper as bmap
@ -432,7 +432,7 @@ def _import_virtools_groups(
if group_name is None: continue if group_name is None: continue
# try extracting sector info # try extracting sector info
potential_sector_count: int | None = UTIL_naming_convention.extract_sector_from_name(group_name) potential_sector_count: int | None = UTIL_naming_convension.extract_sector_from_name(group_name)
if potential_sector_count is not None: if potential_sector_count is not None:
sector_count = max(sector_count, potential_sector_count) sector_count = max(sector_count, potential_sector_count)

View File

@ -2,12 +2,12 @@ import bpy
from . import UTIL_functions from . import UTIL_functions
from . import PROP_virtools_material, PROP_preferences from . import PROP_virtools_material, PROP_preferences
class BBP_OT_fix_all_materials(bpy.types.Operator): class BBP_OT_fix_all_material(bpy.types.Operator):
"""Fix All Materials by Its Referred Ballance Texture Name.""" """Fix All Materials by Its Referred Ballance Texture Name."""
bl_idname = "bbp.fix_all_materials" bl_idname = "bbp.fix_all_material"
bl_label = "Fix All Materials" bl_label = "Fix All Materials"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_fix_all_materials' bl_translation_context = 'BBP_OT_fix_all_material'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -31,12 +31,12 @@ class BBP_OT_fix_all_materials(bpy.types.Operator):
# report and return # report and return
tr_text: str = bpy.app.translations.pgettext_rpt( tr_text: str = bpy.app.translations.pgettext_rpt(
'Fix {0}/{1} materials.', 'BBP_OT_fix_all_materials/draw') 'Fix {0}/{1} materials.', 'BBP_OT_fix_all_material/draw')
self.report({'INFO'}, tr_text.format(counter_suc, counter_all)) self.report({'INFO'}, tr_text.format(counter_suc, counter_all))
return {'FINISHED'} return {'FINISHED'}
def register() -> None: def register() -> None:
bpy.utils.register_class(BBP_OT_fix_all_materials) bpy.utils.register_class(BBP_OT_fix_all_material)
def unregister() -> None: def unregister() -> None:
bpy.utils.unregister_class(BBP_OT_fix_all_materials) bpy.utils.unregister_class(BBP_OT_fix_all_material)

View File

@ -1,6 +1,6 @@
import bpy import bpy
import typing import typing
from . import UTIL_functions, UTIL_icons_manager, UTIL_naming_convention from . import UTIL_naming_convension, UTIL_functions, UTIL_icons_manager
class BBP_OT_regulate_objects_name(bpy.types.Operator): class BBP_OT_regulate_objects_name(bpy.types.Operator):
"""Regulate Objects Name by Virtools Group and Naming Convention""" """Regulate Objects Name by Virtools Group and Naming Convention"""
@ -15,8 +15,8 @@ class BBP_OT_regulate_objects_name(bpy.types.Operator):
def execute(self, context): def execute(self, context):
_rename_core( _rename_core(
UTIL_naming_convention.VirtoolsGroupConvention.parse_from_object, UTIL_naming_convension.VirtoolsGroupConvention.parse_from_object,
UTIL_naming_convention.YYCToolchainConvention.set_to_object UTIL_naming_convension.YYCToolchainConvention.set_to_object
) )
return {'FINISHED'} return {'FINISHED'}
@ -33,8 +33,8 @@ class BBP_OT_auto_grouping(bpy.types.Operator):
def execute(self, context): def execute(self, context):
_rename_core( _rename_core(
UTIL_naming_convention.YYCToolchainConvention.parse_from_object, UTIL_naming_convension.YYCToolchainConvention.parse_from_object,
UTIL_naming_convention.VirtoolsGroupConvention.set_to_object UTIL_naming_convension.VirtoolsGroupConvention.set_to_object
) )
return {'FINISHED'} return {'FINISHED'}
@ -51,26 +51,26 @@ class BBP_OT_convert_to_imengyu(bpy.types.Operator):
def execute(self, context): def execute(self, context):
_rename_core( _rename_core(
UTIL_naming_convention.YYCToolchainConvention.parse_from_object, UTIL_naming_convension.YYCToolchainConvention.parse_from_object,
UTIL_naming_convention.ImengyuConvention.set_to_object UTIL_naming_convension.ImengyuConvention.set_to_object
) )
return {'FINISHED'} return {'FINISHED'}
def _rename_core( def _rename_core(
fct_get_info: typing.Callable[[bpy.types.Object, UTIL_naming_convention.RenameErrorReporter], UTIL_naming_convention.BallanceObjectInfo | None], fct_get_info: typing.Callable[[bpy.types.Object, UTIL_naming_convension.RenameErrorReporter], UTIL_naming_convension.BallanceObjectInfo | None],
ftc_set_info: typing.Callable[[bpy.types.Object, UTIL_naming_convention.BallanceObjectInfo, UTIL_naming_convention.RenameErrorReporter], bool] ftc_set_info: typing.Callable[[bpy.types.Object, UTIL_naming_convension.BallanceObjectInfo, UTIL_naming_convension.RenameErrorReporter], bool]
) -> None: ) -> None:
# get selected objects. allow nested collection # get selected objects. allow nested collection
selected_objects: typing.Iterable[bpy.types.Object] = bpy.context.view_layer.active_layer_collection.collection.all_objects selected_objects: typing.Iterable[bpy.types.Object] = bpy.context.view_layer.active_layer_collection.collection.all_objects
# create reporter # create reporter
with UTIL_naming_convention.RenameErrorReporter() as reporter: with UTIL_naming_convension.RenameErrorReporter() as reporter:
# iterate objects # iterate objects
for obj in selected_objects: for obj in selected_objects:
reporter.enter_object(obj) reporter.enter_object(obj)
# try get info # try get info
info: UTIL_naming_convention.BallanceObjectInfo | None = fct_get_info(obj, reporter) info: UTIL_naming_convension.BallanceObjectInfo | None = fct_get_info(obj, reporter)
if info is not None: if info is not None:
# if info is valid, try assign it # if info is valid, try assign it
if not ftc_set_info(obj, info, reporter): if not ftc_set_info(obj, info, reporter):

View File

@ -124,7 +124,7 @@ def _load_element(mesh: bpy.types.Mesh, element_type: BallanceElementType) -> No
element_filename: str = os.path.join( element_filename: str = os.path.join(
os.path.dirname(__file__), os.path.dirname(__file__),
"meshes", "meshes",
element_name + '.ph' element_name + '.bin'
) )
# open file and read # open file and read

View File

@ -1,6 +1,6 @@
import bpy import bpy
import os, typing import os, typing
from . import UTIL_naming_convention from . import UTIL_naming_convension
class RawPreferences(): class RawPreferences():
cBallanceTextureFolder: typing.ClassVar[str] = "" cBallanceTextureFolder: typing.ClassVar[str] = ""

View File

@ -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, UTIL_naming_convention from . import PROP_virtools_group, PROP_bme_material
from . import UTIL_functions, UTIL_icons_manager, UTIL_blender_mesh, UTIL_virtools_types 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.
@ -271,23 +271,23 @@ def create_bme_struct_wrapper(ident: str, cfgs: dict[str, typing.Any]) -> bpy.ty
# create object and assign prop # create object and assign prop
# get obj info first # get obj info first
obj_info: UTIL_naming_convention.BallanceObjectInfo obj_info: UTIL_naming_convension.BallanceObjectInfo
match(PrototypeShowcaseTypes(proto[TOKEN_SHOWCASE][TOKEN_SHOWCASE_TYPE])): match(PrototypeShowcaseTypes(proto[TOKEN_SHOWCASE][TOKEN_SHOWCASE_TYPE])):
case PrototypeShowcaseTypes.No: case PrototypeShowcaseTypes.No:
obj_info = UTIL_naming_convention.BallanceObjectInfo.create_from_others(UTIL_naming_convention.BallanceObjectType.DECORATION) obj_info = UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.DECORATION)
case PrototypeShowcaseTypes.Floor: case PrototypeShowcaseTypes.Floor:
obj_info = UTIL_naming_convention.BallanceObjectInfo.create_from_others(UTIL_naming_convention.BallanceObjectType.FLOOR) obj_info = UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.FLOOR)
case PrototypeShowcaseTypes.Rail: case PrototypeShowcaseTypes.Rail:
obj_info = UTIL_naming_convention.BallanceObjectInfo.create_from_others(UTIL_naming_convention.BallanceObjectType.RAIL) obj_info = UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.RAIL)
case PrototypeShowcaseTypes.Wood: case PrototypeShowcaseTypes.Wood:
obj_info = UTIL_naming_convention.BallanceObjectInfo.create_from_others(UTIL_naming_convention.BallanceObjectType.WOOD) obj_info = UTIL_naming_convension.BallanceObjectInfo.create_from_others(UTIL_naming_convension.BallanceObjectType.WOOD)
# then get object name # then get object name
obj_name: str | None = UTIL_naming_convention.YYCToolchainConvention.set_to_name(obj_info, None) 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') if obj_name is None: raise UTIL_functions.BBPException('impossible null name')
# create object by name # create object by name
obj: bpy.types.Object = bpy.data.objects.new(obj_name, mesh) obj: bpy.types.Object = bpy.data.objects.new(obj_name, mesh)
# assign virtools groups # assign virtools groups
UTIL_naming_convention.VirtoolsGroupConvention.set_to_object(obj, obj_info, None) UTIL_naming_convension.VirtoolsGroupConvention.set_to_object(obj, obj_info, None)
# return object # return object
return obj return obj

View File

@ -72,7 +72,7 @@ class RenameErrorReporter():
print('============') print('============')
print(bpy.app.translations.pgettext_rpt( print(bpy.app.translations.pgettext_rpt(
'Rename Report', 'Rename Report',
'BBP/UTIL_naming_convention.RenameErrorReporter' 'BBP/UTIL_naming_convension.RenameErrorReporter'
)) ))
print('------------') print('------------')
# return self as context # return self as context
@ -82,7 +82,7 @@ class RenameErrorReporter():
# print console report tail # print console report tail
print('------------') print('------------')
tr_text: str = bpy.app.translations.pgettext_rpt( tr_text: str = bpy.app.translations.pgettext_rpt(
'All / Failed - {0} / {1}', 'BBP/UTIL_naming_convention.RenameErrorReporter') 'All / Failed - {0} / {1}', 'BBP/UTIL_naming_convension.RenameErrorReporter')
print(tr_text.format(self.mAllObjCounter, self.mFailedObjCounter)) print(tr_text.format(self.mAllObjCounter, self.mFailedObjCounter))
print('============') print('============')
# reset variables # reset variables
@ -107,10 +107,10 @@ class RenameErrorReporter():
tr_text: str tr_text: str
new_name: str = obj.name new_name: str = obj.name
if self.mOldName == new_name: if self.mOldName == new_name:
tr_text = bpy.app.translations.pgettext_rpt('For object "{0}"', 'BBP/UTIL_naming_convention.RenameErrorReporter') tr_text = bpy.app.translations.pgettext_rpt('For object "{0}"', 'BBP/UTIL_naming_convension.RenameErrorReporter')
print(tr_text.format(new_name)) print(tr_text.format(new_name))
else: else:
tr_text = bpy.app.translations.pgettext_rpt('For object "{0}" (Old name: "{1}")', 'BBP/UTIL_naming_convention.RenameErrorReporter') tr_text = bpy.app.translations.pgettext_rpt('For object "{0}" (Old name: "{1}")', 'BBP/UTIL_naming_convension.RenameErrorReporter')
print(tr_text.format(new_name, self.mOldName)) print(tr_text.format(new_name, self.mOldName))
# output error list with indent # output error list with indent
@ -125,11 +125,11 @@ class RenameErrorReporter():
def __errtype_to_string(err_v: _RenameErrorType) -> str: def __errtype_to_string(err_v: _RenameErrorType) -> str:
match(err_v): match(err_v):
case _RenameErrorType.ERROR: case _RenameErrorType.ERROR:
return bpy.app.translations.pgettext_rpt('ERROR', 'BBP/UTIL_naming_convention.RenameErrorReporter') return bpy.app.translations.pgettext_rpt('ERROR', 'BBP/UTIL_naming_convension.RenameErrorReporter')
case _RenameErrorType.WARNING: case _RenameErrorType.WARNING:
return bpy.app.translations.pgettext_rpt('WARN', 'BBP/UTIL_naming_convention.RenameErrorReporter') return bpy.app.translations.pgettext_rpt('WARN', 'BBP/UTIL_naming_convension.RenameErrorReporter')
case _RenameErrorType.INFO: case _RenameErrorType.INFO:
return bpy.app.translations.pgettext_rpt('INFO', 'BBP/UTIL_naming_convention.RenameErrorReporter') return bpy.app.translations.pgettext_rpt('INFO', 'BBP/UTIL_naming_convension.RenameErrorReporter')
case _: raise UTIL_functions.BBPException("Unknown error type.") case _: raise UTIL_functions.BBPException("Unknown error type.")
@staticmethod @staticmethod
def __erritem_to_string(item: _RenameErrorItem) -> str: def __erritem_to_string(item: _RenameErrorItem) -> str:
@ -292,7 +292,7 @@ class VirtoolsGroupConvention():
) )
tr_text: str = bpy.app.translations.pgettext_rpt( tr_text: str = bpy.app.translations.pgettext_rpt(
"PC_Checkpoints or PR_Resetpoints detected. But couldn't get sector from name.", 'BBP/UTIL_naming_convention.VirtoolsGroupConvention') "PC_Checkpoints or PR_Resetpoints detected. But couldn't get sector from name.", 'BBP/UTIL_naming_convension.VirtoolsGroupConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None
@ -337,12 +337,12 @@ class VirtoolsGroupConvention():
return VirtoolsGroupConvention.__get_pcpr_from_name(obj.name, reporter) return VirtoolsGroupConvention.__get_pcpr_from_name(obj.name, reporter)
case _: case _:
tr_text = bpy.app.translations.pgettext_rpt( tr_text = bpy.app.translations.pgettext_rpt(
"The match of Unique Component lost.", 'BBP/UTIL_naming_convention.VirtoolsGroupConvention') "The match of Unique Component lost.", 'BBP/UTIL_naming_convension.VirtoolsGroupConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None
elif len(inter_gps) != 0: elif len(inter_gps) != 0:
tr_text = bpy.app.translations.pgettext_rpt( tr_text = bpy.app.translations.pgettext_rpt(
"A Multi-grouping Unique Component.", 'BBP/UTIL_naming_convention.VirtoolsGroupConvention') "A Multi-grouping Unique Component.", 'BBP/UTIL_naming_convension.VirtoolsGroupConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None
@ -356,7 +356,7 @@ class VirtoolsGroupConvention():
if gotten_sector is None: if gotten_sector is None:
# fail to get sector # fail to get sector
tr_text = bpy.app.translations.pgettext_rpt( tr_text = bpy.app.translations.pgettext_rpt(
"Component detected. But couldn't get sector from CKGroup data.", 'BBP/UTIL_naming_convention.VirtoolsGroupConvention') "Component detected. But couldn't get sector from CKGroup data.", 'BBP/UTIL_naming_convension.VirtoolsGroupConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None
return BallanceObjectInfo.create_from_component( return BallanceObjectInfo.create_from_component(
@ -366,7 +366,7 @@ class VirtoolsGroupConvention():
elif len(inter_gps) != 0: elif len(inter_gps) != 0:
# must be a weird grouping, report it # must be a weird grouping, report it
tr_text = bpy.app.translations.pgettext_rpt( tr_text = bpy.app.translations.pgettext_rpt(
"A Multi-grouping Component.", 'BBP/UTIL_naming_convention.VirtoolsGroupConvention') "A Multi-grouping Component.", 'BBP/UTIL_naming_convension.VirtoolsGroupConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None
@ -384,7 +384,7 @@ class VirtoolsGroupConvention():
return BallanceObjectInfo.create_from_others(BallanceObjectType.WOOD) return BallanceObjectInfo.create_from_others(BallanceObjectType.WOOD)
else: else:
tr_text = bpy.app.translations.pgettext_rpt( tr_text = bpy.app.translations.pgettext_rpt(
"Can't distinguish object between Floors and Rails. Suppose it is Floors.", 'BBP/UTIL_naming_convention.VirtoolsGroupConvention') "Can't distinguish object between Floors and Rails. Suppose it is Floors.", 'BBP/UTIL_naming_convension.VirtoolsGroupConvention')
if reporter: reporter.add_warning(tr_text) if reporter: reporter.add_warning(tr_text)
return BallanceObjectInfo.create_from_others(BallanceObjectType.FLOOR) return BallanceObjectInfo.create_from_others(BallanceObjectType.FLOOR)
elif gp.contain_group('Phys_FloorStopper'): elif gp.contain_group('Phys_FloorStopper'):
@ -394,7 +394,7 @@ class VirtoolsGroupConvention():
# no matched # no matched
tr_text = bpy.app.translations.pgettext_rpt( tr_text = bpy.app.translations.pgettext_rpt(
"Group match lost.", 'BBP/UTIL_naming_convention.VirtoolsGroupConvention') "Group match lost.", 'BBP/UTIL_naming_convension.VirtoolsGroupConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None
@ -445,7 +445,7 @@ class VirtoolsGroupConvention():
case _: case _:
tr_text: str = bpy.app.translations.pgettext_rpt( tr_text: str = bpy.app.translations.pgettext_rpt(
"No matched info.", 'BBP/UTIL_naming_convention.VirtoolsGroupConvention') "No matched info.", 'BBP/UTIL_naming_convension.VirtoolsGroupConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return False return False
@ -499,7 +499,7 @@ class YYCToolchainConvention():
return BallanceObjectInfo.create_from_others(BallanceObjectType.SKYLAYER) return BallanceObjectInfo.create_from_others(BallanceObjectType.SKYLAYER)
tr_text: str = bpy.app.translations.pgettext_rpt( tr_text: str = bpy.app.translations.pgettext_rpt(
"Name match lost.", 'BBP/UTIL_naming_convention.YYCToolchainConvention') "Name match lost.", 'BBP/UTIL_naming_convension.YYCToolchainConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None
@ -543,7 +543,7 @@ class YYCToolchainConvention():
case _: case _:
tr_text: str = bpy.app.translations.pgettext_rpt( tr_text: str = bpy.app.translations.pgettext_rpt(
"No matched info.", 'BBP/UTIL_naming_convention.YYCToolchainConvention') "No matched info.", 'BBP/UTIL_naming_convension.YYCToolchainConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None
@ -607,7 +607,7 @@ class ImengyuConvention():
return BallanceObjectInfo.create_from_others(BallanceObjectType.SKYLAYER) return BallanceObjectInfo.create_from_others(BallanceObjectType.SKYLAYER)
tr_text: str = bpy.app.translations.pgettext_rpt( tr_text: str = bpy.app.translations.pgettext_rpt(
"Name match lost.", 'BBP/UTIL_naming_convention.ImengyuConvention') "Name match lost.", 'BBP/UTIL_naming_convension.ImengyuConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None
@ -653,7 +653,7 @@ class ImengyuConvention():
case _: case _:
tr_text: str = bpy.app.translations.pgettext_rpt( tr_text: str = bpy.app.translations.pgettext_rpt(
"No matched info.", 'BBP/UTIL_naming_convention.ImengyuConvention') "No matched info.", 'BBP/UTIL_naming_convension.ImengyuConvention')
if reporter: reporter.add_error(tr_text) if reporter: reporter.add_error(tr_text)
return None return None

View File

@ -1,6 +1,6 @@
import bpy, bmesh, mathutils, math import bpy, bmesh, mathutils, math
import typing import typing
from . import UTIL_functions, UTIL_naming_convention from . import UTIL_functions, UTIL_naming_convension
from . import PROP_bme_material from . import PROP_bme_material
#region BMesh Operations Helper #region BMesh Operations Helper
@ -132,16 +132,16 @@ def rail_creator_wrapper(fct_poly_cret: typing.Callable[[bmesh.types.BMesh], Non
# create object and assoc with it # create object and assoc with it
# create info first # create info first
rail_info: UTIL_naming_convention.BallanceObjectInfo = UTIL_naming_convention.BallanceObjectInfo.create_from_others( rail_info: UTIL_naming_convension.BallanceObjectInfo = UTIL_naming_convension.BallanceObjectInfo.create_from_others(
UTIL_naming_convention.BallanceObjectType.RAIL UTIL_naming_convension.BallanceObjectType.RAIL
) )
# then get object name # then get object name
rail_name: str | None = UTIL_naming_convention.YYCToolchainConvention.set_to_name(rail_info, None) rail_name: str | None = UTIL_naming_convension.YYCToolchainConvention.set_to_name(rail_info, None)
if rail_name is None: raise UTIL_functions.BBPException('impossible null name') if rail_name is None: raise UTIL_functions.BBPException('impossible null name')
# create object by name # create object by name
obj: bpy.types.Object = bpy.data.objects.new(rail_name, mesh) obj: bpy.types.Object = bpy.data.objects.new(rail_name, mesh)
# assign virtools groups # assign virtools groups
UTIL_naming_convention.VirtoolsGroupConvention.set_to_object(obj, rail_info, None) UTIL_naming_convension.VirtoolsGroupConvention.set_to_object(obj, rail_info, None)
# move to cursor # move to cursor
UTIL_functions.add_into_scene_and_move_to_cursor(obj) UTIL_functions.add_into_scene_and_move_to_cursor(obj)

View File

@ -23,7 +23,7 @@ from . import PROP_preferences, PROP_ptrprop_resolver, PROP_virtools_material, P
from . import PROP_ballance_element, PROP_bme_material, PROP_ballance_map_info from . import PROP_ballance_element, PROP_bme_material, PROP_ballance_map_info
from . import OP_IMPORT_bmfile, OP_EXPORT_bmfile, OP_IMPORT_virtools, OP_EXPORT_virtools from . import OP_IMPORT_bmfile, OP_EXPORT_bmfile, OP_IMPORT_virtools, OP_EXPORT_virtools
from . import OP_UV_flatten_uv, OP_UV_rail_uv from . import OP_UV_flatten_uv, OP_UV_rail_uv
from . import OP_MTL_fix_materials from . import OP_MTL_fix_material
from . import OP_ADDS_component, OP_ADDS_bme, OP_ADDS_rail from . import OP_ADDS_component, OP_ADDS_bme, OP_ADDS_rail
from . import OP_OBJECT_legacy_align, OP_OBJECT_virtools_group, OP_OBJECT_snoop_group_then_to_mesh, OP_OBJECT_naming_convention from . import OP_OBJECT_legacy_align, OP_OBJECT_virtools_group, OP_OBJECT_snoop_group_then_to_mesh, OP_OBJECT_naming_convention
@ -50,7 +50,7 @@ class BBP_MT_View3DMenu(bpy.types.Menu):
layout.operator(OP_OBJECT_virtools_group.BBP_OT_select_object_by_virtools_group.bl_idname) layout.operator(OP_OBJECT_virtools_group.BBP_OT_select_object_by_virtools_group.bl_idname)
layout.separator() layout.separator()
layout.label(text='Material', icon='MATERIAL', text_ctxt='BBP_MT_View3DMenu/draw') layout.label(text='Material', icon='MATERIAL', text_ctxt='BBP_MT_View3DMenu/draw')
layout.operator(OP_MTL_fix_materials.BBP_OT_fix_all_materials.bl_idname) layout.operator(OP_MTL_fix_material.BBP_OT_fix_all_material.bl_idname)
class BBP_MT_AddBmeMenu(bpy.types.Menu): class BBP_MT_AddBmeMenu(bpy.types.Menu):
"""Add Ballance Floor""" """Add Ballance Floor"""
@ -256,7 +256,7 @@ def register() -> None:
OP_UV_rail_uv.register() OP_UV_rail_uv.register()
OP_UV_flatten_uv.register() OP_UV_flatten_uv.register()
OP_MTL_fix_materials.register() OP_MTL_fix_material.register()
OP_ADDS_component.register() OP_ADDS_component.register()
OP_ADDS_bme.register() OP_ADDS_bme.register()
@ -297,7 +297,7 @@ def unregister() -> None:
OP_ADDS_bme.unregister() OP_ADDS_bme.unregister()
OP_ADDS_component.unregister() OP_ADDS_component.unregister()
OP_MTL_fix_materials.unregister() OP_MTL_fix_material.unregister()
OP_UV_flatten_uv.unregister() OP_UV_flatten_uv.unregister()
OP_UV_rail_uv.unregister() OP_UV_rail_uv.unregister()

View File

@ -1,4 +1,4 @@
# Full context are copied from https://docs.blender.org/manual/en/latest/advanced/extensions/getting_started.html # Full context are copied from https://docs.blender.org/manual/en/dev/extensions/getting_started.html
# Please note any update of this manifest # Please note any update of this manifest
schema_version = "1.0.0" schema_version = "1.0.0"
@ -6,7 +6,7 @@ schema_version = "1.0.0"
# Example of manifest file for a Blender extension # Example of manifest file for a Blender extension
# Change the values according to your extension # Change the values according to your extension
id = "bbp_ng" id = "bbp_ng"
version = "4.3.0" version = "4.2.1"
name = "Ballance Blender Plugin" name = "Ballance Blender Plugin"
tagline = "The specialized add-on served for creating game map of Ballance" tagline = "The specialized add-on served for creating game map of Ballance"
maintainer = "yyc12345 <yyc12321@outlook.com>" maintainer = "yyc12345 <yyc12321@outlook.com>"
@ -20,7 +20,7 @@ website = "https://github.com/yyc12345/BallanceBlenderHelper"
# https://docs.blender.org/manual/en/dev/advanced/extensions/tags.html # https://docs.blender.org/manual/en/dev/advanced/extensions/tags.html
tags = ["Object", "Mesh", "UV", "Import-Export"] tags = ["Object", "Mesh", "UV", "Import-Export"]
blender_version_min = "4.5.0" blender_version_min = "4.2.0"
# # Optional: Blender version that the extension does not support, earlier versions are supported. # # Optional: Blender version that the extension does not support, earlier versions are supported.
# # This can be omitted and defined later on the extensions platform if an issue is found. # # This can be omitted and defined later on the extensions platform if an issue is found.
# blender_version_max = "5.1.0" # blender_version_max = "5.1.0"
@ -37,7 +37,7 @@ license = [
# ] # ]
# Optional list of supported platforms. If omitted, the extension will be available in all operating systems. # Optional list of supported platforms. If omitted, the extension will be available in all operating systems.
platforms = ["windows-x64", "linux-x64"] platforms = ["windows-x64", "linux-x64", "macos-arm64"]
# Supported platforms: "windows-x64", "macos-arm64", "linux-x64", "windows-arm64", "macos-x64" # Supported platforms: "windows-x64", "macos-arm64", "linux-x64", "windows-arm64", "macos-x64"
# Optional: bundle 3rd party Python modules. # Optional: bundle 3rd party Python modules.
@ -71,8 +71,12 @@ files = "Import/export Virtools file from/to disk"
[build] [build]
paths_exclude_pattern = [ paths_exclude_pattern = [
"__pycache__/", # Python runtime cache "__pycache__/", # Python runtime cache
".gitignore", # Git Ignore File
".style.yapf", # Python code style ".style.yapf", # Python code style
"*.gitkeep", # Git directory keeper "*.gitkeep", # Git directory keeper
".gitignore", # Git Ignore File
"*.md", # Useless document. "*.md", # Useless document.
"/raw_jsons", # Raw JSONs.
"/raw_icons", # Raw Icons.
"/tools", # Assistant tools.
"/i18n", # GNU gettext Translation.
] ]

View File

View File

Before

Width:  |  Height:  |  Size: 785 B

After

Width:  |  Height:  |  Size: 785 B

View File

@ -0,0 +1,7 @@
# Raw Icons
This folder contain all images used by this Blender plugin.
This folder should not be distributed in production because all of these files are in original size. It is pretty need too much time to load them in blender.
So we keep these high quality images here and provide a tools in `tools` folder. Builder should run script to generate thumbnails in `icons` folder.
Then this Blender plugin can work normally.

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 663 B

After

Width:  |  Height:  |  Size: 663 B

View File

Before

Width:  |  Height:  |  Size: 745 B

After

Width:  |  Height:  |  Size: 745 B

View File

Before

Width:  |  Height:  |  Size: 945 B

After

Width:  |  Height:  |  Size: 945 B

View File

Before

Width:  |  Height:  |  Size: 818 B

After

Width:  |  Height:  |  Size: 818 B

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 984 B

After

Width:  |  Height:  |  Size: 984 B

View File

Before

Width:  |  Height:  |  Size: 611 B

After

Width:  |  Height:  |  Size: 611 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 471 B

After

Width:  |  Height:  |  Size: 471 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 494 B

After

Width:  |  Height:  |  Size: 494 B

View File

Before

Width:  |  Height:  |  Size: 360 B

After

Width:  |  Height:  |  Size: 360 B

View File

Before

Width:  |  Height:  |  Size: 992 B

After

Width:  |  Height:  |  Size: 992 B

View File

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 444 B

View File

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 691 B

Some files were not shown because too many files have changed in this diff Show More