The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

CAD::Mesh3D - Create and Manipulate 3D Vertexes and Meshes and output for 3D printing

SYNOPSIS

 use CAD::Mesh3D qw(+STL :create :formats);
 my $vect = createVertex();
 my $tri  = createFacet($v1, $v2, $v3);
 my $mesh = createMesh();
 $mesh->addToMesh($tri);
 ...
 $mesh->output(STL => $filehandle_or_filename, $ascii_or_binary);

DESCRIPTION

A framework to create and manipulate 3D vertexes and meshes, suitable for generating STL files (or other similar formats) for 3D printing.

A Mesh is the container for the surface of the shape or object being generated. The surface is broken down into locally-flat pieces known as Facets. Each Facet is a triangle made from three points, called Vertexes (also spelled as vertices). Each Vertex is made up of three x, y, and z coordinates, which are just floating-point values to represent the position in 3D space.

FUNCTIONS

OBJECT CREATION

The following functions will create the Mesh, Triangle, and Vertex array-references. They can be imported into your script en masse using the :create tag.

createVertex

 my $v = createVertex( $x, $y, $z );

Creates a Vertex using the given $x, $y, $z floating-point values to represent the x, y, and z coordinates in 3D space.

createFacet

 my $f = createFacet( $a, $b, $c );

Creates a Facet using the three Vertex arguments as the corner points of the triangle.

Note that the order of the Facet's Vertexes matters, and follows the right-hand rule to determine the "outside" of the Facet: if you are looking at the Facet such that the points are arranged in a counter-clockwise order, then everything from the Facet towards you (and behind you) is "outside" the surface, and everything beyond the Facet is "inside" the surface.

createQuadrangleFacets

 my @f = createQuadrangleFacets( $a, $b, $c, $d );

Creates two Facets using the four Vertex arguments as the corners of a quadrangle (like with createFacet, the arguments are ordered by the right-hand rule). This returns a list of two triangular Facets, for the triangles ABC and ACD.

getx

gety

getz

 my $v = createVertex(1,2,3);
 my $x = getx($v); # 1
 my $y = getx($v); # 2
 my $z = getx($v); # 3

Grabs the individual x, y, or z coordinate from a vertex

createMesh

 my $m = createMesh();          # empty
 my $s = createMesh($f, ...);   # pre-populated

Creates a Mesh, optionally pre-populating the Mesh with the supplied Facets.

addToMesh

 $mesh->addToMesh($f);
 $mesh->addToMesh($f1, ... $fN);
 addToMesh($mesh, $f1, ... $fN);

Adds Facets to an existing Mesh.

MATH FUNCTIONS

 use CAD::Mesh3D qw/:math/;

Most of the math on the three-dimensional Vertexes are handled by Math::Matrix::Real; all the matrix methods will work on Vertexes, as documented for Math::Matrix::Real. However, three-dimensional math can take some special functions that aren't included in the generic matrix library. CAD::Mesh3D implements a few of these special-purpose functions for you.

They can be called as methods on the Vertex variables, or imported as functions into your script using the :math tag.

unitDelta

 my $uAB = unitDelta( $A, $B );
 # or
 my $uAB = $A->unitDelta($B);

Returns a vector (using same structure as a Vertex), which gives the direction from Vertex A to Vertex B. This is scaled so that the vector has a magnitude of 1.0.

unitCross

 my $uN = unitCross( $uAB, $uBC );
 # or
 my $uN = $uAB->unitCross($uBC);

Returns the cross product for the two vectors, which gives a vector perpendicular to both. This is scaled so that the vector has a magnitude of 1.0.

A typical usage would be for finding the direction to the "outside" (the normal-vector) using the right-hand rule. For a Facet with points A, B, and C, first, find the direction from A to B, and from B to C; the unitCross of those two deltas gives you the normal-vector (and, in fact, that's how facetNormal() is implemented).

 my $uAB = unitDelta( $A, $B );
 my $uBC = unitDelta( $B, $C );
 my $uN  = unitCross( $uAB, $uBC );

facetNormal

unitNormal

 my $uN = facetNormal( $facet );
 # or
 my $uN = $facet->normal();
 # or
 my $uN = unitNormal( $vertex1, $vertex2, $vertex3 )

Uses unitDelta() and unitCross() to find the normal-vector for the given Facet, given the right-hand rule order for the Facet's vertexes.

FORMATS

If you want to be able to output your mesh into a format, or input a mesh from a format, you need to enable them. This makes it simple to incorporate an add-on CAD::Mesh3D::NiftyFormat.

Note to developers: CAD::Mesh3D::ProvideNewFormat documents how to write a submodule (usually in the CAD::Mesh3D namespace) to provide the appropriate input and/or output functions for a given format. CAD::Mesh3D:STL is a format that ships with CAD::Mesh3D, and provides an example of how to implement a format module.

The enableFormat, output, and input functions can be imported using the :formats tag.

enableFormat

 use CAD::Mesh3D qw/+STL :formats/;     # for the format 'STL'
  # or
 enableFormat( $format )
  # or
 enableFormat( $format => $moduleName  )

$moduleName should be the name of the module that will provide the $format routines. It will default to 'CAD::Mesh3D::$format'. The $format is case-sensitive, so enableFormat( 'Stl' ); enableFormat( 'STL' ); will try to enable two separate formats.

output

Output the Mesh to a 3D output file in the given format

 use CAD::Mesh3D qw/+STL :formats/;
 $mesh->output('STL' => $file);
 $mesh->output('STL' => $file, @args );

Outputs the given $mesh to the indicated file.

The $file argument is either an already-opened filehandle, or the name of the file (if the full path is not specified, it will default to your script's directory), or "STDOUT" or "STDERR" to direct the output to the standard handles.

You will need to look at the documentation for your selected format to see what additional @args it might want. Often, the args will be used for setting format options, like picking between ASCII and binary file formats, or similar.

You also may need to whether your chosen format even supports file output; it is possible that some do not. (For example, some formats may have a binary structure that is free to read, but requires paying a license to write.)

input

 use CAD::Mesh3D qw/+STL :formats/;
 my $mesh = input( 'STL' => $file, @args );

Creates a Mesh by reading the given file using the specified format.

The $file argument is either an already-opened filehandle, or the name of the file (if the full path is not specified, it will default to your script's directory), or "STDIN" to grab the input from the standard input handle.

You will need to look at the documentation for your selected format to see what additional @args it might want. Often, the args will be used for setting format options, like picking between ASCII and binary file formats, or similar.

You also may need to whether your chosen format even supports file input; it is possible that some do not. (For example, some formats, like a PNG image, may not contain the necessary 3d information to create a mesh.)

SEE ALSO

  • Math::Vector::Real - This provides matrix math

    The Vertexes were implemented using this module, to easily handle the Vertex and Facet calculations.

  • CAD::Format::STL - This provides simple input and output between STL files and an array-of-arrays perl data structure.

    Adding more features to this module (especially the math on the Vertexes and Facets) and making a generic interface (which can be made to work with other formats) were the two primary motivators behind the CAD::Mesh3D development.

    This module is still used as the backend for the CAD::Mesh3D::STL format-module.

TODO

  • Add more math for Vertexes and Facets, as new functions are identified as being useful.

AUTHOR

Peter C. Jones <petercj AT cpan DOT org>

issues appveyor build status travis build status Coverage Status

COPYRIGHT

Copyright (C) 2017,2018,2019,2020,2021 Peter C. Jones

LICENSE

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.