Giter Site home page Giter Site logo

laserscad's Introduction

laserscad 0.3.2

A library for efficient lasercutting with OpenSCAD.

Dominoes modelled using laserscad

Key Features

  • Laser whichever shape you want
  • Model in 3D, then run one command to generate a 2D lasercutting template with all parts
  • Save time, because 2D parts are arranged automatically
  • Add engravings to identify parts (or to make things look fancy)

Installation

You will need:

  • Debian/Ubuntu, Mac OS X or similar
  • openscad 2019.05, GNU make and python3 installed

To set up the library:

Tutorial / Code Example

The library is best explained with an example (click here to jump to the full API reference).

Say we want to create this small table which consists of a table top and two legs:

Small table cut from 5mm MDF

Creating the Model

Let's start by including laserscad and by defining some lengths and a basic table top:

include <laserscad.scad>

thick = 5; // 5mm thick material
top_x = 80;
top_y = 50;
leg_y = 40;
leg_z = 30;

cube([top_x, top_y, thick]);

We need to inform laserscad that our cube should be a lasered part. To do so, we wrap it with lpart(), which takes two arguments: a globally unique string identifying this part and its dimensions on the x and y axes:

lpart("table-top", [top_x, top_y]) {
    cube([top_x, top_y, thick]);
}

Let's translate the table top to where it will sit in the final model. Lparts can be translated using ltranslate, which basically behaves like the ordinary translate operator:

ltranslate([0,0,leg_z-thick]) {
	lpart("table-top", [top_x, top_y]) {
	    cube([top_x, top_y, thick]);
	}
}

Here's what it looks like in OpenSCAD now:

Table top floating in the air

Next, we create a reusable module with more complex geometry for the table legs. We will instantiate two instances of this model in a moment:

module leg(id) {
    lrotate([0,-90,0])
        lpart(str("table-leg-",id), [leg_z, leg_y])
            difference() {
                cube([leg_z, leg_y, thick]);
                translate([0, leg_y/2, 0]) {
                    cylinder(r=leg_y/4, h=thick);
                    translate([leg_z, 0, 0])
                        cylinder(r=leg_y/4, h=thick);
                }
            }
}

There are two more things to point out on this code snippet:

  • The leg is created lying in the xy-plane and is later rotated using lrotate. This is necessary because laserscad needs lparts to lie in the xy-plane for lasercutting. With lrotate we rotate the part for our 3D preview of the final object.
  • As mentioned earlier, the string identifier passed to each lpart call needs to be globally unique. We added an extra id parameter to the module and the lpart call so that we can create multiple table leg parts with unique identifiers.

If we instantiate a leg with leg("left"); it will look like this:

Table leg with two cutouts

What's left to do now is to instantiate and position the two legs and to modify our table top so that it features cutouts for the legs. Afterwards, the model looks like this in 3D:

Table with two legs, assembled

The full code for the example can be found at example/table.scad.

Generating the 2D laser template

Say we saved the model to the file ~/table.scad. To generate the lasercutting template, we open a shell in the folder containing Makefile and run make model=~/table.scad. This creates the file ~/table.dxf which contains the template for our table:

Lasercutting template for the table

There will also be a folder ~/_laserscad_temp which, once we have the DXF file, can be removed manually or by calling make clean model=~/table.scad.

API Reference / Function Overview

This section covers modules/operators offered by laserscad and parameters related to lasercutting.

Including the library

include <laserscad.scad>

lpart

Defines a single object which will be lasercut, consisting of its children. Children must be located in the first octant (in the positive x,y,z range). laserscad projects lparts on the xy-plane, i.e. lparts should be modeled as 3D objects lying on the xy-plane with a thickness in positive z-direction.

lpart(id, [x, y]) { ... }

Parameters

  • id: identifier string, globally unique for each lpart call
  • [x, y]: x and y dimensions of the hull around the children

ltranslate

Use ltranslate to translate lparts. Has the same method signature as the regular translate. To move things around inside of lpart, use the regular translate.

lrotate, lmirror

Similar to ltranslate.

ldummy

Children of ldummy are shown during development but are ignored when exporting 2D templates. This can be useful for modeling laser-cut parts around reference objects.

lengrave

Engraves its children onto its parent lpart. To elaborate on this: lengrave must be used inside of lpart. What is being engraved is defined by the children of lengrave, which can be simple shapes, text, some imported DXF, etc.

lengrave(parent_thick, children_are_2d) { ... }

Parameters

  • parent_thick: Thickness (in z-direction) of the lpart this lengrave is applied to. Only affects the development preview.
  • children_are_2d: Tells lengrave whether its children are a 2D object (true) or a 3D object (false).

Example

See docs/examples/engraving.scad.

Picture of a pattern engraved on an MDF sheet

lslice

Children of lslice are sliced along the z-axis with a specifiable slice thickness. This creates multiple lparts at once. Children must be located in the first octant (in the positive x,y,z range).

lslice(id, [x, y], z, thickness) { ... }

Parameters

  • id: unique identifier string
  • [x, y]: x and y dimensions of the hull around the children
  • z: z dimension of the hull around the children
  • thickness: slice thickness

Example

See docs/examples/slicing.scad. lslice demonstration Low Poly Stanford Bunny by johnny6 is licensed under the Creative Commons - Attribution - Non-Commercial license.

lassert_version

laserscad uses semantic versioning. With lassert_version, one can specify the laserscad version required by a model. This is a bonus feature. It is not necessary to use lassert_version, but it can help to keep one's projects organized.

lassert_version(major=..., minor=...);

Parameters

  • major: the exact major version required
  • minor: minimum required minor version or -1 to accept any minor version

Examples

  • major=0, minor=3 would accept laserscad 0.3.0, 0.3.1, 0.4.0, etc. but not 0.2.0 or 1.0.0
  • major=1, minor=-1 would accept any laserscad 1.x.x (hence 1.0.0, 1.1.0, 1.1.1, etc.) but none of 0.x.x (0.3.0, 0.3.1, etc.)

Other laserscad Parameters

Advanced features of laserscad can be enabled by specifying these parameters anywhere in the global scope of a scad file.

A note about OpenSCAD models consisting of multiple files: These parameter definitions have to find their way into every file where lpart is used. The easiest solution to this is to specify the parameters in some settings.scad file which is imported in everywhere via include <settings.scad>.

lkerf

Compensate kerf (shrinkage caused by the laser beam) for all lparts in millimeters. Default = 0

lmargin

Distance between lparts in the 2D template in millimeters. Default = 2

lidentify

Assembling models with many similar-looking lparts can be a challenge. If the boolean lidentify parameter is set to true, each lpart will be engraved with its unique id, eliminating any confusion. Default = false

Exporting 2D templates

This is a reference of the commands for exporting a template for lasercutting or for engravings.

Lasercutting template

Open a shell and run:

cd laserscad/dist
make cut model=path/to/your/model.scad

The path can be a relative or absolute path pointing to the OpenSCAD model you want to export. This creates a lasercutting template as a DXF file in the same folder as your model.

Engravings

cd laserscad/dist
make engrave model=path/to/your/model.scad

This creates an SVG file with the engravings in the same folder as your model.

Hint: To export the lasercutting template and the engravings in one go, run: make -j 2 cut engrave model=path/to/your/model.scad

Additional options are available for make engrave:

  • model_unit: By default, laserscad assumes that a length of 1 in OpenSCAD corresponds to 1mm in real life. A different unit can be specified, for example model_unit=in. The complete list of allowed values can be found in the W3C SVG specification.
  • engrave_stroke_width: By default, laserscad removes the outline in SVGs because it causes artifacts when engraving complex small shapes. The outline can be re-enabled by specifying a width, for example engrave_stroke_width=0.5. Refer to the W3C SVG Strokes Specification for allowed values.

Lasercutting preview

To check if all lpart dimensions were defined correctly and nothing overlaps, run:

cd laserscad/dist
make preview model=path/to/your/model.scad

Note: Engravings are not shown in the preview.

Cleaning up

The _laserscad_temp folder can be deleted manually, or via:

cd laserscad/dist
make clean model=path/to/your/model.scad

Sheet Size

The default sheet size for arranging parts is 600x300 (millimeters). To export for a different size, add the parameters sheet_xlen=... sheet_ylen=... when calling make.

FAQ

What does laserscad do?

It simplifies and accelerates the process of creating 2D laser-cut objects with OpenSCAD.

What does laserscad not do?

It does not offer methods for creating boxes, different types of joints, and so on. There are, however, several other OpenSCAD libraries for this purpose (like lasercut or JointSCAD) which work great together with laserscad.

Meh, examples. Show me a real application.

That's not a question. Anyway, here you go: Korg Volca Case made with laserscad

How does it work internally?

Several steps are performed internally. The user's model is built with openscad. Meanwhile, laserscad echoes the ids and dimensions of every lpart, which are collected in a file. A python script reads this file and computes a position for every lpart. These positions are used when exporting 2D templates.

laserscad's People

Contributors

hartzell avatar jmgao avatar mbugert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

laserscad's Issues

Error: Duplicate lpart id's

I'm still having problems running laserscad on OS X. Here's the background:

On OS X v 10.13.6
Using laserscad v0.3.2

$ which openscad
returns /usr/local/bin/openscad

which is an executable bash script that looks like this:

#!/bin/bash
/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD $*

When I cd to the new v0.3.2 laserscad/dist and
invoke

$ make cut model=/Users/beesley/perso/shop/3D/openscad/projects/pads/pads.scad

it creates directory _laserscad_temp/ in pads/, puts file pads.echo in it, and then finds an error,
returning

$ make cut model=/Users/beesley/perso/shop/3D/openscad/projects/pads/pads.scad
Getting object bounding boxes...
OpenSCAD reports:
WARNING: Ignoring unknown variable 'lidentify'.
WARNING: Ignoring unknown variable 'lmargin'.
WARNING: Ignoring unknown variable 'lkerf'.
Error: Duplicate lpart id's: pad
make: *** [/Users/beesley/perso/shop/3D/openscad/projects/pads/_laserscad_temp/pads_bb.csv] Error 1

and exits. There's no further output.

The pads.scad file looks like this:
// pads.scad
// Kenneth R. Beesley
/*
Design pads (basically just circles) for saxophone keys to be cut
out of material by a laser cutter

The "material" will be a sandwich of neoprene rubber sheet (1/16"
to 1/8" thick) with a card backing already glued on.  The laser
cutter will need to cut through the rubber and the card backing.

The thickness of the material will vary.  Needs to be specified
for the laser-cutter, I assume?

*/

include <laserscad.scad>

// width of cut left by the laser cutter (see details of the machine)
kerf = 0.5;

thickness = 3; // affects only the development preview in OpenSCAD

// $fn value controls the roundness of the circles
$fn = 200;
font_color = "black";
font_size = 1.5;

module pad(diam) {
lpart("pad", [diam, diam]) {
// text to be engraved
lengrave(thickness, true){
color(font_color)
text(font="DejaVu Sans", size=font_size, str(diam),
halign="center", valign="center");
}
// engrave the text onto a basic cylinder
cylinder(h=thickness, d=diam + kerf);

}

}

module pad_with_hole(odiam, idiam) {
lpart("pad_with_hole", [odiam, odiam]) {
// text to be engraved
lengrave(thickness, true){
color(font_color)
translate([0, 2, 0])
text(font="DejaVu Sans", size=font_size, str(odiam), halign="center",
valign="center");
}

    // engrave the text onto a cylinder with a hole in the middle
    difference() {
        cylinder(h=thickness, d=odiam + kerf);

        translate([0, 0, -1])
        cylinder(h=thickness + 2, d=idiam - kerf);
    }
}

}

union() {
translate([-24, 0, 0])
pad(8.5);

translate([-13, 0, 0])
pad(10);

pad(13);

translate([16, 0, 0])
pad_with_hole(15, 2);

}

********* end of pads.scad ********

So that's where I'm stuck.

What do I need to do to get this working?

Thanks,

Ken

Fails with misleading message for models that don't define lkerf, lidentify, and lmargin

I've spent a couple days trying to debug OpenSCAD's import behavior, when it turned out to be a problem with laserscad.

Laserscad prints the following failure message if any warnings come out of OpenSCAD in from laserscad.scad:

Error: OpenSCAD cannot find 'laserscad.scad'. Put 'laserscad.scad' in the OpenSCAD libraries folder or in the same folder as your model.

That statement is incorrect. In my case, the warnings were

WARNING: Ignoring unknown variable 'lkerf', in file laserscad.scad, line 150.
WARNING: Ignoring unknown variable 'lmargin', in file laserscad.scad, line 151.
WARNING: Ignoring unknown variable 'lidentify', in file laserscad.scad, line 152.

As a workaround, defining all three variables in my design silences the warnings.

Version check utility

  • Add major, minor, patch version to laserscad.scad and add a utility module which complains if the version does not match
  • Document changes in readme

Engraving support

Support for engraving lparts. Either to identify parts after they're lasered or just because it looks fancy.

  • scad, makefile adjustments
  • add png import to example
  • documentation

Proper SVG manipulation via XML

  • don't manipulate SVG via find/replace on plaintext, use proper XML
  • add possibility to change line thickness of exported SVGs
  • documentation

README.md problem, and "make cut" problem (_laserscad_temp/<>.echo not found)

I installed v0.3.0 on OS X.

I created an .scad file, including a call to lengrave, that by itself seems to work as expected in OpenSCAD itself.

I then cd’ed to the dist/ directory and found the following instructions in the laserscad README.md, which
appear to be in error:

    Under “Lasercutting template”
    the instructions say to “Open a shell and run:”
            cd laserscad/dist
            make engrave model=path/to/your/model.scad

    Then under “Engravings”, it tells you to invoke the very same commands.

From other clues, it would appear that the first command should be

            make cut model=path/to/your/model.scad

But when I run that, I get

$ make cut model=/Users/beesley/perso/shop/3D/openscad/projects/pads/pads.scad
Getting object bounding boxes...
Traceback (most recent call last):
File "util/extract_bounding_boxes.py", line 86, in
extract(*sys.argv[1:])
File "util/extract_bounding_boxes.py", line 26, in extract
with open(src, 'r') as file:
FileNotFoundError: [Errno 2] No such file or directory: '/Users/beesley/perso/shop/3D/openscad/projects/pads/_laserscad_temp/pads.echo'
make: *** [/Users/beesley/perso/shop/3D/openscad/projects/pads/_laserscad_temp/pads_bb.csv] Error 1

In the directory where my pads.scad is located, I see that a directory _laserscad_temp/ was created, but
it’s empty.


I continue to look into this, but I’m currently stuck.

Any suggestions?

2D packing with simulated annealing

Proper packing algorithm with multiple quality settings.

  • basic implementation
  • reasonable parameters (quality presets, cooling schedule)
  • documentation/readme

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.