v2 - Finalizing and short testing

This commit is contained in:
Eduard Gerlitz 2025-03-12 14:37:23 +01:00
parent 261e3b4929
commit 10a0e86caf
18 changed files with 218 additions and 249 deletions

View File

@ -1,5 +1,4 @@
# main.py # main.py
from functions import * from functions import *
from funct_inlay import * from funct_inlay import *
from funct_wp import * from funct_wp import *
@ -34,7 +33,7 @@ def setup_group(frame, group_name, data, input_vars, selected_params, group_widg
param_var = selected_params[group_name] # Bind the dropdown to the corresponding selected_param entry 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) param_dropdown = ttk.Combobox(frame, textvariable=param_var, values=param_values)
group_widgets[group_name] = {"param_dropdown": param_dropdown} # Save for later reference group_widgets[group_name] = {"param_dropdown": param_dropdown} # Save for later reference
source_path = f"{folder_pictures}/{data['general']['initpic_name']}" source_path = f"{folder_pictures}/{data['general']['notavailablepic_name']}"
# Handle missing picture case # Handle missing picture case
if not os.path.exists(picture_path): if not os.path.exists(picture_path):
@ -273,7 +272,7 @@ def setup_evaluation(root, folder_pictures, data, folder_output, input_vars, sel
frame.grid(row=2, column=0, columnspan=5, padx=10, pady=10, sticky="nsew") frame.grid(row=2, column=0, columnspan=5, padx=10, pady=10, sticky="nsew")
# Load and display the specific initial picture # Load and display the specific initial picture
picture_path = f"{folder_pictures}/{data['general']['initpic_name']}" picture_path = f"{folder_pictures}/{data['general']['generatorpic_name']}"
group_image_tk = load_image(picture_path, 200) # Assuming a function load_image exists and works as expected 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 = ttk.Label(frame, image=group_image_tk)
image_label.image = group_image_tk # Keep a reference to avoid garbage collection image_label.image = group_image_tk # Keep a reference to avoid garbage collection
@ -290,7 +289,7 @@ def setup_evaluation(root, folder_pictures, data, folder_output, input_vars, sel
# Place buttons in the vertical frame for operations # Place buttons in the vertical frame for operations
button_frame = ttk.Frame(frame) button_frame = ttk.Frame(frame)
button_frame.grid(row=0, column=1, padx=10, pady=10, sticky="n") 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 = ttk.Button(button_frame, text="GEN CFG_DMUAUT.SPF FILE", width=45, command=btn_gen)
button1.grid(row=0, column=0, padx=10, pady=5) button1.grid(row=0, column=0, padx=10, pady=5)
button2 = ttk.Button(button_frame, text="GEN CFG_INLAY.SPF FILE", width=45, command=btn_gen_custom1) button2 = ttk.Button(button_frame, text="GEN CFG_INLAY.SPF FILE", width=45, command=btn_gen_custom1)
button2.grid(row=1, column=0, padx=5, pady=5) button2.grid(row=1, column=0, padx=5, pady=5)

View File

@ -1,4 +0,0 @@
clp1:
clp_offset: '0'
clp2:
clp_offset: '0'

View File

@ -1,28 +0,0 @@
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'

View File

@ -5,6 +5,6 @@
INL_Y_OFFSET: '50' INL_Y_OFFSET: '50'
inlay1: inlay1:
INL_X_NUM: '10' INL_X_NUM: '10'
INL_X_OFFSET: '50' INL_X_OFFSET: '10'
INL_Y_NUM: '9' INL_Y_NUM: '10'
INL_Y_OFFSET: '50' INL_Y_OFFSET: '10'

View File

@ -1,9 +1,9 @@
wp1: wp1:
WPF_X: '20' WPF_X: '15'
WPF_Y: '20' WPF_Y: '20'
WPF_Z: '20' WPF_Z: '15'
WPR_X: '20' WPR_X: '20'
WPR_Y: '20' WPR_Y: '20'
WPR_Z: '33' WPR_Z: '20'
WP_CLP_OFFSET_X: '4' WP_CLP_OFFSET_X: '5'
WP_GRP_OFFSET_Z: '5' WP_GRP_OFFSET_Z: '5'

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
cfg_picture/dog_progr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 93 KiB

BIN
cfg_picture/img_wp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

14
def.yml
View File

@ -1,6 +1,7 @@
general: general:
yolovar: int yolovar: int
initpic_name: puppy.png notavailablepic_name: cat_wondering.png
generatorpic_name: dog_progr.png
groups: groups:
inlay: inlay:
@ -25,8 +26,13 @@ groups:
picture_name: img_wp.png picture_name: img_wp.png
clp: clp:
parameter: parameter:
clp_offset: double CLP_BACKENWEITE: double
CLP_BACKENHOHE: double
CLP_SPANNHOHE: double
CLP_AUFLAGETIEFE: double
MESSPOS_X: double
MESSPOS_Y: double
MESSPOS_Z: double
MESSPOS_TOL: double
cfg: cfg:
picture_name: img_clp.png picture_name: img_clp.png

View File

@ -1,130 +1,116 @@
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection from functions import *
import numpy as np
def generate_picture_clp(all_group_vars, picture_path, DEBUG=False): def generate_picture_clp(all_group_vars, picture_path, DEBUG=False):
try: vars = all_group_vars['clp']
# Get WPR_X, WPR_Y, and WPR_Z values CLP_BACKENWEITE, CLP_BACKENHOHE, CLP_SPANNHOHE, CLP_AUFLAGETIEFE = (float(vars[k]) for k in
vars = all_group_vars['wp'] ['CLP_BACKENWEITE', 'CLP_BACKENHOHE',
x_wpraw = float(vars['WPR_X']) 'CLP_SPANNHOHE', 'CLP_AUFLAGETIEFE'])
y_wpraw = float(vars['WPR_Y'])
z_wpraw = float(vars['WPR_Z'])
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 WPR_X = CLP_BACKENWEITE/2
if x_cube <= 0 or y_cube <= 0 or z_cube <= 0: WPR_Y = CLP_BACKENWEITE/2
raise ValueError("WPR_X, WPR_Y, and WPR_Z must be positive values.") WPR_Z = CLP_SPANNHOHE * 5
# Define the vertices of the cube based on wpraw dimensions if min(WPR_X, WPR_Y, WPR_Z) <= 0:
vertices = (np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0], raise ValueError("Dimensions must be positive.")
[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 fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
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 # Define raw workpiece dimensions
fig = plt.figure() x_cube, y_cube, z_cube = 2 * WPR_X, 2 * WPR_Y, WPR_Z
ax = fig.add_subplot(111, projection='3d') vertices_raw = np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0],
[0, 0, WPR_Z], [x_cube, 0, WPR_Z], [x_cube, y_cube, WPR_Z], [0, y_cube, WPR_Z]])
faces_raw = [vertices_raw[[0, 1, 2, 3]], vertices_raw[[4, 5, 6, 7]], vertices_raw[[0, 3, 7, 4]],
vertices_raw[[1, 2, 6, 5]], vertices_raw[[0, 1, 5, 4]], vertices_raw[[2, 3, 7, 6]]]
# Plot the cube with the specified faces # Set axis properties
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]) ax.set_box_aspect([x_cube, y_cube, z_cube])
ax.set(xticks=[], yticks=[], zticks=[])
# Hide the axis ticks and labels # Draw WP coordinate system
ax.set_xticks([]) # Hide X axis ticks axis_len = max(x_cube, y_cube, z_cube) * 0.2
ax.set_yticks([]) # Hide Y axis ticks colors = ['r', 'g', 'b']
ax.set_zticks([]) # Hide Z axis ticks origin_x = 0
origin_y = 0
origin_z = 0
for i, vec in enumerate(np.eye(3)):
ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3)
ax.text(origin_x, origin_y, origin_z - axis_len * 0.3, 'WP', color='black', fontsize=9, weight='bold', ha='center',
va='top')
# Add a ball (sphere) at the center of the cube # Draw WP
ball_radius = min(x_wpraw, y_wpraw, z_wpraw) * 0.1 # Size relative to cube dimensions ax.add_collection3d(Poly3DCollection(faces_raw, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
u = np.linspace(0, 2 * np.pi, 20) # Draw CLP coordinate system
v = np.linspace(0, np.pi, 20) axis_len = max(x_cube, y_cube, z_cube) * 0.15
x_sphere = x_wpraw + ball_radius * np.outer(np.cos(u), np.sin(v)) colors = ['r', 'g', 'b']
y_sphere = y_wpraw - clp_offset + ball_radius * np.outer(np.sin(u), np.sin(v)) origin_x = WPR_X
z_sphere = z_wpraw + ball_radius * np.outer(np.ones(np.size(u)), np.cos(v)) origin_y = WPR_Y
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='red', alpha=1) origin_z = 0
for i, vec in enumerate(np.eye(3)):
ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3)
ax.text(origin_x, origin_y, origin_z - axis_len * 0.3, 'CLP', color='blue', fontsize=9, weight='bold', ha='center',
va='top')
# Add the origin sparrow (a small 3D marker at the origin) # Define clamping block dimensions
max_size = max(x_cube, y_cube, z_cube) * 0.2 # Scale the arrows relative to the smallest dimension clp_deep = y_cube * 0.3
ax.quiver(0, -clp_offset, 0, max_size, 0, 0, color='red', linewidth=2, label='X-axis') # Red arrow for X-axis base_x = WPR_X - CLP_BACKENWEITE / 2
ax.quiver(0, -clp_offset, 0, 0, max_size, 0, color='green', linewidth=2, label='Y-axis') # Green arrow for Y-axis alpha = 0.35
ax.quiver(0, -clp_offset, 0, 0, 0, max_size, color='blue', linewidth=2, label='Z-axis') # Blue arrow for Z-axis color = 'blue'
linewidth = 1
# Add two black blocks (greifer fingers) on the Y-faces in the middle of the cube height # Draw clamping blocks
max_size2 = max(x_cube, y_cube, z_cube) * 0.4 # Scale the arrows relative to the smallest dimension x = base_x
ax.bar3d(-max_size2, -(2.0-1)/2 * y_cube, -z_wpraw * 0.0, dx = CLP_BACKENWEITE
max_size2, 2.0 * y_cube, z_wpraw * 0.2, y = 0
color='black', alpha=.10) dy1 = clp_deep
ax.bar3d(-max_size2, -(2.0-1)/2 * y_cube, -z_wpraw * 0.0, dy2 = CLP_AUFLAGETIEFE
max_size2+3, 2.0 * y_cube, -z_wpraw * 0.2, z = 0
color='black', alpha=.10) dz1 = CLP_SPANNHOHE
dz2 = CLP_BACKENHOHE
plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color=color,
alpha=alpha, linewidth=linewidth)
y = y_cube
plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color=color,
alpha=alpha, linewidth=linewidth, inverty=True)
ax.bar3d(x_cube, -(2-1)/2 * y_cube, -z_wpraw * 0.0, # Draw text for geometry values
max_size2, 2.0 * y_cube, z_wpraw * 0.2, ax.text(0, 2*WPR_Y+clp_deep, CLP_SPANNHOHE/2, f'{CLP_SPANNHOHE}mm', color='blue', fontsize=9, weight='bold', ha='right', va='center')
color='black', alpha=.10) ax.text(0, 2*WPR_Y+clp_deep, -CLP_BACKENHOHE/2, f'{CLP_BACKENHOHE}mm', color='blue', fontsize=9, weight='bold', ha='right', va='center')
ax.bar3d(x_cube-3, -(2-1)/2 * y_cube, -z_wpraw * 0.0, ax.text(WPR_X, 2*WPR_Y+clp_deep, CLP_SPANNHOHE, f'{CLP_BACKENWEITE}mm', color='blue', fontsize=9, weight='bold', ha='right', va='center')
max_size2+3, 2.0 * y_cube, -z_wpraw * 0.2, ax.text(WPR_X*2, 2*WPR_Y-CLP_AUFLAGETIEFE/2, 0, f'{CLP_AUFLAGETIEFE}mm', color='blue', fontsize=9, weight='bold', ha='left', va='bottom')
color='black', alpha=.10)
# Add the origin sparrow (a small 3D marker at the origin) # Set view properties
max_size3 = max(x_cube, y_cube, z_cube) * 0.3 # Scale the arrows relative to the smallest dimension z_trans = WPR_Z
ax.quiver(x_wpraw, y_wpraw, 0, 0, max_size3, 0, color='red', linewidth=3, label='X-axis') # Red arrow for X-axis zoom_factor = 1.5 # Adjust this factor to zoom out more or less
ax.quiver(x_wpraw, y_wpraw, 0, -max_size3, 0, 0, color='green', linewidth=3, label='Y-axis') # Green arrow for Y-axis ax.view_init(elev=30, azim=-160)
ax.quiver(x_wpraw, y_wpraw, 0, 0, 0, max_size3, color='blue', linewidth=3, label='Z-axis') # Blue arrow for Z-axis ax.set_xlim([-x_cube * zoom_factor * 0.1, x_cube * zoom_factor])
ax.set_ylim([-y_cube * zoom_factor * 0.1, y_cube * zoom_factor])
# Set viewing angle ax.set_zlim([-WPR_Z * zoom_factor * 0.1 - z_trans, WPR_Z * zoom_factor - z_trans])
ax.view_init(elev=30, azim=-150) # Set elevation to 24° and azimuth to -151° ax.set_aspect('auto')
# ax.view_init(elev=90, azim=180) # Set elevation to 24° and azimuth to -151° ax.grid(False) # Remove grid lines
ax.set_xticks([])
# Set limits for the axes ax.set_yticks([])
# ax.set_xlim([0, x_cube]) ax.set_zticks([])
# ax.set_ylim([0, y_cube]) for axis in [ax.xaxis, ax.yaxis, ax.zaxis]:
# ax.set_zlim([0, z_cube]) axis.set_pane_color((1, 1, 1, 0)) # Hide background panes
axis.line.set_color((1, 1, 1, 0)) # Hide axis lines
# Set equal aspect ratio to make grid cells look square
ax.set_aspect('equal')
# Save or display the plot
if not DEBUG: if not DEBUG:
# Save the figure to the specified picture path fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
fig.savefig(picture_path, bbox_inches='tight', pad_inches=0.1, dpi=300, transparent=True)
else: else:
plt.show() plt.show()
# Close the figure to free memory
plt.close() 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 # Example use-case
if __name__ == "__main__": if __name__ == "__main__":
all_group_vars = { all_group_vars = {
'wp_raw': { 'CLP_BACKENWEITE': 25,
'WPR_X': '10', # Example values for testing 'CLP_BACKENHOHE': 20,
'WPR_Y': '15', 'CLP_SPANNHOHE': 3,
'WPR_Z': '20' 'CLP_AUFLAGETIEFE': 3
},
'clp': {
'clp_offset': '4'
} }
} generate_picture_clp({'clp': all_group_vars}, "cfg_picture/TEST_wpraw.jpg", DEBUG=True)
generate_picture_clp(all_group_vars, 'output_image.png', DEBUG=True)

View File

@ -7,7 +7,8 @@ import paramiko
import yaml import yaml
import shutil import shutil
# Function to generate the DMUAUT_CFG.SPF configuration file and save selected parameter sets
# Function to generate the CFG_DMUAUT.SPF configuration file and save selected parameter sets
def generate_config_spf(folder_output, input_vars, selected_params): def generate_config_spf(folder_output, input_vars, selected_params):
# Get the current timestamp for folder name (format: YYMMDD_HHmmSS) # Get the current timestamp for folder name (format: YYMMDD_HHmmSS)
timestamp = time.strftime("%y%m%d_%H%M%S") timestamp = time.strftime("%y%m%d_%H%M%S")
@ -18,7 +19,7 @@ def generate_config_spf(folder_output, input_vars, selected_params):
os.makedirs(folder_path) os.makedirs(folder_path)
# Define the file path for the SPF configuration file # Define the file path for the SPF configuration file
spf_file_path = os.path.join(folder_path, "DMUAUT_CFG.SPF") spf_file_path = os.path.join(folder_path, "CFG_DMUAUT.SPF")
# Generate the SPF file content # Generate the SPF file content
with open(spf_file_path, "w") as spf_file: with open(spf_file_path, "w") as spf_file:
@ -45,14 +46,13 @@ def generate_config_spf(folder_output, input_vars, selected_params):
print(f"Configuration files saved in {folder_path}") print(f"Configuration files saved in {folder_path}")
os.startfile(folder_path)
def generate_config_spf_custom1(folder_output, input_vars, selected_params, filetransfer=False): def generate_config_spf_custom1(folder_output, input_vars, selected_params, filetransfer=False):
filename = "CFG_INL.SPF" filename = "CFG_INL.SPF"
filename2 = "_N_CFG_INL_SPF" filename2 = "_N_CFG_INL_SPF"
# Get the current timestamp for folder name (format: YYMMDD_HHmmSS) # Get the current timestamp for folder name (format: YYMMDD_HHmmSS)
timestamp = time.strftime("%y%m%d_%H%M%S") timestamp = time.strftime("%y%m%d_%H%M%S")
folder_path = os.path.join(folder_output, f"{timestamp}") folder_path = os.path.join(folder_output, f"{timestamp}")
@ -130,4 +130,3 @@ def generate_config_spf_custom1(folder_output, input_vars, selected_params, file
# print(f"ERROR IN FILETRANSFER {e}") # print(f"ERROR IN FILETRANSFER {e}")
else: else:
os.startfile(folder_path) os.startfile(folder_path)

View File

@ -1,33 +1,31 @@
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection from functions import *
import numpy as np
import trimesh
def generate_picture_wp(all_group_vars, picture_path, DEBUG=False): def generate_picture_wp(all_group_vars, picture_path, DEBUG=False):
# try:
vars = all_group_vars['wp'] vars = all_group_vars['wp']
WPR_X, WPR_Y, WPR_Z, WPF_X, WPF_Y, WPF_Z, WP_CLP_OFFSET_X, WP_GRP_OFFSET_Z = (float(vars[k]) for k in WPR_X, WPR_Y, WPR_Z, WPF_X, WPF_Y, WPF_Z, WP_CLP_OFFSET_X, WP_GRP_OFFSET_Z = (float(vars[k]) for k in
['WPR_X', 'WPR_Y', 'WPR_Z', 'WPF_X', 'WPF_Y', 'WPF_Z', 'WP_CLP_OFFSET_X', 'WP_GRP_OFFSET_Z']) ['WPR_X', 'WPR_Y', 'WPR_Z', 'WPF_X',
'WPF_Y', 'WPF_Z', 'WP_CLP_OFFSET_X',
'WP_GRP_OFFSET_Z'])
if min(WPR_X, WPR_Y, WPR_Z, WPF_X, WPF_Y, WPF_Z) <= 0: if min(WPR_X, WPR_Y, WPR_Z, WPF_X, WPF_Y, WPF_Z) <= 0:
raise ValueError("Dimensions must be positive.") raise ValueError("Dimensions must be positive.")
fig, ax = plt.subplots(subplot_kw={'projection': '3d'}) fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
# -------------------- wpraw ------------------------------------------------------------------------------------- # Define raw workpiece dimensions
x_cube, y_cube, z_cube = 2 * WPR_X, 2 * WPR_Y, WPR_Z x_cube, y_cube, z_cube = 2 * WPR_X, 2 * WPR_Y, WPR_Z
vertices_raw = np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0], vertices_raw = np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0],
[0, 0, WPR_Z], [x_cube, 0, WPR_Z], [x_cube, y_cube, WPR_Z], [0, y_cube, WPR_Z]]) [0, 0, WPR_Z], [x_cube, 0, WPR_Z], [x_cube, y_cube, WPR_Z], [0, y_cube, WPR_Z]])
faces_raw = [vertices_raw[[0, 1, 2, 3]], vertices_raw[[4, 5, 6, 7]], vertices_raw[[0, 3, 7, 4]], faces_raw = [vertices_raw[[0, 1, 2, 3]], vertices_raw[[4, 5, 6, 7]], vertices_raw[[0, 3, 7, 4]],
vertices_raw[[1, 2, 6, 5]], vertices_raw[[0, 1, 5, 4]], vertices_raw[[2, 3, 7, 6]]] vertices_raw[[1, 2, 6, 5]], vertices_raw[[0, 1, 5, 4]], vertices_raw[[2, 3, 7, 6]]]
# Achsen-Einstellungen zusammenfassen # Set axis properties
ax.set_box_aspect([x_cube, y_cube, z_cube]) ax.set_box_aspect([x_cube, y_cube, z_cube])
ax.set(xticks=[], yticks=[], zticks=[]) ax.set(xticks=[], yticks=[], zticks=[])
# KOS WP zeichnen # Draw WP coordinate system
axis_len = max(x_cube, y_cube, z_cube) * 0.2 axis_len = max(x_cube, y_cube, z_cube) * 0.2
colors = ['r', 'g', 'b'] colors = ['r', 'g', 'b']
origin_x = 0 origin_x = 0
@ -35,13 +33,13 @@ def generate_picture_wp(all_group_vars, picture_path, DEBUG=False):
origin_z = 0 origin_z = 0
for i, vec in enumerate(np.eye(3)): for i, vec in enumerate(np.eye(3)):
ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3) ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3)
ax.text(origin_x, origin_y, origin_z-axis_len*0.3, 'WP', color='black', fontsize=9, weight='bold') ax.text(origin_x, origin_y, origin_z - axis_len * 0.3, 'WP', color='black', fontsize=9, weight='bold', ha='center',
va='top')
# Draw WP
# WP
ax.add_collection3d(Poly3DCollection(faces_raw, facecolors='k', linewidths=1, edgecolors='k', alpha=.15)) ax.add_collection3d(Poly3DCollection(faces_raw, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
# GRIFFPUNKT # Draw gripping point
u, v = np.mgrid[0:2 * np.pi:20j, 0:np.pi:20j] u, v = np.mgrid[0:2 * np.pi:20j, 0:np.pi:20j]
ball_radius = min(WPR_X, WPR_Y, WPR_Z) * 0.1 ball_radius = min(WPR_X, WPR_Y, WPR_Z) * 0.1
ax.plot_surface( ax.plot_surface(
@ -51,7 +49,7 @@ def generate_picture_wp(all_group_vars, picture_path, DEBUG=False):
color='r' color='r'
) )
# GREIFER # Draw gripper
gripper_thickness = max(x_cube, y_cube, z_cube) * 0.1 gripper_thickness = max(x_cube, y_cube, z_cube) * 0.1
gripper_wide = WPR_X * 0.4 gripper_wide = WPR_X * 0.4
GRP_ALPHA = .40 GRP_ALPHA = .40
@ -66,10 +64,10 @@ def generate_picture_wp(all_group_vars, picture_path, DEBUG=False):
color='r', alpha=GRP_ALPHA, edgecolor='k', linewidth=0.5 color='r', alpha=GRP_ALPHA, edgecolor='k', linewidth=0.5
) )
# -------------------- wpfin--------------------------------------------------------------------------------- # Define finished workpiece dimensions
x_cube2, y_cube2, z_cube2 = 2 * WPF_X, 2 * WPF_Y, WPF_Z x_cube2, y_cube2, z_cube2 = 2 * WPF_X, 2 * WPF_Y, WPF_Z
# GRIFFPUNKT # Draw gripping point for finished workpiece
u, v = np.mgrid[0:2 * np.pi:20j, 0:np.pi:20j] u, v = np.mgrid[0:2 * np.pi:20j, 0:np.pi:20j]
ball_radius = min(WPF_X, WPF_Y, WPF_Z) * 0.08 ball_radius = min(WPF_X, WPF_Y, WPF_Z) * 0.08
ax.plot_surface( ax.plot_surface(
@ -79,12 +77,10 @@ def generate_picture_wp(all_group_vars, picture_path, DEBUG=False):
color='g' color='g'
) )
# Draw gripper for finished workpiece
# GREIFER
gripper_thickness2 = max(x_cube, y_cube, z_cube) * 0.05 gripper_thickness2 = max(x_cube, y_cube, z_cube) * 0.05
gripper_wide2 = WPR_X * 0.4 gripper_wide2 = WPR_X * 0.4
GRP_ALPHA2 = .25 GRP_ALPHA2 = .25
# wpf_y_offs = (np.sign(WPF_Y-WPR_Y)/2+.5) * (WPF_Y-WPR_Y)
yyy2 = [-gripper_thickness2, y_cube2] if WPF_Y < WPR_Y else [-gripper_thickness2 + (WPF_Y - WPR_Y) * 2, y_cube] yyy2 = [-gripper_thickness2, y_cube2] if WPF_Y < WPR_Y else [-gripper_thickness2 + (WPF_Y - WPR_Y) * 2, y_cube]
bars = [ bars = [
((x_cube2 - gripper_wide2) * 0.5, yyy2[0], WPF_Z - WP_GRP_OFFSET_Z), ((x_cube2 - gripper_wide2) * 0.5, yyy2[0], WPF_Z - WP_GRP_OFFSET_Z),
@ -97,9 +93,7 @@ def generate_picture_wp(all_group_vars, picture_path, DEBUG=False):
color='g', alpha=GRP_ALPHA2, edgecolor='k', linewidth=0.5 color='g', alpha=GRP_ALPHA2, edgecolor='k', linewidth=0.5
) )
# -------------------- clp ------------------------------------------------------------------------------------- # Draw CLP coordinate system
# KOS CLP zeichnen
axis_len = max(x_cube, y_cube, z_cube) * 0.15 axis_len = max(x_cube, y_cube, z_cube) * 0.15
colors = ['r', 'g', 'b'] colors = ['r', 'g', 'b']
origin_x = WPR_X - WP_CLP_OFFSET_X origin_x = WPR_X - WP_CLP_OFFSET_X
@ -107,88 +101,65 @@ def generate_picture_wp(all_group_vars, picture_path, DEBUG=False):
origin_z = 0 origin_z = 0
for i, vec in enumerate(np.eye(3)): for i, vec in enumerate(np.eye(3)):
ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3) ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3)
ax.text(origin_x, origin_y, origin_z-axis_len*0.3, 'CLP', color='blue', fontsize=9, weight='bold') ax.text(origin_x, origin_y, origin_z - axis_len * 0.3, 'CLP', color='blue', fontsize=9, weight='bold', ha='center',
va='top')
# Add two black blocks on the Y-faces in the middle of the cube height
# Define clamping block dimensions
clp_height = z_cube * 0.2 clp_height = z_cube * 0.2
clp_width = 0.6 * x_cube clp_width = 0.6 * x_cube
clp_deep = y_cube * 0.3 # Scale the arrows relative to the smallest dimension clp_deep = y_cube * 0.3
clp_supportdeep = 3 # Scale the arrows relative to the smallest dimension clp_supportdeep = 3
base_x = WPR_X - clp_width / 2 base_x = WPR_X - clp_width / 2
alpha = 0.35 alpha = 0.35
color = 'blue' color = 'blue'
linewidth = 0 linewidth = 1
# Draw clamping blocks
# Replace the bar3d calls with plot_merged_cubes_trimesh
x = base_x - WP_CLP_OFFSET_X x = base_x - WP_CLP_OFFSET_X
dx = clp_width dx = clp_width
y = 0 y = 0
dy1 = clp_deep dy1 = clp_deep
dy2 = clp_supportdeep dy2 = clp_supportdeep
z = 0 z = 0
dz = clp_height dz1 = z_cube * 0.2
plot_clamping(ax, x, y, z, dx, dy1, dy2, dz, color=color, dz2 = z_cube * 0.6
plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color=color,
alpha=alpha, linewidth=linewidth) alpha=alpha, linewidth=linewidth)
y = y_cube y = y_cube
plot_clamping(ax, x, y, z, dx, dy1, dy2, dz, color=color, plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color=color,
alpha=alpha, linewidth=linewidth, inverty=True) alpha=alpha, linewidth=linewidth, inverty=True)
# Set view properties
z_trans = WPR_Z*0.2
# -------------------- view ------------------------------------------------------------------------------------- zoom_factor = 1.1 # Adjust this factor to zoom out more or less
ax.view_init(elev=18, azim=-130) ax.view_init(elev=30, azim=-160)
# ax.view_init(elev=45, azim=-160) ax.set_xlim([-x_cube * zoom_factor * 0.1, x_cube * zoom_factor])
ax.set_xlim([0, x_cube]); ax.set_ylim([0, y_cube]); ax.set_zlim([0, WPR_Z]) ax.set_ylim([-y_cube * zoom_factor * 0.1, y_cube * zoom_factor])
ax.set_zlim([-WPR_Z * zoom_factor * 0.1 - z_trans, WPR_Z * zoom_factor - z_trans])
ax.set_aspect('auto') ax.set_aspect('auto')
ax.grid(False) # Remove grid lines
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
for axis in [ax.xaxis, ax.yaxis, ax.zaxis]:
axis.set_pane_color((1, 1, 1, 0)) # Hide background panes
axis.line.set_color((1, 1, 1, 0)) # Hide axis lines
# Save or display the plot
if not DEBUG: if not DEBUG:
fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True) fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
else: else:
plt.show() plt.show()
plt.close() plt.close()
# except Exception as e:
# print(f"An error occurred: {e}")
def plot_clamping(ax, x, y, z, dx, dy1, dy2, dz, color='blue', alpha=0.5,
linewidth=1, inverty=False):
"""Plots merged cubes using trimesh, hiding mesh edges and drawing specific edges manually."""
dyy1 = y - dy1 / 2 if not inverty else y + dy1 / 2
dyy2 = y - (dy1-dy2) / 2 if not inverty else y + (dy1-dy2)/2
# Create and translate Cube 1
cube1 = trimesh.creation.box(extents=[dx, dy1, dz])
cube1.apply_translation([x + dx / 2, dyy1, z + dz / 2])
# Create and translate Cube 2
cube2 = trimesh.creation.box(extents=[dx, dy2+dy1, dz])
cube2.apply_translation([x + dx / 2, dyy2, z - dz / 2])
try:
# Perform boolean union
merged = trimesh.boolean.union([cube1, cube2])
# Create Poly3DCollection with NO edges
ax.add_collection3d(Poly3DCollection(
merged.vertices[merged.faces],
facecolors=color, alpha=alpha, edgecolors=color, linewidth=linewidth
))
except Exception as e:
print(f"Trimesh union failed: {e}")
if __name__ == "__main__": if __name__ == "__main__":
vars = {'WPR_X': 20, 'WPR_Y': 15, 'WPR_Z': 20, 'WPF_X': 10, 'WPF_Y': 18, 'WPF_Z': 10, 'WP_CLP_OFFSET_X': 3, 'WP_GRP_OFFSET_Z': 5} vars = {'WPR_X': 20,
'WPR_Y': 15,
'WPR_Z': 20,
'WPF_X': 10,
'WPF_Y': 18,
'WPF_Z': 15,
'WP_CLP_OFFSET_X': 3,
'WP_GRP_OFFSET_Z': 5}
generate_picture_wp({'wp': vars}, "cfg_picture/TEST_wpraw.jpg", DEBUG=True) generate_picture_wp({'wp': 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)

View File

@ -5,6 +5,9 @@ from PIL import Image, ImageTk
from tkinter import ttk, filedialog, messagebox from tkinter import ttk, filedialog, messagebox
import tkinter as tk import tkinter as tk
import os import os
import trimesh
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import numpy as np
# Function to load object definitions from YAML # Function to load object definitions from YAML
@ -87,3 +90,40 @@ def create_new_param_popup(root, group_name, input_vars, param_values, param_dro
new_window.destroy() new_window.destroy()
tk.Button(new_window, text="Create", command=create_param_set).pack(pady=10) 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}")