stl

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2017 License: MIT Imports: 11 Imported by: 0

README

stl

A library to read, write, and transform Stereolithography (.stl) files in Go. It is used in the command line STL manipulation tool stltool.

Features

  • Read and write STL files in either binary or ASCII form
  • Check correctness of STL files
  • Measure models
  • Various linear model transformations
    • Scale
    • Rotate
    • Translate (Move)
    • Fit into box
    • Apply generic 4x4 transformation matrix

Applications

  • Save 3D models as STL
  • Import STL models
  • Repair and manipulation of STL models
  • General pre-processing before processing STL models in a 3D printing slicer
  • Writing a slicer in Go (I hope someone does this one day)

Installation

Using go's builtin installation mechanism:

go get github.com/hschendel/stl

Usage Example

solid, errRead := stl.ReadFile(inputFilename)
if errRead != nil {
  // handle
}
solid.Scale(25.4) // Convert from Inches to mm
errWrite := solid.WriteFile(outputFilename)

Further Reading

The package godoc documentation should be helpful. Or just start a local godoc server using this command:

godoc -http=:6060

Then open http://localhost:6060/pkg/github.com/hschendel/stl/ in your browser.

License

The stl package is licensed under the MIT license. See LICENSE file.

Documentation

Overview

Package stl implements functions to read, write, and transform files in the Stereolithography/Surface Tesselation Language (.stl) file format used in 3D modelling.

The format specification was taken from http://www.ennex.com/~fabbers/StL.asp, found at http://en.wikipedia.org/wiki/STL_%28file_format%29.

While STL stores the data in single precision 32 bit floating point numbers, the stl package does all calculations beyond simple addition in double precision 64 bit (float64).

Usage Example

// Read STL file
solid, errRead := stl.ReadFile(inputFilename)
if errRead != nil {
  fmt.Fprintln(os.Stderr, errRead)
  os.Exit(1)
}

// Convert from Inches to mm
solid.Scale(25.4)

// Write STL file
errWrite := solid.WriteFile(outputFilename)
if errWrite != nil {
  fmt.Fprintln(os.Stderr, errWrite)
  os.Exit(2)
}

Everything that operates on a model is defined as a method of Solid.

Note that The STL format has two variants, a human-readable ASCII variant, and a more compact and precise binary variant which is preferrable.

ASCII Format Specialities

The Solid.BinaryHeader field and the Triangle.Attributes fields will be empty, after reading, as these are not part of the ASCII format. The Solid.Name field is read from the first line after "solid ". It is not checked against the name at the end of the file after "endsolid ". The stl package will also not cope with Unicode byte order marks, which some text editors might automatically place at the beginning of a file.

Binary Format Specialities

The Solid.BinaryHeader field is filled with all 80 bytes of header data. Then, ReadFile will try to fill solid.Name with an ASCII string read from the header data from the first byte until a \0 or a non-ASCII character is detected.

Numerical Errors

As always when you do linear transformations on floating point numbers, you get numerical errors. So you should expect a vertex being rotated for 360° not to end up at exactly the original coordinates, but instead just very close to them. As the error is usually far smaller than the available precision of 3D printing applications, this is not an issue in most cases.

Index

Constants

View Source
const HalfPi = math.Pi * 0.5

Just for convenience.

View Source
const Pi = math.Pi

Just for convenience.

View Source
const QuarterPi = math.Pi * 0.25

Just for convenience.

View Source
const TwoPi = math.Pi * 2

Just for convenience.

Variables

View Source
var ErrIncompleteBinaryHeader = errors.New("Incomplete STL binary header, 84 bytes expected")

Error when reading binary STL files with incomplete header.

View Source
var ErrUnexpectedEOF = errors.New("Unexpected end of file")

Used by ReadFile and ReadAll to signify an incomplete file.

View Source
var Mat4Identity = Mat4{
	Vec4{1, 0, 0, 0},
	Vec4{0, 1, 0, 0},
	Vec4{0, 0, 1, 0},
	Vec4{0, 0, 0, 1},
}

The identity matrix

Functions

func RotationMatrix

func RotationMatrix(pos Vec3, dir Vec3, angle float64, rotationMatrix *Mat4)

Calculates a 4x4 rotation matrix for a rotation of angle in radians around a rotation axis defined by a point on it (pos) and its direction (dir). The result is written into *rotationMatrix.

Types

type EdgeError

type EdgeError struct {
	// Indexes in Solid.Triangles of triangles that contain exactly the same edge.
	SameEdgeTriangles []int

	// Indexes in Solid.Triangles of triangles that contain the edge in the
	// opposite direction. If there is exactly one other triangle, this is no
	// error.
	CounterEdgeTriangles []int
}

Describes the errors found for a single edge within a triangle using Solid.Validate().

func (*EdgeError) HasMultipleCounterEdges

func (eer *EdgeError) HasMultipleCounterEdges() bool

true if there is more than one other triangle with this edge in the opposite direction

func (*EdgeError) HasNoCounterEdge

func (eer *EdgeError) HasNoCounterEdge() bool

true if there is no other triangle with this edge in the opposite direction, meaning that there is no neighboring triangle

func (*EdgeError) IsUsedInOtherTriangles

func (eer *EdgeError) IsUsedInOtherTriangles() bool

true if this edge is also used in another triangle, meaning that there is probably something wrong with this or the other triangle's orientation.

type Mat4

type Mat4 [4]Vec4

4x4 Matrix of float64 used for 3D transformations. The 4th column can be used for moving the solid on the axes. Accessing matrix elements goes like this:

matrix[row][column]

func (*Mat4) MultMat4

func (m *Mat4) MultMat4(o *Mat4, r *Mat4)

Multiply m with o and write the result into r.

func (*Mat4) MultVec3

func (m *Mat4) MultVec3(v Vec3) Vec3

Multiply m with v, where v[3] is assumed to be 1, and the 4th result value is not calculated, as is usual in 3D transformations.

type Solid

type Solid struct {
	// only used in binary format
	BinaryHeader []byte

	Name string

	Triangles []Triangle

	// true, if this Solid was read from an ASCII file, and false, if read
	// from a binary file. Also used to determine the format when writing
	// to a file.
	IsAscii bool
}

A 3D model made out of triangles, called solid in STL, representing an STL file

func ReadAll

func ReadAll(r io.Reader) (solid *Solid, err error)

Reads the contents of a file into a new Solid object. The file can be either in STL ASCII format, beginning with "solid ", or in STL binary format, beginning with a 84 byte header. Because of this, the file pointer has to be at the beginning of the file.

func ReadFile

func ReadFile(filename string) (solid *Solid, err error)

Reads the contents of a file into a new Solid object. The file can be either in STL ASCII format, beginning with "solid ", or in STL binary format, beginning with a 84 byte header. Shorthand for os.Open and ReadAll

func (*Solid) IsInPositive

func (solid *Solid) IsInPositive() bool

Returns true if every vertex in this solid is within the positive octant, i.e. all coordinate values are positive or 0.

func (*Solid) Measure

func (solid *Solid) Measure() SolidMeasure

Calculate the dimensions of a solid in its own units

func (*Solid) MoveToPositive

func (solid *Solid) MoveToPositive()

Move solid into positive octant if necessary, as prescribed by the original STL format spec. Some applications tolerate negative coordinates. This also makes sense, as the origin is a perfect reference point for rotations.

func (*Solid) RecalculateNormals

func (solid *Solid) RecalculateNormals()

Recalculate all triangle normal vectors from the vertices. Can be used after multiple transformations using the TransformNR method that does not recalculate the normal vectors.

func (*Solid) Rotate

func (solid *Solid) Rotate(pos, dir Vec3, angle float64)

Rotate the solid by angle radians around a rotation axis defined by a point pos on the axis and a direction vector dir. This example would rotate the solid by 90 degree around the z-axis:

stl.Rotate(stl.Vec3{0,0,0}, stl.Vec3{0,0,1}, stl.HalfPi)

func (*Solid) Scale

func (solid *Solid) Scale(factor float64)

Scale all vertex coordinates by scalar factor

func (*Solid) ScaleLinearDowntoSizeBox

func (solid *Solid) ScaleLinearDowntoSizeBox(sizeBox Vec3)

If solid does not fit into size box defined by sizeBox, it is scaled down accordingly. It is not scaled up, if it is smaller than sizeBox. All sizes have to be > 0.

func (*Solid) Stretch

func (solid *Solid) Stretch(vec Vec3)

Scale all vertex coordinates by different factors per axis

func (*Solid) Transform

func (solid *Solid) Transform(transformationMatrix *Mat4)

Applies a 4x4 transformation matrix to every vertex and recalculates the normal for every triangle

func (*Solid) TransformNR

func (solid *Solid) TransformNR(transformationMatrix *Mat4)

Applies a 4x4 transformation matrix to every vertex and does not recalculate the normal vector for every triangle. This could be used to speed things up when multiple transformations are applied successively to a solid, and the transformation matrix is not calculated beforehand. Before writing this solid to disk then, RecalculateNormals() should be called.

func (*Solid) Translate

func (solid *Solid) Translate(vec Vec3)

Translate (i.e. move) the solid by vec

func (*Solid) Validate

func (solid *Solid) Validate() map[int]*TriangleErrors

Looks for triangles that are really lines or dots, and for edges that violate the vertex-to-vertex rule. Returns a map of errors by triangle index that could be used to print out an error report.

func (*Solid) WriteAll

func (solid *Solid) WriteAll(w io.Writer) error

Write contents of this solid to an io.Writer. Depending on solid.IsAscii the STL ASCII format, or the STL binary format is used. If IsAscii is false, and the binary format is used, solid.Name will be used for the header, if solid.BinaryHeader is empty.

func (*Solid) WriteFile

func (solid *Solid) WriteFile(filename string) error

Create file with name filename and write contents of this Solid. Shorthand for os.Create and Solid.WriteAll

type SolidMeasure

type SolidMeasure struct {
	// Minimum values for axes
	Min Vec3

	// Maximum values for axes
	Max Vec3

	// Max - Min
	Len Vec3
}

Type used to store the result of Solid.Measure()

type Triangle

type Triangle struct {
	// Normal vector of triangle, should be normalized...
	Normal Vec3

	// Vertices of triangle in right hand order.
	// I.e. from the front the triangle's vertices are ordered counterclockwise
	// and the normal vector is orthogonal to the front pointing outside.
	Vertices [3]Vec3

	// 16 bits of attributes. Not available in ASCII format. Could be used
	// for color selection, texture selection, refraction etc. Some tools ignore
	// this field completely, always writing 0 on export.
	Attributes uint16
}

Data type for single triangles used in Solid.Triangles. The vertices have to be ordered counter-clockwise when looking at their outside surface. The vector Normal is orthogonal to the triangle, pointing outside, and has length 1. This is redundant but included in the STL format in order to avoid recalculation.

type TriangleErrors

type TriangleErrors struct {
	// true if some vertices are identical, meaning we are having
	// a line, or even a point, as opposed to a triangle.
	HasEqualVertices bool

	// true if the normal vector does not match a normal calculated from the
	// vertices in the right hand order, even allowing for an angular difference
	// of < 90 degree.
	NormalDoesNotMatch bool

	// Errors by edge. The edge is indexed by it's first vertex, i.e.
	//    0: V0 -> V1
	//    1: V1 -> V2
	//    2: V2 -> V0
	// If the edge has no error its value is nil.
	EdgeErrors [3]*EdgeError
}

Describes the errors found in a single triangle.

type Vec3

type Vec3 [3]float32

3D Vector, used in Triangle for normal vector and vertices.

type Vec4

type Vec4 [4]float64

Used to construct Mat4

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL