Smooth Saw Operator :)

This commit is contained in:
babayaga 2025-07-04 12:53:10 +02:00
parent 935c8cb526
commit 64f676a716
9 changed files with 321 additions and 1 deletions

Binary file not shown.

View File

@ -18,7 +18,7 @@ Nb_Boxes_V = 2; // [1:10]
// View control
Folded_View = false; // [true, false]
// Use "export" to render all parts separately for STEP conversion
view_mode = "preview"; // ["preview", "export"]
view_mode = "preview"; // ["preview", "export", "dxf", "cutlist"]
// Note: InnerBox_Width from the screenshot (100) is not used directly.
// Instead, the compartment widths are calculated based on TotalWidth, Height, and Nb_Boxes_U/V.
@ -254,11 +254,70 @@ module internal_divider_horizontal_export(length, compartment_u_size) {
}
}
// ---------------------------------------------------------------------
// Module to generate a cut list for the operator
// ---------------------------------------------------------------------
module generate_cutlist() {
// --- Calculations ---
InnerWidth = TotalWidth - 2 * Height;
InnerLength = TotalLength - 2 * Height;
// --- Header ---
echo("--- Cut List for Saw Operator ---");
echo(str("Board Dimensions: ", TotalWidth, " x ", TotalLength, " mm"));
echo("All distances are for the centerline of the slots.");
echo("---");
// --- Vertical Cuts (Parallel to Y-axis) ---
echo("VERTICAL CUTS (Distances from left edge):");
// Outer walls
v_outer_1 = Height;
v_outer_2 = TotalWidth - Height;
echo(str(" Outer Wall 1: ", v_outer_1, " mm"));
echo(str(" Outer Wall 2: ", v_outer_2, " mm"));
// Internal dividers
if (Nb_Boxes_U > 1) {
CompartmentWidth = (InnerWidth - (Nb_Boxes_U - 1) * Slot_Width_Walls) / Nb_Boxes_U;
for (i = [1 : Nb_Boxes_U - 1]) {
x_pos_abs = Height + i * CompartmentWidth + i * Slot_Width_Walls;
echo(str(" Internal Divider ", i, ": ", x_pos_abs, " mm"));
}
}
echo("---");
// --- Horizontal Cuts (Parallel to X-axis) ---
echo("HORIZONTAL CUTS (Distances from bottom edge):");
// Outer walls
h_outer_1 = Height;
h_outer_2 = TotalLength - Height;
echo(str(" Outer Wall 1: ", h_outer_1, " mm"));
echo(str(" Outer Wall 2: ", h_outer_2, " mm"));
// Internal dividers
if (Nb_Boxes_V > 1) {
CompartmentLength = (InnerLength - (Nb_Boxes_V - 1) * Slot_Width_Walls) / Nb_Boxes_V;
for (i = [1 : Nb_Boxes_V - 1]) {
y_pos_abs = Height + i * CompartmentLength + i * Slot_Width_Walls;
echo(str(" Internal Divider ", i, ": ", y_pos_abs, " mm"));
}
}
echo("--- End of List ---");
// Generate a tiny invisible cube because OpenSCAD needs to produce some geometry.
cube(0.01);
}
// ---------------------------------------------------------------------
// Render the final object
// ---------------------------------------------------------------------
if (view_mode == "export") {
export_layout();
} else if (view_mode == "dxf") {
// Project the 2D unfolded pattern for DXF export
projection(cut = true) unfolded_pattern();
} else if (view_mode == "cutlist") {
generate_cutlist();
} else {
if (Folded_View) {
folded_box();

View File

@ -0,0 +1,70 @@
0
SECTION
2
BLOCKS
0
ENDSEC
0
SECTION
2
ENTITIES
0
LINE
8
0
10
-250
20
-250
11
250
21
-250
0
LINE
8
0
10
250
20
-250
11
250
21
250
0
LINE
8
0
10
250
20
250
11
-250
21
250
0
LINE
8
0
10
-250
20
250
11
-250
21
-250
0
ENDSEC
0
SECTION
2
OBJECTS
0
DICTIONARY
0
ENDSEC
0
EOF

View File

@ -0,0 +1,14 @@
--- Cut List for Saw Operator ---
Board Dimensions: 500 x 500 mm
All distances are for the centerline of the slots.
---
VERTICAL CUTS (Distances from left edge):
Outer Wall 1: 80 mm
Outer Wall 2: 420 mm
Internal Divider 1: 254 mm
---
HORIZONTAL CUTS (Distances from bottom edge):
Outer Wall 1: 80 mm
Outer Wall 2: 420 mm
Internal Divider 1: 254 mm
--- End of List ---

View File

@ -0,0 +1,41 @@
#!/bin/bash
# --- export_dxf.sh ---
# Exports a 2D projection of an OpenSCAD file to a DXF file.
#
# Usage: ./export_dxf.sh <source.scad> [output.dxf]
#
# Arguments:
# $1: source_file - Input .scad file (Required)
# $2: output_file - Output .dxf file (Optional)
# --- Input Validation ---
if [ -z "$1" ]; then
echo "Usage: $0 <source.scad> [output.dxf]"
echo "Error: Source file not specified."
exit 1
fi
# --- Argument Parsing ---
SOURCE_FILE="$1"
OUTPUT_FILE="$2"
# --- Set Default Output Filename ---
if [ -z "$OUTPUT_FILE" ]; then
OUTPUT_FILE="${SOURCE_FILE%.scad}_unfolded.dxf"
fi
# --- OpenSCAD DXF Export Command ---
echo "Exporting 2D projection from '$SOURCE_FILE' to '$OUTPUT_FILE'..."
openscad \
-o "$OUTPUT_FILE" \
-D "view_mode=\"dxf\"" \
"$SOURCE_FILE"
# --- Completion Message ---
if [ $? -eq 0 ]; then
echo "Export complete: '$OUTPUT_FILE' created successfully."
else
echo "Error: OpenSCAD DXF export failed."
exit 1
fi

View File

@ -0,0 +1,44 @@
#!/bin/bash
# --- export_freecad.sh ---
# Imports an OpenSCAD file into FreeCAD and saves it as a .FCStd project.
#
# !! REQUIRES FREECAD & OPENSCAD WORKBENCH !!
# This script depends on FreeCAD being installed, 'FreeCADCmd.exe'
# being in your system's PATH, and the OpenSCAD workbench being installed
# within FreeCAD.
#
# Usage: ./export_freecad.sh <source.scad> [output.FCStd]
#
# Arguments:
# $1: source_file - Input .scad file (Required)
# $2: output_file - Output .FCStd file (Optional)
# --- Input Validation ---
if [ -z "$1" ]; then
echo "Usage: $0 <source.scad> [output.FCStd]"
echo "Error: Source file not specified."
exit 1
fi
# --- Argument Parsing ---
SOURCE_FILE="$1"
OUTPUT_FILE="$2"
# --- Set Default Output Filename ---
if [ -z "$OUTPUT_FILE" ]; then
OUTPUT_FILE="${SOURCE_FILE%.scad}.FCStd"
fi
# --- Step 1: Import .scad and save as .FCStd using FreeCAD ---
echo "Importing '$SOURCE_FILE' and creating '$OUTPUT_FILE' using FreeCAD..."
# Note: Assuming FreeCADCmd.exe for Windows. Use 'freecadcmd' on Linux.
FreeCADCmd.exe -c save_fcstd.py "$SOURCE_FILE" "$OUTPUT_FILE"
if [ $? -ne 0 ]; then
echo "Error: FreeCAD project creation failed. Is FreeCAD and the OpenSCAD workbench installed and in your PATH?"
exit 1
fi
# --- Completion Message ---
echo "Export complete: '$OUTPUT_FILE' created successfully."

View File

@ -0,0 +1,51 @@
#!/bin/bash
# --- generate_cutlist.sh ---
# Generates a cut list of slot distances from an OpenSCAD file.
#
# Usage: ./generate_cutlist.sh <source.scad> [output.txt]
# If output file is not provided, prints to console.
# --- Input Validation ---
if [ -z "$1" ]; then
echo "Usage: $0 <source.scad> [output.txt]"
echo "Error: Source file not specified."
exit 1
fi
SOURCE_FILE="$1"
OUTPUT_FILE="$2"
DUMMY_OUTPUT="cutlist_dummy.stl" # A dummy file to force command-line execution
# --- OpenSCAD Command ---
# We force a dummy output file with -o to prevent the GUI from launching.
# OpenSCAD prints echo() statements to stderr. We redirect stderr to stdout (2>&1),
# then use grep to filter for only the lines starting with "ECHO:",
# and then use sed to remove the prefix and surrounding quotes for a clean output.
CUTLIST_CONTENT=$(openscad \
-o "$DUMMY_OUTPUT" \
-D "view_mode=\"cutlist\"" \
"$SOURCE_FILE" \
2>&1 | grep "ECHO:" | sed 's/ECHO: "//;s/"$//')
# Check the exit status of the openscad command.
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo ""
echo "Error: OpenSCAD command failed."
rm -f "$DUMMY_OUTPUT" # Clean up dummy file on failure
exit 1
fi
# Clean up the dummy file
rm -f "$DUMMY_OUTPUT"
# --- Output the result ---
if [ -z "$OUTPUT_FILE" ]; then
echo ""
echo "--- Generated Cut List ---"
echo "$CUTLIST_CONTENT"
echo "--------------------------"
else
echo "$CUTLIST_CONTENT" > "$OUTPUT_FILE"
echo "Cut list successfully saved to '$OUTPUT_FILE'."
fi

View File

@ -0,0 +1,41 @@
# save_fcstd.py
# A Python script for use with FreeCAD's command-line interface.
# Imports an OpenSCAD file and saves it as a FreeCAD project.
import sys
import FreeCAD
import Part
# --- Argument Validation ---
if len(sys.argv) < 3:
print("Converter script usage: <input_file.scad> <output_file.FCStd>")
sys.exit(1)
input_file_path = sys.argv[-2]
output_file_path = sys.argv[-1]
print(f"Input file: {input_file_path}")
print(f"Output file: {output_file_path}")
# --- Conversion Logic ---
try:
# 1. Create a new, empty FreeCAD document
doc = FreeCAD.newDocument("ImportedSCAD")
# 2. Use the Part module to import the .scad file into the document.
# This requires the OpenSCAD workbench to be installed in FreeCAD.
# FreeCAD manages the call to the 'openscad' executable itself.
Part.insert(input_file_path, doc.Name)
# 3. It's good practice to recompute the model after an import.
doc.recompute()
# 4. Save the document to the specified output file path.
doc.saveAs(output_file_path)
print("FreeCAD project file saved successfully.")
sys.exit(0)
except Exception as e:
print(f"An error occurred during FreeCAD project creation: {e}")
sys.exit(1)