Remove obsolete perl files

This commit is contained in:
Martin Šach 2023-12-18 13:23:23 +01:00 committed by SachCZ
parent 6b01ae30db
commit f2868767ab
25 changed files with 0 additions and 10354 deletions

132
Build.PL
View File

@ -1,132 +0,0 @@
#!/usr/bin/perl
print "This script is currently used for installing Perl dependenices for running\n";
print "the libslic3r unit / integration tests through Perl prove.\n";
print "If you don't plan to run the unit / integration tests, you don't need to\n";
print "install these dependencies to build and run PrusaSlicer.\n";
use strict;
use warnings;
use Config;
use File::Spec;
my %prereqs = qw(
Devel::CheckLib 0
ExtUtils::MakeMaker 6.80
ExtUtils::ParseXS 3.22
ExtUtils::XSpp 0
ExtUtils::XSpp::Cmd 0
ExtUtils::CppGuess 0
ExtUtils::Typemaps 0
ExtUtils::Typemaps::Basic 0
File::Basename 0
File::Spec 0
Getopt::Long 0
Module::Build::WithXSpp 0.14
Moo 1.003001
POSIX 0
Scalar::Util 0
Test::More 0
IO::Scalar 0
Time::HiRes 0
);
my %recommends = qw(
Class::XSAccessor 0
Test::Harness 0
);
my $sudo = grep { $_ eq '--sudo' } @ARGV;
my $nolocal = grep { $_ eq '--nolocal' } @ARGV;
my @missing_prereqs = ();
if ($ENV{SLIC3R_NO_AUTO}) {
foreach my $module (sort keys %prereqs) {
my $version = $prereqs{$module};
next if eval "use $module $version; 1";
push @missing_prereqs, $module if exists $prereqs{$module};
print "Missing prerequisite $module $version\n";
}
foreach my $module (sort keys %recommends) {
my $version = $recommends{$module};
next if eval "use $module $version; 1";
print "Missing optional $module $version\n";
}
} else {
my @try = (
$ENV{CPANM} // (),
File::Spec->catfile($Config{sitebin}, 'cpanm'),
File::Spec->catfile($Config{installscript}, 'cpanm'),
);
my $cpanm;
foreach my $path (@try) {
if (-e $path) { # don't use -x because it fails on Windows
$cpanm = $path;
last;
}
}
if (!$cpanm) {
if ($^O =~ /^(?:darwin|linux)$/ && system(qw(which cpanm)) == 0) {
$cpanm = 'cpanm';
}
}
die <<'EOF'
cpanm was not found. Please install it before running this script.
There are several ways to install cpanm, try one of these:
apt-get install cpanminus
curl -L http://cpanmin.us | perl - --sudo App::cpanminus
cpan App::cpanminus
If it is installed in a non-standard location you can do:
CPANM=/path/to/cpanm perl Build.PL
EOF
if !$cpanm;
my @cpanm_args = ();
push @cpanm_args, "--sudo" if $sudo;
# install local::lib without --local-lib otherwise it's not usable afterwards
if (!eval "use local::lib qw(local-lib); 1") {
my $res = system $cpanm, @cpanm_args, 'local::lib';
warn "Warning: local::lib is required. You might need to run the `cpanm --sudo local::lib` command in order to install it.\n"
if $res != 0;
}
push @cpanm_args, ('--local-lib', 'local-lib') if ! $nolocal;
# make sure our cpanm is updated (old ones don't support the ~ syntax)
system $cpanm, @cpanm_args, 'App::cpanminus';
my %modules = (%prereqs, %recommends);
foreach my $module (sort keys %modules) {
my $version = $modules{$module};
my @cmd = ($cpanm, @cpanm_args);
# temporary workaround for upstream bug in test
push @cmd, '--notest'
if $module =~ /^(?:OpenGL|Test::Harness)$/;
push @cmd, "$module~$version";
my $res = system @cmd;
if ($res != 0) {
if (exists $prereqs{$module}) {
push @missing_prereqs, $module;
} else {
printf "Don't worry, this module is optional.\n";
}
}
}
}
print "\n";
print "In the next step, you need to build the PrusaSlicer C++ library.\n";
print "1) Create a build directory and change to it\n";
print "2) run cmake .. -DCMAKE_BUILD_TYPE=Release\n";
print "3) run make\n";
print "4) to execute the automatic tests, run ctest --verbose\n";
__END__

View File

@ -39,7 +39,6 @@ option(SLIC3R_FHS "Assume PrusaSlicer is to be installed in a FHS
option(SLIC3R_PCH "Use precompiled headers" 1)
option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1)
option(SLIC3R_PERL_XS "Compile XS Perl module and enable Perl unit and integration tests" 0)
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
option(SLIC3R_UBSAN "Enable UBSan on Clang and GCC" 0)
option(SLIC3R_ENABLE_FORMAT_STEP "Enable compilation of STEP file support" ON)
@ -83,7 +82,6 @@ option(SLIC3R_BUILD_TESTS "Build unit tests" ON)
if (IS_CROSS_COMPILE)
message("Detected cross compilation setup. Tests and encoding checks will be forcedly disabled!")
set(SLIC3R_PERL_XS OFF CACHE BOOL "" FORCE)
set(SLIC3R_BUILD_TESTS OFF CACHE BOOL "" FORCE)
endif ()
@ -176,10 +174,6 @@ if(NOT WIN32)
add_compile_options("$<$<CONFIG:DEBUG>:-DDEBUG>")
endif()
# To be able to link libslic3r with the Perl XS module.
# Once we get rid of Perl and libslic3r is linked statically, we can get rid of -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# WIN10SDK_PATH is used to point CMake to the WIN10 SDK installation directory.
# We pick it from environment if it is not defined in another way
if(WIN32)
@ -619,13 +613,6 @@ set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT P
add_dependencies(gettext_make_pot hintsToPot)
# Perl bindings, currently only used for the unit / integration tests of libslic3r.
# Also runs the unit / integration tests.
#FIXME Port the tests into C++ to finally get rid of the Perl!
if (SLIC3R_PERL_XS)
add_subdirectory(xs)
endif ()
if(SLIC3R_BUILD_SANDBOXES)
add_subdirectory(sandboxes)
endif()

View File

@ -1,88 +0,0 @@
# Find the dependencies for linking with the Perl runtime library.
# Check for the Perl & PerlLib modules
include(LibFindMacros)
libfind_package(PerlEmbed Perl)
libfind_package(PerlEmbed PerlLibs)
# Execute an Alien::Wx module to find the relevant information regarding
# the wxWidgets used by the Perl interpreter.
# Perl specific stuff
set(PerlEmbed_TEMP_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/PerlEmbed_TEMP_INCLUDE.txt)
execute_process(
COMMAND ${PERL_EXECUTABLE} -MExtUtils::Embed -e "
# Import Perl modules.
use strict;
use warnings;
use Config;
use Text::ParseWords;
use ExtUtils::CppGuess;
# Test for a Visual Studio compiler
my \$cpp_guess = ExtUtils::CppGuess->new;
my \$mswin = \$^O eq 'MSWin32';
my \$msvc = \$cpp_guess->is_msvc;
# Query the available data from Alien::wxWidgets.
my \$ccflags;
my \$ldflags;
{ local *STDOUT; open STDOUT, '>', \\\$ccflags; ccflags; }
{ local *STDOUT; open STDOUT, '>', \\\$ldflags; ldopts; }
\$ccflags = ' ' . \$ccflags;
\$ldflags = ' ' . \$ldflags;
my \$filename = '${PerlEmbed_TEMP_INCLUDE}';
open(my $fh, '>', \$filename) or die \"Could not open file '\$filename' \$!\";
# Convert a space separated lists to CMake semicolon separated lists,
# escape the backslashes,
# export the resulting list to a temp file.
sub cmake_set_var {
my (\$varname, \$content) = @_;
# Remove line separators.
\$content =~ s/\\r|\\n//g;
# Escape the path separators.
\$content =~ s/\\\\/\\\\\\\\\\\\\\\\/g;
my @words = shellwords(\$content);
print \$fh \"set(PerlEmbed_\$varname \\\"\" . join(';', @words) . \"\\\")\\n\";
}
cmake_set_var('ARCHNAME', \$Config{archname});
cmake_set_var('CCFLAGS', \$ccflags);
\$ldflags =~ s/ -L/ -LIBPATH:/g if \$msvc;
cmake_set_var('LD', \$Config{ld});
cmake_set_var('LDFLAGS', \$ldflags);
cmake_set_var('CCCDLFLAGS', \$Config{cccdlflags});
cmake_set_var('LDDLFLAGS', \$Config{lddlflags});
cmake_set_var('DLEXT', \$Config{dlext});
close \$fh;
")
include(${PerlEmbed_TEMP_INCLUDE})
file(REMOVE ${PerlEmbed_TEMP_INCLUDE})
unset(PerlEmbed_TEMP_INCLUDE)
if (PerlEmbed_DEBUG)
# First show the configuration extracted by FindPerl & FindPerlLibs:
message(STATUS " PERL_INCLUDE_PATH = ${PERL_INCLUDE_PATH}")
message(STATUS " PERL_LIBRARY = ${PERL_LIBRARY}")
message(STATUS " PERL_EXECUTABLE = ${PERL_EXECUTABLE}")
message(STATUS " PERL_SITESEARCH = ${PERL_SITESEARCH}")
message(STATUS " PERL_SITELIB = ${PERL_SITELIB}")
message(STATUS " PERL_VENDORARCH = ${PERL_VENDORARCH}")
message(STATUS " PERL_VENDORLIB = ${PERL_VENDORLIB}")
message(STATUS " PERL_ARCHLIB = ${PERL_ARCHLIB}")
message(STATUS " PERL_PRIVLIB = ${PERL_PRIVLIB}")
message(STATUS " PERL_EXTRA_C_FLAGS = ${PERL_EXTRA_C_FLAGS}")
# Second show the configuration extracted by this module (FindPerlEmbed):
message(STATUS " PerlEmbed_ARCHNAME = ${PerlEmbed_ARCHNAME}")
message(STATUS " PerlEmbed_CCFLAGS = ${PerlEmbed_CCFLAGS}")
message(STATUS " PerlEmbed_CCCDLFLAGS = ${PerlEmbed_CCCDLFLAGS}")
message(STATUS " LD = ${PerlEmbed_LD}")
message(STATUS " PerlEmbed_LDFLAGS = ${PerlEmbed_LDFLAGS}")
message(STATUS " PerlEmbed_LDDLFLAGS = ${PerlEmbed_LDDLFLAGS}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PerlEmbed
REQUIRED_VARS PerlEmbed_CCFLAGS PerlEmbed_LDFLAGS
VERSION_VAR PERL_VERSION)

View File

@ -1,237 +0,0 @@
project(XS)
# Find the Perl interpreter, add local-lib to PATH and PERL5LIB environment variables,
# so the locally installed modules (mainly the Alien::wxPerl) will be reached.
if (WIN32)
set(ENV_PATH_SEPARATOR ";")
else()
set(ENV_PATH_SEPARATOR ":")
endif()
# Install the XS.pm and XS.{so,dll,bundle} into the local-lib directory.
set(PERL_LOCAL_LIB_DIR ${PROJECT_SOURCE_DIR}/../local-lib)
set(ENV{PATH} "${PERL_LOCAL_LIB_DIR}/bin${ENV_PATH_SEPARATOR}$ENV{PATH}")
set(PERL_INCLUDE "${PERL_LOCAL_LIB_DIR}/lib/perl5${ENV_PATH_SEPARATOR}$ENV{PERL5LIB}")
message("PATH: $ENV{PATH}")
message("PERL_INCLUDE: ${PERL_INCLUDE}")
find_package(Perl REQUIRED)
if (WIN32)
# On Windows passing the PERL5LIB variable causes various problems (such as with MAX_PATH and others),
# basically I've found no good way to do it on Windows.
set(PERL5LIB_ENV_CMD "")
else()
set(PERL5LIB_ENV_CMD ${CMAKE_COMMAND} -E env PERL5LIB=${PERL_INCLUDE})
endif()
# Perl specific stuff
find_package(PerlLibs REQUIRED)
set(PerlEmbed_DEBUG 1)
find_package(PerlEmbed REQUIRED)
# Generate the Slic3r Perl module (XS) typemap file.
set(MyTypemap ${CMAKE_CURRENT_BINARY_DIR}/typemap)
add_custom_command(
OUTPUT ${MyTypemap}
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/xsp/my.map
COMMAND ${PERL5LIB_ENV_CMD} ${PERL_EXECUTABLE} -MExtUtils::Typemaps -MExtUtils::Typemaps::Basic -e "$typemap = ExtUtils::Typemaps->new(file => \"${CMAKE_CURRENT_LIST_DIR}/xsp/my.map\"); $typemap->merge(typemap => ExtUtils::Typemaps::Basic->new); $typemap->write(file => \"${MyTypemap}\")"
VERBATIM
)
# Generate the Slic3r Perl module (XS) main.xs file.
set(XS_MAIN_XS ${CMAKE_CURRENT_BINARY_DIR}/main.xs)
set(XSP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xsp)
#FIXME list the dependecies explicitely, add dependency on the typemap.
set(XS_XSP_FILES
${XSP_DIR}/Config.xsp
${XSP_DIR}/ExPolygon.xsp
${XSP_DIR}/Geometry.xsp
${XSP_DIR}/Line.xsp
${XSP_DIR}/Model.xsp
${XSP_DIR}/Point.xsp
${XSP_DIR}/Polygon.xsp
${XSP_DIR}/Polyline.xsp
${XSP_DIR}/Print.xsp
${XSP_DIR}/TriangleMesh.xsp
${XSP_DIR}/XS.xsp
)
foreach (file ${XS_XSP_FILES})
if (MSVC)
# Visual Studio C compiler has issues with FILE pragmas containing quotes.
set(INCLUDE_COMMANDS "${INCLUDE_COMMANDS}INCLUDE_COMMAND: $^X -MExtUtils::XSpp::Cmd -e xspp -- -t ${CMAKE_CURRENT_LIST_DIR}/xsp/typemap.xspt ${file}\n")
else ()
set(INCLUDE_COMMANDS "${INCLUDE_COMMANDS}INCLUDE_COMMAND: $^X -MExtUtils::XSpp::Cmd -e xspp -- -t \"${CMAKE_CURRENT_LIST_DIR}/xsp/typemap.xspt\" \"${file}\"\n")
endif ()
endforeach ()
configure_file(main.xs.in ${XS_MAIN_XS} @ONLY) # Insert INCLUDE_COMMANDS into main.xs
# Generate the Slic3r Perl module (XS) XS.cpp file.
#FIXME add the dependency on main.xs and typemap.
set(XS_MAIN_CPP ${CMAKE_CURRENT_BINARY_DIR}/XS.cpp)
add_custom_command(
OUTPUT ${XS_MAIN_CPP}
DEPENDS ${MyTypemap} ${XS_XSP_FILES} ${CMAKE_CURRENT_LIST_DIR}/xsp/typemap.xspt
COMMAND ${PERL5LIB_ENV_CMD} xsubpp -typemap typemap -output ${XS_MAIN_CPP} -hiertype ${XS_MAIN_XS}
VERBATIM
)
# Define the Perl XS shared library.
if(APPLE)
set(XS_SHARED_LIBRARY_TYPE MODULE)
else()
set(XS_SHARED_LIBRARY_TYPE SHARED)
endif()
add_library(XS ${XS_SHARED_LIBRARY_TYPE}
${XS_MAIN_CPP}
src/perlglue.cpp
src/ppport.h
src/xsinit.h
xsp/my.map
# mytype.map is empty. Is it required by Build.PL or the Perl xspp module?
xsp/mytype.map
# Used by Perl xsubpp to generate XS.cpp
xsp/typemap.xspt
)
if(APPLE)
set_target_properties(XS PROPERTIES BUNDLE TRUE)
# Ignore undefined symbols of the perl interpreter, they will be found in the caller image.
target_link_libraries(XS "-undefined dynamic_lookup")
endif()
target_link_libraries(XS libslic3r)
target_include_directories(XS PRIVATE src ${LIBDIR}/libslic3r)
target_compile_definitions(XS PRIVATE -DSLIC3RXS)
set_target_properties(XS PROPERTIES PREFIX "") # Prevent cmake from generating libXS.so instead of XS.so
if (APPLE)
# -liconv: boost links to libiconv by default
target_link_libraries(XS "-liconv -framework IOKit" "-framework CoreFoundation" -lc++)
elseif (MSVC)
target_link_libraries(XS )
else ()
target_link_libraries(XS -lstdc++)
endif ()
# Windows specific stuff
if (WIN32)
target_compile_definitions(XS PRIVATE -DNOGDI -DNOMINMAX -DHAS_BOOL)
endif ()
# SLIC3R_MSVC_PDB
if (MSVC AND SLIC3R_MSVC_PDB AND "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
set_target_properties(XS PROPERTIES
COMPILE_FLAGS "/Zi"
LINK_FLAGS "/DEBUG /OPT:REF /OPT:ICF"
)
endif()
if (CMAKE_BUILD_TYPE MATCHES DEBUG)
target_compile_definitions(XS PRIVATE -DSLIC3R_DEBUG -DDEBUG -D_DEBUG)
else ()
target_compile_definitions(XS PRIVATE -DNDEBUG)
endif ()
target_include_directories(XS PRIVATE ${PERL_INCLUDE_PATH})
target_compile_options(XS PRIVATE ${PerlEmbed_CCFLAGS})
if (WIN32)
target_link_libraries(XS ${PERL_LIBRARY})
endif()
set(PERL_LOCAL_LIB_ARCH_DIR "${PERL_LOCAL_LIB_DIR}/lib/perl5/${PerlEmbed_ARCHNAME}")
add_custom_command(
TARGET XS
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${PERL_LOCAL_LIB_ARCH_DIR}/auto/Slic3r/XS/"
COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:XS>" "${PERL_LOCAL_LIB_ARCH_DIR}/auto/Slic3r/XS/"
COMMAND ${CMAKE_COMMAND} -E make_directory "${PERL_LOCAL_LIB_ARCH_DIR}/Slic3r/"
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/lib/Slic3r/XS.pm" "${PERL_LOCAL_LIB_ARCH_DIR}/Slic3r/"
COMMENT "Installing XS.pm and XS.{so,dll,bundle} into the local-lib directory ..."
)
if(APPLE)
add_custom_command(
TARGET XS
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E rename "${PERL_LOCAL_LIB_ARCH_DIR}/auto/Slic3r/XS/XS" "${PERL_LOCAL_LIB_ARCH_DIR}/auto/Slic3r/XS/XS.bundle"
)
endif()
if (MSVC)
# Here we associate some additional properties with the MSVC project to enable compilation and debugging out of the box.
get_filename_component(PROPS_PERL_BIN_PATH "${PERL_EXECUTABLE}" DIRECTORY)
string(REPLACE "/" "\\" PROPS_PERL_BIN_PATH "${PROPS_PERL_BIN_PATH}")
string(REPLACE "/" "\\" PROPS_PERL_EXECUTABLE "${PERL_EXECUTABLE}")
string(REPLACE "/" "\\" PROPS_CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}")
configure_file("../cmake/msvc/xs.wperl.props.in" "${CMAKE_BINARY_DIR}/xs.wperl.props" NEWLINE_STYLE CRLF)
set_target_properties(XS PROPERTIES VS_USER_PROPS "${CMAKE_BINARY_DIR}/xs.wperl.props")
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(_bits 64)
elseif ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
set(_bits 32)
endif ()
add_custom_command(TARGET XS POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${TOP_LEVEL_PROJECT_DIR}/deps/+GMP/gmp/lib/win${_bits}/libgmp-10.dll "${PERL_LOCAL_LIB_ARCH_DIR}/auto/Slic3r/XS/"
COMMENT "Installing gmp runtime into the local-lib directory ..."
VERBATIM)
add_custom_command(TARGET XS POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${TOP_LEVEL_PROJECT_DIR}/deps/+MPFR/mpfr/lib/win${_bits}/libmpfr-4.dll "${PERL_LOCAL_LIB_ARCH_DIR}/auto/Slic3r/XS/"
COMMENT "Installing mpfr runtime into the local-lib directory ..."
VERBATIM)
endif()
# Installation
install(TARGETS XS DESTINATION ${PERL_VENDORARCH}/auto/Slic3r/XS)
install(FILES lib/Slic3r/XS.pm DESTINATION ${PERL_VENDORLIB}/Slic3r)
# Unit / integration tests
enable_testing()
get_filename_component(PERL_BIN_PATH "${PERL_EXECUTABLE}" DIRECTORY)
if (MSVC)
set(PERL_PROVE "${PERL_BIN_PATH}/prove.bat")
else ()
set(PERL_PROVE "${PERL_BIN_PATH}/prove")
endif ()
set(PERL_ENV_VARS "")
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT CMAKE_CROSSCOMPILING AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
if (SLIC3R_ASAN OR SLIC3R_UBSAN)
set(PERL_ENV_VARS env)
endif ()
if (SLIC3R_ASAN)
# Find the location of libasan.so for passing it into LD_PRELOAD. It works with GCC and Clang on Linux.
# On Centos 7 calling "gcc -print-file-name=libasan.so" returns path to "ld script" instead of path to shared library.
set(_asan_compiled_bin ${CMAKE_CURRENT_BINARY_DIR}/detect_libasan)
set(_asan_source_file ${_asan_compiled_bin}.c)
# Compile and link simple C application with enabled address sanitizer.
file(WRITE ${_asan_source_file} "int main(){}")
include(GetPrerequisites)
execute_process(COMMAND ${CMAKE_C_COMPILER} ${_asan_source_file} -fsanitize=address -lasan -o ${_asan_compiled_bin})
# Extract from the compiled application absolute path of libasan.
get_prerequisites(${_asan_compiled_bin} _asan_shared_libraries_list 0 0 "" "")
list(FILTER _asan_shared_libraries_list INCLUDE REGEX libasan)
set(PERL_ENV_VARS ${PERL_ENV_VARS} "LD_PRELOAD=${_asan_shared_libraries_list}")
# Suppressed memory leak reports that come from Perl.
set(PERL_LEAK_SUPPRESSION_FILE ${CMAKE_CURRENT_BINARY_DIR}/leak_suppression.txt)
file(WRITE ${PERL_LEAK_SUPPRESSION_FILE}
"leak:Perl_safesysmalloc\n"
"leak:Perl_safesyscalloc\n"
"leak:Perl_safesysrealloc\n"
"leak:__newlocale\n")
# Suppress a few memory leak reports and disable informing about suppressions.
# Print reports about memory leaks but exit with zero exit code when any memory leaks is found to make unit tests pass.
set(PERL_ENV_VARS ${PERL_ENV_VARS} "LSAN_OPTIONS=suppressions=${PERL_LEAK_SUPPRESSION_FILE}:print_suppressions=0:exitcode=0")
endif ()
if (SLIC3R_UBSAN)
# Do not show full stacktrace for reports from UndefinedBehaviorSanitizer in Perl tests.
set(PERL_ENV_VARS ${PERL_ENV_VARS} "UBSAN_OPTIONS=print_stacktrace=0")
endif ()
endif ()
add_test (NAME xs COMMAND ${PERL_ENV_VARS} "${PERL_EXECUTABLE}" ${PERL_PROVE} -I ${PERL_LOCAL_LIB_DIR}/lib/perl5 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})

View File

@ -1,125 +0,0 @@
package Slic3r::XS;
use warnings;
use strict;
our $VERSION = '0.01';
use Carp qw();
use XSLoader;
XSLoader::load(__PACKAGE__, $VERSION);
package Slic3r::Line;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
package Slic3r::Point;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
package Slic3r::Pointf;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
package Slic3r::Pointf3;
use overload
'@{}' => sub { [ $_[0]->x, $_[0]->y, $_[0]->z ] }, #,
'fallback' => 1;
sub pp {
my ($self) = @_;
return [ @$self ];
}
package Slic3r::ExPolygon;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
package Slic3r::Polyline;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
package Slic3r::Polygon;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
package Slic3r::Surface;
sub new {
my ($class, %args) = @_;
# defensive programming: make sure no negative bridge_angle is supplied
die "Error: invalid negative bridge_angle\n"
if defined $args{bridge_angle} && $args{bridge_angle} < 0;
return $class->_new(
$args{expolygon} // (die "Missing required expolygon\n"),
$args{surface_type} // (die "Missing required surface_type\n"),
$args{thickness} // -1,
$args{thickness_layers} // 1,
$args{bridge_angle} // -1,
$args{extra_perimeters} // 0,
);
}
sub clone {
my ($self, %args) = @_;
return (ref $self)->_new(
delete $args{expolygon} // $self->expolygon,
delete $args{surface_type} // $self->surface_type,
delete $args{thickness} // $self->thickness,
delete $args{thickness_layers} // $self->thickness_layers,
delete $args{bridge_angle} // $self->bridge_angle,
delete $args{extra_perimeters} // $self->extra_perimeters,
);
}
package Slic3r::Surface::Collection;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
sub new {
my ($class, @surfaces) = @_;
my $self = $class->_new;
$self->append($_) for @surfaces;
return $self;
}
package main;
for my $class (qw(
Slic3r::Config
Slic3r::Config::GCode
Slic3r::Config::Print
Slic3r::Config::Static
Slic3r::ExPolygon
Slic3r::Line
Slic3r::Model
Slic3r::Model::Instance
Slic3r::Model::Material
Slic3r::Model::Object
Slic3r::Model::Volume
Slic3r::Point
Slic3r::Point3
Slic3r::Pointf
Slic3r::Pointf3
Slic3r::Polygon
Slic3r::Polyline
Slic3r::Polyline::Collection
Slic3r::Print
Slic3r::TriangleMesh
))
{
no strict 'refs';
my $ref_class = $class . "::Ref";
eval "package $ref_class; our \@ISA = '$class'; sub DESTROY {};";
}
1;

View File

@ -1,26 +0,0 @@
#include <cstring>
#include <cstdlib>
#include <ostream>
#include <sstream>
#ifdef __cplusplus
/* extern "C" { */
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#undef do_open
#undef do_close
#ifdef __cplusplus
/* } */
#endif
#ifdef _WIN32
#undef XS_EXTERNAL
#define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
#endif /* MSVC */
MODULE = Slic3r::XS PACKAGE = Slic3r::XS
@INCLUDE_COMMANDS@

View File

@ -1,527 +0,0 @@
#ifdef SLIC3RXS
#include <xsinit.h>
namespace Slic3r {
REGISTER_CLASS(ExPolygon, "ExPolygon");
REGISTER_CLASS(GCodeGenerator, "GCode");
REGISTER_CLASS(Line, "Line");
REGISTER_CLASS(Polygon, "Polygon");
REGISTER_CLASS(Polyline, "Polyline");
REGISTER_CLASS(Print, "Print");
REGISTER_CLASS(PrintObject, "Print::Object");
REGISTER_CLASS(PrintRegion, "Print::Region");
REGISTER_CLASS(Model, "Model");
REGISTER_CLASS(ModelMaterial, "Model::Material");
REGISTER_CLASS(ModelObject, "Model::Object");
REGISTER_CLASS(ModelVolume, "Model::Volume");
REGISTER_CLASS(ModelInstance, "Model::Instance");
REGISTER_CLASS(BoundingBox, "Geometry::BoundingBox");
REGISTER_CLASS(Point, "Point");
__REGISTER_CLASS(Vec2d, "Pointf");
__REGISTER_CLASS(Vec3d, "Pointf3");
REGISTER_CLASS(DynamicPrintConfig, "Config");
REGISTER_CLASS(StaticPrintConfig, "Config::Static");
REGISTER_CLASS(GCodeConfig, "Config::GCode");
REGISTER_CLASS(PrintConfig, "Config::Print");
REGISTER_CLASS(Surface, "Surface");
REGISTER_CLASS(SurfaceCollection, "Surface::Collection");
REGISTER_CLASS(FullPrintConfig, "Config::Full");
REGISTER_CLASS(TriangleMesh, "TriangleMesh");
SV* ConfigBase__as_hash(ConfigBase* THIS)
{
HV* hv = newHV();
for (auto &key : THIS->keys())
(void)hv_store(hv, key.c_str(), key.length(), ConfigBase__get(THIS, key), 0);
return newRV_noinc((SV*)hv);
}
SV* ConfigBase__get(ConfigBase* THIS, const t_config_option_key &opt_key)
{
ConfigOption *opt = THIS->option(opt_key, false);
return (opt == nullptr) ?
&PL_sv_undef :
ConfigOption_to_SV(*opt, *THIS->def()->get(opt_key));
}
SV* ConfigOption_to_SV(const ConfigOption &opt, const ConfigOptionDef &def)
{
switch (def.type) {
case coFloat:
case coPercent:
return newSVnv(static_cast<const ConfigOptionFloat*>(&opt)->value);
case coFloats:
case coPercents:
{
auto optv = static_cast<const ConfigOptionFloats*>(&opt);
AV* av = newAV();
av_fill(av, optv->values.size()-1);
for (const double &v : optv->values)
av_store(av, &v - optv->values.data(), newSVnv(v));
return newRV_noinc((SV*)av);
}
case coInt:
return newSViv(static_cast<const ConfigOptionInt*>(&opt)->value);
case coInts:
{
auto optv = static_cast<const ConfigOptionInts*>(&opt);
AV* av = newAV();
av_fill(av, optv->values.size()-1);
for (const int &v : optv->values)
av_store(av, &v - optv->values.data(), newSViv(v));
return newRV_noinc((SV*)av);
}
case coString:
{
auto optv = static_cast<const ConfigOptionString*>(&opt);
// we don't serialize() because that would escape newlines
return newSVpvn_utf8(optv->value.c_str(), optv->value.length(), true);
}
case coStrings:
{
auto optv = static_cast<const ConfigOptionStrings*>(&opt);
AV* av = newAV();
av_fill(av, optv->values.size()-1);
for (const std::string &v : optv->values)
av_store(av, &v - optv->values.data(), newSVpvn_utf8(v.c_str(), v.length(), true));
return newRV_noinc((SV*)av);
}
case coPoint:
return perl_to_SV_clone_ref(static_cast<const ConfigOptionPoint*>(&opt)->value);
case coPoint3:
return perl_to_SV_clone_ref(static_cast<const ConfigOptionPoint3*>(&opt)->value);
case coPoints:
{
auto optv = static_cast<const ConfigOptionPoints*>(&opt);
AV* av = newAV();
av_fill(av, optv->values.size()-1);
for (const Vec2d &v : optv->values)
av_store(av, &v - optv->values.data(), perl_to_SV_clone_ref(v));
return newRV_noinc((SV*)av);
}
case coBool:
return newSViv(static_cast<const ConfigOptionBool*>(&opt)->value ? 1 : 0);
case coBools:
{
auto optv = static_cast<const ConfigOptionBools*>(&opt);
AV* av = newAV();
av_fill(av, optv->values.size()-1);
for (size_t i = 0; i < optv->values.size(); ++ i)
av_store(av, i, newSViv(optv->values[i] ? 1 : 0));
return newRV_noinc((SV*)av);
}
default:
std::string serialized = opt.serialize();
return newSVpvn_utf8(serialized.c_str(), serialized.length(), true);
}
}
SV* ConfigBase__get_at(ConfigBase* THIS, const t_config_option_key &opt_key, size_t i)
{
ConfigOption* opt = THIS->option(opt_key, false);
if (opt == nullptr)
return &PL_sv_undef;
const ConfigOptionDef* def = THIS->def()->get(opt_key);
switch (def->type) {
case coFloats:
case coPercents:
return newSVnv(static_cast<ConfigOptionFloats*>(opt)->get_at(i));
case coInts:
return newSViv(static_cast<ConfigOptionInts*>(opt)->get_at(i));
case coStrings:
{
// we don't serialize() because that would escape newlines
const std::string &val = static_cast<ConfigOptionStrings*>(opt)->get_at(i);
return newSVpvn_utf8(val.c_str(), val.length(), true);
}
case coPoints:
return perl_to_SV_clone_ref(static_cast<ConfigOptionPoints*>(opt)->get_at(i));
case coBools:
return newSViv(static_cast<ConfigOptionBools*>(opt)->get_at(i) ? 1 : 0);
default:
return &PL_sv_undef;
}
}
bool ConfigBase__set(ConfigBase* THIS, const t_config_option_key &opt_key, SV* value)
{
ConfigOption* opt = THIS->option(opt_key, true);
if (opt == nullptr)
CONFESS("Trying to set non-existing option");
const ConfigOptionDef* def = THIS->def()->get(opt_key);
if (opt->type() != def->type)
CONFESS("Option type is different from the definition");
switch (def->type) {
case coFloat:
if (!looks_like_number(value))
return false;
static_cast<ConfigOptionFloat*>(opt)->value = SvNV(value);
break;
case coFloats:
{
std::vector<double> &values = static_cast<ConfigOptionFloats*>(opt)->values;
AV* av = (AV*)SvRV(value);
const size_t len = av_len(av)+1;
values.clear();
values.reserve(len);
for (size_t i = 0; i < len; ++ i) {
SV** elem = av_fetch(av, i, 0);
if (elem == NULL || !looks_like_number(*elem)) return false;
values.emplace_back(SvNV(*elem));
}
break;
}
case coPercents:
{
std::vector<double> &values = static_cast<ConfigOptionPercents*>(opt)->values;
AV* av = (AV*)SvRV(value);
const size_t len = av_len(av)+1;
values.clear();
values.reserve(len);
for (size_t i = 0; i < len; i++) {
SV** elem = av_fetch(av, i, 0);
if (elem == NULL || !looks_like_number(*elem)) return false;
values.emplace_back(SvNV(*elem));
}
break;
}
case coInt:
if (!looks_like_number(value)) return false;
static_cast<ConfigOptionInt*>(opt)->value = SvIV(value);
break;
case coInts:
{
std::vector<int> &values = static_cast<ConfigOptionInts*>(opt)->values;
AV* av = (AV*)SvRV(value);
const size_t len = av_len(av)+1;
values.clear();
values.reserve(len);
for (size_t i = 0; i < len; i++) {
SV** elem = av_fetch(av, i, 0);
if (elem == NULL || !looks_like_number(*elem)) return false;
values.emplace_back(SvIV(*elem));
}
break;
}
case coString:
static_cast<ConfigOptionString*>(opt)->value = std::string(SvPV_nolen(value), SvCUR(value));
break;
case coStrings:
{
std::vector<std::string> &values = static_cast<ConfigOptionStrings*>(opt)->values;
AV* av = (AV*)SvRV(value);
const size_t len = av_len(av)+1;
values.clear();
values.reserve(len);
for (size_t i = 0; i < len; i++) {
SV** elem = av_fetch(av, i, 0);
if (elem == NULL) return false;
values.emplace_back(std::string(SvPV_nolen(*elem), SvCUR(*elem)));
}
break;
}
case coPoint:
return from_SV_check(value, &static_cast<ConfigOptionPoint*>(opt)->value);
// case coPoint3:
// not gonna fix it, die Perl die!
// return from_SV_check(value, &static_cast<ConfigOptionPoint3*>(opt)->value);
case coPoints:
{
std::vector<Vec2d> &values = static_cast<ConfigOptionPoints*>(opt)->values;
AV* av = (AV*)SvRV(value);
const size_t len = av_len(av)+1;
values.clear();
values.reserve(len);
for (size_t i = 0; i < len; i++) {
SV** elem = av_fetch(av, i, 0);
Vec2d point(Vec2d::Zero());
if (elem == NULL || !from_SV_check(*elem, &point)) return false;
values.emplace_back(point);
}
break;
}
case coBool:
static_cast<ConfigOptionBool*>(opt)->value = SvTRUE(value);
break;
case coBools:
{
std::vector<unsigned char> &values = static_cast<ConfigOptionBools*>(opt)->values;
AV* av = (AV*)SvRV(value);
const size_t len = av_len(av)+1;
values.clear();
values.reserve(len);
for (size_t i = 0; i < len; i++) {
SV** elem = av_fetch(av, i, 0);
if (elem == NULL) return false;
values.emplace_back(SvTRUE(*elem));
}
break;
}
default:
if (! opt->deserialize(std::string(SvPV_nolen(value)), ForwardCompatibilitySubstitutionRule::Disable))
return false;
}
return true;
}
/* This method is implemented as a workaround for this typemap bug:
https://rt.cpan.org/Public/Bug/Display.html?id=94110 */
bool ConfigBase__set_deserialize(ConfigBase* THIS, const t_config_option_key &opt_key, SV* str)
{
size_t len;
const char * c = SvPV(str, len);
std::string value(c, len);
ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Disable };
return THIS->set_deserialize_nothrow(opt_key, value, ctxt);
}
void ConfigBase__set_ifndef(ConfigBase* THIS, const t_config_option_key &opt_key, SV* value, bool deserialize)
{
if (THIS->has(opt_key))
return;
if (deserialize)
ConfigBase__set_deserialize(THIS, opt_key, value);
else
ConfigBase__set(THIS, opt_key, value);
}
bool StaticConfig__set(StaticConfig* THIS, const t_config_option_key &opt_key, SV* value)
{
const ConfigOptionDef* optdef = THIS->def()->get(opt_key);
if (optdef->shortcut.empty())
return ConfigBase__set(THIS, opt_key, value);
for (const t_config_option_key &key : optdef->shortcut)
if (! StaticConfig__set(THIS, key, value))
return false;
return true;
}
SV* to_AV(ExPolygon* expolygon)
{
const unsigned int num_holes = expolygon->holes.size();
AV* av = newAV();
av_extend(av, num_holes); // -1 +1
av_store(av, 0, perl_to_SV_ref(expolygon->contour));
for (unsigned int i = 0; i < num_holes; i++) {
av_store(av, i+1, perl_to_SV_ref(expolygon->holes[i]));
}
return newRV_noinc((SV*)av);
}
SV* to_SV_pureperl(const ExPolygon* expolygon)
{
const unsigned int num_holes = expolygon->holes.size();
AV* av = newAV();
av_extend(av, num_holes); // -1 +1
av_store(av, 0, to_SV_pureperl(&expolygon->contour));
for (unsigned int i = 0; i < num_holes; i++) {
av_store(av, i+1, to_SV_pureperl(&expolygon->holes[i]));
}
return newRV_noinc((SV*)av);
}
void from_SV(SV* expoly_sv, ExPolygon* expolygon)
{
AV* expoly_av = (AV*)SvRV(expoly_sv);
const unsigned int num_polygons = av_len(expoly_av)+1;
expolygon->holes.resize(num_polygons-1);
SV** polygon_sv = av_fetch(expoly_av, 0, 0);
from_SV(*polygon_sv, &expolygon->contour);
for (unsigned int i = 0; i < num_polygons-1; i++) {
polygon_sv = av_fetch(expoly_av, i+1, 0);
from_SV(*polygon_sv, &expolygon->holes[i]);
}
}
void from_SV_check(SV* expoly_sv, ExPolygon* expolygon)
{
if (sv_isobject(expoly_sv) && (SvTYPE(SvRV(expoly_sv)) == SVt_PVMG)) {
if (!sv_isa(expoly_sv, perl_class_name(expolygon)) && !sv_isa(expoly_sv, perl_class_name_ref(expolygon)))
CONFESS("Not a valid %s object", perl_class_name(expolygon));
// a XS ExPolygon was supplied
*expolygon = *(ExPolygon *)SvIV((SV*)SvRV( expoly_sv ));
} else {
// a Perl arrayref was supplied
from_SV(expoly_sv, expolygon);
}
}
void from_SV(SV* line_sv, Line* THIS)
{
AV* line_av = (AV*)SvRV(line_sv);
from_SV_check(*av_fetch(line_av, 0, 0), &THIS->a);
from_SV_check(*av_fetch(line_av, 1, 0), &THIS->b);
}
void from_SV_check(SV* line_sv, Line* THIS)
{
if (sv_isobject(line_sv) && (SvTYPE(SvRV(line_sv)) == SVt_PVMG)) {
if (!sv_isa(line_sv, perl_class_name(THIS)) && !sv_isa(line_sv, perl_class_name_ref(THIS)))
CONFESS("Not a valid %s object", perl_class_name(THIS));
*THIS = *(Line*)SvIV((SV*)SvRV( line_sv ));
} else {
from_SV(line_sv, THIS);
}
}
SV* to_AV(Line* THIS)
{
AV* av = newAV();
av_extend(av, 1);
av_store(av, 0, perl_to_SV_ref(THIS->a));
av_store(av, 1, perl_to_SV_ref(THIS->b));
return newRV_noinc((SV*)av);
}
SV* to_SV_pureperl(const Line* THIS)
{
AV* av = newAV();
av_extend(av, 1);
av_store(av, 0, to_SV_pureperl(&THIS->a));
av_store(av, 1, to_SV_pureperl(&THIS->b));
return newRV_noinc((SV*)av);
}
void from_SV(SV* poly_sv, MultiPoint* THIS)
{
AV* poly_av = (AV*)SvRV(poly_sv);
const unsigned int num_points = av_len(poly_av)+1;
THIS->points.resize(num_points);
for (unsigned int i = 0; i < num_points; i++) {
SV** point_sv = av_fetch(poly_av, i, 0);
from_SV_check(*point_sv, &THIS->points[i]);
}
}
void from_SV_check(SV* poly_sv, MultiPoint* THIS)
{
if (sv_isobject(poly_sv) && (SvTYPE(SvRV(poly_sv)) == SVt_PVMG)) {
*THIS = *(MultiPoint*)SvIV((SV*)SvRV( poly_sv ));
} else {
from_SV(poly_sv, THIS);
}
}
SV* to_AV(MultiPoint* THIS)
{
const unsigned int num_points = THIS->points.size();
AV* av = newAV();
if (num_points > 0) av_extend(av, num_points-1);
for (unsigned int i = 0; i < num_points; i++) {
av_store(av, i, perl_to_SV_ref(THIS->points[i]));
}
return newRV_noinc((SV*)av);
}
SV* to_SV_pureperl(const MultiPoint* THIS)
{
const unsigned int num_points = THIS->points.size();
AV* av = newAV();
if (num_points > 0) av_extend(av, num_points-1);
for (unsigned int i = 0; i < num_points; i++) {
av_store(av, i, to_SV_pureperl(&THIS->points[i]));
}
return newRV_noinc((SV*)av);
}
void from_SV_check(SV* poly_sv, Polygon* THIS)
{
if (sv_isobject(poly_sv) && !sv_isa(poly_sv, perl_class_name(THIS)) && !sv_isa(poly_sv, perl_class_name_ref(THIS)))
CONFESS("Not a valid %s object", perl_class_name(THIS));
from_SV_check(poly_sv, (MultiPoint*)THIS);
}
void from_SV_check(SV* poly_sv, Polyline* THIS)
{
if (!sv_isa(poly_sv, perl_class_name(THIS)) && !sv_isa(poly_sv, perl_class_name_ref(THIS)))
CONFESS("Not a valid %s object", perl_class_name(THIS));
from_SV_check(poly_sv, (MultiPoint*)THIS);
}
SV* to_SV_pureperl(const Point* THIS)
{
AV* av = newAV();
av_fill(av, 1);
av_store(av, 0, newSViv((*THIS)(0)));
av_store(av, 1, newSViv((*THIS)(1)));
return newRV_noinc((SV*)av);
}
void from_SV(SV* point_sv, Point* point)
{
AV* point_av = (AV*)SvRV(point_sv);
// get a double from Perl and round it, otherwise
// it would get truncated
(*point) = Point(SvNV(*av_fetch(point_av, 0, 0)), SvNV(*av_fetch(point_av, 1, 0)));
}
void from_SV_check(SV* point_sv, Point* point)
{
if (sv_isobject(point_sv) && (SvTYPE(SvRV(point_sv)) == SVt_PVMG)) {
if (!sv_isa(point_sv, perl_class_name(point)) && !sv_isa(point_sv, perl_class_name_ref(point)))
CONFESS("Not a valid %s object (got %s)", perl_class_name(point), HvNAME(SvSTASH(SvRV(point_sv))));
*point = *(Point*)SvIV((SV*)SvRV( point_sv ));
} else {
from_SV(point_sv, point);
}
}
SV* to_SV_pureperl(const Vec2d* point)
{
AV* av = newAV();
av_fill(av, 1);
av_store(av, 0, newSVnv((*point)(0)));
av_store(av, 1, newSVnv((*point)(1)));
return newRV_noinc((SV*)av);
}
bool from_SV(SV* point_sv, Vec2d* point)
{
AV* point_av = (AV*)SvRV(point_sv);
SV* sv_x = *av_fetch(point_av, 0, 0);
SV* sv_y = *av_fetch(point_av, 1, 0);
if (!looks_like_number(sv_x) || !looks_like_number(sv_y)) return false;
*point = Vec2d(SvNV(sv_x), SvNV(sv_y));
return true;
}
bool from_SV_check(SV* point_sv, Vec2d* point)
{
if (sv_isobject(point_sv) && (SvTYPE(SvRV(point_sv)) == SVt_PVMG)) {
if (!sv_isa(point_sv, perl_class_name(point)) && !sv_isa(point_sv, perl_class_name_ref(point)))
CONFESS("Not a valid %s object (got %s)", perl_class_name(point), HvNAME(SvSTASH(SvRV(point_sv))));
*point = *(Vec2d*)SvIV((SV*)SvRV( point_sv ));
return true;
} else {
return from_SV(point_sv, point);
}
}
void from_SV_check(SV* surface_sv, Surface* THIS)
{
if (!sv_isa(surface_sv, perl_class_name(THIS)) && !sv_isa(surface_sv, perl_class_name_ref(THIS)))
CONFESS("Not a valid %s object", perl_class_name(THIS));
// a XS Surface was supplied
*THIS = *(Surface *)SvIV((SV*)SvRV( surface_sv ));
}
SV* to_SV(TriangleMesh* THIS)
{
SV* sv = newSV(0);
sv_setref_pv( sv, perl_class_name(THIS), (void*)THIS );
return sv;
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,262 +0,0 @@
#ifndef _xsinit_h_
#define _xsinit_h_
#ifdef _MSC_VER
// Disable some obnoxious warnings given by Visual Studio with the default warning level 4.
#pragma warning(disable: 4100 4127 4189 4244 4267 4700 4702 4800)
#endif
// undef some macros set by Perl which cause compilation errors on Win32
#undef read
#undef seekdir
#undef bind
#undef send
#undef connect
#undef wait
#undef accept
#undef close
#undef open
#undef write
#undef socket
#undef listen
#undef shutdown
#undef ioctl
#undef getpeername
#undef rect
#undef setsockopt
#undef getsockopt
#undef getsockname
#undef gethostname
#undef select
#undef socketpair
#undef recvfrom
#undef sendto
#undef pause
// these need to be included early for Win32 (listing it in Build.PL is not enough)
#include <ostream>
#include <iostream>
#include <sstream>
// #include <libslic3r.h>
#ifdef SLIC3RXS
// extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#undef do_open
#undef do_close
#undef bind
#undef seed
#undef push
#undef pop
#ifdef _MSC_VER
// Undef some of the macros set by Perl <xsinit.h>, which cause compilation errors on Win32
#undef connect
#undef link
#undef unlink
#undef seek
#undef send
#undef write
#undef open
#undef close
#undef seekdir
#undef setbuf
#undef fread
#undef fseek
#undef fputc
#undef fwrite
#undef fclose
#undef sleep
#undef snprintf
#undef vsnprintf
#undef strerror
#undef test
#undef times
#undef accept
#undef wait
#undef abort
#undef pause
// Breaks compilation with Eigen matrices embedded into Slic3r::Point.
#undef malloc
#undef realloc
#undef free
#undef select
// Because of TBB
#undef _WIN32_WINNT // To avoid compiler warnings
#define _WIN32_WINNT 0x0502
#endif /* _MSC_VER */
#undef Zero
#undef Packet
#undef _
// }
#endif
#include <ClipperUtils.hpp>
#include <Config.hpp>
#include <ExPolygon.hpp>
#include <MultiPoint.hpp>
#include <Point.hpp>
#include <Polygon.hpp>
#include <Polyline.hpp>
#include <TriangleMesh.hpp>
namespace Slic3r {
template<class T>
struct ClassTraits {
// Name of a Perl alias of a C++ class type, owned by Perl, reference counted.
static const char* name;
// Name of a Perl alias of a C++ class type, owned by the C++ code.
// The references shall be enumerated at the end of XS.pm, where the desctructor is undefined with sub DESTROY {},
// so Perl will never delete the object instance.
static const char* name_ref;
};
// use this for typedefs for which the forward prototype
// in REGISTER_CLASS won't work
#define __REGISTER_CLASS(cname, perlname) \
template <>const char* ClassTraits<cname>::name = "Slic3r::" perlname; \
template <>const char* ClassTraits<cname>::name_ref = "Slic3r::" perlname "::Ref";
#define REGISTER_CLASS(cname,perlname) \
class cname; \
__REGISTER_CLASS(cname, perlname);
// Return Perl alias to a C++ class name.
template<class T>
const char* perl_class_name(const T*) { return ClassTraits<T>::name; }
// Return Perl alias to a C++ class name, suffixed with ::Ref.
// Such a C++ class instance will not be destroyed by Perl, the instance destruction is left to the C++ code.
template<class T>
const char* perl_class_name_ref(const T*) { return ClassTraits<T>::name_ref; }
// Mark the Perl SV (Scalar Value) as owning a "blessed" pointer to an object reference.
// Perl will never release the C++ instance.
template<class T>
SV* perl_to_SV_ref(T &t) {
SV* sv = newSV(0);
sv_setref_pv( sv, perl_class_name_ref(&t), &t );
return sv;
}
// Mark the Perl SV (Scalar Value) as owning a "blessed" pointer to an object instance.
// Perl will own the C++ instance, therefore it will also release it.
template<class T>
SV* perl_to_SV_clone_ref(const T &t) {
SV* sv = newSV(0);
sv_setref_pv( sv, perl_class_name(&t), new T(t) );
return sv;
}
// Reference wrapper to provide a C++ instance to Perl while keeping Perl from destroying the instance.
// The instance is created temporarily by XS.cpp just to provide Perl with a CLASS name and a object instance pointer.
template <class T>
class Ref {
T* val;
public:
Ref() : val(NULL) {}
Ref(T* t) : val(t) {}
Ref(const T* t) : val(const_cast<T*>(t)) {}
// Called by XS.cpp to convert the referenced object instance to a Perl SV, before it is blessed with the name
// returned by CLASS()
operator T*() const { return val; }
// Name to bless the Perl SV with. The name ends with a "::Ref" suffix to keep Perl from destroying the object instance.
static const char* CLASS() { return ClassTraits<T>::name_ref; }
};
// Wrapper to clone a C++ object instance before passing it to Perl for ownership.
// This wrapper instance is created temporarily by XS.cpp to provide Perl with a CLASS name and a object instance pointer.
template <class T>
class Clone {
T* val;
public:
Clone() : val(NULL) {}
Clone(T* t) : val(new T(*t)) {}
Clone(const T& t) : val(new T(t)) {}
// Called by XS.cpp to convert the cloned object instance to a Perl SV, before it is blessed with the name
// returned by CLASS()
operator T*() const { return val; }
// Name to bless the Perl SV with. If there is a destructor registered in the XSP file for this class, then Perl will
// call this destructor when the reference counter of this SV drops to zero.
static const char* CLASS() { return ClassTraits<T>::name; }
};
SV* ConfigBase__as_hash(ConfigBase* THIS);
SV* ConfigOption_to_SV(const ConfigOption &opt, const ConfigOptionDef &def);
SV* ConfigBase__get(ConfigBase* THIS, const t_config_option_key &opt_key);
SV* ConfigBase__get_at(ConfigBase* THIS, const t_config_option_key &opt_key, size_t i);
bool ConfigBase__set(ConfigBase* THIS, const t_config_option_key &opt_key, SV* value);
bool ConfigBase__set_deserialize(ConfigBase* THIS, const t_config_option_key &opt_key, SV* str);
void ConfigBase__set_ifndef(ConfigBase* THIS, const t_config_option_key &opt_key, SV* value, bool deserialize = false);
bool StaticConfig__set(StaticConfig* THIS, const t_config_option_key &opt_key, SV* value);
SV* to_AV(ExPolygon* expolygon);
SV* to_SV_pureperl(const ExPolygon* expolygon);
void from_SV(SV* expoly_sv, ExPolygon* expolygon);
void from_SV_check(SV* expoly_sv, ExPolygon* expolygon);
void from_SV(SV* line_sv, Line* THIS);
void from_SV_check(SV* line_sv, Line* THIS);
SV* to_AV(Line* THIS);
SV* to_SV_pureperl(const Line* THIS);
void from_SV(SV* poly_sv, MultiPoint* THIS);
void from_SV_check(SV* poly_sv, MultiPoint* THIS);
SV* to_AV(MultiPoint* THIS);
SV* to_SV_pureperl(const MultiPoint* THIS);
void from_SV_check(SV* poly_sv, Polygon* THIS);
void from_SV_check(SV* poly_sv, Polyline* THIS);
SV* to_SV_pureperl(const Point* THIS);
void from_SV(SV* point_sv, Point* point);
void from_SV_check(SV* point_sv, Point* point);
SV* to_SV_pureperl(const Vec2d* point);
bool from_SV(SV* point_sv, Vec2d* point);
bool from_SV_check(SV* point_sv, Vec2d* point);
void from_SV_check(SV* surface_sv, Surface* THIS);
SV* to_SV(TriangleMesh* THIS);
}
// Defined in wxPerlIface.cpp
// Return a pointer to the associated wxWidgets object instance given by classname.
extern void* wxPli_sv_2_object( pTHX_ SV* scalar, const char* classname );
inline void confess_at(const char *file, int line, const char *func, const char *pat, ...)
{
#ifdef SLIC3RXS
va_list args;
SV *error_sv = newSVpvf("Error in function %s at %s:%d: ", func,
file, line);
va_start(args, pat);
sv_vcatpvf(error_sv, pat, &args);
va_end(args);
sv_catpvn(error_sv, "\n\t", 2);
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs( sv_2mortal(error_sv) );
PUTBACK;
call_pv("Carp::confess", G_DISCARD);
FREETMPS;
LEAVE;
#endif
}
#ifndef CONFESS
/* Implementation of CONFESS("foo"): */
#ifdef _MSC_VER
#define CONFESS(...) confess_at(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#else
#define CONFESS(...) confess_at(__FILE__, __LINE__, __func__, __VA_ARGS__)
#endif
/* End implementation of CONFESS("foo"): */
#endif /* CONFESS */
using namespace Slic3r;
#endif

View File

@ -1,252 +0,0 @@
#!/usr/bin/perl
use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 143;
foreach my $config (Slic3r::Config->new, Slic3r::Config::Static::new_FullPrintConfig) {
$config->set('layer_height', 0.3);
ok abs($config->get('layer_height') - 0.3) < 1e-4, 'set/get float';
is $config->opt_serialize('layer_height'), '0.3', 'serialize float';
$config->set('perimeters', 2);
is $config->get('perimeters'), 2, 'set/get int';
is $config->opt_serialize('perimeters'), '2', 'serialize int';
$config->set('extrusion_axis', 'A');
is $config->get('extrusion_axis'), 'A', 'set/get string';
is $config->opt_serialize('extrusion_axis'), 'A', 'serialize string';
$config->set('notes', "foo\nbar");
is $config->get('notes'), "foo\nbar", 'set/get string with newline';
is $config->opt_serialize('notes'), 'foo\nbar', 'serialize string with newline';
$config->set_deserialize('notes', 'bar\nbaz');
is $config->get('notes'), "bar\nbaz", 'deserialize string with newline';
foreach my $test_data (
{
name => 'empty',
values => [],
serialized => ''
},
{
name => 'single empty',
values => [''],
serialized => '""'
},
{
name => 'single noempty, simple',
values => ['RGB'],
serialized => 'RGB'
},
{
name => 'multiple noempty, simple',
values => ['ABC', 'DEF', '09182745@!#$*(&'],
serialized => 'ABC;DEF;09182745@!#$*(&'
},
{
name => 'multiple, simple, some empty',
values => ['ABC', 'DEF', '', '09182745@!#$*(&', ''],
serialized => 'ABC;DEF;;09182745@!#$*(&;'
},
{
name => 'complex',
values => ['some "quoted" notes', "yet\n some notes", "whatever \n notes", ''],
serialized => '"some \"quoted\" notes";"yet\n some notes";"whatever \n notes";'
}
)
{
$config->set('filament_notes', $test_data->{values});
is $config->opt_serialize('filament_notes'), $test_data->{serialized}, 'serialize multi-string value ' . $test_data->{name};
$config->set_deserialize('filament_notes', '');
is_deeply $config->get('filament_notes'), [], 'deserialize multi-string value - empty ' . $test_data->{name};
$config->set_deserialize('filament_notes', $test_data->{serialized});
is_deeply $config->get('filament_notes'), $test_data->{values}, 'deserialize complex multi-string value ' . $test_data->{name};
}
$config->set('first_layer_height', 0.3);
ok abs($config->get('first_layer_height') - 0.3) < 1e-4, 'set/get absolute floatOrPercent';
is $config->opt_serialize('first_layer_height'), '0.3', 'serialize absolute floatOrPercent';
# This is no more supported after first_layer_height was moved from PrintObjectConfig to PrintConfig.
# $config->set('first_layer_height', $config->get('layer_height'));
# $config->get_abs_value('first_layer_height');
# ok abs($config->get_abs_value('first_layer_height') - 0.15) < 1e-4, 'set/get relative floatOrPercent';
# is $config->opt_serialize('first_layer_height'), '50%', 'serialize relative floatOrPercent';
# Uh-oh, we have no point option to test at the moment
#ok $config->set('print_center', [50,80]), 'valid point coordinates';
#is_deeply $config->get('print_center'), [50,80], 'set/get point';
#is $config->serialize('print_center'), '50,80', 'serialize point';
#$config->set_deserialize('print_center', '20,10');
#is_deeply $config->get('print_center'), [20,10], 'deserialize point';
#ok !$config->set('print_center', ['t',80]), 'invalid point X';
#ok !$config->set('print_center', [50,'t']), 'invalid point Y';
$config->set('use_relative_e_distances', 1);
is $config->get('use_relative_e_distances'), 1, 'set/get bool';
is $config->opt_serialize('use_relative_e_distances'), '1', 'serialize bool';
$config->set('gcode_flavor', 'teacup');
is $config->get('gcode_flavor'), 'teacup', 'set/get enum';
is $config->opt_serialize('gcode_flavor'), 'teacup', 'serialize enum';
$config->set_deserialize('gcode_flavor', 'mach3');
is $config->get('gcode_flavor'), 'mach3', 'deserialize enum (gcode_flavor)';
$config->set_deserialize('gcode_flavor', 'machinekit');
is $config->get('gcode_flavor'), 'machinekit', 'deserialize enum (gcode_flavor)';
$config->set_deserialize('fill_pattern', 'line');
is $config->get('fill_pattern'), 'line', 'deserialize enum (fill_pattern)';
$config->set_deserialize('support_material_pattern', 'rectilinear');
is $config->get('support_material_pattern'), 'rectilinear', 'deserialize enum (support_material_pattern)';
$config->set('extruder_offset', [[10,20],[30,45]]);
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [[10,20],[30,45]], 'set/get points';
$config->set('extruder_offset', [Slic3r::Pointf->new(10,20),Slic3r::Pointf->new(30,45)]);
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [[10,20],[30,45]], 'set/get points';
is $config->opt_serialize('extruder_offset'), '10x20,30x45', 'serialize points';
$config->set_deserialize('extruder_offset', '20x10');
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [[20,10]], 'deserialize points';
$config->set_deserialize('extruder_offset', '0x0');
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [[0,0]], 'deserialize points';
{
my @values = ([10,20]);
$values[2] = [10,20]; # implicitely extend array; this is not the same as explicitely assigning undef to second item
ok !$config->set('extruder_offset', \@values), 'reject undef points';
}
# truncate ->get() to first decimal digit
$config->set('nozzle_diameter', [0.2,3]);
is_deeply [ map int($_*10)/10, @{$config->get('nozzle_diameter')} ], [0.2,3], 'set/get floats';
is $config->opt_serialize('nozzle_diameter'), '0.2,3', 'serialize floats';
$config->set_deserialize('nozzle_diameter', '0.1,0.4');
is_deeply [ map int($_*10)/10, @{$config->get('nozzle_diameter')} ], [0.1,0.4], 'deserialize floats';
$config->set_deserialize('nozzle_diameter', '3');
is_deeply [ map int($_*10)/10, @{$config->get('nozzle_diameter')} ], [3], 'deserialize a single float';
{
my @values = (0.4);
$values[2] = 2; # implicitely extend array; this is not the same as explicitely assigning undef to second item
ok !$config->set('nozzle_diameter', \@values), 'reject undef floats';
}
$config->set('temperature', [180,210]);
is_deeply $config->get('temperature'), [180,210], 'set/get ints';
is $config->opt_serialize('temperature'), '180,210', 'serialize ints';
$config->set_deserialize('temperature', '195,220');
is_deeply $config->get('temperature'), [195,220], 'deserialize ints';
{
my @values = (180);
$values[2] = 200; # implicitely extend array; this is not the same as explicitely assigning undef to second item
ok !$config->set('temperature', \@values), 'reject undef ints';
}
$config->set('wipe', [1,0]);
is_deeply $config->get('wipe'), [1,0], 'set/get bools';
is $config->get_at('wipe', 0), 1, 'get_at bools';
is $config->get_at('wipe', 1), 0, 'get_at bools';
is $config->get_at('wipe', 9), 1, 'get_at bools';
is $config->opt_serialize('wipe'), '1,0', 'serialize bools';
$config->set_deserialize('wipe', '0,1,1');
is_deeply $config->get('wipe'), [0,1,1], 'deserialize bools';
$config->set_deserialize('wipe', '');
is_deeply $config->get('wipe'), [], 'deserialize bools from empty string';
$config->set_deserialize('retract_layer_change', 0);
is_deeply $config->get('retract_layer_change'), [0], 'deserialize bools from non-string value';
{
my @values = (1);
$values[2] = 1; # implicitely extend array; this is not the same as explicitely assigning undef to second item
ok !$config->set('wipe', \@values), 'reject undef bools';
}
$config->set('post_process', ['foo','bar']);
is_deeply $config->get('post_process'), ['foo','bar'], 'set/get strings';
is $config->opt_serialize('post_process'), 'foo;bar', 'serialize strings';
$config->set_deserialize('post_process', 'bar;baz');
is_deeply $config->get('post_process'), ['bar','baz'], 'deserialize strings';
{
my @values = ('foo');
$values[2] = 'bar'; # implicitely extend array; this is not the same as explicitely assigning undef to second item
ok !$config->set('post_process', \@values), 'reject undef strings';
}
is_deeply [ sort @{$config->get_keys} ], [ sort keys %{$config->as_hash} ], 'get_keys and as_hash';
}
{
my $config = Slic3r::Config->new;
$config->set('perimeters', 2);
# test that no crash happens when using set_deserialize() with a key that hasn't been set() yet
$config->set_deserialize('filament_diameter', '3');
my $config2 = Slic3r::Config::Static::new_FullPrintConfig;
$config2->apply_dynamic($config);
is $config2->get('perimeters'), 2, 'apply_dynamic';
}
{
my $config = Slic3r::Config::Static::new_FullPrintConfig;
my $config2 = Slic3r::Config->new;
$config2->apply_static($config);
is $config2->get('perimeters'), Slic3r::Config::print_config_def()->{perimeters}{default}, 'apply_static and print_config_def';
$config->set('top_solid_infill_speed', 70);
is $config->get_abs_value('top_solid_infill_speed'), 70, 'get_abs_value() works when ratio_over references a floatOrPercent option';
}
{
my $config = Slic3r::Config->new;
$config->set('fill_pattern', 'line');
my $config2 = Slic3r::Config->new;
$config2->set('fill_pattern', 'hilbertcurve');
is $config->get('fill_pattern'), 'line', 'no interferences between DynamicConfig objects';
}
{
my $config = Slic3r::Config->new;
# the pair [0,0] is part of the test, since it checks whether the 0x0 serialized value is correctly parsed
$config->set('extruder_offset', [ [0,0], [20,0], [0,20] ]);
my $config2 = Slic3r::Config->new;
$config2->apply($config);
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [ map $_->pp, @{$config2->get('extruder_offset')} ],
'apply dynamic over dynamic';
}
{
my $config = Slic3r::Config->new;
$config->set('extruder', 2);
$config->set('perimeter_extruder', 3);
$config->normalize_fdm;
ok !$config->has('extruder'), 'extruder option is removed after normalize()';
is $config->get('infill_extruder'), 2, 'undefined extruder is populated with default extruder';
is $config->get('perimeter_extruder'), 3, 'defined extruder is not overwritten by default extruder';
}
{
my $config = Slic3r::Config->new;
$config->set('infill_extruder', 2);
$config->normalize_fdm;
is $config->get('solid_infill_extruder'), 2, 'undefined solid infill extruder is populated with infill extruder';
}
{
my $config = Slic3r::Config->new;
$config->set('spiral_vase', 1);
$config->set('retract_layer_change', [1,0]);
$config->normalize_fdm;
is_deeply $config->get('retract_layer_change'), [0,0], 'retract_layer_change is disabled with spiral_vase';
}
{
use Cwd qw(abs_path);
use File::Basename qw(dirname);
my $path = abs_path($0);
my $config = Slic3r::Config::load(dirname($path)."/inc/22_config_bad_config_options.ini");
ok 1, 'did not crash on reading invalid items in config';
}
__END__

View File

@ -1,7 +0,0 @@
# generated by Slic3r 1.1.7 on Tue Aug 19 21:49:50 2014
avoid_crossing_perimeters = 1
bed_size = 200,180
g0 = 0
perimeter_acceleration = 0
support_material_extruder = 1
support_material_extrusion_width = 0

View File

@ -1,218 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/PrintConfig.hpp"
%}
%name{Slic3r::Config} class DynamicPrintConfig {
DynamicPrintConfig();
~DynamicPrintConfig();
static DynamicPrintConfig* new_from_defaults()
%code{% RETVAL = DynamicPrintConfig::new_from_defaults_keys(FullPrintConfig::defaults().keys()); %};
static DynamicPrintConfig* new_from_defaults_keys(std::vector<std::string> keys);
DynamicPrintConfig* clone() %code{% RETVAL = new DynamicPrintConfig(*THIS); %};
DynamicPrintConfig* clone_only(std::vector<std::string> keys)
%code{% RETVAL = new DynamicPrintConfig(); RETVAL->apply_only(*THIS, keys, true); %};
bool has(t_config_option_key opt_key);
SV* as_hash()
%code{% RETVAL = ConfigBase__as_hash(THIS); %};
SV* get(t_config_option_key opt_key)
%code{% RETVAL = ConfigBase__get(THIS, opt_key); %};
SV* get_at(t_config_option_key opt_key, int i)
%code{% RETVAL = ConfigBase__get_at(THIS, opt_key, i); %};
SV* get_value(t_config_option_key opt_key)
%code{%
const ConfigOptionDef *def = THIS->def()->get(opt_key);
RETVAL = (def != nullptr && ! def->ratio_over.empty()) ?
newSVnv(THIS->get_abs_value(opt_key)) :
ConfigBase__get(THIS, opt_key);
%};
bool set(t_config_option_key opt_key, SV* value)
%code{% RETVAL = ConfigBase__set(THIS, opt_key, value); %};
bool set_deserialize(t_config_option_key opt_key, SV* str)
%code{% RETVAL = ConfigBase__set_deserialize(THIS, opt_key, str); %};
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false)
%code{% ConfigBase__set_ifndef(THIS, opt_key, value, deserialize); %};
std::string opt_serialize(t_config_option_key opt_key);
double get_abs_value(t_config_option_key opt_key);
%name{get_abs_value_over}
double get_abs_value(t_config_option_key opt_key, double ratio_over);
void apply(DynamicPrintConfig* other)
%code{% THIS->apply(*other, true); %};
std::vector<std::string> diff(DynamicPrintConfig* other)
%code{% RETVAL = THIS->diff(*other); %};
bool equals(DynamicPrintConfig* other)
%code{% RETVAL = THIS->equals(*other); %};
void apply_static(StaticPrintConfig* other)
%code{% THIS->apply(*other, true); %};
%name{get_keys} std::vector<std::string> keys();
void erase(t_config_option_key opt_key);
void normalize_fdm();
%name{setenv} void setenv_();
double min_object_distance() %code{% RETVAL = Slic3r::min_object_distance(*THIS); %};
static DynamicPrintConfig* load(char *path)
%code%{
auto config = new DynamicPrintConfig();
try {
config->load(path, ForwardCompatibilitySubstitutionRule::Disable);
RETVAL = config;
} catch (std::exception& e) {
delete config;
croak("Error extracting configuration from %s:\n%s\n", path, e.what());
}
%};
void save(std::string file);
int validate() %code%{
std::string err = THIS->validate();
if (! err.empty())
croak("Configuration is not valid: %s\n", err.c_str());
RETVAL = 1;
%};
};
%name{Slic3r::Config::Static} class StaticPrintConfig {
static StaticPrintConfig* new_GCodeConfig()
%code{% RETVAL = new GCodeConfig(); %};
static StaticPrintConfig* new_PrintConfig()
%code{% RETVAL = static_cast<GCodeConfig*>(new PrintConfig()); %};
static StaticPrintConfig* new_FullPrintConfig()
%code{% RETVAL = static_cast<GCodeConfig*>(new FullPrintConfig()); %};
~StaticPrintConfig();
bool has(t_config_option_key opt_key);
SV* as_hash()
%code{% RETVAL = ConfigBase__as_hash(THIS); %};
SV* get(t_config_option_key opt_key)
%code{% RETVAL = ConfigBase__get(THIS, opt_key); %};
SV* get_at(t_config_option_key opt_key, int i)
%code{% RETVAL = ConfigBase__get_at(THIS, opt_key, i); %};
bool set(t_config_option_key opt_key, SV* value)
%code{% RETVAL = StaticConfig__set(THIS, opt_key, value); %};
bool set_deserialize(t_config_option_key opt_key, SV* str)
%code{% RETVAL = ConfigBase__set_deserialize(THIS, opt_key, str); %};
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false)
%code{% ConfigBase__set_ifndef(THIS, opt_key, value, deserialize); %};
std::string opt_serialize(t_config_option_key opt_key);
double get_abs_value(t_config_option_key opt_key);
%name{get_abs_value_over}
double get_abs_value(t_config_option_key opt_key, double ratio_over);
void apply_static(StaticPrintConfig* other)
%code{% THIS->apply(*other, true); %};
void apply_dynamic(DynamicPrintConfig* other)
%code{% THIS->apply(*other, true); %};
%name{get_keys} std::vector<std::string> keys();
std::string get_extrusion_axis()
%code{%
if (GCodeConfig* config = dynamic_cast<GCodeConfig*>(THIS)) {
RETVAL = get_extrusion_axis(*config);
} else {
CONFESS("This StaticConfig object does not provide get_extrusion_axis()");
}
%};
%name{setenv} void setenv_();
double min_object_distance() %code{% RETVAL = Slic3r::min_object_distance(*THIS); %};
static StaticPrintConfig* load(char *path)
%code%{
auto config = new FullPrintConfig();
try {
config->load(path, ForwardCompatibilitySubstitutionRule::Disable);
RETVAL = static_cast<GCodeConfig*>(config);
} catch (std::exception& e) {
delete config;
croak("Error extracting configuration from %s:\n%s\n", path, e.what());
}
%};
void save(std::string file);
};
%package{Slic3r::Config};
%{
PROTOTYPES: DISABLE
SV*
print_config_def()
CODE:
t_optiondef_map &def = *const_cast<t_optiondef_map*>(&Slic3r::print_config_def.options);
HV* options_hv = newHV();
for (t_optiondef_map::iterator oit = def.begin(); oit != def.end(); ++oit) {
HV* hv = newHV();
t_config_option_key opt_key = oit->first;
ConfigOptionDef* optdef = &oit->second;
const char* opt_type;
if (optdef->type == coFloat || optdef->type == coFloats || optdef->type == coFloatOrPercent || optdef->type == coFloatsOrPercents) {
opt_type = "f";
} else if (optdef->type == coPercent || optdef->type == coPercents) {
opt_type = "percent";
} else if (optdef->type == coInt || optdef->type == coInts) {
opt_type = "i";
} else if (optdef->type == coString) {
opt_type = "s";
} else if (optdef->type == coStrings) {
opt_type = "s@";
} else if (optdef->type == coPoint || optdef->type == coPoints) {
opt_type = "point";
} else if (optdef->type == coPoint3) {
opt_type = "point3";
} else if (optdef->type == coBool || optdef->type == coBools) {
opt_type = "bool";
} else if (optdef->type == coEnum) {
opt_type = "select";
} else {
throw "Unknown option type";
}
(void)hv_stores( hv, "type", newSVpv(opt_type, 0) );
(void)hv_stores( hv, "height", newSViv(optdef->height) );
(void)hv_stores( hv, "width", newSViv(optdef->width) );
(void)hv_stores( hv, "min", newSViv(optdef->min) );
(void)hv_stores( hv, "max", newSViv(optdef->max) );
// aliases
if (!optdef->aliases.empty()) {
AV* av = newAV();
av_fill(av, optdef->aliases.size()-1);
for (std::vector<t_config_option_key>::iterator it = optdef->aliases.begin(); it != optdef->aliases.end(); ++it)
av_store(av, it - optdef->aliases.begin(), newSVpvn(it->c_str(), it->length()));
(void)hv_stores( hv, "aliases", newRV_noinc((SV*)av) );
}
// shortcut
if (!optdef->shortcut.empty()) {
AV* av = newAV();
av_fill(av, optdef->shortcut.size()-1);
for (std::vector<t_config_option_key>::iterator it = optdef->shortcut.begin(); it != optdef->shortcut.end(); ++it)
av_store(av, it - optdef->shortcut.begin(), newSVpvn(it->c_str(), it->length()));
(void)hv_stores( hv, "shortcut", newRV_noinc((SV*)av) );
}
// enum_values
if (optdef->enum_def && !optdef->enum_def->values().empty()) {
AV* av = newAV();
av_fill(av, optdef->enum_def->values().size()-1);
for (std::vector<std::string>::const_iterator it = optdef->enum_def->values().begin(); it != optdef->enum_def->values().end(); ++it)
av_store(av, it - optdef->enum_def->values().begin(), newSVpvn(it->c_str(), it->length()));
(void)hv_stores( hv, "values", newRV_noinc((SV*)av) );
}
// enum_labels
if (optdef->enum_def && !optdef->enum_def->labels().empty()) {
AV* av = newAV();
av_fill(av, optdef->enum_def->labels().size()-1);
for (std::vector<std::string>::const_iterator it = optdef->enum_def->labels().begin(); it != optdef->enum_def->labels().end(); ++it)
av_store(av, it - optdef->enum_def->labels().begin(), newSVpvn_utf8(it->c_str(), it->length(), true));
(void)hv_stores( hv, "labels", newRV_noinc((SV*)av) );
}
if (optdef->default_value)
(void)hv_stores( hv, "default", ConfigOption_to_SV(*optdef->default_value.get(), *optdef) );
(void)hv_store( options_hv, opt_key.c_str(), opt_key.length(), newRV_noinc((SV*)hv), 0 );
}
RETVAL = newRV_noinc((SV*)options_hv);
OUTPUT:
RETVAL
%}

View File

@ -1,57 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/ExPolygon.hpp"
%}
%name{Slic3r::ExPolygon} class ExPolygon {
~ExPolygon();
Clone<ExPolygon> clone()
%code{% RETVAL = THIS; %};
SV* arrayref()
%code{% RETVAL = to_AV(THIS); %};
SV* pp()
%code{% RETVAL = to_SV_pureperl(THIS); %};
Ref<Polygon> contour()
%code{% RETVAL = &(THIS->contour); %};
Polygons* holes()
%code{% RETVAL = &(THIS->holes); %};
void scale(double factor);
void translate(double x, double y);
double area();
bool is_valid();
bool contains_line(Line* line)
%code{% RETVAL = THIS->contains(*line); %};
bool contains_polyline(Polyline* polyline)
%code{% RETVAL = THIS->contains(*polyline); %};
bool contains_point(Point* point)
%code{% RETVAL = THIS->contains(*point); %};
ExPolygons simplify(double tolerance);
Polygons simplify_p(double tolerance);
%{
ExPolygon*
ExPolygon::new(...)
CODE:
RETVAL = new ExPolygon ();
// ST(0) is class name, ST(1) is contour and others are holes
from_SV_check(ST(1), &RETVAL->contour);
RETVAL->holes.resize(items-2);
for (unsigned int i = 2; i < items; i++) {
from_SV_check(ST(i), &RETVAL->holes[i-2]);
}
OUTPUT:
RETVAL
void
ExPolygon::rotate(angle, center_sv)
double angle;
SV* center_sv;
CODE:
Point center;
from_SV_check(center_sv, &center);
THIS->rotate(angle, center);
%}
};

View File

@ -1,51 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/Geometry.hpp"
#include "libslic3r/Geometry/ConvexHull.hpp"
#include "libslic3r/ShortestPath.hpp"
%}
%package{Slic3r::Geometry};
%{
Clone<Polygon>
convex_hull(points)
Points points
CODE:
RETVAL = Slic3r::Geometry::convex_hull(points);
OUTPUT:
RETVAL
double
rad2deg(angle)
double angle
CODE:
RETVAL = Slic3r::Geometry::rad2deg(angle);
OUTPUT:
RETVAL
double
deg2rad(angle)
double angle
CODE:
RETVAL = Slic3r::Geometry::deg2rad(angle);
OUTPUT:
RETVAL
IV
_constant()
ALIAS:
X = X
Y = Y
Z = Z
PROTOTYPE:
CODE:
RETVAL = ix;
OUTPUT: RETVAL
%}

View File

@ -1,78 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/Line.hpp"
#include "libslic3r/Polyline.hpp"
%}
%name{Slic3r::Line} class Line {
~Line();
Clone<Line> clone()
%code{% RETVAL = THIS; %};
SV* arrayref()
%code{% RETVAL = to_AV(THIS); %};
SV* pp()
%code{% RETVAL = to_SV_pureperl(THIS); %};
Ref<Point> a()
%code{% RETVAL=&THIS->a; %};
Ref<Point> b()
%code{% RETVAL=&THIS->b; %};
void reverse();
void scale(double factor);
void translate(double x, double y);
double length();
double atan2_();
double orientation();
double direction();
bool parallel_to(double angle);
bool parallel_to_line(Line* line)
%code{% RETVAL = THIS->parallel_to(*line); %};
Clone<Point> midpoint();
Clone<Point> intersection_infinite(Line* other)
%code{%
Point p;
bool res = THIS->intersection_infinite(*other, &p);
if (!res) CONFESS("Intersection failed");
RETVAL = p;
%};
Polyline* as_polyline()
%code{% RETVAL = new Polyline(THIS->a, THIS->b); %};
Clone<Point> normal();
Clone<Point> vector();
double ccw(Point* point)
%code{% RETVAL = cross2((THIS->a - *point).cast<double>(), (THIS->b - THIS->a).cast<double>()); %};
%{
Line*
Line::new(...)
CODE:
RETVAL = new Line ();
// ST(0) is class name, ST(1) and ST(2) are endpoints
from_SV_check(ST(1), &RETVAL->a);
from_SV_check(ST(2), &RETVAL->b);
OUTPUT:
RETVAL
void
Line::rotate(angle, center_sv)
double angle;
SV* center_sv;
CODE:
Point center;
from_SV_check(center_sv, &center);
THIS->rotate(angle, center);
bool
Line::coincides_with(line_sv)
SV* line_sv;
CODE:
Line line;
from_SV_check(line_sv, &line);
RETVAL = (*THIS) == line;
OUTPUT:
RETVAL
%}
};

View File

@ -1,286 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/Model.hpp"
#include "libslic3r/ModelArrange.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/Slicing.hpp"
#include "libslic3r/Format/AMF.hpp"
#include "libslic3r/Format/3mf.hpp"
#include "libslic3r/Format/OBJ.hpp"
#include "libslic3r/Format/STL.hpp"
#include "libslic3r/PresetBundle.hpp"
%}
%name{Slic3r::Model} class Model {
Model();
~Model();
%name{read_from_file} Model(std::string input_file, bool add_default_instances = true)
%code%{
try {
RETVAL = new Model(Model::read_from_file(input_file, nullptr, nullptr, only_if(add_default_instances, Model::LoadAttribute::AddDefaultInstances)));
} catch (std::exception& e) {
croak("Error while opening %s: %s\n", input_file.c_str(), e.what());
}
%};
Clone<Model> clone()
%code%{ RETVAL = THIS; %};
%name{_add_object} Ref<ModelObject> add_object();
Ref<ModelObject> _add_object_clone(ModelObject* other, bool copy_volumes = true)
%code%{ auto ptr = THIS->add_object(*other); if (! copy_volumes) ptr->clear_volumes(); RETVAL = ptr; %};
void delete_object(size_t idx);
void clear_objects();
size_t objects_count()
%code%{ RETVAL = THIS->objects.size(); %};
Ref<ModelObject> get_object(int idx)
%code%{ RETVAL = THIS->objects.at(idx); %};
Ref<ModelMaterial> get_material(t_model_material_id material_id)
%code%{
RETVAL = THIS->get_material(material_id);
if (RETVAL == NULL) {
XSRETURN_UNDEF;
}
%};
%name{add_material} Ref<ModelMaterial> add_material(t_model_material_id material_id);
Ref<ModelMaterial> add_material_clone(t_model_material_id material_id, ModelMaterial* other)
%code%{ RETVAL = THIS->add_material(material_id, *other); %};
bool has_material(t_model_material_id material_id) const
%code%{
RETVAL = (THIS->get_material(material_id) != NULL);
%};
void delete_material(t_model_material_id material_id);
void clear_materials();
std::vector<std::string> material_names() const
%code%{
for (ModelMaterialMap::iterator i = THIS->materials.begin();
i != THIS->materials.end(); ++i)
{
RETVAL.push_back(i->first);
}
%};
size_t material_count() const
%code%{ RETVAL = THIS->materials.size(); %};
bool add_default_instances();
void center_instances_around_point(Vec2d* point)
%code%{ THIS->center_instances_around_point(*point); %};
void translate(double x, double y, double z);
Clone<TriangleMesh> mesh();
ModelObjectPtrs* objects()
%code%{ RETVAL = &THIS->objects; %};
bool arrange_objects(double dist) %code%{ arrange_objects(*THIS, arr2::InfiniteBed{}, arr2::ArrangeSettings{}.set_distance_from_objects(dist) ); %};
void duplicate(unsigned int copies_num, double dist) %code%{ duplicate(*THIS, copies_num, arr2::InfiniteBed{}, arr2::ArrangeSettings{}.set_distance_from_objects(dist) ); %};
bool looks_like_multipart_object() const;
void convert_multipart_object(unsigned int max_extruders);
bool store_stl(char *path, bool binary)
%code%{ TriangleMesh mesh = THIS->mesh(); RETVAL = Slic3r::store_stl(path, &mesh, binary); %};
%{
Model*
load_stl(CLASS, path, object_name)
char* CLASS;
char* path;
char* object_name;
CODE:
RETVAL = new Model();
if (! load_stl(path, RETVAL, object_name)) {
delete RETVAL;
RETVAL = NULL;
}
OUTPUT:
RETVAL
%}
};
%name{Slic3r::Model::Material} class ModelMaterial {
Ref<Model> model()
%code%{ RETVAL = THIS->get_model(); %};
Ref<DynamicPrintConfig> config()
%code%{ RETVAL = &const_cast<DynamicPrintConfig&>(THIS->config.get()); %};
std::string get_attribute(std::string name)
%code%{ if (THIS->attributes.find(name) != THIS->attributes.end()) RETVAL = THIS->attributes[name]; %};
void set_attribute(std::string name, std::string value)
%code%{ THIS->attributes[name] = value; %};
%{
SV*
ModelMaterial::attributes()
CODE:
HV* hv = newHV();
for (t_model_material_attributes::const_iterator attr = THIS->attributes.begin(); attr != THIS->attributes.end(); ++attr) {
(void)hv_store( hv, attr->first.c_str(), attr->first.length(), newSVpv(attr->second.c_str(), attr->second.length()), 0 );
}
RETVAL = (SV*)newRV_noinc((SV*)hv);
OUTPUT:
RETVAL
%}
};
%name{Slic3r::Model::Object} class ModelObject {
ModelVolumePtrs* volumes()
%code%{ RETVAL = &THIS->volumes; %};
ModelInstancePtrs* instances()
%code%{ RETVAL = &THIS->instances; %};
void invalidate_bounding_box();
Clone<TriangleMesh> mesh();
Clone<TriangleMesh> raw_mesh();
%name{_add_volume} Ref<ModelVolume> add_volume(TriangleMesh* mesh)
%code%{ RETVAL = THIS->add_volume(*mesh); %};
Ref<ModelVolume> _add_volume_clone(ModelVolume* other)
%code%{ RETVAL = THIS->add_volume(*other); %};
void delete_volume(size_t idx);
void clear_volumes();
int volumes_count()
%code%{ RETVAL = THIS->volumes.size(); %};
Ref<ModelVolume> get_volume(int idx)
%code%{ RETVAL = THIS->volumes.at(idx); %};
bool move_volume_up(int idx)
%code%{
if (idx > 0 && idx < int(THIS->volumes.size())) {
std::swap(THIS->volumes[idx-1], THIS->volumes[idx]);
RETVAL = true;
} else
RETVAL = false;
%};
bool move_volume_down(int idx)
%code%{
if (idx >= 0 && idx + 1 < int(THIS->volumes.size())) {
std::swap(THIS->volumes[idx+1], THIS->volumes[idx]);
RETVAL = true;
} else
RETVAL = false;
%};
%name{_add_instance} Ref<ModelInstance> add_instance();
Ref<ModelInstance> _add_instance_clone(ModelInstance* other)
%code%{ RETVAL = THIS->add_instance(*other); %};
void delete_last_instance();
void clear_instances();
int instances_count()
%code%{ RETVAL = THIS->instances.size(); %};
std::string name()
%code%{ RETVAL = THIS->name; %};
void set_name(std::string value)
%code%{ THIS->name = value; %};
std::string input_file()
%code%{ RETVAL = THIS->input_file; %};
void set_input_file(std::string value)
%code%{ THIS->input_file = value; %};
Ref<DynamicPrintConfig> config()
%code%{ RETVAL = &const_cast<DynamicPrintConfig&>(THIS->config.get()); %};
Ref<Model> model()
%code%{ RETVAL = THIS->get_model(); %};
Ref<Vec3d> origin_translation()
%code%{ RETVAL = &THIS->origin_translation; %};
void set_origin_translation(Vec3d* point)
%code%{ THIS->origin_translation = *point; %};
void ensure_on_bed();
int materials_count() const;
int facets_count();
void center_around_origin();
void translate(double x, double y, double z);
void scale_xyz(Vec3d* versor)
%code{% THIS->scale(*versor); %};
void rotate(float angle, Vec3d* axis)
%code{% THIS->rotate(angle, *axis); %};
void mirror(Axis axis);
};
%name{Slic3r::Model::Volume} class ModelVolume {
Ref<ModelObject> object()
%code%{ RETVAL = THIS->get_object(); %};
std::string name()
%code%{ RETVAL = THIS->name; %};
void set_name(std::string value)
%code%{ THIS->name = value; %};
t_model_material_id material_id();
void set_material_id(t_model_material_id material_id)
%code%{ THIS->set_material_id(material_id); %};
Ref<ModelMaterial> material();
Ref<DynamicPrintConfig> config()
%code%{ RETVAL = &const_cast<DynamicPrintConfig&>(THIS->config.get()); %};
Ref<TriangleMesh> mesh()
%code%{ RETVAL = &THIS->mesh(); %};
bool modifier()
%code%{ RETVAL = THIS->is_modifier(); %};
void set_modifier(bool modifier)
%code%{ THIS->set_type(modifier ? ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART); %};
bool model_part()
%code%{ RETVAL = THIS->is_model_part(); %};
bool support_enforcer()
%code%{ RETVAL = THIS->is_support_enforcer(); %};
void set_support_enforcer()
%code%{ THIS->set_type(ModelVolumeType::SUPPORT_ENFORCER); %};
bool support_blocker()
%code%{ RETVAL = THIS->is_support_blocker(); %};
void set_support_blocker()
%code%{ THIS->set_type(ModelVolumeType::SUPPORT_BLOCKER); %};
size_t split(unsigned int max_extruders);
};
%name{Slic3r::Model::Instance} class ModelInstance {
Ref<ModelObject> object()
%code%{ RETVAL = THIS->get_object(); %};
Vec3d* rotation()
%code%{ RETVAL = new Vec3d(THIS->get_rotation(X), THIS->get_rotation(Y), THIS->get_rotation(Z)); %};
Vec3d* scaling_factor()
%code%{ RETVAL = new Vec3d(THIS->get_scaling_factor(X), THIS->get_scaling_factor(Y), THIS->get_scaling_factor(Z)); %};
Vec2d* offset()
%code%{ RETVAL = new Vec2d(THIS->get_offset(X), THIS->get_offset(Y)); %};
void set_rotation(double val)
%code%{ THIS->set_rotation(Z, val); THIS->get_object()->invalidate_bounding_box(); %};
void set_rotations(Vec3d *rotation)
%code%{ THIS->set_rotation(*rotation); THIS->get_object()->invalidate_bounding_box(); %};
void set_scaling_factor(double val)
%code%{ THIS->set_scaling_factor(X, val); THIS->set_scaling_factor(Y, val); THIS->set_scaling_factor(Z, val); THIS->get_object()->invalidate_bounding_box(); %};
void set_scaling_factors(Vec3d *scale)
%code%{ THIS->set_scaling_factor(*scale); THIS->get_object()->invalidate_bounding_box(); %};
void set_offset(Vec2d *offset)
%code%{
THIS->set_offset(X, (*offset)(0));
THIS->set_offset(Y, (*offset)(1));
%};
};

View File

@ -1,129 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/Point.hpp"
#include "libslic3r/Line.hpp"
#include "libslic3r/Polygon.hpp"
#include "libslic3r/Polyline.hpp"
%}
%name{Slic3r::Point} class Point {
Point(int _x = 0, int _y = 0);
~Point();
Clone<Point> clone()
%code{% RETVAL=THIS; %};
void scale(double factor)
%code{% *THIS *= factor; %};
void translate(double x, double y)
%code{% *THIS += Point(x, y); %};
SV* arrayref()
%code{% RETVAL = to_SV_pureperl(THIS); %};
SV* pp()
%code{% RETVAL = to_SV_pureperl(THIS); %};
int x()
%code{% RETVAL = (*THIS)(0); %};
int y()
%code{% RETVAL = (*THIS)(1); %};
void set_x(int val)
%code{% (*THIS)(0) = val; %};
void set_y(int val)
%code{% (*THIS)(1) = val; %};
Clone<Point> nearest_point(Points points)
%code{% RETVAL = nearest_point(points, *THIS).first; %};
double distance_to(Point* point)
%code{% RETVAL = (*point - *THIS).cast<double>().norm(); %};
double distance_to_line(Line* line)
%code{% RETVAL = line->distance_to(*THIS); %};
double perp_distance_to_line(Line* line)
%code{% RETVAL = line->perp_distance_to(*THIS); %};
double ccw(Point* p1, Point* p2)
%code{% RETVAL = cross2((*p1 - *THIS).cast<double>(), (*p2 - *p1).cast<double>()); %};
Point* negative()
%code{% RETVAL = new Point(- *THIS); %};
std::string serialize() %code{% char buf[2048]; sprintf(buf, "%ld,%ld", (*THIS)(0), (*THIS)(1)); RETVAL = buf; %};
%{
void
Point::rotate(angle, center_sv)
double angle;
SV* center_sv;
CODE:
Point center;
from_SV_check(center_sv, &center);
THIS->rotate(angle, center);
bool
Point::coincides_with(point_sv)
SV* point_sv;
CODE:
Point point;
from_SV_check(point_sv, &point);
RETVAL = (*THIS) == point;
OUTPUT:
RETVAL
%}
};
%name{Slic3r::Pointf} class Vec2d {
Vec2d(double _x = 0, double _y = 0);
~Vec2d();
Clone<Vec2d> clone()
%code{% RETVAL = THIS; %};
SV* arrayref()
%code{% RETVAL = to_SV_pureperl(THIS); %};
SV* pp()
%code{% RETVAL = to_SV_pureperl(THIS); %};
double x()
%code{% RETVAL = (*THIS)(0); %};
double y()
%code{% RETVAL = (*THIS)(1); %};
void set_x(double val)
%code{% (*THIS)(0) = val; %};
void set_y(double val)
%code{% (*THIS)(1) = val; %};
void translate(double x, double y)
%code{% *THIS += Vec2d(x, y); %};
void scale(double factor)
%code{% *THIS *= factor; %};
void rotate(double angle, Vec2d* center)
%code{% *THIS = Eigen::Translation2d(*center) * Eigen::Rotation2Dd(angle) * Eigen::Translation2d(- *center) * Eigen::Vector2d((*THIS)(0), (*THIS)(1)); %};
Vec2d* negative()
%code{% RETVAL = new Vec2d(- *THIS); %};
Vec2d* vector_to(Vec2d* point)
%code{% RETVAL = new Vec2d(*point - *THIS); %};
std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf", (*THIS)(0), (*THIS)(1)); RETVAL = buf; %};
};
%name{Slic3r::Pointf3} class Vec3d {
Vec3d(double _x = 0, double _y = 0, double _z = 0);
~Vec3d();
Clone<Vec3d> clone()
%code{% RETVAL = THIS; %};
double x()
%code{% RETVAL = (*THIS)(0); %};
double y()
%code{% RETVAL = (*THIS)(1); %};
double z()
%code{% RETVAL = (*THIS)(2); %};
void set_x(double val)
%code{% (*THIS)(0) = val; %};
void set_y(double val)
%code{% (*THIS)(1) = val; %};
void set_z(double val)
%code{% (*THIS)(2) = val; %};
void translate(double x, double y, double z)
%code{% *THIS += Vec3d(x, y, z); %};
void scale(double factor)
%code{% *THIS *= factor; %};
double distance_to(Vec3d* point)
%code{% RETVAL = (*point - *THIS).norm(); %};
Vec3d* negative()
%code{% RETVAL = new Vec3d(- *THIS); %};
Vec3d* vector_to(Vec3d* point)
%code{% RETVAL = new Vec3d(*point - *THIS); %};
std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf,%lf", (*THIS)(0), (*THIS)(1), (*THIS)(2)); RETVAL = buf; %};
};

View File

@ -1,65 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/Polygon.hpp"
%}
%name{Slic3r::Polygon} class Polygon {
~Polygon();
Clone<Polygon> clone()
%code{% RETVAL = THIS; %};
SV* arrayref()
%code{% RETVAL = to_AV(THIS); %};
SV* pp()
%code{% RETVAL = to_SV_pureperl(THIS); %};
void scale(double factor);
void translate(double x, double y);
void reverse();
Lines lines();
Clone<Polyline> split_at_vertex(Point* point)
%code{% RETVAL = THIS->split_at_vertex(*point); %};
Clone<Polyline> split_at_first_point();
double length();
double area();
bool is_counter_clockwise();
bool is_clockwise();
bool make_counter_clockwise();
bool make_clockwise();
bool is_valid();
Clone<Point> first_point();
bool contains_point(Point* point)
%code{% RETVAL = THIS->contains(*point); %};
Polygons simplify(double tolerance);
Clone<Point> centroid();
Clone<Point> first_intersection(Line* line)
%code{%
Point p;
(void)THIS->first_intersection(*line, &p);
RETVAL = p;
%};
%{
Polygon*
Polygon::new(...)
CODE:
RETVAL = new Polygon ();
// ST(0) is class name, ST(1) is first point
RETVAL->points.resize(items-1);
for (unsigned int i = 1; i < items; i++) {
from_SV_check(ST(i), &RETVAL->points[i-1]);
}
OUTPUT:
RETVAL
void
Polygon::rotate(angle, center_sv)
double angle;
SV* center_sv;
CODE:
Point center;
from_SV_check(center_sv, &center);
THIS->rotate(angle, center);
%}
};

View File

@ -1,74 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/Polyline.hpp"
%}
%name{Slic3r::Polyline} class Polyline {
~Polyline();
Clone<Polyline> clone()
%code{% RETVAL = THIS; %};
SV* arrayref()
%code{% RETVAL = to_AV(THIS); %};
SV* pp()
%code{% RETVAL = to_SV_pureperl(THIS); %};
void scale(double factor);
void translate(double x, double y);
void pop_back()
%code{% THIS->points.pop_back(); %};
void reverse();
Lines lines();
Clone<Point> first_point();
Clone<Point> last_point();
double length();
bool is_valid();
void clip_end(double distance);
void clip_start(double distance);
void extend_end(double distance);
void extend_start(double distance);
void simplify(double tolerance);
void split_at(Point* point, Polyline* p1, Polyline* p2)
%code{% THIS->split_at(*point, p1, p2); %};
%{
Polyline*
Polyline::new(...)
CODE:
RETVAL = new Polyline ();
// ST(0) is class name, ST(1) is first point
RETVAL->points.resize(items-1);
for (unsigned int i = 1; i < items; i++) {
from_SV_check(ST(i), &RETVAL->points[i-1]);
}
OUTPUT:
RETVAL
void
Polyline::append(...)
CODE:
for (unsigned int i = 1; i < items; i++) {
Point p;
from_SV_check(ST(i), &p);
THIS->points.push_back(p);
}
void
Polyline::append_polyline(polyline)
Polyline* polyline;
CODE:
for (Points::const_iterator it = polyline->points.begin(); it != polyline->points.end(); ++it) {
THIS->points.push_back((*it));
}
void
Polyline::rotate(angle, center_sv)
double angle;
SV* center_sv;
CODE:
Point center;
from_SV_check(center_sv, &center);
THIS->rotate(angle, center);
%}
};

View File

@ -1,68 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/Print.hpp"
%}
%name{Slic3r::Print} class Print {
Print();
~Print();
Ref<Model> model()
%code%{ RETVAL = const_cast<Model*>(&THIS->model()); %};
Ref<StaticPrintConfig> config()
%code%{ RETVAL = const_cast<GCodeConfig*>(static_cast<const GCodeConfig*>(&THIS->config())); %};
double total_used_filament()
%code%{ RETVAL = THIS->print_statistics().total_used_filament; %};
void auto_assign_extruders(ModelObject* model_object);
std::string output_filepath(std::string path = "")
%code%{
try {
RETVAL = THIS->output_filepath(path);
} catch (std::exception& e) {
croak("%s\n", e.what());
}
%};
bool apply(Model *model, DynamicPrintConfig* config)
%code%{
// Touching every config as the Perl bindings does not correctly export ModelConfig,
// therefore the configs have often invalid timestamps.
for (auto obj : model->objects) {
obj->config.touch();
for (auto vol : obj->volumes)
vol->config.touch();
}
for (auto mat : model->materials)
mat.second->config.touch();
RETVAL = THIS->apply(*model, *config);
%};
std::vector<unsigned int> extruders() const;
int validate() %code%{
std::string err = THIS->validate();
if (! err.empty())
croak("Configuration is not valid: %s\n", err.c_str());
RETVAL = 1;
%};
void set_status_silent();
void process() %code%{
try {
THIS->process();
} catch (std::exception& e) {
croak("%s\n", e.what());
}
%};
void export_gcode(char *path_template) %code%{
try {
THIS->export_gcode(path_template, nullptr);
} catch (std::exception& e) {
croak("%s\n", e.what());
}
%};
};

View File

@ -1,115 +0,0 @@
%module{Slic3r::XS};
%{
#include <xsinit.h>
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/TriangleMeshSlicer.hpp"
%}
%name{Slic3r::TriangleMesh} class TriangleMesh {
TriangleMesh();
~TriangleMesh();
Clone<TriangleMesh> clone()
%code{% RETVAL = THIS; %};
void write_ascii(char* output_file);
void write_binary(char* output_file);
void scale(float factor);
void scale_xyz(Vec3d* versor)
%code{% THIS->scale(versor->cast<float>()); %};
void translate(float x, float y, float z);
void rotate_x(float angle);
void rotate_y(float angle);
void rotate_z(float angle);
void mirror_x();
void mirror_y();
void mirror_z();
void align_to_origin();
void rotate(double angle, Point* center);
void merge(TriangleMesh* mesh)
%code{% THIS->merge(*mesh); %};
Clone<Polygon> convex_hull();
Clone<Vec3d> center()
%code{% RETVAL = THIS->bounding_box().center(); %};
int facets_count();
%{
void
TriangleMesh::ReadFromPerl(vertices, facets)
SV* vertices
SV* facets
CODE:
std::vector<Slic3r::Vec3f> out_vertices;
{
AV* vertices_av = (AV*)SvRV(vertices);
int number_of_vertices = av_len(vertices_av) + 1;
out_vertices.reserve(number_of_vertices);
for (int i = 0; i < number_of_vertices; ++ i) {
AV* vertex_av = (AV*)SvRV(*av_fetch(vertices_av, i, 0));
out_vertices.push_back(Slic3r::Vec3f(SvNV(*av_fetch(vertex_av, 0, 0)), SvNV(*av_fetch(vertex_av, 1, 0)), SvNV(*av_fetch(vertex_av, 2, 0))));
}
}
std::vector<Slic3r::Vec3i> out_indices;
{
AV* facets_av = (AV*)SvRV(facets);
int number_of_facets = av_len(facets_av) + 1;
out_indices.reserve(number_of_facets);
for (int i = 0; i < number_of_facets; ++ i) {
AV* facet_av = (AV*)SvRV(*av_fetch(facets_av, i, 0));
out_indices.push_back(Slic3r::Vec3i(SvIV(*av_fetch(facet_av, 0, 0)), SvIV(*av_fetch(facet_av, 1, 0)), SvIV(*av_fetch(facet_av, 2, 0))));
}
}
*THIS = TriangleMesh(std::move(out_vertices), std::move(out_indices));
SV*
TriangleMesh::vertices()
CODE:
// vertices
AV* vertices = newAV();
av_extend(vertices, THIS->its.vertices.size());
for (size_t i = 0; i < THIS->its.vertices.size(); i++) {
AV* vertex = newAV();
av_store(vertices, i, newRV_noinc((SV*)vertex));
av_extend(vertex, 2);
av_store(vertex, 0, newSVnv(THIS->its.vertices[i](0)));
av_store(vertex, 1, newSVnv(THIS->its.vertices[i](1)));
av_store(vertex, 2, newSVnv(THIS->its.vertices[i](2)));
}
RETVAL = newRV_noinc((SV*)vertices);
OUTPUT:
RETVAL
SV*
TriangleMesh::facets()
CODE:
// facets
AV* facets = newAV();
av_extend(facets, THIS->facets_count());
for (int i = 0; i < THIS->facets_count(); i++) {
AV* facet = newAV();
av_store(facets, i, newRV_noinc((SV*)facet));
av_extend(facet, 2);
av_store(facet, 0, newSVnv(THIS->its.indices[i][0]));
av_store(facet, 1, newSVnv(THIS->its.indices[i][1]));
av_store(facet, 2, newSVnv(THIS->its.indices[i][2]));
}
RETVAL = newRV_noinc((SV*)facets);
OUTPUT:
RETVAL
SV*
TriangleMesh::size()
CODE:
AV* size = newAV();
av_extend(size, 2);
av_store(size, 0, newSVnv(THIS->stats().size(0)));
av_store(size, 1, newSVnv(THIS->stats().size(1)));
av_store(size, 2, newSVnv(THIS->stats().size(2)));
RETVAL = newRV_noinc((SV*)size);
OUTPUT:
RETVAL
%}
};

View File

@ -1,38 +0,0 @@
%module{Slic3r::XS};
%package{Slic3r::XS};
#include <xsinit.h>
#include "Utils.hpp"
%{
%}
%package{Slic3r};
%{
SV*
VERSION()
CODE:
RETVAL = newSVpv(SLIC3R_VERSION, 0);
OUTPUT: RETVAL
SV*
BUILD()
CODE:
RETVAL = newSVpv(SLIC3R_BUILD_ID, 0);
OUTPUT: RETVAL
SV*
FORK_NAME()
CODE:
RETVAL = newSVpv(SLIC3R_APP_NAME, 0);
OUTPUT: RETVAL
void
set_logging_level(level)
unsigned int level;
CODE:
Slic3r::set_logging_level(level);
%}

View File

@ -1,344 +0,0 @@
coordf_t T_NV
std::string T_STD_STRING
t_config_option_key T_STD_STRING
t_model_material_id T_STD_STRING
std::vector<std::string> T_STD_VECTOR_STD_STRING
std::vector<int> T_STD_VECTOR_INT
std::vector<Points::size_type> T_STD_VECTOR_INT
std::vector<size_t> T_STD_VECTOR_INT
std::vector<unsigned int> T_STD_VECTOR_UINT
std::vector<double> T_STD_VECTOR_DOUBLE
DynamicPrintConfig* O_OBJECT_SLIC3R
Ref<DynamicPrintConfig> O_OBJECT_SLIC3R_T
Clone<DynamicPrintConfig> O_OBJECT_SLIC3R_T
StaticPrintConfig* O_OBJECT_SLIC3R
Ref<StaticPrintConfig> O_OBJECT_SLIC3R_T
GCodeConfig* O_OBJECT_SLIC3R
Ref<GCodeConfig> O_OBJECT_SLIC3R_T
PrintConfig* O_OBJECT_SLIC3R
Ref<PrintConfig> O_OBJECT_SLIC3R_T
FullPrintConfig* O_OBJECT_SLIC3R
Ref<FullPrintConfig> O_OBJECT_SLIC3R_T
TriangleMesh* O_OBJECT_SLIC3R
Ref<TriangleMesh> O_OBJECT_SLIC3R_T
Clone<TriangleMesh> O_OBJECT_SLIC3R_T
Point* O_OBJECT_SLIC3R
Ref<Point> O_OBJECT_SLIC3R_T
Clone<Point> O_OBJECT_SLIC3R_T
Point3* O_OBJECT_SLIC3R
Ref<Point3> O_OBJECT_SLIC3R_T
Clone<Point3> O_OBJECT_SLIC3R_T
Vec2d* O_OBJECT_SLIC3R
Ref<Vec2d> O_OBJECT_SLIC3R_T
Clone<Vec2d> O_OBJECT_SLIC3R_T
Vec3d* O_OBJECT_SLIC3R
Ref<Vec3d> O_OBJECT_SLIC3R_T
Clone<Vec3d> O_OBJECT_SLIC3R_T
Line* O_OBJECT_SLIC3R
Ref<Line> O_OBJECT_SLIC3R_T
Clone<Line> O_OBJECT_SLIC3R_T
Polyline* O_OBJECT_SLIC3R
Ref<Polyline> O_OBJECT_SLIC3R_T
Clone<Polyline> O_OBJECT_SLIC3R_T
Polygon* O_OBJECT_SLIC3R
Ref<Polygon> O_OBJECT_SLIC3R_T
Clone<Polygon> O_OBJECT_SLIC3R_T
ExPolygon* O_OBJECT_SLIC3R
Ref<ExPolygon> O_OBJECT_SLIC3R_T
Clone<ExPolygon> O_OBJECT_SLIC3R_T
Model* O_OBJECT_SLIC3R
Ref<Model> O_OBJECT_SLIC3R_T
Clone<Model> O_OBJECT_SLIC3R_T
ModelMaterial* O_OBJECT_SLIC3R
Ref<ModelMaterial> O_OBJECT_SLIC3R_T
Clone<ModelMaterial> O_OBJECT_SLIC3R_T
ModelObject* O_OBJECT_SLIC3R
Ref<ModelObject> O_OBJECT_SLIC3R_T
Clone<ModelObject> O_OBJECT_SLIC3R_T
ModelVolume* O_OBJECT_SLIC3R
Ref<ModelVolume> O_OBJECT_SLIC3R_T
Clone<ModelVolume> O_OBJECT_SLIC3R_T
ModelInstance* O_OBJECT_SLIC3R
Ref<ModelInstance> O_OBJECT_SLIC3R_T
Clone<ModelInstance> O_OBJECT_SLIC3R_T
Print* O_OBJECT_SLIC3R
Ref<Print> O_OBJECT_SLIC3R_T
Clone<Print> O_OBJECT_SLIC3R_T
Axis T_UV
ExtrusionLoopRole T_UV
ExtrusionRole T_UV
SurfaceType T_UV
# we return these types whenever we want the items to be cloned
Points T_ARRAYREF
Pointfs T_ARRAYREF
Lines T_ARRAYREF
Polygons T_ARRAYREF
Polylines T_ARRAYREF
ExPolygons T_ARRAYREF
# we return these types whenever we want the items to be returned
# by reference and marked ::Ref because they're contained in another
# Perl object
Polygons* T_ARRAYREF_PTR
ModelObjectPtrs* T_PTR_ARRAYREF_PTR
ModelVolumePtrs* T_PTR_ARRAYREF_PTR
ModelInstancePtrs* T_PTR_ARRAYREF_PTR
# we return these types whenever we want the items to be returned
# by reference and not marked ::Ref because they're newly allocated
# and not referenced by any Perl object
INPUT
T_STD_STRING
{
size_t len;
// const char * c = SvPV($arg, len);
// Always convert strings to UTF-8 before passing them to XS
const char * c = SvPVutf8($arg, len);
$var = std::string(c, len);
}
T_STD_VECTOR_STD_STRING
if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
AV* av = (AV*)SvRV($arg);
const unsigned int alen = av_len(av)+1;
$var = std::vector<std::string>(alen);
STRLEN len;
char* tmp;
SV** elem;
for (unsigned int i = 0; i < alen; i++) {
elem = av_fetch(av, i, 0);
if (elem != NULL) {
tmp = SvPV(*elem, len);
${var}[i] = std::string(tmp, len);
}
else
${var}[i] = std::string(\"\");
}
}
else
Perl_croak(aTHX_ \"%s: %s is not an array reference\",
${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
\"$var\");
T_STD_VECTOR_INT
if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
AV* av = (AV*)SvRV($arg);
const unsigned int len = av_len(av)+1;
$var = std::vector<int>(len);
SV** elem;
for (unsigned int i = 0; i < len; i++) {
elem = av_fetch(av, i, 0);
if (elem != NULL)
${var}[i] = SvIV(*elem);
else
${var}[i] = 0;
}
}
else
Perl_croak(aTHX_ \"%s: %s is not an array reference\",
${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
\"$var\");
T_STD_VECTOR_UINT
if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
AV* av = (AV*)SvRV($arg);
const unsigned int len = av_len(av)+1;
$var = std::vector<unsigned int>(len);
SV** elem;
for (unsigned int i = 0; i < len; i++) {
elem = av_fetch(av, i, 0);
if (elem != NULL)
${var}[i] = SvUV(*elem);
else
${var}[i] = 0;
}
}
else
Perl_croak(aTHX_ \"%s: %s is not an array reference\",
${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
\"$var\");
T_STD_VECTOR_DOUBLE
if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
AV* av = (AV*)SvRV($arg);
const unsigned int len = av_len(av)+1;
$var = std::vector<double>(len);
SV** elem;
for (unsigned int i = 0; i < len; i++) {
elem = av_fetch(av, i, 0);
if (elem != NULL)
${var}[i] = SvNV(*elem);
else
${var}[i] = 0.;
}
}
else
Perl_croak(aTHX_ \"%s: %s is not an array reference\",
${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
\"$var\");
O_OBJECT_SLIC3R
if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) {
if ( sv_isa($arg, Slic3r::perl_class_name($var) ) || sv_isa($arg, Slic3r::perl_class_name_ref($var) )) {
$var = ($type)SvIV((SV*)SvRV( $arg ));
} else {
croak(\"$var is not of type %s (got %s)\", Slic3r::perl_class_name($var), HvNAME(SvSTASH(SvRV($arg))));
XSRETURN_UNDEF;
}
} else {
warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" );
XSRETURN_UNDEF;
}
T_ARRAYREF
if (SvROK($arg) && SvTYPE(SvRV($arg)) == SVt_PVAV) {
AV* av = (AV*)SvRV($arg);
const unsigned int len = av_len(av)+1;
$var.resize(len);
for (unsigned int i = 0; i < len; i++) {
SV** elem = av_fetch(av, i, 0);
from_SV_check(*elem, &$var\[i]);
}
} else
Perl_croak(aTHX_ \"%s: %s is not an array reference\",
${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
\"$var\");
OUTPUT
T_STD_STRING
$arg = newSVpvn_utf8( $var.c_str(), $var.length(), true );
T_STD_VECTOR_STD_STRING
AV* av = newAV();
$arg = newRV_noinc((SV*)av);
sv_2mortal($arg);
const unsigned int len = $var.size();
if (len)
av_extend(av, len-1);
for (unsigned int i = 0; i < len; i++) {
const std::string& str = ${var}[i];
STRLEN len = str.length();
av_store(av, i, newSVpvn_utf8(str.c_str(), len, true));
}
T_STD_VECTOR_INT
AV* av = newAV();
$arg = newRV_noinc((SV*)av);
sv_2mortal($arg);
const unsigned int len = $var.size();
if (len)
av_extend(av, len-1);
for (unsigned int i = 0; i < len; i++) {
av_store(av, i, newSViv(${var}[i]));
}
T_STD_VECTOR_UINT
AV* av = newAV();
$arg = newRV_noinc((SV*)av);
sv_2mortal($arg);
const unsigned int len = $var.size();
if (len)
av_extend(av, len-1);
for (unsigned int i = 0; i < len; i++) {
av_store(av, i, newSVuv(${var}[i]));
}
T_STD_VECTOR_DOUBLE
AV* av = newAV();
$arg = newRV_noinc((SV*)av);
sv_2mortal($arg);
const unsigned int len = $var.size();
if (len)
av_extend(av, len-1);
for (unsigned int i = 0; i < len; i++) {
av_store(av, i, newSVnv(${var}[i]));
}
# return object from pointer
O_OBJECT_SLIC3R
if ($var == NULL)
XSRETURN_UNDEF;
sv_setref_pv( $arg, Slic3r::perl_class_name($var), (void*)$var );
# return value handled by template class
O_OBJECT_SLIC3R_T
if ($var == NULL)
XSRETURN_UNDEF;
sv_setref_pv( $arg, $type\::CLASS(), (void*)$var );
T_ARRAYREF
AV* av = newAV();
$arg = newRV_noinc((SV*)av);
sv_2mortal($arg);
const unsigned int len = $var.size();
if (len > 0) av_extend(av, len-1);
int i = 0;
for (${type}::const_iterator it = $var.begin(); it != $var.end(); ++it) {
av_store(av, i++, perl_to_SV_clone_ref(*it));
}
T_ARRAYREF_PTR
AV* av = newAV();
$arg = newRV_noinc((SV*)av);
sv_2mortal($arg);
const unsigned int len = $var->size();
if (len > 0) av_extend(av, len-1);
int i = 0;
for (${ my $t = $type; $t =~ s/\*$//; \$t }::iterator it = $var->begin(); it != $var->end(); ++it) {
av_store(av, i++, perl_to_SV_ref(*it));
}
T_PTR_ARRAYREF_PTR
AV* av = newAV();
$arg = newRV_noinc((SV*)av);
sv_2mortal($arg);
const unsigned int len = $var->size();
if (len > 0) av_extend(av, len-1);
int i = 0;
for (${ my $t = $type; $t =~ s/\*$//; \$t }::iterator it = $var->begin(); it != $var->end(); ++it) {
av_store(av, i++, perl_to_SV_ref(**it));
}
T_PTR_ARRAYREF
AV* av = newAV();
$arg = newRV_noinc((SV*)av);
sv_2mortal($arg);
const unsigned int len = $var.size();
if (len > 0) av_extend(av, len-1);
int i = 0;
for (${type}::iterator it = $var.begin(); it != $var.end(); ++it) {
av_store(av, i++, to_SV(*it));
}

View File

View File

@ -1,99 +0,0 @@
%typemap{bool}{simple};
%typemap{size_t}{simple};
%typemap{coordf_t}{simple};
%typemap{std::string};
%typemap{t_config_option_key};
%typemap{t_model_material_id};
%typemap{std::vector<int>};
%typemap{std::vector<size_t>};
%typemap{std::vector<unsigned int>*};
%typemap{std::vector<double>};
%typemap{std::vector<double>*};
%typemap{std::vector<unsigned int>};
%typemap{std::vector<unsigned int>*};
%typemap{std::vector<std::string>};
%typemap{void*};
%typemap{SV*};
%typemap{AV*};
%typemap{Point*};
%typemap{Ref<Point>}{simple};
%typemap{Clone<Point>}{simple};
%typemap{Point3*};
%typemap{Ref<Point3>}{simple};
%typemap{Clone<Point3>}{simple};
%typemap{Vec2d*};
%typemap{Ref<Vec2d>}{simple};
%typemap{Clone<Vec2d>}{simple};
%typemap{Vec3d*};
%typemap{Ref<Vec3d>}{simple};
%typemap{Clone<Vec3d>}{simple};
%typemap{DynamicPrintConfig*};
%typemap{Ref<DynamicPrintConfig>}{simple};
%typemap{Clone<DynamicPrintConfig>}{simple};
%typemap{StaticPrintConfig*};
%typemap{Ref<StaticPrintConfig>}{simple};
%typemap{GCodeConfig*};
%typemap{Ref<GCodeConfig>}{simple};
%typemap{PrintConfig*};
%typemap{Ref<PrintConfig>}{simple};
%typemap{FullPrintConfig*};
%typemap{Ref<FullPrintConfig>}{simple};
%typemap{ExPolygon*};
%typemap{Ref<ExPolygon>}{simple};
%typemap{Clone<ExPolygon>}{simple};
%typemap{Line*};
%typemap{Ref<Line>}{simple};
%typemap{Clone<Line>}{simple};
%typemap{Polyline*};
%typemap{Ref<Polyline>}{simple};
%typemap{Clone<Polyline>}{simple};
%typemap{Polygon*};
%typemap{Ref<Polygon>}{simple};
%typemap{Clone<Polygon>}{simple};
%typemap{TriangleMesh*};
%typemap{Ref<TriangleMesh>}{simple};
%typemap{Clone<TriangleMesh>}{simple};
%typemap{Print*};
%typemap{Ref<Print>}{simple};
%typemap{Clone<Print>}{simple};
%typemap{Points};
%typemap{Pointfs};
%typemap{Lines};
%typemap{Polygons};
%typemap{Polylines};
%typemap{ExPolygons};
%typemap{Polygons*};
%typemap{TriangleMesh*};
%typemap{Model*};
%typemap{Ref<Model>}{simple};
%typemap{Clone<Model>}{simple};
%typemap{ModelMaterial*};
%typemap{Ref<ModelMaterial>}{simple};
%typemap{Clone<ModelMaterial>}{simple};
%typemap{ModelObject*};
%typemap{Ref<ModelObject>}{simple};
%typemap{Clone<ModelObject>}{simple};
%typemap{ModelObjectPtrs*};
%typemap{Ref<ModelObjectPtrs>}{simple};
%typemap{Clone<ModelObjectPtrs>}{simple};
%typemap{ModelVolume*};
%typemap{Ref<ModelVolume>}{simple};
%typemap{Clone<ModelVolume>}{simple};
%typemap{ModelVolumePtrs*};
%typemap{Ref<ModelVolumePtrs>}{simple};
%typemap{Clone<ModelVolumePtrs>}{simple};
%typemap{ModelInstance*};
%typemap{Ref<ModelInstance>}{simple};
%typemap{Clone<ModelInstance>}{simple};
%typemap{ModelInstancePtrs*};
%typemap{Ref<ModelInstancePtrs>}{simple};
%typemap{Clone<ModelInstancePtrs>}{simple};
%typemap{Axis}{parsed}{
%cpp_type{Axis};
%precall_code{%
$CVar = (Axis)SvUV($PerlVar);
%};
};