Adding legenda
This commit is contained in:
parent
27c1c0d53b
commit
94228b603f
9994
.gitignore
vendored
9994
.gitignore
vendored
File diff suppressed because it is too large
Load Diff
@ -1,56 +0,0 @@
|
|||||||
import zipfile
|
|
||||||
import os
|
|
||||||
|
|
||||||
def extract_java_textures(java_jar_path, output_dir):
|
|
||||||
"""
|
|
||||||
Extracts block textures from a Minecraft Java Edition client JAR.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
java_jar_path (str): Full path to the Minecraft client JAR file (e.g., "C:/Users/YourUser/AppData/Roaming/.minecraft/versions/1.20.1/1.20.1.jar").
|
|
||||||
output_dir (str): Directory where the extracted textures will be saved.
|
|
||||||
"""
|
|
||||||
if not os.path.exists(java_jar_path):
|
|
||||||
print(f"Error: Java JAR file not found at {java_jar_path}")
|
|
||||||
return
|
|
||||||
|
|
||||||
texture_source_path_in_jar = 'assets/minecraft/textures/block/'
|
|
||||||
extracted_texture_path = os.path.join(output_dir, 'java_textures')
|
|
||||||
|
|
||||||
os.makedirs(extracted_texture_path, exist_ok=True)
|
|
||||||
|
|
||||||
print(f"Extracting textures from {java_jar_path} to {extracted_texture_path}...")
|
|
||||||
|
|
||||||
with zipfile.ZipFile(java_jar_path, 'r') as zip_ref:
|
|
||||||
for member in zip_ref.namelist():
|
|
||||||
if member.startswith(texture_source_path_in_jar) and member.endswith('.png'):
|
|
||||||
# Get the relative path within the block textures folder
|
|
||||||
relative_path = os.path.relpath(member, texture_source_path_in_jar)
|
|
||||||
|
|
||||||
# Construct the full output path
|
|
||||||
destination_path = os.path.join(extracted_texture_path, relative_path)
|
|
||||||
|
|
||||||
# Ensure the directory exists
|
|
||||||
os.makedirs(os.path.dirname(destination_path), exist_ok=True)
|
|
||||||
|
|
||||||
# Extract the file
|
|
||||||
with open(destination_path, 'wb') as outfile:
|
|
||||||
outfile.write(zip_ref.read(member))
|
|
||||||
|
|
||||||
print("Texture extraction complete.")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# --- IMPORTANT: Set these paths correctly ---
|
|
||||||
# Path to your Minecraft Java Edition JAR file
|
|
||||||
mc_java_version = "1.21.5"
|
|
||||||
java_game_jar = f"C:/Users/NP110306/AppData/Roaming/.minecraft/versions/{mc_java_version}/{mc_java_version}.jar" # Adjust as needed!
|
|
||||||
|
|
||||||
# Directory where you want to save the extracted Java textures
|
|
||||||
output_textures_base_dir = "resources/" # Adjust as needed!
|
|
||||||
|
|
||||||
extract_java_textures(java_game_jar, output_textures_base_dir)
|
|
||||||
|
|
||||||
# Now, the 'java_textures' folder inside output_textures_base_dir
|
|
||||||
# will contain all the Java block PNGs.
|
|
||||||
# You can then directly map "minecraft:stone" to
|
|
||||||
# "C:/Users/NP110306/Desktop/Blueprint_Resources/java_textures/stone.png"
|
|
||||||
# (after handling the .png extension)
|
|
||||||
139
helpers.py
139
helpers.py
@ -376,5 +376,144 @@ def render_grid(
|
|||||||
|
|
||||||
return out_img
|
return out_img
|
||||||
|
|
||||||
|
def draw_blueprint_legend(
|
||||||
|
image: Image.Image,
|
||||||
|
font_path="arial.ttf",
|
||||||
|
font_size=14,
|
||||||
|
margin=16,
|
||||||
|
box_width=220,
|
||||||
|
box_height=110
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Draws a legend box in the top-left corner of the blueprint image.
|
||||||
|
Explains gridlines, padlock, hinge bar, and other symbols.
|
||||||
|
"""
|
||||||
|
draw = ImageDraw.Draw(image)
|
||||||
|
try:
|
||||||
|
font = ImageFont.truetype(font_path, font_size)
|
||||||
|
except Exception:
|
||||||
|
font = ImageFont.load_default()
|
||||||
|
|
||||||
|
# Legend box background
|
||||||
|
box_x0, box_y0 = margin, margin
|
||||||
|
box_x1, box_y1 = box_x0 + box_width, box_y0 + box_height
|
||||||
|
draw.rectangle([box_x0, box_y0, box_x1, box_y1], fill=(255, 255, 255, 230), outline=(80, 80, 80, 255), width=2)
|
||||||
|
|
||||||
|
y = box_y0 + 10
|
||||||
|
x = box_x0 + 10
|
||||||
|
line_spacing = font_size + 6
|
||||||
|
|
||||||
|
# 1. Gridlines
|
||||||
|
# Normal
|
||||||
|
draw.line([x, y + font_size // 2, x + 30, y + font_size // 2], fill=(150, 150, 150, 255), width=1)
|
||||||
|
draw.text((x + 40, y), "Normal gridline", fill=(0, 0, 0, 255), font=font)
|
||||||
|
y += line_spacing
|
||||||
|
# Bold
|
||||||
|
draw.line([x, y + font_size // 2, x + 30, y + font_size // 2], fill=(80, 80, 80, 255), width=3)
|
||||||
|
draw.text((x + 40, y), "Every 5th gridline", fill=(0, 0, 0, 255), font=font)
|
||||||
|
y += line_spacing
|
||||||
|
|
||||||
|
# 2. Padlock (unlocked)
|
||||||
|
padlock_x = x + 5
|
||||||
|
padlock_y = y + 2
|
||||||
|
# Draw padlock body
|
||||||
|
draw.rectangle([padlock_x, padlock_y + 8, padlock_x + 12, padlock_y + 16], fill=(200, 200, 0, 255), outline=(120, 120, 0, 255), width=1)
|
||||||
|
# Draw shackle (open arc)
|
||||||
|
draw.arc([padlock_x - 2, padlock_y + 2, padlock_x + 14, padlock_y + 14], start=30, end=150, fill=(120, 120, 0, 255), width=2)
|
||||||
|
draw.text((x + 40, y), "Unlocked door", fill=(0, 0, 0, 255), font=font)
|
||||||
|
y += line_spacing
|
||||||
|
|
||||||
|
# 3. Hinge bar
|
||||||
|
bar_x = x + 5
|
||||||
|
bar_y = y + 4
|
||||||
|
draw.rectangle([bar_x, bar_y, bar_x + 4, bar_y + 16], fill=(120, 120, 120, 255))
|
||||||
|
draw.text((x + 40, y), "Door hinge side", fill=(0, 0, 0, 255), font=font)
|
||||||
|
y += line_spacing
|
||||||
|
|
||||||
|
# 4. Arrow
|
||||||
|
arrow_x = x + 5
|
||||||
|
arrow_y = y + 10
|
||||||
|
draw.line([arrow_x, arrow_y, arrow_x + 16, arrow_y], fill=(200, 0, 0, 255), width=3)
|
||||||
|
draw.polygon([arrow_x + 16, arrow_y - 4, arrow_x + 24, arrow_y, arrow_x + 16, arrow_y + 4], fill=(200, 0, 0, 255))
|
||||||
|
draw.text((x + 40, y), "Facing direction", fill=(0, 0, 0, 255), font=font)
|
||||||
|
# (Add more symbols as needed)
|
||||||
|
|
||||||
|
def draw_dynamic_block_legend_left(
|
||||||
|
grid_image: Image.Image,
|
||||||
|
textures_2d,
|
||||||
|
java_textures_loaded,
|
||||||
|
block_names_2d,
|
||||||
|
font_path="arial.ttf",
|
||||||
|
font_size=14,
|
||||||
|
margin=24,
|
||||||
|
entry_height=28,
|
||||||
|
entry_icon_size=20,
|
||||||
|
legend_bg=(255, 255, 255, 230),
|
||||||
|
legend_outline=(80, 80, 80, 255)
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Draws a legend for only the block types used in the current layer, in a margin to the left of the grid.
|
||||||
|
Returns a new image with the legend and the grid side by side.
|
||||||
|
Args:
|
||||||
|
grid_image: The rendered grid image (PIL.Image).
|
||||||
|
textures_2d: 2D list of PIL.Image objects for the layer.
|
||||||
|
java_textures_loaded: dict mapping block name to PIL.Image.
|
||||||
|
block_names_2d: 2D list of block base names (same shape as textures_2d).
|
||||||
|
font_path: Path to font file.
|
||||||
|
font_size: Font size for legend text.
|
||||||
|
margin: Margin between legend and grid.
|
||||||
|
entry_height: Height of each legend entry.
|
||||||
|
entry_icon_size: Size of the block icon in the legend.
|
||||||
|
legend_bg: RGBA tuple for legend background.
|
||||||
|
legend_outline: RGBA tuple for legend outline.
|
||||||
|
Returns:
|
||||||
|
PIL.Image: New image with legend on the left and grid on the right.
|
||||||
|
"""
|
||||||
|
# 1. Find unique block types in the layer (excluding 'air')
|
||||||
|
unique_blocks = []
|
||||||
|
seen = set()
|
||||||
|
for row in block_names_2d:
|
||||||
|
for name in row:
|
||||||
|
if name != 'air' and name not in seen:
|
||||||
|
unique_blocks.append(name)
|
||||||
|
seen.add(name)
|
||||||
|
|
||||||
|
if not unique_blocks:
|
||||||
|
# No blocks, just return the grid image
|
||||||
|
return grid_image
|
||||||
|
|
||||||
|
# 2. Prepare legend image
|
||||||
|
legend_width = margin + entry_icon_size + 10 + 120 + margin # icon + spacing + text + margin
|
||||||
|
legend_height = margin + len(unique_blocks) * entry_height + margin
|
||||||
|
legend_img = Image.new('RGBA', (legend_width, legend_height), (0, 0, 0, 0))
|
||||||
|
draw = ImageDraw.Draw(legend_img)
|
||||||
|
try:
|
||||||
|
font = ImageFont.truetype(font_path, font_size)
|
||||||
|
except Exception:
|
||||||
|
font = ImageFont.load_default()
|
||||||
|
|
||||||
|
# Draw legend background and outline
|
||||||
|
draw.rectangle([0, 0, legend_width-1, legend_height-1], fill=legend_bg, outline=legend_outline, width=2)
|
||||||
|
|
||||||
|
# 3. Draw each block type in the legend
|
||||||
|
y = margin
|
||||||
|
for block_name in unique_blocks:
|
||||||
|
# Draw block icon
|
||||||
|
icon = java_textures_loaded.get(block_name)
|
||||||
|
if icon is not None:
|
||||||
|
icon = icon.resize((entry_icon_size, entry_icon_size), Image.NEAREST)
|
||||||
|
legend_img.paste(icon, (margin, y), icon)
|
||||||
|
# Draw block name
|
||||||
|
text_x = margin + entry_icon_size + 10
|
||||||
|
draw.text((text_x, y + (entry_height - font_size) // 2), block_name, fill=(0, 0, 0, 255), font=font)
|
||||||
|
y += entry_height
|
||||||
|
|
||||||
|
# 4. Combine legend and grid image side by side
|
||||||
|
total_height = max(legend_img.height, grid_image.height)
|
||||||
|
total_width = legend_img.width + grid_image.width
|
||||||
|
combined_img = Image.new('RGBA', (total_width, total_height), (255, 255, 255, 0))
|
||||||
|
combined_img.paste(legend_img, (0, 0), legend_img)
|
||||||
|
combined_img.paste(grid_image, (legend_img.width, 0), grid_image)
|
||||||
|
|
||||||
|
return combined_img
|
||||||
|
|
||||||
|
|||||||
177
main copy.py
177
main copy.py
@ -1,177 +0,0 @@
|
|||||||
import nbtlib
|
|
||||||
import nbtlib.tag
|
|
||||||
from nbtlib.tag import Int
|
|
||||||
import gzip
|
|
||||||
import os
|
|
||||||
import sys # Import sys to print interpreter info
|
|
||||||
|
|
||||||
NBTFormatError = getattr(nbtlib, 'NBTFormatError', None)
|
|
||||||
if NBTFormatError is None:
|
|
||||||
# Fallback for older nbtlib where it might have been in nbtlib.exceptions
|
|
||||||
try:
|
|
||||||
import nbtlib.exceptions
|
|
||||||
NBTFormatError = nbtlib.exceptions.NBTFormatError
|
|
||||||
except ImportError:
|
|
||||||
NBTFormatError = Exception # Generic fallback if not found
|
|
||||||
|
|
||||||
def parse_schem_file(filepath):
|
|
||||||
"""
|
|
||||||
Parses a .schem file and extracts its main components.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
filepath (str): The path to the .schem file.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: A dictionary containing schematic dimensions, block palette,
|
|
||||||
block data, and potentially block entities and entities.
|
|
||||||
Returns None if parsing fails.
|
|
||||||
"""
|
|
||||||
if not os.path.exists(filepath):
|
|
||||||
print(f"Error: File not found at {filepath}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
|
||||||
# nbtlib can directly load GZipped NBT files
|
|
||||||
schematic = nbtlib.load(filepath)
|
|
||||||
|
|
||||||
# Access the root compound tag
|
|
||||||
root = schematic
|
|
||||||
|
|
||||||
# --- Extract Header Information ---
|
|
||||||
version = root["Version"]
|
|
||||||
if version != Int(2):
|
|
||||||
print(f"Warning: Schematic version is {version}. Expected 2 for .schem files. May not parse correctly.")
|
|
||||||
|
|
||||||
width = root["Width"].value
|
|
||||||
height = root["Height"].value
|
|
||||||
length = root["Length"].value
|
|
||||||
|
|
||||||
print(f"Schematic Dimensions: Width={width}, Height={height}, Length={length}")
|
|
||||||
print(f"Schematic Version: {version}")
|
|
||||||
|
|
||||||
# --- Extract Block Palette ---
|
|
||||||
block_palette_nbt = root["BlockPalette"]
|
|
||||||
block_palette = {}
|
|
||||||
# The BlockPalette in .schem is a compound where keys are block string IDs
|
|
||||||
# and values are integer IDs. We reverse this to map int ID -> string ID.
|
|
||||||
for block_id_str, int_id_tag in block_palette_nbt.items():
|
|
||||||
block_palette[int_id_tag.value] = block_id_str
|
|
||||||
|
|
||||||
print(f"\nBlock Palette ({len(block_palette)} entries):")
|
|
||||||
# print(block_palette) # Uncomment to see the full palette
|
|
||||||
|
|
||||||
# --- Extract Block Data ---
|
|
||||||
# BlockData is typically a byte array or sometimes an int array
|
|
||||||
block_data_raw = root["BlockData"].value # This is a bytes object
|
|
||||||
|
|
||||||
# BlockData in .schem is often variable-length encoded (VLQ)
|
|
||||||
# We need to decode it to get the actual block IDs
|
|
||||||
# This part requires a custom VLQ decoder. nbtlib doesn't do this automatically.
|
|
||||||
|
|
||||||
# A simple VLQ decoder (from WorldEdit docs / common implementations)
|
|
||||||
# This function reads integers that are variable-length encoded.
|
|
||||||
# Each byte, if its 7th bit is 1, indicates more bytes follow.
|
|
||||||
# The actual value is in the lower 7 bits.
|
|
||||||
|
|
||||||
decoded_block_ids = []
|
|
||||||
i = 0
|
|
||||||
while i < len(block_data_raw):
|
|
||||||
value = 0
|
|
||||||
j = 0
|
|
||||||
while True:
|
|
||||||
byte = block_data_raw[i]
|
|
||||||
value |= (byte & 0x7F) << (7 * j)
|
|
||||||
i += 1
|
|
||||||
if not (byte & 0x80): # If the 7th bit is 0, this is the last byte
|
|
||||||
break
|
|
||||||
j += 1
|
|
||||||
if j > 5: # Prevent infinite loops for corrupted data
|
|
||||||
raise Exception("Corrupted VLQ data: too many bytes in integer")
|
|
||||||
decoded_block_ids.append(value)
|
|
||||||
|
|
||||||
print(f"\nDecoded Block Data Length: {len(decoded_block_ids)}")
|
|
||||||
# print(decoded_block_ids[:10]) # Print first 10 decoded IDs
|
|
||||||
|
|
||||||
# --- Reconstruct 3D block array (optional, but useful for processing) ---
|
|
||||||
# Order is typically (Y * Length + Z) * Width + X
|
|
||||||
blocks_3d = [[[None for _ in range(width)] for _ in range(length)] for _ in range(height)]
|
|
||||||
|
|
||||||
for y in range(height):
|
|
||||||
for z in range(length):
|
|
||||||
for x in range(width):
|
|
||||||
# Calculate the 1D index
|
|
||||||
idx_1d = (y * length + z) * width + x
|
|
||||||
|
|
||||||
if idx_1d < len(decoded_block_ids):
|
|
||||||
palette_id = decoded_block_ids[idx_1d]
|
|
||||||
block_string_id = block_palette.get(palette_id, "minecraft:unknown")
|
|
||||||
blocks_3d[y][z][x] = block_string_id
|
|
||||||
else:
|
|
||||||
blocks_3d[y][z][x] = "minecraft:missing"
|
|
||||||
|
|
||||||
|
|
||||||
# --- Extract Block Entities and Entities (if present) ---
|
|
||||||
block_entities = root.get("BlockEntities", nbtlib.tag.List()) # List of Compound Tags
|
|
||||||
entities = root.get("Entities", nbtlib.tag.List()) # List of Compound Tags
|
|
||||||
|
|
||||||
print(f"\nNumber of Block Entities: {len(block_entities)}")
|
|
||||||
if len(block_entities) > 0:
|
|
||||||
# print("First Block Entity:", block_entities[0].pretty_tree()) # Pretty print first one
|
|
||||||
pass # Or process them further
|
|
||||||
|
|
||||||
print(f"Number of Entities: {len(entities)}")
|
|
||||||
if len(entities) > 0:
|
|
||||||
# print("First Entity:", entities[0].pretty_tree()) # Pretty print first one
|
|
||||||
pass # Or process them further
|
|
||||||
|
|
||||||
return {
|
|
||||||
"version": version,
|
|
||||||
"width": width,
|
|
||||||
"height": height,
|
|
||||||
"length": length,
|
|
||||||
"block_palette": block_palette,
|
|
||||||
"decoded_block_ids": decoded_block_ids,
|
|
||||||
"blocks_3d": blocks_3d,
|
|
||||||
"block_entities": block_entities,
|
|
||||||
"entities": entities
|
|
||||||
}
|
|
||||||
|
|
||||||
except NBTFormatError as e:
|
|
||||||
print(f"Error: Not a valid NBT or schematic file. {e}")
|
|
||||||
except KeyError as e:
|
|
||||||
print(f"Error: Missing expected NBT tag in schematic. Likely not a valid .schem file or corrupted. Missing tag: {e}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"An unexpected error occurred: {e}")
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
# def import_schem_file(filepath):
|
|
||||||
# nbtfile = nbtlib.load(filepath)
|
|
||||||
# input()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# inputfile = "18805.schem"
|
|
||||||
# import_schem_file(inputfile)
|
|
||||||
schem_file_path = "18805.schem"
|
|
||||||
|
|
||||||
parsed_data = parse_schem_file(schem_file_path)
|
|
||||||
if parsed_data:
|
|
||||||
print("\nSuccessfully parsed schematic data.")
|
|
||||||
# You can now access and process the data:
|
|
||||||
# print(parsed_data["blocks_3d"][0][0][0]) # Block at Y=0, Z=0, X=0
|
|
||||||
# print(parsed_data["block_palette"])
|
|
||||||
|
|
||||||
# Example: Print a top-down view of the first layer (Y=0)
|
|
||||||
print("\n--- Top-Down View of Layer 0 (Y=0) ---")
|
|
||||||
for z in range(parsed_data["length"]):
|
|
||||||
row_blocks = []
|
|
||||||
for x in range(parsed_data["width"]):
|
|
||||||
# Get the block string ID and truncate for display
|
|
||||||
block_id = parsed_data["blocks_3d"][0][z][x]
|
|
||||||
row_blocks.append(block_id.replace("minecraft:", "")[:6].ljust(6)) # Shorten for display
|
|
||||||
print(" ".join(row_blocks))
|
|
||||||
print("---------------------------------------")
|
|
||||||
|
|
||||||
|
|
||||||
21
main.py
21
main.py
@ -219,7 +219,7 @@ def parse_schem_file(filepath):
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# --- IMPORTANT: Replace with the actual path to your .schem file ---
|
# --- IMPORTANT: Replace with the actual path to your .schem file ---
|
||||||
schem_file_path = "18805.schem"
|
schem_file_path = "18805.schem"
|
||||||
BLUEPRINT_VERSION = "v2.3"
|
BLUEPRINT_VERSION = "v2.4"
|
||||||
# schem_file_path = "13774.schematic"
|
# schem_file_path = "13774.schematic"
|
||||||
|
|
||||||
# Path to your Minecraft Java Edition JAR file (e.g., from .minecraft/versions/1.20.1/1.20.1.jar)
|
# Path to your Minecraft Java Edition JAR file (e.g., from .minecraft/versions/1.20.1/1.20.1.jar)
|
||||||
@ -278,14 +278,15 @@ if __name__ == "__main__":
|
|||||||
current_layer = blocks_3d[y_layer]
|
current_layer = blocks_3d[y_layer]
|
||||||
# Prepare a 2D list of textures for this layer
|
# Prepare a 2D list of textures for this layer
|
||||||
textures_2d = []
|
textures_2d = []
|
||||||
|
block_names_2d = []
|
||||||
for z in range(length):
|
for z in range(length):
|
||||||
row_textures = []
|
row_textures = []
|
||||||
|
row_names =[]
|
||||||
for x in range(width):
|
for x in range(width):
|
||||||
java_block_string = blocks_3d[y_layer][z][x]
|
java_block_string = blocks_3d[y_layer][z][x]
|
||||||
original_base_block_id = java_block_string.replace("minecraft:", "").split('[')[0]
|
original_base_block_id = java_block_string.replace("minecraft:", "").split('[')[0]
|
||||||
|
|
||||||
base_block_name_for_texture_lookup = get_base_java_block_name(java_block_string, TEXTURE_NAME_OVERRIDES)
|
base_block_name_for_texture_lookup = get_base_java_block_name(java_block_string, TEXTURE_NAME_OVERRIDES)
|
||||||
|
row_names.append(base_block_name_for_texture_lookup)
|
||||||
block_states = parse_block_states(java_block_string)
|
block_states = parse_block_states(java_block_string)
|
||||||
|
|
||||||
# Get the base texture to start with. IMPORTANT: Make a .copy()!
|
# Get the base texture to start with. IMPORTANT: Make a .copy()!
|
||||||
@ -400,6 +401,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
row_textures.append(texture_to_paste)
|
row_textures.append(texture_to_paste)
|
||||||
textures_2d.append(row_textures)
|
textures_2d.append(row_textures)
|
||||||
|
block_names_2d.append(row_names)
|
||||||
|
|
||||||
# --- Draw Grid Lines ---
|
# --- Draw Grid Lines ---
|
||||||
layer_image_with_grid_and_numbers = render_grid(
|
layer_image_with_grid_and_numbers = render_grid(
|
||||||
@ -415,14 +417,23 @@ if __name__ == "__main__":
|
|||||||
margin=GRID_LAYER_MARGIN # or your preferred margin
|
margin=GRID_LAYER_MARGIN # or your preferred margin
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add legend to the left
|
||||||
|
layer_with_legend = draw_dynamic_block_legend_left(
|
||||||
|
layer_image_with_grid_and_numbers,
|
||||||
|
textures_2d,
|
||||||
|
java_textures_loaded,
|
||||||
|
block_names_2d,
|
||||||
|
font_size=14,
|
||||||
|
margin=24
|
||||||
|
)
|
||||||
|
|
||||||
# Save the generated layer image
|
# Save the generated layer image
|
||||||
output_filepath = os.path.join(OUTPUT_BLUEPRINT_DIR, BLUEPRINT_VERSION, f"blueprint_layer_{y_layer:03d}.png")
|
output_filepath = os.path.join(OUTPUT_BLUEPRINT_DIR, BLUEPRINT_VERSION, f"blueprint_layer_{y_layer:03d}.png")
|
||||||
layer_image_with_grid_and_numbers.save(output_filepath)
|
layer_with_legend.save(output_filepath)
|
||||||
print(f"Generated blueprint for layer {y_layer} at {output_filepath}")
|
print(f"Generated blueprint for layer {y_layer} at {output_filepath}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print("\nBlueprint generation complete!")
|
print("\nBlueprint generation complete!")
|
||||||
else:
|
else:
|
||||||
print("Schematic parsing failed. Cannot generate blueprints.")
|
print("Schematic parsing failed. Cannot generate blueprints.")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user