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.
This commit is contained in:
bubnikv 2017-10-17 20:00:15 +02:00
parent af51220f34
commit d9d6d996e9
9 changed files with 157 additions and 3 deletions

View File

@ -325,6 +325,7 @@ endif()
add_library(XS ${XS_SHARED_LIBRARY_TYPE} add_library(XS ${XS_SHARED_LIBRARY_TYPE}
${XS_MAIN_CPP} ${XS_MAIN_CPP}
${LIBDIR}/libslic3r/utils.cpp ${LIBDIR}/libslic3r/utils.cpp
${LIBDIR}/slic3r/GUI/wxPerlIface.cpp
${LIBDIR}/perlglue.cpp ${LIBDIR}/perlglue.cpp
${LIBDIR}/ppport.h ${LIBDIR}/ppport.h
${LIBDIR}/xsinit.h ${LIBDIR}/xsinit.h

View File

@ -257,6 +257,13 @@ use overload
sub CLONE_SKIP { 1 } sub CLONE_SKIP { 1 }
package Slic3r::GUI::PresetCollection;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
sub CLONE_SKIP { 1 }
package main; package main;
for my $class (qw( for my $class (qw(
Slic3r::BridgeDetector Slic3r::BridgeDetector

View File

@ -666,7 +666,7 @@ void ModelObject::cut(coordf_t z, Model* model) const
// we rather split the mesh into multiple non-intersecting pieces. // we rather split the mesh into multiple non-intersecting pieces.
TriangleMeshPtrs meshptrs = volume->mesh.split(); TriangleMeshPtrs meshptrs = volume->mesh.split();
for (TriangleMeshPtrs::iterator mesh = meshptrs.begin(); mesh != meshptrs.end(); ++mesh) { 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(); (*mesh)->repair();
TriangleMeshSlicer tms(*mesh); TriangleMeshSlicer tms(*mesh);
if (mesh == meshptrs.begin()) { if (mesh == meshptrs.begin()) {

View File

@ -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->x == rhs.x && this->y == rhs.y; }
bool operator!=(const Pointf &rhs) const { return ! (*this == rhs); } 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); } inline Pointf operator+(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x + point2.x, point1.y + point2.y); }

View File

@ -6,6 +6,13 @@ namespace Slic3r {
extern void set_logging_level(unsigned int level); extern void set_logging_level(unsigned int level);
extern void trace(unsigned int level, const char *message); 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 encode_path(const char *src);
extern std::string decode_path(const char *src); extern std::string decode_path(const char *src);
extern std::string normalize_utf8_nfc(const char *src); extern std::string normalize_utf8_nfc(const char *src);

View File

@ -6,6 +6,8 @@
#include <boost/locale.hpp> #include <boost/locale.hpp>
#include <boost/filesystem.hpp>
#include <boost/nowide/integration/filesystem.hpp> #include <boost/nowide/integration/filesystem.hpp>
#include <boost/nowide/convert.hpp> #include <boost/nowide/convert.hpp>
@ -67,6 +69,24 @@ void trace(unsigned int level, const char *message)
(::boost::log::keywords::severity = severity)) << 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 } // namespace Slic3r
#ifdef SLIC3R_HAS_BROKEN_CROAK #ifdef SLIC3R_HAS_BROKEN_CROAK

View File

@ -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 <xsinit.h>
// ----------------------------------------------------------------------------
// 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
}
}

View File

@ -159,8 +159,6 @@ bool from_SV(SV* point_sv, Pointf* point);
bool from_SV_check(SV* point_sv, Pointf* point); bool from_SV_check(SV* point_sv, Pointf* point);
void from_SV_check(SV* surface_sv, Surface* THIS); void from_SV_check(SV* surface_sv, Surface* THIS);
SV* to_SV(TriangleMesh* 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
#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; using namespace Slic3r;
#endif #endif

View File

@ -48,6 +48,25 @@ trace(level, message)
CODE: CODE:
Slic3r::trace(level, message); Slic3r::trace(level, message);
void
set_var_dir(dir)
char *dir;
CODE:
Slic3r::set_var_dir(dir);
char*
var_dir()
CODE:
RETVAL = const_cast<char*>(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 std::string
encode_path(src) encode_path(src)
const char *src; const char *src;