1 / 4
AI CAD PRODUCTION : OPENSCAD + AI = ZIP TIE. — zdjęcie 1
1 / 4

AI CAD PRODUCTION : OPENSCAD + AI = ZIP TIE.

Zamów wydruk tego modelu

Obliczymy ostateczną cenę na podstawie wybranego pliku. Sprawdzisz ją i zaakceptujesz przed płatnością.

Zapisane na tym urządzeniu.

Community Service Announcment. Made a zip tie by teaching gemini to code for openscad. ZIP TIE (that almost works) tpu

Ocena
0 / 5
Polubienia
20
Pobrania
62
Wydruki
1
Wyświetlenia
325
Oceny
0

Aktualizacja u źródła:

Informacje o modelu

Źródło
Printables
Licencja
Creative Commons — Public Domain

The Making of a 3D Printable Zip Tie Using AI with OpensCad:                                                          A Design Journey

What started as a simple request—"create a reusable zip tie in OpenSCAD"—blossomed into a fascinating, iterative design process. This project is a perfect showcase of how a great idea, combined with the power of generative AI and the crucial feedback of a human designer, can evolve from a basic concept into a fully functional, 3D printable object.

Here’s a breakdown of our collaborative journey, from the first line of code to the final, robust model.

Step 1: Laying the Foundation - A Unique Starting Point

Before a single line of OpenSCAD was written, this project began in a unique way. The user provided the entire OpenSCAD documentation, using a custom-built Python web scraper and a shell script to compile a comprehensive PDF. This wasn't just a reference guide; it was the complete knowledge base, ensuring the AI had access to the best practices, syntax, and rules of the language from the very beginning. This foundational step set the stage for a more informed and capable design process.

Create_pdf.sh

#!/bin/bash

=============================================================================

SCRIPT TO CONVERT A WEBSITE TO A SINGLE PDF DOCUMENT

=============================================================================

--- CONFIGURATION ---

Define the URL of the main documentation page

URL="https://openscad.org/documentation.html"

Define the output file name for the final PDF

OUTPUT_PDF="OpenSCAD_Documentation.pdf"

Define the name of the directory to store temporary files

TEMP_DIR="openscad_docs_temp"

Define a temporary file to hold the list of PDFs

PDF_LIST="pdfs.txt"

--- EXECUTION ---

echo "Starting process to create $OUTPUT_PDF..." echo "------------------------------------------------------"

1. Create a temporary directory and navigate into it

echo "Creating temporary directory: $TEMP_DIR" mkdir -p "$TEMP_DIR" cd "$TEMP_DIR"

2. Download the website documentation recursively

--recursive: downloads all pages linked from the main URL

--no-clobber: prevents overwriting existing files

--page-requisites: downloads all supporting files like CSS and images

--span-hosts: allows downloading linked content from other domains

--convert-links: converts links to be local so they work after conversion

echo "Downloading documentation from $URL..." wget --recursive --no-clobber --page-requisites --span-hosts --convert-links "$URL"

3. Find all downloaded HTML files and convert them to individual PDFs

echo "Converting HTML pages to PDF files..."

Find all files with the .html extension and store their names in an array

mapfile -t html_files < <(find . -name "*.html")

Loop through each HTML file and convert it to a PDF using wkhtmltopdf

for html_file in "${html_files[@]}"; do # Create a clean filename for the PDF pdf_file="${html_file%.html}.pdf"

# Use wkhtmltopdf to convert the HTML to a PDF
# The --quiet flag suppresses output
# The --disable-smart-shrinking flag helps with layout consistency
wkhtmltopdf --quiet --disable-smart-shrinking "$html_file" "$pdf_file"

# Add the newly created PDF to our list for merging later
echo "$pdf_file" &gt;&gt; "$PDF_LIST"

done

4. Merge all the individual PDFs into a single file

Use qpdf to concatenate all the PDF files listed in pdfs.txt

echo "Merging all individual PDFs into $OUTPUT_PDF..." qpdf --empty --pages "$PDF_LIST" -- "$OUTPUT_PDF"

5. Move the final PDF to the parent directory and clean up

echo "Finalizing and cleaning up..." mv "$OUTPUT_PDF" .. cd .. rm -rf "$TEMP_DIR"

echo "------------------------------------------------------" echo "Success! The final PDF is saved as $OUTPUT_PDF"

scrape_docs.py

 

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import sys

The base URL of the documentation site

BASE_URL = "https://openscad.org/documentation.html"

try: response = requests.get(BASE_URL) response.raise_for_status() except requests.exceptions.RequestException as e: print(f"An error occurred while fetching the URL: {e}", file=sys.stderr) sys.exit(1)

soup = BeautifulSoup(response.content, 'html.parser') unique_links = set()

Find the main content div

main_article = soup.find('article')

if main_article: # Find all links within the main article all_links_in_content = main_article.find_all('a', href=True)

for link in all_links_in_content:
    href = link['href']
    full_url = urljoin(BASE_URL, href)
    
    # Filter for links that are part of the documentation and not external
    # This is a much more reliable filter than relying on headings
    if "wikibooks.org" in full_url:
        unique_links.add(full_url)
    elif "cheatsheet" in full_url:
        unique_links.add(full_url)
    # Add a final filter for other documentation links if they exist
    elif "documentation-" in href:
         unique_links.add(full_url)

Print each unique link on a new line

for link in sorted(list(unique_links)): print(link)

if not unique_links: print("No documentation links were found.", file=sys.stderr) sys.exit(1)

BIRTH

The first script was a direct translation of the request. It generated a zip tie with all the basic components: a strap, a head, and teeth. It looked like a zip tie, but as the user quickly pointed out, it had a critical flaw: the locking mechanism was just a static, angled block. It wasn't reusable and highlighted a key challenge in 3D modeling: a model can look right without being functional.

Step 3: The Iterative Debugging Cycle - Where the Magic Happened

This is where the project really came to life. The user provided renders and error logs at each stage, acting as the "chief engineer" guiding the design. Each piece of feedback targeted a specific, real-world problem.

The Geometry Flaw: The next major issue was a classic OpenSCAD mistake. The teeth on the strap were standing up vertically instead of lying flat. The user's keen eye and a quick render immediately showed that the design was physically impossible. We corrected this by switching to the polyhedron module, which allowed us to define the exact 3D wedge shape for each tooth in the correct orientation.

The Dreaded "2-Manifold" Error: Any 3D printing enthusiast will recognize this roadblock. Our model was generating "non-manifold" errors, meaning it wasn't a single, "watertight" object. The renderer saw the strap, head, and locking mechanism as separate, disconnected pieces floating in space. The solution involved a significant redesign to ensure every single part of the zip tie physically overlapped with another, allowing OpenSCAD's union() function to fuse them into one solid volume.

Real-World Tolerances: The design looked better, but the user pointed out another critical, practical issue: the strap was the exact same size as the opening in the head! This led to an important revision where we introduced a clearance variable, adding a small tolerance to the opening to ensure the strap could slide through smoothly.

Perfecting the Lock: The final and most challenging step was the locking mechanism itself. Several versions failed because the "pawl" (the little tooth inside the head) was either blocking the channel, cutting into the wrong surface, or simply not connecting to the head. The final, successful design was achieved by using a difference() operation. We started with a solid head block and then carved out the internal channel and the angled locking surface with a precisely shaped "cutter" object.

The Final Product: A Testament to Collaboration

After more than ten versions, each one refining the design based on direct user feedback, we arrived at a final, printable model. The result is a robust, functional zip tie that is a true product of human-AI collaboration.

The final OpenSCAD script is more than just a model; it's the result of a true back-and-forth design conversation. It demonstrates a powerful workflow:

A human provides a comprehensive knowledge base and a clear goal.

AI generates a rapid prototype based on that knowledge.

The human provides critical, real-world feedback, spotting functional and geometric flaws.

The AI refines the code, incorporating the feedback to solve specific problems.

This cycle of iteration, debugging, and refinement is what took us from a library of documentation to a robust, intelligent, and printable design. We hope you enjoy printing it as much as we enjoyed creating it!

THE FINAL OPENSCAD FILE

/ Reusable Cable Tie for Cable Management (V12.1 - Typo Fix)
//
// This version corrects a critical typo in the parameters that was causing
// a cascade of rendering errors. The model should now be fully functional.

// --- Parameters --- length = 120; // Total length of the zip tie strap width = 8; // Width of the strap thickness = 1.5; // Thickness of the strap head_width = 12; // Width of the locking head head_length = 12; // Length of the locking head head_thickness = 6; // Thickness of the head tooth_spacing = 2.5; // Spacing between teeth on the strap tooth_height = 0.7; // Height of the teeth

// --- Helper variable for ensuring unions are solid --- epsilon = 0.01; // A small value for overlaps

// --- Main Module for the zip tie --- module reusable_zip_tie(length, width, thickness, head_width, head_length, head_thickness, tooth_spacing, tooth_height) {

union() {
    // Main strap with teeth
    union() {
        // Strap body
        cube([length, width, thickness]);

        // Teeth on the strap
        for (i = [head_length + 5 : tooth_spacing : length - 10]) {
            translate([i, 0, thickness - epsilon]) {
                polyhedron(
                    points=[
                        [0, 0, 0], [0, width, 0], [tooth_spacing, 0, 0], [tooth_spacing, width, 0],
                        [tooth_spacing/2, 0, tooth_height], [tooth_spacing/2, width, tooth_height]
                    ],
                    faces=[
                        [0,2,3,1], [0,1,5,4], [2,4,5,3], [0,4,2], [1,3,5]
                    ]
                );
            }
        }

        // Tapered end for easy insertion
        translate([length - epsilon, 0, 0]) {
             linear_extrude(height=thickness){
                polygon(points=[[0,0],[5,width/4],[5,width*3/4],[0,width]]);
            }
        }
    }
    
    // --- Locking Head ---
    // Built as a solid block directly attached to the strap, then hollowed out.
    // This guarantees a single, manifold object.
    difference() {
        // 1. The solid head, positioned to overlap the end of the strap
        translate([-head_length+10, (width - head_width) / 2, 0]) {
            cube([head_length + epsilon, head_width, head_thickness]);
        }
        
        // 2. The "cutter" object that carves out the inside of the head
        union() {
            // The main channel for the strap
            clearance = 0.4; // Generous tolerance for a smooth fit
            channel_height = thickness + tooth_height + clearance+.5;
            translate([-head_length+10 - epsilon, (width - width)/2, 0]) {
                cube([head_length + (2*epsilon), width, channel_height]);
            }
            
            // The pawl/nip cutter, which carves the locking surface
            pawl_length = 5;
            pawl_height = tooth_height ;
            translate([-pawl_length+10, (width - width)/2, channel_height - pawl_height]) {
                rotate([0, 45, 0]) {
                    // This cube is angled to cut the locking ramp
                    cube([pawl_length*2, width, pawl_height*3]);
                }
            }
        }
    }
}

}

// --- Create the final object --- reusable_zip_tie(length, width, thickness, head_width, head_length, head_thickness, tooth_spacing, tooth_height);

Tagi