130 lines
5.0 KiB
Python
130 lines
5.0 KiB
Python
# functions.py
|
|
|
|
import yaml
|
|
from PIL import Image, ImageTk
|
|
from tkinter import ttk, filedialog, messagebox
|
|
import tkinter as tk
|
|
import os
|
|
import trimesh
|
|
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
|
import numpy as np
|
|
|
|
# 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)
|
|
|
|
|
|
# -------------------------------------------------------------------------------------------------------
|
|
def plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color='blue', alpha=0.5, linewidth=1, inverty=False):
|
|
"""Efficiently plots an L-shaped merged cube structure and draws only axis-aligned edges."""
|
|
|
|
# Compute Y offsets
|
|
dyy1, dyy2 = (y - dy1 / 2, y - (dy1 - dy2) / 2) if not inverty else (y + dy1 / 2, y + (dy1 - dy2) / 2)
|
|
|
|
# Create and position both cubes
|
|
cubes = [
|
|
trimesh.creation.box(extents=[dx, dy1, dz1]).apply_translation([x + dx / 2, dyy1, z + dz1 / 2]),
|
|
trimesh.creation.box(extents=[dx, dy1 + dy2, dz2]).apply_translation([x + dx / 2, dyy2, z - dz2 / 2])
|
|
]
|
|
|
|
try:
|
|
# Perform boolean union on merged cubes
|
|
merged = trimesh.boolean.union(cubes)
|
|
|
|
# Extract vertices and edges
|
|
vertices = np.array(merged.vertices)
|
|
edges = merged.edges_unique
|
|
|
|
# Add merged faces without visible edges
|
|
ax.add_collection3d(Poly3DCollection(
|
|
vertices[merged.faces], facecolors=color, alpha=alpha, edgecolors=None, linewidth=0
|
|
))
|
|
|
|
# Draw only axis-aligned edges
|
|
for edge in edges:
|
|
v1, v2 = vertices[edge]
|
|
if np.isclose(v1, v2, atol=1e-6).sum() == 2: # Only one coordinate changes
|
|
ax.plot(*zip(*[v1, v2]), color='black', linewidth=linewidth)
|
|
|
|
except Exception as e:
|
|
print(f"Trimesh union failed: {e}")
|
|
|