Initial commit
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/.idea
|
||||
/__pycache__/
|
||||
*ARCHIV*
|
||||
*BAK*
|
||||
*BACKUP*
|
||||
8
EXEC_INSTALL.ps1
Normal file
@ -0,0 +1,8 @@
|
||||
# Construct the full path to the Python script
|
||||
$ymlPath = "./_condaenv.yml"
|
||||
|
||||
# Execute the Python script
|
||||
& conda env create -f $ymlPath
|
||||
|
||||
# Pause at the end of the script
|
||||
Read-Host -Prompt "Press any key to exit"
|
||||
16
EXEC_MAIN.ps1
Normal file
@ -0,0 +1,16 @@
|
||||
#---------- USER DEFINE --------------
|
||||
$venvName = "dmu50_wingui"
|
||||
$scriptPath = "./MAIN.py"
|
||||
#-------------------------------------
|
||||
|
||||
# Get the current username
|
||||
$username = [System.Environment]::UserName
|
||||
|
||||
# Construct the path to the Python executable
|
||||
$pythonExe = "C:\Users\$username\AppData\Local\miniconda3\envs\$venvName\python.exe"
|
||||
|
||||
# Execute the Python script
|
||||
& $pythonExe $scriptPath
|
||||
|
||||
# Pause at the end of the script
|
||||
Read-Host -Prompt "Press Enter to exit"
|
||||
351
MAIN.py
Normal file
@ -0,0 +1,351 @@
|
||||
# main.py
|
||||
|
||||
from functions import *
|
||||
from funct_inlay import *
|
||||
from funct_wp import *
|
||||
from funct_grp import *
|
||||
from funct_clp import *
|
||||
from funct_gen import *
|
||||
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
import yaml
|
||||
import shutil
|
||||
|
||||
folder_parsets = "cfg_parsets"
|
||||
folder_pictures = "cfg_picture"
|
||||
folder_output = "out"
|
||||
file_def = "def.yml"
|
||||
file_jobs = "jobs.yml"
|
||||
name_newparset = "<<new par set>>"
|
||||
name_newjob = "<<new job>>"
|
||||
pic_sizelimit = 200
|
||||
|
||||
|
||||
def setup_group(frame, group_name, data, input_vars, selected_params, group_widgets):
|
||||
group_data = data['groups'][group_name]
|
||||
picture_name = group_data['cfg']['picture_name'] # Picture name defined in def.yml
|
||||
picture_path = os.path.join(folder_pictures, picture_name) # Full path to the picture
|
||||
|
||||
|
||||
# Dropdown for parameter sets
|
||||
param_values = get_existing_parameters(group_name, folder_parsets)
|
||||
param_values.append(name_newparset)
|
||||
param_var = selected_params[group_name] # Bind the dropdown to the corresponding selected_param entry
|
||||
param_dropdown = ttk.Combobox(frame, textvariable=param_var, values=param_values)
|
||||
group_widgets[group_name] = {"param_dropdown": param_dropdown} # Save for later reference
|
||||
source_path = f"{folder_pictures}/{data['general']['initpic_name']}"
|
||||
|
||||
# Handle missing picture case
|
||||
if not os.path.exists(picture_path):
|
||||
shutil.copy(source_path, picture_path)
|
||||
|
||||
|
||||
# Function to update the picture based on inputs or use the init picture
|
||||
def update_inlay_picture():
|
||||
grpnm = group_name
|
||||
all_group_vars = {group_name: {key: var.get() for key, var in group_vars.items()} for group_name, group_vars in
|
||||
input_vars.items()}
|
||||
|
||||
# Use the source_path if the selected parameter set is the new parameter set placeholder
|
||||
# print(param_dropdown.get())
|
||||
if param_dropdown.get() == name_newparset:
|
||||
picture_to_use = source_path
|
||||
else:
|
||||
picture_to_use = picture_path
|
||||
if grpnm == "inlay":
|
||||
generate_picture_inlay(all_group_vars, picture_to_use)
|
||||
elif grpnm == "wp_raw":
|
||||
generate_picture_wpraw(all_group_vars, picture_to_use)
|
||||
elif grpnm == "wp_fin":
|
||||
generate_picture_wpfin(all_group_vars, picture_to_use)
|
||||
elif grpnm == "grp":
|
||||
generate_picture_grp(all_group_vars, picture_to_use)
|
||||
elif grpnm == "clp":
|
||||
generate_picture_clp(all_group_vars, picture_to_use)
|
||||
|
||||
group_image_tk = load_image(picture_to_use, pic_sizelimit)
|
||||
image_label.configure(image=group_image_tk)
|
||||
image_label.image = group_image_tk # Keep a reference to avoid garbage collection
|
||||
|
||||
|
||||
# Function to load a parameter set
|
||||
def load_selected_param():
|
||||
selected_param = param_dropdown.get()
|
||||
if selected_param != name_newparset:
|
||||
param_data = load_yaml(group_name, selected_param, folder_parsets)
|
||||
for key, value in param_data.items():
|
||||
input_vars[group_name][key].set(value)
|
||||
update_inlay_picture()
|
||||
|
||||
# Function to save the current parameter set
|
||||
def save_current_param():
|
||||
param_name = param_dropdown.get()
|
||||
if param_name not in param_values and param_name.strip():
|
||||
param_values.insert(-1, param_name) # Insert before '<<new parameter set>>'
|
||||
param_dropdown['values'] = param_values
|
||||
param_dropdown.set(param_name)
|
||||
if name_newparset not in param_values:
|
||||
param_values.append(name_newparset) # Ensure it's only appended once
|
||||
param_data = {key: var.get() for key, var in input_vars[group_name].items()}
|
||||
save_yaml(group_name, param_name, param_data, folder_parsets)
|
||||
update_inlay_picture()
|
||||
|
||||
# Function to delete the current parameter set
|
||||
def delete_current_param():
|
||||
param_name = param_dropdown.get()
|
||||
if param_name in param_values and param_name != name_newparset:
|
||||
confirm = messagebox.askyesno("Delete Parameter", f"Are you sure you want to delete '{param_name}'?")
|
||||
if confirm:
|
||||
delete_yaml(group_name, param_name, folder_parsets)
|
||||
param_values.remove(param_name)
|
||||
if name_newparset not in param_values:
|
||||
param_values.append(name_newparset) # Ensure it's only appended once
|
||||
|
||||
# If there are any parameter sets left, select the next one; otherwise, show name_newparset
|
||||
if param_values and param_values[0] != name_newparset:
|
||||
param_dropdown['values'] = param_values
|
||||
param_dropdown.set(param_values[0]) # Select the first remaining parameter set
|
||||
load_selected_param() # Load the values of the first remaining parameter set
|
||||
else:
|
||||
# If no parameter sets left, show name_newparset
|
||||
param_dropdown['values'] = [name_newparset]
|
||||
param_dropdown.set(name_newparset)
|
||||
|
||||
# Clear the input fields when no parameter sets are left
|
||||
for key in input_vars[group_name]:
|
||||
input_vars[group_name][key].set('')
|
||||
|
||||
# Detect and save a new parameter set if entered via dropdown (press Enter)
|
||||
def on_enter_new_param(event):
|
||||
selected_param = param_dropdown.get()
|
||||
if selected_param not in param_values and selected_param.strip():
|
||||
param_values.insert(-1, selected_param)
|
||||
param_dropdown['values'] = param_values
|
||||
save_current_param()
|
||||
param_dropdown.set(selected_param)
|
||||
if name_newparset not in param_values:
|
||||
param_values.append(name_newparset) # Ensure it's only appended once
|
||||
update_inlay_picture()
|
||||
|
||||
# Load and display the specific group picture
|
||||
group_image_tk = load_image(source_path, pic_sizelimit)
|
||||
image_label = ttk.Label(frame, image=group_image_tk)
|
||||
image_label.image = group_image_tk # Keep a reference to avoid garbage collection
|
||||
image_label.grid(row=0, column=0, columnspan=2, padx=10, pady=10, sticky="") # Center the image in the middle
|
||||
frame.grid_rowconfigure(0, minsize=230)
|
||||
|
||||
# Add horizontal line
|
||||
ttk.Separator(frame, orient='horizontal').grid(row=1, column=0, columnspan=2, sticky="ew", pady=10)
|
||||
|
||||
# Dropdown field and buttons for save/load/delete
|
||||
ttk.Label(frame, text="Parameter Set:").grid(row=2, column=0, padx=5, pady=5, sticky="w")
|
||||
param_dropdown.grid(row=2, column=1, padx=5, pady=5)
|
||||
# ttk.Button(frame, text="Load", command=load_selected_param).grid(row=3, column=0, padx=5, pady=5, sticky="w")
|
||||
ttk.Button(frame, text="Save", command=save_current_param).grid(row=3, column=0, padx=5, pady=5, sticky="w")
|
||||
ttk.Button(frame, text="Delete", command=delete_current_param).grid(row=3, column=1, padx=5, pady=5, sticky="w")
|
||||
|
||||
# Add horizontal line
|
||||
ttk.Separator(frame, orient='horizontal').grid(row=4, column=0, columnspan=2, sticky="ew", pady=10)
|
||||
|
||||
# Setup input fields below dropdown and buttons
|
||||
row = 5
|
||||
group_vars = {}
|
||||
for var_name, _ in group_data['parameter'].items():
|
||||
ttk.Label(frame, text=var_name).grid(row=row, column=0, padx=5, pady=5, sticky="e")
|
||||
var = tk.StringVar()
|
||||
group_vars[var_name] = var
|
||||
ttk.Entry(frame, textvariable=var).grid(row=row, column=1, padx=5, pady=5, sticky="w")
|
||||
row += 1
|
||||
input_vars[group_name] = group_vars
|
||||
|
||||
# Automatically select and load the first parameter set
|
||||
if param_values and param_values[0] != name_newparset:
|
||||
param_var.set(param_values[0])
|
||||
load_selected_param() # Directly load the first parameter set
|
||||
else:
|
||||
param_var.set(name_newparset) # If no parameters available, set to default
|
||||
|
||||
# Bind the dropdown selection event
|
||||
param_dropdown.bind("<<ComboboxSelected>>", lambda event: load_selected_param())
|
||||
# param_dropdown.event_generate("<<ComboboxSelected>>") # Trigger the ComboboxSelected
|
||||
|
||||
# Bind the Enter key to detect when a new parameter set is typed and saved
|
||||
param_dropdown.bind("<Return>", on_enter_new_param)
|
||||
|
||||
# Automatically generate and display the picture at startup
|
||||
update_inlay_picture()
|
||||
|
||||
|
||||
|
||||
def setup_jobs(frame, data, selected_job, selected_params, input_vars, group_widgets):
|
||||
# Load existing jobs from the jobs.yml file
|
||||
job_values = get_existing_parameters("jobs", folder_parsets)
|
||||
job_values.append(name_newjob)
|
||||
|
||||
# Function to load selected job and update each group
|
||||
def load_selected_job():
|
||||
job_name = selected_job.get()
|
||||
if job_name != name_newjob:
|
||||
job_data = load_yaml("jobs", job_name, folder_parsets)
|
||||
# Update the parameter sets for each group according to the job
|
||||
for group_name, param_set in job_data.items():
|
||||
if group_name in selected_params:
|
||||
# Check if the parameter set exists for the group
|
||||
param_values = get_existing_parameters(group_name, folder_parsets)
|
||||
if param_set not in param_values:
|
||||
# If parameter set is missing, set to <<new par set>> and clear fields
|
||||
selected_params[group_name].set(name_newparset)
|
||||
clear_input_fields(group_name)
|
||||
else:
|
||||
selected_params[group_name].set(param_set)
|
||||
# Manually trigger the parameter dropdown change for the group
|
||||
param_dropdown = group_widgets[group_name]["param_dropdown"]
|
||||
param_dropdown.set(param_set) # Update dropdown to show selected set
|
||||
param_dropdown.event_generate("<<ComboboxSelected>>")
|
||||
|
||||
# Function to clear the input fields when a parameter set is missing
|
||||
def clear_input_fields(group_name):
|
||||
for key in input_vars[group_name]:
|
||||
input_vars[group_name][key].set('') # Clear the input fields
|
||||
|
||||
# Function to load the selected parameter set for a group and update inputs
|
||||
def load_selected_param_for_group(group_name, param_set):
|
||||
try:
|
||||
param_data = load_yaml(group_name, param_set, folder_parsets)
|
||||
for key, value in param_data.items():
|
||||
input_vars[group_name][key].set(value)
|
||||
# Trigger the picture update by generating the ComboboxSelected event
|
||||
param_dropdown = group_widgets[group_name]["param_dropdown"]
|
||||
param_dropdown.event_generate("<<ComboboxSelected>>")
|
||||
except FileNotFoundError:
|
||||
# Handle missing parameter set gracefully
|
||||
selected_params[group_name].set(name_newparset)
|
||||
clear_input_fields(group_name)
|
||||
|
||||
# Function to save the current job
|
||||
def save_current_job():
|
||||
job_name = selected_job.get()
|
||||
if job_name not in job_values and job_name.strip():
|
||||
job_values.insert(-1, job_name) # Insert before '<<new job>>'
|
||||
selected_job.set(job_name)
|
||||
job_data = {group_name: selected_params[group_name].get() for group_name in data['groups']}
|
||||
save_yaml("jobs", job_name, job_data, folder_parsets)
|
||||
|
||||
# Update job dropdown after saving a new job
|
||||
job_dropdown['values'] = job_values
|
||||
job_dropdown.set(job_name)
|
||||
|
||||
# Function to delete the selected job
|
||||
def delete_current_job():
|
||||
job_name = selected_job.get()
|
||||
if job_name in job_values and job_name != name_newjob:
|
||||
confirm = messagebox.askyesno("Delete Job", f"Are you sure you want to delete '{job_name}'?")
|
||||
if confirm:
|
||||
delete_yaml("jobs", job_name, folder_parsets)
|
||||
job_values.remove(job_name)
|
||||
selected_job.set(job_values[0] if job_values else name_newjob)
|
||||
# Update job dropdown after deletion
|
||||
job_dropdown['values'] = job_values
|
||||
load_selected_job()
|
||||
|
||||
# Job dropdown and buttons for save/load/delete
|
||||
ttk.Label(frame, text="Job:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
|
||||
job_dropdown = ttk.Combobox(frame, textvariable=selected_job, values=job_values)
|
||||
job_dropdown.grid(row=0, column=1, padx=5, pady=5)
|
||||
ttk.Button(frame, text="Save", command=save_current_job).grid(row=1, column=0, padx=5, pady=5, sticky="w")
|
||||
ttk.Button(frame, text="Delete", command=delete_current_job).grid(row=1, column=1, padx=5, pady=5, sticky="w")
|
||||
|
||||
# Bind job selection to loading the selected job and updating the groups
|
||||
job_dropdown.bind("<<ComboboxSelected>>", lambda event: load_selected_job())
|
||||
job_dropdown.bind("<Return>", lambda event: save_current_job())
|
||||
|
||||
# After setting up all UI components
|
||||
if job_values and job_values[0] != name_newjob:
|
||||
selected_job.set(job_values[0]) # Select the first job automatically
|
||||
load_selected_job() # Load the first job's parameters and update the corresponding parameter sets
|
||||
|
||||
return load_selected_job
|
||||
|
||||
|
||||
|
||||
def setup_evaluation(root, folder_pictures, data, folder_output, input_vars, selected_params):
|
||||
# Create a frame for the EVALUATION section
|
||||
frame = ttk.LabelFrame(root, text="EVALUATION", padding=(10, 10))
|
||||
frame.grid(row=2, column=0, columnspan=5, padx=10, pady=10, sticky="nsew")
|
||||
|
||||
# Load and display the specific initial picture
|
||||
picture_path = f"{folder_pictures}/{data['general']['initpic_name']}"
|
||||
group_image_tk = load_image(picture_path, 200) # Assuming a function load_image exists and works as expected
|
||||
image_label = ttk.Label(frame, image=group_image_tk)
|
||||
image_label.image = group_image_tk # Keep a reference to avoid garbage collection
|
||||
image_label.grid(row=0, column=0, rowspan=2, padx=10, pady=10)
|
||||
|
||||
# Function to generate configuration file based on current parameters
|
||||
def btn_gen():
|
||||
generate_config_spf(folder_output, input_vars, selected_params)
|
||||
|
||||
# Place buttons in the vertical frame for operations
|
||||
button_frame = ttk.Frame(frame)
|
||||
button_frame.grid(row=0, column=1, padx=10, pady=10, sticky="n")
|
||||
button1 = ttk.Button(button_frame, text="GENERATE DMUAUT_CFG.SPF FILE", width=45, command=btn_gen)
|
||||
button1.grid(row=0, column=0, padx=10, pady=5)
|
||||
|
||||
root.grid_columnconfigure(0, weight=1)
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
# Tkinter root setup
|
||||
root = tk.Tk()
|
||||
root.title("DMU50")
|
||||
|
||||
# Load object definitions from YAML
|
||||
with open(file_def, 'r') as file:
|
||||
data = yaml.safe_load(file)
|
||||
|
||||
input_vars = {}
|
||||
selected_params = {} # Dictionary to track selected parameters for each group
|
||||
selected_job = tk.StringVar()
|
||||
group_widgets = {} # Dictionary to store widgets related to groups
|
||||
|
||||
def setup_ui():
|
||||
# ---- Setup Jobs UI
|
||||
frame = ttk.LabelFrame(root, text="Jobs", padding=(10, 10))
|
||||
frame.grid(row=0, column=0, columnspan=5, padx=10, pady=10, sticky="nsew")
|
||||
load_selected_job = setup_jobs(frame, data, selected_job, selected_params, input_vars, group_widgets)
|
||||
|
||||
# ---- Create the UI for each group
|
||||
for col_idx, group_name in enumerate(data['groups']):
|
||||
frame_group = ttk.LabelFrame(root, text=group_name, padding=(10, 10))
|
||||
frame_group.grid(row=1, column=col_idx, padx=10, pady=10, sticky="nsew")
|
||||
|
||||
selected_params[group_name] = tk.StringVar()
|
||||
setup_group(frame_group, group_name, data, input_vars, selected_params, group_widgets)
|
||||
|
||||
root.grid_columnconfigure(list(range(col_idx + 1)), weight=1)
|
||||
root.grid_rowconfigure(0, weight=1)
|
||||
|
||||
# ---- Setup the EVALUATION section
|
||||
setup_evaluation(root, folder_pictures, data, folder_output, input_vars, selected_params)
|
||||
|
||||
# After the UI is fully set up, load the selected job to update parameter lists
|
||||
load_selected_job() # Ensure this is called to load the job parameters
|
||||
|
||||
# Show the window after setup is complete
|
||||
root.deiconify()
|
||||
|
||||
# Initially hide the root window
|
||||
root.withdraw()
|
||||
|
||||
# Delay UI setup by 1000 milliseconds (1 second)
|
||||
root.after(300, setup_ui)
|
||||
|
||||
# Start the Tkinter event loop
|
||||
root.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
10
_condaenv.yml
Normal file
@ -0,0 +1,10 @@
|
||||
name: dmu50_wingui
|
||||
channels:
|
||||
- defaults
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- python=3.10
|
||||
- pyyaml
|
||||
- jsonschema
|
||||
- tk
|
||||
- pillow
|
||||
4
cfg_parsets/clp.yml
Normal file
@ -0,0 +1,4 @@
|
||||
clp1:
|
||||
clp_offset: '0'
|
||||
clp2:
|
||||
clp_offset: '0'
|
||||
28
cfg_parsets/grp.yml
Normal file
@ -0,0 +1,28 @@
|
||||
grp1:
|
||||
h_offset: '30'
|
||||
h_step: '10'
|
||||
hub: '50'
|
||||
steps_num: '5'
|
||||
w_offset: '40'
|
||||
w_step: '45'
|
||||
grp2:
|
||||
h_offset: '30'
|
||||
h_step: '5'
|
||||
hub: '10'
|
||||
steps_num: '6'
|
||||
w_offset: '20'
|
||||
w_step: '10'
|
||||
grp3:
|
||||
h_offset: '10'
|
||||
h_step: '25'
|
||||
hub: '10'
|
||||
steps_num: '5'
|
||||
w_offset: '25'
|
||||
w_step: '45'
|
||||
newset:
|
||||
h_offset: '10'
|
||||
h_step: '25'
|
||||
hub: '10'
|
||||
steps_num: '5'
|
||||
w_offset: '25'
|
||||
w_step: '45'
|
||||
12
cfg_parsets/inlay.yml
Normal file
@ -0,0 +1,12 @@
|
||||
inlay7:
|
||||
kos: '4'
|
||||
x_num: '4'
|
||||
x_offset: '30'
|
||||
y_num: '3'
|
||||
y_offset: '30'
|
||||
inlay_kleinteil:
|
||||
kos: '4'
|
||||
x_num: '7'
|
||||
x_offset: '5'
|
||||
y_num: '4'
|
||||
y_offset: '4'
|
||||
12
cfg_parsets/jobs.yml
Normal file
@ -0,0 +1,12 @@
|
||||
job1:
|
||||
clp: clp1
|
||||
grp: grp1
|
||||
inlay: inlay7
|
||||
wp_fin: wpfin1
|
||||
wp_raw: wpraw1
|
||||
job3:
|
||||
clp: clp1
|
||||
grp: grp3
|
||||
inlay: inlay_kleinteil
|
||||
wp_fin: wpfin1
|
||||
wp_raw: wpraw1
|
||||
5
cfg_parsets/wp_fin.yml
Normal file
@ -0,0 +1,5 @@
|
||||
wpfin1:
|
||||
l_wpfin: '8'
|
||||
x_wpfin: '20'
|
||||
y_wpfin: '10'
|
||||
z_wpfin: '13'
|
||||
8
cfg_parsets/wp_raw.yml
Normal file
@ -0,0 +1,8 @@
|
||||
test:
|
||||
x_wpraw: '20'
|
||||
y_wpraw: '10'
|
||||
z_wpraw: '20'
|
||||
wpraw1:
|
||||
x_wpraw: '10'
|
||||
y_wpraw: '10'
|
||||
z_wpraw: '20'
|
||||
BIN
cfg_picture/Thumbs.db
Normal file
BIN
cfg_picture/img_clp.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
BIN
cfg_picture/img_grp.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
cfg_picture/img_inlay.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
cfg_picture/img_wpfin.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
cfg_picture/img_wpraw.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
cfg_picture/puppy - Kopie.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
cfg_picture/puppy.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
44
def.yml
Normal file
@ -0,0 +1,44 @@
|
||||
general:
|
||||
yolovar: int
|
||||
initpic_name: puppy.png
|
||||
|
||||
groups:
|
||||
inlay:
|
||||
parameter:
|
||||
x_num: int
|
||||
x_offset: double
|
||||
y_num: int
|
||||
y_offset: double
|
||||
kos: str
|
||||
cfg:
|
||||
picture_name: img_inlay.png
|
||||
wp_raw:
|
||||
parameter:
|
||||
x_wpraw: double
|
||||
y_wpraw: double
|
||||
z_wpraw: double
|
||||
cfg:
|
||||
picture_name: img_wpraw.png
|
||||
wp_fin:
|
||||
parameter:
|
||||
x_wpfin: double
|
||||
y_wpfin: double
|
||||
z_wpfin: double
|
||||
l_wpfin: double
|
||||
cfg:
|
||||
picture_name: img_wpfin.png
|
||||
grp:
|
||||
parameter:
|
||||
hub: double
|
||||
h_offset: double
|
||||
h_step: double
|
||||
w_offset: double
|
||||
w_step: double
|
||||
steps_num: int
|
||||
cfg:
|
||||
picture_name: img_grp.png
|
||||
clp:
|
||||
parameter:
|
||||
clp_offset: double
|
||||
cfg:
|
||||
picture_name: img_clp.png
|
||||
130
funct_clp.py
Normal file
@ -0,0 +1,130 @@
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
||||
import numpy as np
|
||||
|
||||
|
||||
def generate_picture_clp(all_group_vars, picture_path, DEBUG=False):
|
||||
try:
|
||||
# Get x_wpraw, y_wpraw, and z_wpraw values
|
||||
vars = all_group_vars['wp_raw']
|
||||
x_wpraw = float(vars['x_wpraw'])
|
||||
y_wpraw = float(vars['y_wpraw'])
|
||||
z_wpraw = float(vars['z_wpraw'])
|
||||
x_cube = x_wpraw*2
|
||||
y_cube = y_wpraw*2
|
||||
z_cube = z_wpraw
|
||||
clp_offset = float(all_group_vars['clp']['clp_offset'])
|
||||
|
||||
# ERROR HANDLING
|
||||
if x_cube <= 0 or y_cube <= 0 or z_cube <= 0:
|
||||
raise ValueError("x_wpraw, y_wpraw, and z_wpraw must be positive values.")
|
||||
|
||||
# Define the vertices of the cube based on wpraw dimensions
|
||||
vertices = (np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0],
|
||||
[0, 0, z_cube], [x_cube, 0, z_cube], [x_cube, y_cube, z_cube], [0, y_cube, z_cube]])
|
||||
+ np.array([0, -clp_offset, 0]))
|
||||
|
||||
# Define the 6 faces of the cube
|
||||
faces = [[vertices[j] for j in [0, 1, 2, 3]], # Bottom face
|
||||
[vertices[j] for j in [4, 5, 6, 7]], # Top face
|
||||
[vertices[j] for j in [0, 3, 7, 4]], # Left face
|
||||
[vertices[j] for j in [1, 2, 6, 5]], # Right face
|
||||
[vertices[j] for j in [0, 1, 5, 4]], # Front face
|
||||
[vertices[j] for j in [2, 3, 7, 6]]] # Back face
|
||||
|
||||
# Plot the cube in 3D
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(111, projection='3d')
|
||||
|
||||
# Plot the cube with the specified faces
|
||||
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
|
||||
|
||||
# Set the aspect ratio for each axis
|
||||
ax.set_box_aspect([x_cube, y_cube, z_cube])
|
||||
|
||||
# Hide the axis ticks and labels
|
||||
ax.set_xticks([]) # Hide X axis ticks
|
||||
ax.set_yticks([]) # Hide Y axis ticks
|
||||
ax.set_zticks([]) # Hide Z axis ticks
|
||||
|
||||
# Add a ball (sphere) at the center of the cube
|
||||
ball_radius = min(x_wpraw, y_wpraw, z_wpraw) * 0.1 # Size relative to cube dimensions
|
||||
|
||||
u = np.linspace(0, 2 * np.pi, 20)
|
||||
v = np.linspace(0, np.pi, 20)
|
||||
x_sphere = x_wpraw + ball_radius * np.outer(np.cos(u), np.sin(v))
|
||||
y_sphere = y_wpraw - clp_offset + ball_radius * np.outer(np.sin(u), np.sin(v))
|
||||
z_sphere = z_wpraw + ball_radius * np.outer(np.ones(np.size(u)), np.cos(v))
|
||||
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='red', alpha=1)
|
||||
|
||||
# Add the origin sparrow (a small 3D marker at the origin)
|
||||
max_size = max(x_cube, y_cube, z_cube) * 0.2 # Scale the arrows relative to the smallest dimension
|
||||
ax.quiver(0, -clp_offset, 0, max_size, 0, 0, color='red', linewidth=2, label='X-axis') # Red arrow for X-axis
|
||||
ax.quiver(0, -clp_offset, 0, 0, max_size, 0, color='green', linewidth=2, label='Y-axis') # Green arrow for Y-axis
|
||||
ax.quiver(0, -clp_offset, 0, 0, 0, max_size, color='blue', linewidth=2, label='Z-axis') # Blue arrow for Z-axis
|
||||
|
||||
# Add two black blocks (greifer fingers) on the Y-faces in the middle of the cube height
|
||||
max_size2 = max(x_cube, y_cube, z_cube) * 0.4 # Scale the arrows relative to the smallest dimension
|
||||
ax.bar3d(-max_size2, -(2.0-1)/2 * y_cube, -z_wpraw * 0.0,
|
||||
max_size2, 2.0 * y_cube, z_wpraw * 0.2,
|
||||
color='black', alpha=.10)
|
||||
ax.bar3d(-max_size2, -(2.0-1)/2 * y_cube, -z_wpraw * 0.0,
|
||||
max_size2+3, 2.0 * y_cube, -z_wpraw * 0.2,
|
||||
color='black', alpha=.10)
|
||||
|
||||
ax.bar3d(x_cube, -(2-1)/2 * y_cube, -z_wpraw * 0.0,
|
||||
max_size2, 2.0 * y_cube, z_wpraw * 0.2,
|
||||
color='black', alpha=.10)
|
||||
ax.bar3d(x_cube-3, -(2-1)/2 * y_cube, -z_wpraw * 0.0,
|
||||
max_size2+3, 2.0 * y_cube, -z_wpraw * 0.2,
|
||||
color='black', alpha=.10)
|
||||
|
||||
# Add the origin sparrow (a small 3D marker at the origin)
|
||||
max_size3 = max(x_cube, y_cube, z_cube) * 0.3 # Scale the arrows relative to the smallest dimension
|
||||
ax.quiver(x_wpraw, y_wpraw, 0, max_size3, 0, 0, color='red', linewidth=3, label='X-axis') # Red arrow for X-axis
|
||||
ax.quiver(x_wpraw, y_wpraw, 0, 0, max_size3, 0, color='green', linewidth=3, label='Y-axis') # Green arrow for Y-axis
|
||||
ax.quiver(x_wpraw, y_wpraw, 0, 0, 0, max_size3, color='blue', linewidth=3, label='Z-axis') # Blue arrow for Z-axis
|
||||
|
||||
# Set viewing angle
|
||||
ax.view_init(elev=30, azim=-150) # Set elevation to 24° and azimuth to -151°
|
||||
# ax.view_init(elev=90, azim=180) # Set elevation to 24° and azimuth to -151°
|
||||
|
||||
# Set limits for the axes
|
||||
# ax.set_xlim([0, x_cube])
|
||||
# ax.set_ylim([0, y_cube])
|
||||
# ax.set_zlim([0, z_cube])
|
||||
|
||||
# Set equal aspect ratio to make grid cells look square
|
||||
ax.set_aspect('equal')
|
||||
|
||||
if not DEBUG:
|
||||
# Save the figure to the specified picture path
|
||||
fig.savefig(picture_path, bbox_inches='tight', pad_inches=0.1, dpi=300, transparent=True)
|
||||
else:
|
||||
plt.show()
|
||||
|
||||
# Close the figure to free memory
|
||||
plt.close()
|
||||
|
||||
except ValueError as ve:
|
||||
# Handle value error (e.g., invalid input)
|
||||
print(f"Invalid Input: Error: {ve}")
|
||||
|
||||
except Exception as e:
|
||||
# Catch any other exceptions and show a generic error message
|
||||
print(f"An error occurred while generating the 3D cube: {e}")
|
||||
|
||||
|
||||
# Example use-case
|
||||
if __name__ == "__main__":
|
||||
all_group_vars = {
|
||||
'wp_raw': {
|
||||
'x_wpraw': '10', # Example values for testing
|
||||
'y_wpraw': '15',
|
||||
'z_wpraw': '20'
|
||||
},
|
||||
'clp': {
|
||||
'clp_offset': '4'
|
||||
}
|
||||
}
|
||||
generate_picture_clp(all_group_vars, 'output_image.png', DEBUG=True)
|
||||
46
funct_gen.py
Normal file
@ -0,0 +1,46 @@
|
||||
# funct_gen.py
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
# Function to generate the DMUAUT_CFG.SPF configuration file and save selected parameter sets
|
||||
def generate_config_spf(folder_output, input_vars, selected_params):
|
||||
# Get the current timestamp for folder name (format: YYMMDD_HHmmSS)
|
||||
timestamp = time.strftime("%y%m%d_%H%M%S")
|
||||
folder_path = os.path.join(folder_output, f"{timestamp}")
|
||||
|
||||
# Create the folder with the timestamp
|
||||
if not os.path.exists(folder_path):
|
||||
os.makedirs(folder_path)
|
||||
|
||||
# Define the file path for the SPF configuration file
|
||||
spf_file_path = os.path.join(folder_path, "DMUAUT_CFG.SPF")
|
||||
|
||||
# Generate the SPF file content
|
||||
with open(spf_file_path, "w") as spf_file:
|
||||
spf_file.write(f"; CFG FILE FOR DMU50 AUTOMATION\n")
|
||||
spf_file.write(f"; GENERATED: {timestamp}\n")
|
||||
spf_file.write("; ---------------------------------------------------\n")
|
||||
|
||||
# Iterate over the input variables (each group), and write them into the file
|
||||
for group_name, variables in input_vars.items():
|
||||
for var_name, var_value in variables.items():
|
||||
spf_file.write(f"{var_name.upper()} = {var_value.get()}\n")
|
||||
spf_file.write("\n")
|
||||
spf_file.write("; ---------------------------------------------------\n")
|
||||
|
||||
# Define the file path for the text file with selected parameter sets
|
||||
selected_params_file_path = os.path.join(folder_path, "selected_param_sets.txt")
|
||||
|
||||
# Save the currently selected parameter sets in a .txt file
|
||||
with open(selected_params_file_path, "w") as param_file:
|
||||
param_file.write("Selected Parameter Sets:\n")
|
||||
for group_name, param_name in selected_params.items():
|
||||
# Extract the actual value from the tk.StringVar object using .get()
|
||||
param_file.write(f"{group_name}: {param_name.get()}\n")
|
||||
|
||||
print(f"Configuration files saved in {folder_path}")
|
||||
|
||||
# def generate_config_spf():
|
||||
# tbd
|
||||
88
funct_grp.py
Normal file
@ -0,0 +1,88 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
|
||||
def generate_picture_grp(all_group_vars, picture_path, DEBUG=False):
|
||||
try:
|
||||
# Extract variables for the gripper
|
||||
vars = all_group_vars['grp']
|
||||
h_offset = float(vars['h_offset'])
|
||||
h_step = float(vars['h_step'])
|
||||
w_offset = float(vars['w_offset'])
|
||||
w_step = float(vars['w_step'])
|
||||
steps_num = int(vars['steps_num'])
|
||||
|
||||
# ERROR HANDLING
|
||||
if h_step <= 0 or w_step <= 0 or steps_num <= 0:
|
||||
raise ValueError("h_step, w_step, and steps_num must be positive values.")
|
||||
|
||||
# Initialize figure
|
||||
fig, ax = plt.subplots(figsize=(6, 6)) # Square figure
|
||||
ax.set_aspect('equal')
|
||||
|
||||
# Draw the gripper finger
|
||||
def draw_gripper(x_sign=1):
|
||||
max_width = x_sign * (w_offset + w_step * (steps_num - 1))
|
||||
current_height = h_offset
|
||||
current_width = x_sign * w_offset
|
||||
|
||||
# Draw the first block
|
||||
rect = plt.Rectangle((x_sign, 0), max_width - x_sign, h_offset, facecolor='black', linewidth=0)
|
||||
ax.add_patch(rect)
|
||||
|
||||
# Draw the steps
|
||||
for _ in range(steps_num):
|
||||
rect = plt.Rectangle((current_width, current_height), max_width - current_width, h_step, facecolor='black', linewidth=0)
|
||||
ax.add_patch(rect)
|
||||
current_height += h_step
|
||||
current_width += x_sign * w_step
|
||||
|
||||
# Draw original gripper finger and x flipped
|
||||
draw_gripper()
|
||||
draw_gripper(x_sign=-1)
|
||||
|
||||
# Plot the origin point at (0, 0)
|
||||
ax.plot(0, 0, marker='o', markersize=10, color='red') # Red point at origin
|
||||
|
||||
# Flip the y-axis (invert it)
|
||||
ax.invert_yaxis()
|
||||
|
||||
# Set equal aspect ratio to make grid cells look square
|
||||
ax.set_aspect('equal')
|
||||
|
||||
# Hide major ticks and labels (only gridlines should be visible)
|
||||
ax.set_xticks([])
|
||||
ax.set_yticks([])
|
||||
|
||||
# Add a white border around the plot to ensure the outer gridlines are visible
|
||||
fig.patch.set_facecolor('white')
|
||||
plt.subplots_adjust(left=0.05, right=0.95, top=0.95, bottom=0.05) # Adjust padding for the white border
|
||||
|
||||
if not DEBUG:
|
||||
# Save the figure to the specified picture path
|
||||
plt.gca().set_aspect('equal', adjustable='box')
|
||||
fig.savefig(picture_path, bbox_inches='tight', pad_inches=0.1, dpi=300, transparent=True)
|
||||
else:
|
||||
plt.show()
|
||||
|
||||
# Close the figure to free memory
|
||||
plt.close()
|
||||
|
||||
except ValueError as ve:
|
||||
# Handle value error (e.g., invalid input)
|
||||
print(f"Invalid Input: Error: {ve}")
|
||||
except Exception as e:
|
||||
# Catch any other exceptions and show a generic error message
|
||||
print(f"An error occurred while generating the gripper finger: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
vars = {
|
||||
'h_offset': 10,
|
||||
'h_step': 5,
|
||||
'w_offset': 20,
|
||||
'w_step': 10,
|
||||
'steps_num': 5
|
||||
}
|
||||
picture_path = "cfg_picture/TEST_gripper_finger.jpg"
|
||||
generate_picture_grp(vars, picture_path, DEBUG=True)
|
||||
63
funct_inlay.py
Normal file
@ -0,0 +1,63 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
def generate_picture_inlay(all_group_vars, picture_path, DEBUG=False):
|
||||
try:
|
||||
vars = all_group_vars['inlay']
|
||||
x_num, y_num = int(vars['x_num']), int(vars['y_num'])
|
||||
x_offset_mm, y_offset_mm = float(vars['x_offset']), float(vars['y_offset'])
|
||||
canvas_width_mm, canvas_height_mm = 800, 1200
|
||||
x_offset = x_offset_mm / canvas_height_mm # Swapping due to axis swap
|
||||
y_offset = y_offset_mm / canvas_width_mm # Swapping due to axis swap
|
||||
|
||||
if x_num <= 0 or y_num <= 0:
|
||||
raise ValueError("x_num and y_num must be positive integers.")
|
||||
|
||||
fig, ax = plt.subplots(figsize=(12, 8))
|
||||
ax.set_facecolor('black')
|
||||
|
||||
total_x_offset = x_offset * (y_num + 1)
|
||||
total_y_offset = y_offset * (x_num + 1)
|
||||
rect_width = (1 - total_y_offset) / x_num
|
||||
rect_height = (1 - total_x_offset) / y_num
|
||||
|
||||
for j in range(x_num):
|
||||
for i in range(y_num):
|
||||
# Mirroring horizontally
|
||||
x_start = 1 - (y_offset + i * (rect_height + y_offset) + rect_height)
|
||||
y_start = x_offset + j * (rect_width + x_offset)
|
||||
|
||||
rect = plt.Rectangle((x_start, y_start), rect_height, rect_width, color='white')
|
||||
ax.add_patch(rect)
|
||||
|
||||
triangle = plt.Polygon([
|
||||
(x_start + rect_height, y_start), # Bottom right of the rectangle
|
||||
(x_start + rect_height - 0.05 * rect_height, y_start), # Left along the bottom
|
||||
(x_start + rect_height, y_start + 0.05 * rect_width) # Up from the bottom right
|
||||
], color='black')
|
||||
ax.add_patch(triangle)
|
||||
|
||||
# Arrows with adjusted margins
|
||||
ax.arrow(0.98, 0.02, -0.9, 0, head_width=0.03, head_length=0.02, fc='green', ec='green', linewidth=2, edgecolor='white')
|
||||
ax.arrow(0.98, 0.02, 0, 0.9, head_width=0.02, head_length=0.03, fc='red', ec='red', linewidth=2, edgecolor='white')
|
||||
|
||||
ax.set_xlim(0, 1)
|
||||
ax.set_ylim(0, 1)
|
||||
ax.set_xticks([]), ax.set_yticks([])
|
||||
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1) # Adjusting the margins
|
||||
|
||||
if DEBUG:
|
||||
plt.show()
|
||||
else:
|
||||
fig.savefig(picture_path, bbox_inches='tight', pad_inches=0.5, dpi=300, transparent=True) # Adjusted padding
|
||||
plt.close()
|
||||
|
||||
except ValueError as ve:
|
||||
print(f"Invalid Input: {ve}")
|
||||
except Exception as e:
|
||||
print(f"Error generating matrix: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
vars = {'x_num': 5, 'y_num': 3, 'x_offset': 20, 'y_offset': 20}
|
||||
picture_path = "cfg_picture/TEST_inlay.jpg"
|
||||
generate_picture_inlay({'inlay': vars}, picture_path, DEBUG=True)
|
||||
142
funct_wp.py
Normal file
@ -0,0 +1,142 @@
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
||||
import numpy as np
|
||||
|
||||
|
||||
def generate_picture_wpraw(all_group_vars, picture_path, DEBUG=False):
|
||||
try:
|
||||
# --- wpraw
|
||||
vars = all_group_vars['wp_raw']
|
||||
x, y, z = float(vars['x_wpraw']), float(vars['y_wpraw']), float(vars['z_wpraw'])
|
||||
if min(x, y, z) <= 0:
|
||||
raise ValueError("Dimensions must be positive.")
|
||||
|
||||
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
|
||||
x_cube, y_cube = 2 * x, 2 * y
|
||||
vertices = np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0],
|
||||
[0, 0, z], [x_cube, 0, z], [x_cube, y_cube, z], [0, y_cube, z]])
|
||||
faces = [vertices[[0, 1, 2, 3]], vertices[[4, 5, 6, 7]], vertices[[0, 3, 7, 4]],
|
||||
vertices[[1, 2, 6, 5]], vertices[[0, 1, 5, 4]], vertices[[2, 3, 7, 6]]]
|
||||
|
||||
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
|
||||
ax.set_box_aspect([x_cube, y_cube, z])
|
||||
ax.set_xticks([]);
|
||||
ax.set_yticks([]);
|
||||
ax.set_zticks([])
|
||||
ball_radius = min(x, y, z) * 0.1
|
||||
u, v = np.linspace(0, 2 * np.pi, 20), np.linspace(0, np.pi, 20)
|
||||
x_sphere = x + ball_radius * np.outer(np.cos(u), np.sin(v))
|
||||
y_sphere = y + ball_radius * np.outer(np.sin(u), np.sin(v))
|
||||
z_sphere = z + ball_radius * np.outer(np.ones_like(u), np.cos(v))
|
||||
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='r', alpha=1)
|
||||
|
||||
max_size = max(x_cube, y_cube, z) * 0.3
|
||||
ax.quiver(0, 0, 0, max_size, 0, 0, color='r', linewidth=5)
|
||||
ax.quiver(0, 0, 0, 0, max_size, 0, color='g', linewidth=5)
|
||||
ax.quiver(0, 0, 0, 0, 0, max_size, color='b', linewidth=5)
|
||||
|
||||
block_depth = y * 0.4
|
||||
ax.bar3d(-max_size, (y_cube - block_depth) * 0.5, z * 0.8, max_size, block_depth, z * 0.8, color='k', alpha=.25)
|
||||
ax.bar3d(x_cube, (y_cube - block_depth) * 0.5, z * 0.8, max_size, block_depth, z * 0.8, color='k', alpha=.25)
|
||||
|
||||
|
||||
|
||||
ax.view_init(elev=18, azim=-130)
|
||||
ax.set_xlim([0, x_cube]); ax.set_ylim([0, y_cube]); ax.set_zlim([0, z])
|
||||
ax.set_aspect('auto')
|
||||
|
||||
if not DEBUG:
|
||||
fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
|
||||
else:
|
||||
plt.show()
|
||||
plt.close()
|
||||
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
|
||||
|
||||
def generate_picture_wpfin(all_group_vars, picture_path, DEBUG=False):
|
||||
try:
|
||||
# --- wpraw
|
||||
vars = all_group_vars['wp_raw']
|
||||
x, y, z = float(vars['x_wpraw']), float(vars['y_wpraw']), float(vars['z_wpraw'])
|
||||
if min(x, y, z) <= 0:
|
||||
raise ValueError("Dimensions must be positive.")
|
||||
|
||||
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
|
||||
x_cube, y_cube = 2 * x, 2 * y
|
||||
vertices = np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0],
|
||||
[0, 0, z], [x_cube, 0, z], [x_cube, y_cube, z], [0, y_cube, z]])
|
||||
faces = [vertices[[0, 1, 2, 3]], vertices[[4, 5, 6, 7]], vertices[[0, 3, 7, 4]],
|
||||
vertices[[1, 2, 6, 5]], vertices[[0, 1, 5, 4]], vertices[[2, 3, 7, 6]]]
|
||||
|
||||
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
|
||||
ax.set_box_aspect([x_cube, y_cube, z])
|
||||
ax.set_xticks([]);
|
||||
ax.set_yticks([]);
|
||||
ax.set_zticks([])
|
||||
ball_radius = min(x, y, z) * 0.1
|
||||
u, v = np.linspace(0, 2 * np.pi, 20), np.linspace(0, np.pi, 20)
|
||||
x_sphere = x + ball_radius * np.outer(np.cos(u), np.sin(v))
|
||||
y_sphere = y + ball_radius * np.outer(np.sin(u), np.sin(v))
|
||||
z_sphere = z + ball_radius * np.outer(np.ones_like(u), np.cos(v))
|
||||
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='r', alpha=1)
|
||||
|
||||
|
||||
# --- wprfin
|
||||
vars = all_group_vars['wp_fin']
|
||||
x, y, z, l = float(vars['x_wpfin']), float(vars['y_wpfin']), float(vars['z_wpfin']), float(vars['l_wpfin'])
|
||||
if min(x, y, z, l) <= 0:
|
||||
raise ValueError("Dimensions must be positive.")
|
||||
|
||||
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
|
||||
x_offset = x - l / 2
|
||||
vertices = np.array([[0, 0, 0], [l, 0, 0], [l, 2 * y, 0], [0, 2 * y, 0],
|
||||
[0, 0, z], [l, 0, z], [l, 2 * y, z], [0, 2 * y, z]]) + np.array([x_offset, 0, 0])
|
||||
faces = [vertices[[0, 1, 2, 3]], vertices[[4, 5, 6, 7]], vertices[[0, 3, 7, 4]],
|
||||
vertices[[1, 2, 6, 5]], vertices[[0, 1, 5, 4]], vertices[[2, 3, 7, 6]]]
|
||||
|
||||
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
|
||||
ball_radius = min(x, y, z) * 0.1
|
||||
u, v = np.linspace(0, 2 * np.pi, 20), np.linspace(0, np.pi, 20)
|
||||
x_sphere = x + ball_radius * np.outer(np.cos(u), np.sin(v))
|
||||
y_sphere = y + ball_radius * np.outer(np.sin(u), np.sin(v))
|
||||
z_sphere = z + ball_radius * np.outer(np.ones_like(u), np.cos(v))
|
||||
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='blue', alpha=1)
|
||||
|
||||
max_size = max(l, 2 * y, z) * 0.3
|
||||
ax.quiver(0, 0, 0, max_size, 0, 0, color='red', linewidth=5)
|
||||
ax.quiver(0, 0, 0, 0, max_size, 0, color='green', linewidth=5)
|
||||
ax.quiver(0, 0, 0, 0, 0, max_size, color='blue', linewidth=5)
|
||||
|
||||
block_depth = y * 0.4
|
||||
ax.bar3d(-max_size + x_offset, (2 * y - block_depth) * 0.5, z * 0.8, max_size, block_depth, z * 0.8,
|
||||
color='black', alpha=.25)
|
||||
ax.bar3d(l + x_offset, (2 * y - block_depth) * 0.5, z * 0.8, max_size, block_depth, z * 0.8, color='black',
|
||||
alpha=.25)
|
||||
|
||||
ax.view_init(elev=18, azim=-130)
|
||||
ax.set_xticks([]);
|
||||
ax.set_yticks([]);
|
||||
ax.set_zticks([])
|
||||
ax.set_xlim([0, l + x_offset]);
|
||||
ax.set_ylim([0, 2 * y]);
|
||||
ax.set_zlim([0, z])
|
||||
ax.set_aspect('equal')
|
||||
|
||||
if not DEBUG:
|
||||
fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
|
||||
else:
|
||||
plt.show()
|
||||
plt.close()
|
||||
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
vars = {'x_wpraw': 10, 'y_wpraw': 15, 'z_wpraw': 20}
|
||||
generate_picture_wpraw({'wp_raw': vars}, "cfg_picture/TEST_wpraw.jpg", DEBUG=True)
|
||||
|
||||
vars = {'x_wpfin': 10, 'y_wpfin': 20, 'z_wpfin': 20, 'l_wpfin': 10}
|
||||
generate_picture_wpfin({'wp_fin': vars}, "cfg_picture/TEST_wpfin.jpg", DEBUG=True)
|
||||
89
functions.py
Normal file
@ -0,0 +1,89 @@
|
||||
# functions.py
|
||||
|
||||
import yaml
|
||||
from PIL import Image, ImageTk
|
||||
from tkinter import ttk, filedialog, messagebox
|
||||
import tkinter as tk
|
||||
import os
|
||||
|
||||
# Function to load object definitions from YAML
|
||||
|
||||
# Load a specific parameter set from a YAML file for a group
|
||||
def load_yaml(group_name, param_name, folder_parsets):
|
||||
yml_file = os.path.join(folder_parsets, f"{group_name}.yml")
|
||||
if os.path.exists(yml_file):
|
||||
with open(yml_file, 'r') as file:
|
||||
data = yaml.safe_load(file)
|
||||
return data.get(param_name, {})
|
||||
return {}
|
||||
|
||||
# Save a parameter set to a YAML file for a group
|
||||
def save_yaml(group_name, param_name, param_data, folder_parsets):
|
||||
yml_file = os.path.join(folder_parsets, f"{group_name}.yml")
|
||||
all_data = load_existing_data(yml_file)
|
||||
all_data[param_name] = param_data
|
||||
with open(yml_file, 'w') as file:
|
||||
yaml.dump(all_data, file)
|
||||
# messagebox.showinfo("Success", f"Parameter set '{param_name}' saved to {group_name}.yml")
|
||||
|
||||
def delete_yaml(group_name, param_name, folder_parsets):
|
||||
yml_file = os.path.join(folder_parsets, f"{group_name}.yml")
|
||||
if os.path.exists(yml_file):
|
||||
with open(yml_file, 'r') as file:
|
||||
data = yaml.safe_load(file)
|
||||
if param_name in data:
|
||||
del data[param_name] # Remove the specific parameter set
|
||||
with open(yml_file, 'w') as file:
|
||||
yaml.safe_dump(data, file)
|
||||
|
||||
# Load existing data from a YAML file
|
||||
def load_existing_data(yml_file):
|
||||
if os.path.exists(yml_file):
|
||||
with open(yml_file, 'r') as file:
|
||||
return yaml.safe_load(file) or {}
|
||||
return {}
|
||||
|
||||
# Fetch existing parameter sets from a group-specific YAML file
|
||||
def get_existing_parameters(group_name, folder_parsets):
|
||||
yml_file = os.path.join(folder_parsets, f"{group_name}.yml")
|
||||
data = load_existing_data(yml_file)
|
||||
return list(data.keys())
|
||||
|
||||
# Load the image for the UI
|
||||
def load_image(image_file, sizelimit=200):
|
||||
image = Image.open(image_file)
|
||||
w, h = image.size
|
||||
if w > h:
|
||||
new_w, new_h = sizelimit, int(sizelimit * h / w)
|
||||
else:
|
||||
new_h, new_w = sizelimit, int(sizelimit * w / h)
|
||||
return ImageTk.PhotoImage(image.resize((new_w, new_h), Image.Resampling.LANCZOS))
|
||||
|
||||
# Create a new parameter set and save it
|
||||
def create_new_parameter_set(group_name, param_name, input_vars, folder_parsets):
|
||||
if not param_name:
|
||||
messagebox.showerror("Error", "Parameter set name cannot be empty.")
|
||||
return
|
||||
param_data = {key: var.get() for key, var in input_vars[group_name].items()}
|
||||
save_yaml(group_name, param_name, param_data, folder_parsets)
|
||||
|
||||
# Update the dropdown after saving new parameter set
|
||||
def update_dropdown(param_values, param_name, param_dropdown):
|
||||
param_values.insert(-1, param_name)
|
||||
param_dropdown['values'] = param_values
|
||||
|
||||
# Create a popup window for creating a new parameter set
|
||||
def create_new_param_popup(root, group_name, input_vars, param_values, param_dropdown, folder_parsets):
|
||||
new_window = tk.Toplevel(root)
|
||||
new_window.title(f"Create New Parameter Set for {group_name}")
|
||||
tk.Label(new_window, text="Parameter Set Name:").pack(pady=10)
|
||||
param_name_entry = tk.Entry(new_window)
|
||||
param_name_entry.pack(pady=10)
|
||||
|
||||
def create_param_set():
|
||||
param_name = param_name_entry.get()
|
||||
create_new_parameter_set(group_name, param_name, input_vars, folder_parsets)
|
||||
update_dropdown(param_values, param_name, param_dropdown)
|
||||
new_window.destroy()
|
||||
|
||||
tk.Button(new_window, text="Create", command=create_param_set).pack(pady=10)
|
||||
29
out/241016_164629/DMUAUT_CFG.SPF
Normal file
@ -0,0 +1,29 @@
|
||||
; CFG FILE FOR DMU50 AUTOMATION
|
||||
; GENERATED: 241016_164629
|
||||
; ---------------------------------------------------
|
||||
X_NUM = 8
|
||||
X_OFFSET = 5
|
||||
Y_NUM = 7
|
||||
Y_OFFSET = 4
|
||||
KOS = 4
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPRAW = 10
|
||||
Y_WPRAW = 1
|
||||
Z_WPRAW = 1
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPFIN =
|
||||
Y_WPFIN =
|
||||
Z_WPFIN =
|
||||
L_WPFIN =
|
||||
|
||||
; ---------------------------------------------------
|
||||
HUB = 10
|
||||
H_OFFSET = 20
|
||||
H_STEP = 5
|
||||
W_OFFSET = 20
|
||||
W_STEP = 10
|
||||
STEPS_NUM = 6
|
||||
|
||||
; ---------------------------------------------------
|
||||
5
out/241016_164629/selected_param_sets.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay7
|
||||
wp_raw: wpraw1
|
||||
wp_fin: <<new par set>>
|
||||
grp: grp1
|
||||
29
out/241017_101415/DMUAUT_CFG.SPF
Normal file
@ -0,0 +1,29 @@
|
||||
; CFG FILE FOR DMU50 AUTOMATION
|
||||
; GENERATED: 241017_101415
|
||||
; ---------------------------------------------------
|
||||
X_NUM = 11
|
||||
X_OFFSET = 5
|
||||
Y_NUM = 4
|
||||
Y_OFFSET = 4
|
||||
KOS = 4
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPRAW = 10
|
||||
Y_WPRAW = 10
|
||||
Z_WPRAW = 20
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPFIN = 10
|
||||
Y_WPFIN = 10
|
||||
Z_WPFIN = 20
|
||||
L_WPFIN = 10
|
||||
|
||||
; ---------------------------------------------------
|
||||
HUB = 10
|
||||
H_OFFSET = 20
|
||||
H_STEP = 5
|
||||
W_OFFSET = 20
|
||||
W_STEP = 10
|
||||
STEPS_NUM = 6
|
||||
|
||||
; ---------------------------------------------------
|
||||
5
out/241017_101415/selected_param_sets.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay4
|
||||
wp_raw: wpraw1
|
||||
wp_fin: wpfin1
|
||||
grp: grp1
|
||||
29
out/241017_103326/DMUAUT_CFG.SPF
Normal file
@ -0,0 +1,29 @@
|
||||
; CFG FILE FOR DMU50 AUTOMATION
|
||||
; GENERATED: 241017_103326
|
||||
; ---------------------------------------------------
|
||||
X_NUM = 7
|
||||
X_OFFSET = 5
|
||||
Y_NUM = 4
|
||||
Y_OFFSET = 4
|
||||
KOS = g54
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPRAW = 5
|
||||
Y_WPRAW = 5
|
||||
Z_WPRAW = 15
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPFIN = 10
|
||||
Y_WPFIN = 10
|
||||
Z_WPFIN = 13
|
||||
L_WPFIN = 8
|
||||
|
||||
; ---------------------------------------------------
|
||||
HUB = 10
|
||||
H_OFFSET = 10
|
||||
H_STEP = 5
|
||||
W_OFFSET = 25
|
||||
W_STEP = 4
|
||||
STEPS_NUM = 6
|
||||
|
||||
; ---------------------------------------------------
|
||||
5
out/241017_103326/selected_param_sets.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay_kleinteil
|
||||
wp_raw: wpraw2
|
||||
wp_fin: wpfin1
|
||||
grp: grp1
|
||||
32
out/241017_180108/DMUAUT_CFG.SPF
Normal file
@ -0,0 +1,32 @@
|
||||
; CFG FILE FOR DMU50 AUTOMATION
|
||||
; GENERATED: 241017_180108
|
||||
; ---------------------------------------------------
|
||||
X_NUM = 8
|
||||
X_OFFSET = 5
|
||||
Y_NUM = 7
|
||||
Y_OFFSET = 4
|
||||
KOS = 4
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPRAW = 10
|
||||
Y_WPRAW = 10
|
||||
Z_WPRAW = 20
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPFIN = 10
|
||||
Y_WPFIN = 10
|
||||
Z_WPFIN = 13
|
||||
L_WPFIN = 8
|
||||
|
||||
; ---------------------------------------------------
|
||||
HUB = 50
|
||||
H_OFFSET = 30
|
||||
H_STEP = 10
|
||||
W_OFFSET = 40
|
||||
W_STEP = 45
|
||||
STEPS_NUM = 5
|
||||
|
||||
; ---------------------------------------------------
|
||||
CLP_OFFSET =
|
||||
|
||||
; ---------------------------------------------------
|
||||
6
out/241017_180108/selected_param_sets.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay7
|
||||
wp_raw: wpraw1
|
||||
wp_fin: wpfin1
|
||||
grp: grp1
|
||||
clp: <<new par set>>
|
||||
32
out/241017_181437/DMUAUT_CFG.SPF
Normal file
@ -0,0 +1,32 @@
|
||||
; CFG FILE FOR DMU50 AUTOMATION
|
||||
; GENERATED: 241017_181437
|
||||
; ---------------------------------------------------
|
||||
X_NUM = 8
|
||||
X_OFFSET = 5
|
||||
Y_NUM = 7
|
||||
Y_OFFSET = 4
|
||||
KOS = 4
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPRAW = 5
|
||||
Y_WPRAW = 5
|
||||
Z_WPRAW = 15
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPFIN = 10
|
||||
Y_WPFIN = 10
|
||||
Z_WPFIN = 13
|
||||
L_WPFIN = 8
|
||||
|
||||
; ---------------------------------------------------
|
||||
HUB = 50
|
||||
H_OFFSET = 30
|
||||
H_STEP = 10
|
||||
W_OFFSET = 40
|
||||
W_STEP = 45
|
||||
STEPS_NUM = 5
|
||||
|
||||
; ---------------------------------------------------
|
||||
CLP_OFFSET = 0
|
||||
|
||||
; ---------------------------------------------------
|
||||
6
out/241017_181437/selected_param_sets.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay7
|
||||
wp_raw: wpraw2
|
||||
wp_fin: wpfin1
|
||||
grp: grp1
|
||||
clp: clp2
|
||||
32
out/241017_184239/DMUAUT_CFG.SPF
Normal file
@ -0,0 +1,32 @@
|
||||
; CFG FILE FOR DMU50 AUTOMATION
|
||||
; GENERATED: 241017_184239
|
||||
; ---------------------------------------------------
|
||||
X_NUM =
|
||||
X_OFFSET =
|
||||
Y_NUM =
|
||||
Y_OFFSET =
|
||||
KOS =
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPRAW = 10
|
||||
Y_WPRAW = 10
|
||||
Z_WPRAW = 20
|
||||
|
||||
; ---------------------------------------------------
|
||||
X_WPFIN = 10
|
||||
Y_WPFIN = 10
|
||||
Z_WPFIN = 13
|
||||
L_WPFIN = 8
|
||||
|
||||
; ---------------------------------------------------
|
||||
HUB = 10
|
||||
H_OFFSET = 10
|
||||
H_STEP = 5
|
||||
W_OFFSET = 25
|
||||
W_STEP = 45
|
||||
STEPS_NUM = 2
|
||||
|
||||
; ---------------------------------------------------
|
||||
CLP_OFFSET = 4
|
||||
|
||||
; ---------------------------------------------------
|
||||
6
out/241017_184239/selected_param_sets.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: <<new par set>>
|
||||
wp_raw: wpraw1
|
||||
wp_fin: wpfin1
|
||||
grp: grp3
|
||||
clp: clp1
|
||||