Skip to content

Commit

Permalink
consistent naming
Browse files Browse the repository at this point in the history
-change camelcase to snake case for all variable and function names
-changed "color" to "colour" where possible to be consistent with LDraw documentation
-updadet GUI screenshot
  • Loading branch information
Nexusnui committed Oct 28, 2023
1 parent 31a71dd commit 2db6c0e
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 53 deletions.
File renamed without changes.
88 changes: 44 additions & 44 deletions app/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from stlToDat import stlToDat
from brickcolor import is_brickcolor, brickcolor, get_contrast_color
from stlToDat import stl_to_dat
from brickcolour import is_brickcolour, brickcolour, get_contrast_colour
import customtkinter
from tkinter import messagebox as tkMessageBox
import os
Expand All @@ -23,11 +23,11 @@ def __init__(self):

self.input_file_Var = customtkinter.StringVar()
self.output_file_Var = customtkinter.StringVar()
self.color_code_Var = customtkinter.StringVar()
self.color_toggle_Var = customtkinter.StringVar(value="off")
self.colour_code_Var = customtkinter.StringVar()
self.colour_toggle_Var = customtkinter.StringVar(value="off")

self.color_code_Var.trace("w", self.update_color_preview)
self.color_toggle_Var.trace("w", self.update_color_preview)
self.colour_code_Var.trace("w", self.update_colour_preview)
self.colour_toggle_Var.trace("w", self.update_colour_preview)

customtkinter.CTkLabel(self.main_frame, text="Input File:").grid(sticky="w", columnspan=2, row=0, column=0)
self.input_file_path_label = customtkinter.CTkEntry(self.main_frame, textvariable=self.input_file_Var)
Expand All @@ -37,20 +37,20 @@ def __init__(self):
command=self.get_input_file)
self.load_file_button.grid(sticky="ew", row=1, column=2)

customtkinter.CTkLabel(self.main_frame, text="LDraw Color Code:").grid(sticky="w", columnspan=2,
customtkinter.CTkLabel(self.main_frame, text="LDraw Colour Code:").grid(sticky="w", columnspan=2,
row=2, column=0)
self.color_code_label = customtkinter.CTkEntry(self.main_frame, textvariable=self.color_code_Var)
self.color_code_label.grid(sticky="ew", columnspan=2, row=3, column=0)
self.color_toggle_checkbox = customtkinter.CTkCheckBox(self.main_frame, text="Apply",
variable=self.color_toggle_Var, onvalue="on",
offvalue="off")
self.color_toggle_checkbox.grid(sticky="ew", columnspan=2, row=3, column=2)

customtkinter.CTkLabel(self.main_frame, text="Color Preview:").grid(sticky="w", columnspan=1,
self.colour_code_label = customtkinter.CTkEntry(self.main_frame, textvariable=self.colour_code_Var)
self.colour_code_label.grid(sticky="ew", columnspan=2, row=3, column=0)
self.colour_toggle_checkbox = customtkinter.CTkCheckBox(self.main_frame, text="Apply",
variable=self.colour_toggle_Var, onvalue="on",
offvalue="off")
self.colour_toggle_checkbox.grid(sticky="ew", columnspan=2, row=3, column=2)

customtkinter.CTkLabel(self.main_frame, text="Colour Preview:").grid(sticky="w", columnspan=1,
row=4, column=0)
self.color_preview = customtkinter.CTkLabel(self.main_frame, text="Main_Colour", text_color="#00008F",
fg_color="#FFFF80", padx=3, corner_radius=6)
self.color_preview.grid(sticky="w", columnspan=2, row=4, column=1)
self.colour_preview = customtkinter.CTkLabel(self.main_frame, text="Main_Colour", text_color="#00008F",
fg_color="#FFFF80", padx=3, corner_radius=6)
self.colour_preview.grid(sticky="w", columnspan=2, row=4, column=1)

customtkinter.CTkLabel(self.main_frame, text="Output File:").grid(sticky="w", columnspan=2, row=5, column=0)
self.output_file_label = customtkinter.CTkEntry(self.main_frame, textvariable=self.output_file_Var)
Expand All @@ -60,8 +60,8 @@ def __init__(self):
command=self.set_output_file)
self.output_file_button.grid(sticky="ew", row=6, column=2)

self.convertFileButton = customtkinter.CTkButton(self.main_frame, text="convert file", command=self.convert_file)
self.convertFileButton.grid(sticky="ew", row=7, column=1)
self.convert_file_button = customtkinter.CTkButton(self.main_frame, text="convert file", command=self.convert_file)
self.convert_file_button.grid(sticky="ew", row=7, column=1)

def get_input_file(self):
input_file_path = customtkinter.filedialog.askopenfilename(filetypes=[('stl files', '*.stl')])
Expand All @@ -85,38 +85,38 @@ def set_output_file(self):
if len(output_file_path) > 0:
self.output_file_Var.set(output_file_path)

def update_color_preview(self, *args):
set_color = brickcolor("16")
if self.color_toggle_Var.get() == "on":
set_color = brickcolor(self.color_code_Var.get())
if set_color is not None:
if set_color.color_type == "LDraw" and set_color.ldrawname is not None:
text_color = get_contrast_color(set_color.rgb_values)
self.color_preview.configure(text=set_color.ldrawname, text_color=text_color,
fg_color=set_color.rgb_values)
def update_colour_preview(self, *args):
set_colour = brickcolour("16")
if self.colour_toggle_Var.get() == "on":
set_colour = brickcolour(self.colour_code_Var.get())
if set_colour is not None:
if set_colour.colour_type == "LDraw" and set_colour.ldrawname is not None:
text_colour = get_contrast_colour(set_colour.rgb_values)
self.colour_preview.configure(text=set_colour.ldrawname, text_color=text_colour,
fg_color=set_colour.rgb_values)
return
elif set_color.color_type == "Direct":
self.color_preview.configure(text=set_color.rgb_values, text_color=set_color.rgb_edge,
fg_color=set_color.rgb_values)
elif set_colour.colour_type == "Direct":
self.colour_preview.configure(text=set_colour.rgb_values, text_color=set_colour.rgb_edge,
fg_color=set_colour.rgb_values)
return
else:
self.color_preview.configure(text="Unknown or invalid color", text_color="#FFFFFF",
fg_color="#000000")
elif len(self.color_code_Var.get()) == 0:
self.color_preview.configure(text="", fg_color="transparent")
self.colour_preview.configure(text="Unknown or invalid colour", text_color="#FFFFFF",
fg_color="#000000")
elif len(self.colour_code_Var.get()) == 0:
self.colour_preview.configure(text="", fg_color="transparent")
return
else:
self.color_preview.configure(text="Unknown or invalid color", text_color="#FFFFFF", fg_color="#000000")
self.colour_preview.configure(text="Unknown or invalid colour", text_color="#FFFFFF", fg_color="#000000")

def convert_file(self):
input_file_path = self.input_file_Var.get()
output_file_path = self.output_file_Var.get()
color_code = "16"
if self.color_toggle_Var.get() == "on":
color_code = self.color_code_Var.get()
color_check = is_brickcolor(color_code)
if not color_check[0]:
tkMessageBox.showwarning(color_check[1], color_check[2])
colour_code = "16"
if self.colour_toggle_Var.get() == "on":
colour_code = self.colour_code_Var.get()
colour_check = is_brickcolour(colour_code)
if not colour_check[0]:
tkMessageBox.showwarning(colour_check[1], colour_check[2])
return

if not os.path.isfile(input_file_path):
Expand All @@ -130,7 +130,7 @@ def convert_file(self):
f"'{os.path.dirname(output_file_path)}' is not a valid output directory")
return

number_triangles = stlToDat(input_file_path, output_file_path, color_code)
number_triangles = stl_to_dat(input_file_path, output_file_path, colour_code)
tkMessageBox.showwarning('Converted File', f'stl file converted to "{output_file_path}"\n'
f'Part contains {number_triangles} triangles.')

Expand Down
97 changes: 97 additions & 0 deletions app/brickcolour.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
def is_brickcolour(colour_code: str):
if len(colour_code) < 1:
return False, "No Colour Code", "Apply Checkbox was toggled, but no colour code provided"
elif not colour_code.startswith("0x2"):
if not colour_code.isdigit():
return (False, "Invalid Colour Code",
f"The provided colour code '{colour_code}' is not a number.\n "
f"Use a code from the LDraw Colour Definition Reference.\n"
f"If you wanted to use a Direct/HTML colour the format is 0x2RRGGBB "
f"(R,B and G are hexadecimal).")
elif colour_code.startswith("0x2"):
if len(colour_code) > 9:
return (False, "Invalid Colour Code",
f"The provided colour '{colour_code}' seems to be a Direct/HTML colour but is to long.")
elif len(colour_code) < 9:
return (False, "Invalid Colour Code",
f"The provided colour '{colour_code}' seems to be a Direct/HTML colour but is to short.")
for i in range(2, 9):
if colour_code[i] not in ["A", "B", "C", "D", "E", "F"] and not colour_code[i].isdigit():
return (False, "Invalid Colour Code",
f"The provided colour '{colour_code}' seems to be a Direct/HTML colour, "
f"but contains a invalid charcter at position: {i - 2} - '{colour_code[i]}'.\n"
f"Valid characters are 0-9 and A-F(uppercase)")
return True,


class brickcolour:
def __new__(cls, colour_code: str):
if not is_brickcolour(colour_code)[0]:
return None
instance = super().__new__(cls)
return instance

def __init__(self, colour_code: str):
self.colour_code = colour_code
if colour_code.startswith("0x2"):
self.colour_type = "Direct"
self.rgb_values = f"#{self.colour_code[3:]}"
self.rgb_edge = get_contrast_colour(self.rgb_values)
else:
self.colour_type = "LDraw"
self.ldrawname, _, \
self.rgb_values, \
self.rgb_edge, \
self.alpha, \
self.luminance, \
self.material, \
self.legoname, \
self.legoid, \
self.category = get_colour_info_by_id(self.colour_code)

def __str__(self):
if self.colour_type == "Direct":
return f"Direct Colour: {self.colour_code}"
else:
if self.ldrawname is not None:
return f"LDraw Colour {self.colour_code}: {self.ldrawname}, {self.rgb_values}"
else:
return f"Unknown LDraw Colour {self.colour_code}"

def __repr__(self):
return f"brickcolour({self.colour_code})"


def get_colour_info_by_id(id: str):
found_colour = [None] * 10
with open("BrickColours.csv", "r", encoding="utf-8") as source:
# skip row with column names
source.readline()
for line in source:
values = line.split(";")
if values[1] == id:
for i in range(len(values)):
# replace empty values with None
if len(values[i]) == 0:
values[i] = None
found_colour = values
break

return found_colour

def get_contrast_colour(rgb_values: str):
r = 0 if int(rgb_values[1:3], 16) < 128 else 1
g = 0 if int(rgb_values[3:5], 16) < 128 else 1
b = 0 if int(rgb_values[5:7], 16) < 128 else 1
if r+g+b < 2:
return "#FFFFFF"
else:
return "#000000"


def get_complementary_colour(rgb_values: str):
red = '%02X' % (255 - int(rgb_values[1:3], 16))
green = '%02X' % (255 - int(rgb_values[3:5], 16))
blue = '%02X' % (255 - int(rgb_values[5:7], 16))

return f"#{''.join([red, green, blue])}"
18 changes: 9 additions & 9 deletions app/stlToDat.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
from stl import mesh


def stlToDat(input_filename: str, output_filename: str, colour: str = "16"):
def stl_to_dat(input_filename: str, output_filename: str, colour: str = "16"):
mm_to_ldu = 1.0 / 0.4
inputMesh = mesh.Mesh.from_file(input_filename)
input_mesh = mesh.Mesh.from_file(input_filename)

inputMesh.x *= mm_to_ldu
inputMesh.y *= mm_to_ldu
inputMesh.z *= mm_to_ldu
input_mesh.x *= mm_to_ldu
input_mesh.y *= mm_to_ldu
input_mesh.z *= mm_to_ldu

with open(output_filename, "w", encoding="utf-8") as fp_out:
# 0: Comment or META command the first 0 line is alway the filename
Expand All @@ -26,12 +26,12 @@ def stlToDat(input_filename: str, output_filename: str, colour: str = "16"):
# Todo: Add License Meta command to file
fp_out.write("0 BFC CERTIFY CCW\n")

for index, triangle in enumerate(inputMesh):
# 3:filled triangle, 16:Default color
for index, triangle in enumerate(input_mesh):
# 3:filled triangle, 16:Default colour
fp_out.write(f"3 {colour} {' '.join(map(lambda a: str(a), triangle))}\n")

# return number of triangles
return len(inputMesh)
return len(input_mesh)


if __name__ == '__main__':
Expand Down Expand Up @@ -59,4 +59,4 @@ def stlToDat(input_filename: str, output_filename: str, colour: str = "16"):
elif sys.argv[4] == "-c":
colour = sys.argv[5]

print(f"Part contains {stlToDat(input_filename, output_filename, colour)} triangles.")
print(f"Part contains {stl_to_dat(input_filename, output_filename, colour)} triangles.")
Binary file modified graphical_userinterface.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2db6c0e

Please sign in to comment.