-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementing CommonMCOBJ Support #555
Merged
Merged
Changes from 47 commits
Commits
Show all changes
50 commits
Select commit
Hold shift + click to select a range
487bfcb
Added msg field to MCprepError
StandingPadAnimations 936cb84
refactor: have convert_mtl use MCprepError
StandingPadAnimations f29d308
refactor: General refactoring of world.py
StandingPadAnimations d57a48e
refactor: util.py refactoring for new error type
StandingPadAnimations 49e5bbb
Removed default_materials.py
StandingPadAnimations 4a8cc63
refactor: Refactored find_from_texture_pack
StandingPadAnimations fddbe9c
feat: Implemented CommonMCOBJ handling for imports
StandingPadAnimations 61eff57
refactor: updated UI to use new exporter handling
StandingPadAnimations 8e98cfb
Fixed typo in export_bounds_* keys
StandingPadAnimations 373ae95
Fixed typo in export_bounds_* keys
StandingPadAnimations a419189
Added guard statement in get_exporter
StandingPadAnimations 0454218
refactor: Migrated remaining pure string checks
StandingPadAnimations d5760d1
Updated is_atlas_export
StandingPadAnimations 12123ef
Fixed incorrect keyword args in parser
StandingPadAnimations ab2e163
fix: Reduced memory usage of header parser
StandingPadAnimations 2da614e
Added BSD license to commonmcobj_parser.py
StandingPadAnimations 8d4efc0
Added email to copyright in commonmcobj_parser.py
StandingPadAnimations 5d8ff42
Added licensing information for other components
StandingPadAnimations c7b82e2
Cleaned up LICENSE-3RD-PARTY.txt a little
StandingPadAnimations 383f71e
Removed extra .txt in README
StandingPadAnimations e3b75a7
reft: updated uses of find_from_texturepack
StandingPadAnimations 0b25c43
doc: updated docstring for detect_form
StandingPadAnimations 5ba5556
feat: added basic forward compat for headers
StandingPadAnimations 4b920a4
Merge branch 'common-mc-obj-v1' into refactoring-3-6-0
StandingPadAnimations 76a6d4d
chore: Merge refactoring-3-6-0
StandingPadAnimations 74a5367
build: Added Blender 4.1 and 4.2 to build config
StandingPadAnimations 62ceb23
cmcobj: Header info is now stored inside an empty
StandingPadAnimations 6b9257f
tracking: Re-enabled exporter tracking
StandingPadAnimations d4c711c
Merge branch 'dev' into common-mc-obj-v1
StandingPadAnimations 07a5b92
style: Moved update_matrices to util.py
StandingPadAnimations 841db9e
feat(CommonMCOBJ): Hide OBJ empty in viewport
StandingPadAnimations a4328a2
fix: Fixed missing variables for exporter tracking
StandingPadAnimations cb347b2
Merge remote-tracking branch 'origin/dev' into common-mc-obj-v1
StandingPadAnimations ddb92f7
fix: Parent empty to all OBJs
StandingPadAnimations b5ea9e8
Updated several partial migrations to use pathlib, fixes some tests
TheDuckCow 0d65ffd
Moving the added empty to the same collection as the rest of the world
TheDuckCow 0afc1c9
Added new test world save and exports from jmc2obj and mineways
TheDuckCow 23d4fa4
Fix obj file header parsing from being cleared and some pep8 cleanup
TheDuckCow 1fec0da
refactor: Remove bv28
StandingPadAnimations f678b9f
style: set MCprepEnv.material_sync_cache to typing.List
StandingPadAnimations ef36932
Merge branch 'dev' into common-mc-obj-v1
StandingPadAnimations c2269b0
fix: Add filepath to "File not found" error
StandingPadAnimations 4e664ee
test: Fix test_convert_mtl_simple with convert_mtl return types
StandingPadAnimations 2b4418f
fix: Don't disable textureswap with WorldExporter.Unknown
StandingPadAnimations 1b38d08
style: Return bool for convert_mtl instead of None
StandingPadAnimations f141844
fix: Add Khronos PBR Neutral and AgX to natively supported spaces
StandingPadAnimations 6f2c226
Resolve 2x tests with more consistent use of world WorldExporter
TheDuckCow 3a30cfe
revert: Add nuance back to get_exporter return value
StandingPadAnimations acec9ea
Fixing the mapping test code to use the generalize functions.
TheDuckCow a0a2f29
rc-files: Update patches for MCprep 3.6 RC-3
StandingPadAnimations File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
----------------------------------------------------------------------------- | ||
The BSD 3-Clause License | ||
|
||
Applies to: | ||
commonmcobj_parser.py Copyright (c) 2024, Mahid Sheikh | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
1. Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
|
||
2. Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
3. Neither the name of the copyright holder nor the names of its | ||
contributors may be used to endorse or promote products derived from | ||
this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
----------------------------------------------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
# BSD 3-Clause License | ||
# | ||
# Copyright (c) 2024, Mahid Sheikh <[email protected]> | ||
# | ||
# Redistribution and use in source and binary forms, with or without | ||
# modification, are permitted provided that the following conditions are met: | ||
# | ||
# 1. Redistributions of source code must retain the above copyright notice, this | ||
# list of conditions and the following disclaimer. | ||
# | ||
# 2. Redistributions in binary form must reproduce the above copyright notice, | ||
# this list of conditions and the following disclaimer in the documentation | ||
# and/or other materials provided with the distribution. | ||
# | ||
# 3. Neither the name of the copyright holder nor the names of its | ||
# contributors may be used to endorse or promote products derived from | ||
# this software without specific prior written permission. | ||
# | ||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
# The parser is under a more permissive BSD 3-Clause license to make it easier | ||
# for developers to use in non-GPL code. Normally, I wouldn't do dual licensing, | ||
# but in this case, it makes sense as it would allow developers to reuse this | ||
# parser for their own uses under more permissive terms. This doesn't change anything | ||
# related to MCprep, which is GPL, as BSD 3-Clause is compatible with GPL. The | ||
# only part that might conflict is Clause 3, but it could be argued that one | ||
# can't do that under GPL anyway, or any license for that matter, and that | ||
# Clause 3 is just a reminder to developers. | ||
# | ||
# - Mahid Sheikh | ||
|
||
from dataclasses import dataclass | ||
from enum import Enum | ||
from typing import List, Optional, Tuple, TextIO | ||
|
||
MAX_SUPPORTED_VERSION = 1 | ||
|
||
class CommonMCOBJTextureType(Enum): | ||
ATLAS = "ATLAS" | ||
INDIVIDUAL_TILES = "INDIVIDUAL_TILES" | ||
|
||
@dataclass | ||
class CommonMCOBJ: | ||
StandingPadAnimations marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
Python representation of the CommonMCOBJ header | ||
""" | ||
# Version of the CommonMCOBJ spec | ||
version: int | ||
|
||
# Exporter name in all lowercase | ||
exporter: str | ||
|
||
# Name of source world | ||
world_name: str | ||
|
||
# Path of source world* | ||
world_path: str | ||
|
||
# Min values of the selection bounding box | ||
export_bounds_min: Tuple[int, int, int] | ||
|
||
# Max values of the selection bounding box | ||
export_bounds_max: Tuple[int, int, int] | ||
|
||
# Offset from (0, 0, 0) | ||
export_offset: Tuple[float, float, float] | ||
|
||
# Scale of each block in meters; by default, this should be 1 meter | ||
block_scale: float | ||
|
||
# Coordinate offset for blocks | ||
block_origin_offset: Tuple[float, float, float] | ||
|
||
# Is the Z axis of the OBJ considered up? | ||
z_up: bool | ||
|
||
# Are the textures using large texture atlases or | ||
# individual textures? | ||
texture_type: CommonMCOBJTextureType | ||
|
||
# Are blocks split by type? | ||
has_split_blocks: bool | ||
|
||
# Original header | ||
original_header: Optional[str] | ||
|
||
def parse_common_header(header_lines: list[str]) -> CommonMCOBJ: | ||
""" | ||
Parses the CommonMCOBJ header information from a list of strings. | ||
|
||
header_lines list[str]: | ||
list of strings representing each line of the header. | ||
|
||
returns: | ||
CommonMCOBJ object | ||
""" | ||
|
||
# Split at the colon and clean up formatting | ||
def clean_and_extract(line: str) -> Tuple[str, str]: | ||
split = line.split(':', 1) | ||
pos = 0 | ||
for i,x in enumerate(split[0]): | ||
if x.isalpha(): | ||
pos = i | ||
break | ||
return (split[0][pos:], split[1].strip()) | ||
|
||
# Basic values | ||
header = CommonMCOBJ( | ||
version=0, | ||
exporter="NULL", | ||
world_name="NULL", | ||
world_path="NULL", | ||
export_bounds_min=(0, 0, 0), | ||
export_bounds_max=(0, 0, 0), | ||
export_offset=(0, 0, 0), | ||
block_scale=0, | ||
block_origin_offset=(0, 0, 0), | ||
z_up=False, | ||
texture_type=CommonMCOBJTextureType.ATLAS, | ||
has_split_blocks=False, | ||
original_header=None | ||
) | ||
|
||
# Keys whose values do not need extra processing | ||
NO_VALUE_PARSE = [ | ||
"exporter", | ||
"world_name", | ||
"world_path", | ||
] | ||
|
||
# Keys whose values are tuples | ||
TUPLE_PARSE_INT = [ | ||
"export_bounds_min", | ||
"export_bounds_max", | ||
] | ||
|
||
TUPLE_PARSE_FLOAT = [ | ||
"export_offset", | ||
"block_origin_offset" | ||
] | ||
|
||
# Keys whose values are booleans | ||
BOOLEAN_PARSE = [ | ||
"z_up", | ||
"has_split_blocks" | ||
] | ||
|
||
# Although CommonMCOBJ states that | ||
# order does matter in the header, | ||
# future versions may change the order | ||
# of some values, so it's best to | ||
# use a non-order specific parser | ||
for line in header_lines: | ||
if ":" not in line: | ||
continue | ||
key, value = clean_and_extract(line) | ||
|
||
if key == "version": | ||
try: | ||
header.version = int(value) | ||
if header.version > MAX_SUPPORTED_VERSION: | ||
header.original_header = "\n".join(header_lines) | ||
except Exception: | ||
pass | ||
|
||
elif key == "block_scale": | ||
try: | ||
header.block_scale = float(value) | ||
except Exception: | ||
pass | ||
|
||
elif key == "texture_type": | ||
try: | ||
header.texture_type = CommonMCOBJTextureType[value] | ||
except Exception: | ||
pass | ||
|
||
# All of these are parsed the same, with | ||
# no parsing need to value | ||
# | ||
# No keys here will be classed as failed | ||
elif key in NO_VALUE_PARSE: | ||
setattr(header, key, value) | ||
|
||
# All of these are parsed the same, with | ||
# parsing the value to a tuple | ||
elif key in TUPLE_PARSE_INT: | ||
try: | ||
setattr(header, key, tuple(map(int, value[1:-1].split(', ')))) | ||
except Exception: | ||
pass | ||
|
||
elif key in TUPLE_PARSE_FLOAT: | ||
try: | ||
setattr(header, key, tuple(map(float, value[1:-1].split(', ')))) | ||
except Exception: | ||
pass | ||
|
||
elif key in BOOLEAN_PARSE: | ||
try: | ||
setattr(header, key, value == "true") | ||
except Exception: | ||
pass | ||
|
||
return header | ||
|
||
|
||
def parse_header(f: TextIO) -> Optional[CommonMCOBJ]: | ||
""" | ||
Parses a file and returns a CommonMCOBJ object if the header exists. | ||
|
||
f: TextIO | ||
File object | ||
|
||
Returns: | ||
- CommonMCOBJ object if header exists | ||
- None otherwise | ||
""" | ||
|
||
header: List[str] = [] | ||
found_header = False | ||
|
||
# Read in the header | ||
lines_read = 0 | ||
for _l in f: | ||
tl = " ".join(_l.rstrip().split()) | ||
lines_read += 1 | ||
if lines_read > 100 and tl and not tl.startswith("#"): | ||
StandingPadAnimations marked this conversation as resolved.
Show resolved
Hide resolved
|
||
break # no need to parse further than the true header area | ||
elif tl == "# COMMON_MC_OBJ_START": | ||
header.append(tl) | ||
found_header = True | ||
continue | ||
elif tl == "# COMMON_MC_OBJ_END": | ||
header.append(tl) | ||
break | ||
if not found_header or tl == "#": | ||
continue | ||
header.append(tl) | ||
if not len(header): | ||
return None | ||
return parse_common_header(header) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A note to self that we should create unit tests for this, I can take that in a follow up since I know you're having trouble running this currently. I'm planning to have both a mineways and jmc2obj sample for this.