From d9d6d996e96a223a33580a19299312eadc3e5e53 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 17 Oct 2017 20:00:15 +0200 Subject: [PATCH] Utility functions to pass wxWidgets pointers from Perl to C++ code. C++ var_dir / set_var_dir() interface to access the UI resources from the C++ code. --- xs/CMakeLists.txt | 1 + xs/lib/Slic3r/XS.pm | 7 +++ xs/src/libslic3r/Model.cpp | 2 +- xs/src/libslic3r/Point.hpp | 1 + xs/src/libslic3r/Utils.hpp | 7 +++ xs/src/libslic3r/utils.cpp | 20 +++++++ xs/src/slic3r/GUI/wxPerlIface.cpp | 97 +++++++++++++++++++++++++++++++ xs/src/xsinit.h | 6 +- xs/xsp/XS.xsp | 19 ++++++ 9 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 xs/src/slic3r/GUI/wxPerlIface.cpp diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index e761d388b..7224353d4 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -325,6 +325,7 @@ endif() add_library(XS ${XS_SHARED_LIBRARY_TYPE} ${XS_MAIN_CPP} ${LIBDIR}/libslic3r/utils.cpp + ${LIBDIR}/slic3r/GUI/wxPerlIface.cpp ${LIBDIR}/perlglue.cpp ${LIBDIR}/ppport.h ${LIBDIR}/xsinit.h diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm index b79abac7c..0e995acf2 100644 --- a/xs/lib/Slic3r/XS.pm +++ b/xs/lib/Slic3r/XS.pm @@ -257,6 +257,13 @@ use overload sub CLONE_SKIP { 1 } +package Slic3r::GUI::PresetCollection; +use overload + '@{}' => sub { $_[0]->arrayref }, + 'fallback' => 1; + +sub CLONE_SKIP { 1 } + package main; for my $class (qw( Slic3r::BridgeDetector diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp index e21f36c43..88a0b8279 100644 --- a/xs/src/libslic3r/Model.cpp +++ b/xs/src/libslic3r/Model.cpp @@ -666,7 +666,7 @@ void ModelObject::cut(coordf_t z, Model* model) const // we rather split the mesh into multiple non-intersecting pieces. TriangleMeshPtrs meshptrs = volume->mesh.split(); for (TriangleMeshPtrs::iterator mesh = meshptrs.begin(); mesh != meshptrs.end(); ++mesh) { - printf("Cutting mesh patch %d of %d\n", size_t(mesh - meshptrs.begin())); + printf("Cutting mesh patch %d of %d\n", int(mesh - meshptrs.begin()), int(meshptrs.size())); (*mesh)->repair(); TriangleMeshSlicer tms(*mesh); if (mesh == meshptrs.begin()) { diff --git a/xs/src/libslic3r/Point.hpp b/xs/src/libslic3r/Point.hpp index b81427f73..77e07bec8 100644 --- a/xs/src/libslic3r/Point.hpp +++ b/xs/src/libslic3r/Point.hpp @@ -223,6 +223,7 @@ public: bool operator==(const Pointf &rhs) const { return this->x == rhs.x && this->y == rhs.y; } bool operator!=(const Pointf &rhs) const { return ! (*this == rhs); } + bool operator< (const Pointf& rhs) const { return this->x < rhs.x || (this->x == rhs.x && this->y < rhs.y); } }; inline Pointf operator+(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x + point2.x, point1.y + point2.y); } diff --git a/xs/src/libslic3r/Utils.hpp b/xs/src/libslic3r/Utils.hpp index 45d1f2c51..79e1c2e2e 100644 --- a/xs/src/libslic3r/Utils.hpp +++ b/xs/src/libslic3r/Utils.hpp @@ -6,6 +6,13 @@ namespace Slic3r { extern void set_logging_level(unsigned int level); extern void trace(unsigned int level, const char *message); +// Set a path with GUI resource files. +void set_var_dir(const std::string &path); +// Return a path to the GUI resource files. +const std::string& var_dir(); +// Return a resource path for a file_name. +std::string var(const std::string &file_name); + extern std::string encode_path(const char *src); extern std::string decode_path(const char *src); extern std::string normalize_utf8_nfc(const char *src); diff --git a/xs/src/libslic3r/utils.cpp b/xs/src/libslic3r/utils.cpp index e3cdd5084..6e60f978d 100644 --- a/xs/src/libslic3r/utils.cpp +++ b/xs/src/libslic3r/utils.cpp @@ -6,6 +6,8 @@ #include +#include + #include #include @@ -67,6 +69,24 @@ void trace(unsigned int level, const char *message) (::boost::log::keywords::severity = severity)) << message; } +static std::string g_var_dir; + +void set_var_dir(const std::string &dir) +{ + g_var_dir = dir; +} + +const std::string& var_dir() +{ + return g_var_dir; +} + +std::string var(const std::string &file_name) +{ + auto file = boost::filesystem::canonical(boost::filesystem::path(g_var_dir) / file_name).make_preferred(); + return file.string(); +} + } // namespace Slic3r #ifdef SLIC3R_HAS_BROKEN_CROAK diff --git a/xs/src/slic3r/GUI/wxPerlIface.cpp b/xs/src/slic3r/GUI/wxPerlIface.cpp new file mode 100644 index 000000000..216ca4b3b --- /dev/null +++ b/xs/src/slic3r/GUI/wxPerlIface.cpp @@ -0,0 +1,97 @@ +// Derived from the following: + +///////////////////////////////////////////////////////////////////////////// +// Name: cpp/helpers.cpp +// Purpose: implementation for helpers.h +// Author: Mattia Barbon +// Modified by: +// Created: 29/10/2000 +// RCS-ID: $Id: helpers.cpp 3397 2012-09-30 02:26:07Z mdootson $ +// Copyright: (c) 2000-2011 Mattia Barbon +// Licence: This program is free software; you can redistribute it and/or +// modify it under the same terms as Perl itself +///////////////////////////////////////////////////////////////////////////// + +#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 + +//#include + +// ---------------------------------------------------------------------------- +// Utility functions for working with MAGIC +// ---------------------------------------------------------------------------- + +struct my_magic +{ + my_magic() : object( NULL ), deleteable( true ) { } + + void* object; + bool deleteable; +}; + +//STATIC MGVTBL my_vtbl = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +my_magic* wxPli_get_magic( pTHX_ SV* rv ) +{ + // check for reference + if( !SvROK( rv ) ) + return NULL; + SV* ref = SvRV( rv ); + + // if it isn't a SvPVMG, then it can't have MAGIC + // so it is deleteable + if( !ref || SvTYPE( ref ) < SVt_PVMG ) + return NULL; + + // search for '~' / PERL_MAGIC_ext magic, and check the value +// MAGIC* magic = mg_findext( ref, PERL_MAGIC_ext, &my_vtbl ); + MAGIC* magic = mg_find( ref, '~' ); + if( !magic ) + return NULL; + + return (my_magic*)magic->mg_ptr; +} + +// gets 'this' pointer from a blessed scalar/hash reference +void* wxPli_sv_2_object( pTHX_ SV* scalar, const char* classname ) +{ + // is it correct to use undef as 'NULL'? + if( !SvOK( scalar ) ) + { + return NULL; + } + + if( !SvROK( scalar ) ) + croak( "variable is not an object: it must have type %s", classname ); + + if( !classname || sv_derived_from( scalar, (char*) classname ) ) + { + SV* ref = SvRV( scalar ); + + my_magic* mg = wxPli_get_magic( aTHX_ scalar ); + + // rationale: if this is an hash-ish object, it always + // has both mg and mg->object; if however this is a + // scalar-ish object that has been marked/unmarked deletable + // it has mg, but not mg->object + if( !mg || !mg->object ) + return INT2PTR( void*, SvOK( ref ) ? SvIV( ref ) : 0 ); + + return mg->object; + } + else + { + croak( "variable is not of type %s", classname ); + return NULL; // dummy, for compiler + } +} diff --git a/xs/src/xsinit.h b/xs/src/xsinit.h index c375c7e62..dcf54bdbc 100644 --- a/xs/src/xsinit.h +++ b/xs/src/xsinit.h @@ -159,8 +159,6 @@ bool from_SV(SV* point_sv, Pointf* point); bool from_SV_check(SV* point_sv, Pointf* point); void from_SV_check(SV* surface_sv, Surface* THIS); SV* to_SV(TriangleMesh* THIS); -SV* polynode_children_2_perl(const ClipperLib::PolyNode& node); -SV* polynode2perl(const ClipperLib::PolyNode& node); } @@ -173,6 +171,10 @@ SV* polynode2perl(const ClipperLib::PolyNode& node); #endif #endif +// 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 ); + using namespace Slic3r; #endif diff --git a/xs/xsp/XS.xsp b/xs/xsp/XS.xsp index 5fa3a4b7d..7265334ae 100644 --- a/xs/xsp/XS.xsp +++ b/xs/xsp/XS.xsp @@ -48,6 +48,25 @@ trace(level, message) CODE: Slic3r::trace(level, message); +void +set_var_dir(dir) + char *dir; + CODE: + Slic3r::set_var_dir(dir); + +char* +var_dir() + CODE: + RETVAL = const_cast(Slic3r::var_dir().c_str()); + OUTPUT: RETVAL + +std::string +var(file_name) + const char *file_name; + CODE: + RETVAL = Slic3r::var(file_name); + OUTPUT: RETVAL + std::string encode_path(src) const char *src;