NAME

CAD::Mesh3D::ProvideNewFormat - Documents how to provide a new format to CAD::Mesh3D

DESCRIPTION

CAD::Mesh3D will be used to handle the math, and provides wrappers to output to or input from a given format. But each format will need to separately implement those input and output functions, and will need to provide a function that will tell CAD::Mesh3D what the input and output functions are.

ENABLING FORMATS

Please tell your user to enable your format. For example, if you're developing CAD::Mesh3D::PNG, then tell your user to enable using

use CAD::Mesh3D qw/+PNG :formats/;

or

use CAD::Mesh3D;
enableFormat( 'PNG' );

If you are using a different namespace, such as I::Must::Be::Different::PngFormat, they can enable your format using

use CAD::Mesh3D;
enableFormat( 'PNG' => 'I::Must::Be::Different::PngFormat');

When enableFormat( $format ) is used without a $module argument, the module name will default to $module = "CAD::Mesh3D::$format".

Either way, $module is the module you're developing.

INPUT AND OUTPUT FUNCTIONS

You need to define input and/or output functions, to tell CAD::Mesh3D how to needs to know how to find your input and output functions. These input and output functions will be used to transfer data in your format into a CAD::Mesh3D Mesh, and convert a Mesh into your format. You also need to inform CAD::Mesh3D how to access your functions.

_io_functions

To inform CAD::Mesh3D of the location of your functions, CAD::Mesh3D requires you to provide a function named _io_functions() which returns a hash with input and/or output keys, pointing to coderef values.

sub _io_functions {
    return (
        output => \&outputStl,
        input => sub { croak sprintf "Sorry, %s's developer has not yet debugged inputting from STL", __PACKAGE__ },
    );
}

If your _io_functions() returns a hash missing one or both of those keys, or if you have the key set to undef, as in these next two examples, then CAD::Mesh3D will define some error functions which will die with a meaningful message.

sub _io_functions {
    return (
        output => \&outputStl,
    );
}

sub _io_functions {
    return (
        output => \&outputStl,
        input => undef,
    );
}

Output Function

Your output function should take at least two arguments, the $mesh and the $file, and should output that mesh using your file format into $file. You may feel free to define other arguments as needed, but those two should be first, to maintain consistency across file formats.

The user will call CAD::Mesh3D::output( $mesh, $formatName => $file ). CAD::Mesh3D will check its list of enabled formats against $formatName; if $formatName is found, it will pass the remaining arguments to the output it obtained from _io_functions().

Note that $file could, in theory, be either a file name, or a filehandle to the file, already opened in the right mode. CAD::Mesh3D::STL gives an example of how to handle that. It is recommend, though not required, that your function accepts either one.

This snippet shows the basic form of the output function, or you can see CAD::Mesh3D::STL for a working example:

sub my_plaintext_output_function {
    my $mesh = shift;
    my $file = shift;
    my %args = @_;

    # open $file if necesssary, or do error checking
    ...

    for my $facet ( @$mesh ) {
        ... # process facets and write to file as approrpriate
    }
}

When documenting how your user will use this function, it is recommended to use the CAD::Mesh3D::output() wrapper, rather than telling your user to use your internal function directly. For example, your SYNOPSIS might be:

use CAD::Mesh3D qw/+YourFormat :formats/;
$mesh = ...;  # define your mesh here using CAD::Mesh3D
$mesh->output( YourFormat => $filename );

Input Function

Your input function needs take at least one argument, the $file, and should populate that mesh from the supplied $file. You may feel free to define other arguments as needed, but those two should be first, to maintain consistency across file formats.

The user will call my $mesh = CAD::Mesh3D::input( $formatName => $file ). CAD::Mesh3D will check its list of enabled formats against $formatName; if $formatName is found, it will pass the remaining arguments to the output it obtained from _io_functions().

Note that $file could, in theory, be either a file name, or a filehandle to the file, already opened in the right mode. CAD::Mesh3D::STL gives an example of how to handle that. It is recommend, though not required, that your function accepts either one.

This snippet shows the basic form of the output function, or you can see CAD::Mesh3D::STL for a working example:

sub my_plaintext_input_function {
    my $file = shift;
    my %args = @_;

    # open $file if necesssary, or do error checking
    ...

    my @facets = ();
    foreach my $f ( 1 .. $nFacetsDesired ) {
       # populate with three vertexes, preferably using createVertex(), from your $file
       my @verts = ( createVertex(...), createVertex(...), createVertex(...) );

       # append to the list of facets
       push @facets, createFacet(@verts);
    }

    # combine those facets into a mesh
    return createMesh( @facets );
}

When documenting how your user will use this function, it is recommended to use the CAD::Mesh3D::input() wrapper, rather than telling your user to use your internal function directly. For example, your SYNOPSIS might be:

use CAD::Mesh3D qw/+YourFormat :formats/;
$mesh = input( YourFormat => $filename );

EXAMPLE

The CAD::Mesh3D::STL shows an example of how I used these rules to implement the STL file format.

AUTHOR

Peter C. Jones <petercj AT cpan DOT org>

COPYRIGHT

Copyright (C) 2017,2018,2019,2020,2021,2024 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.