mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-17 03:37:54 -06:00
Initial working implementation of the "Fix by Netfabb" function.
This commit is contained in:
parent
e65fac5e84
commit
d05d3cb652
6 changed files with 136 additions and 11 deletions
|
@ -49,6 +49,22 @@ if(NOT DEFINED CMAKE_PREFIX_PATH)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
if(NOT DEFINED WIN10SDK_PATH)
|
||||||
|
if(DEFINED ENV{WIN10SDK_PATH})
|
||||||
|
set(WIN10SDK_PATH "$ENV{WIN10SDK_PATH}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(DEFINED WIN10SDK_PATH AND NOT EXISTS "${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h")
|
||||||
|
message("WIN10SDK_PATH is invalid: ${WIN10SDK_PATH}")
|
||||||
|
message("${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h was not found")
|
||||||
|
message("STL fixing by the Netfabb service will not be compiled")
|
||||||
|
unset(WIN10SDK_PATH)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(xs)
|
add_subdirectory(xs)
|
||||||
|
|
||||||
get_filename_component(PERL_BIN_PATH "${PERL_EXECUTABLE}" DIRECTORY)
|
get_filename_component(PERL_BIN_PATH "${PERL_EXECUTABLE}" DIRECTORY)
|
||||||
|
|
|
@ -1620,6 +1620,34 @@ sub export_object_stl {
|
||||||
$self->statusbar->SetStatusText(L("STL file exported to ").$output_file);
|
$self->statusbar->SetStatusText(L("STL file exported to ").$output_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub fix_through_netfabb {
|
||||||
|
my ($self) = @_;
|
||||||
|
my ($obj_idx, $object) = $self->selected_object;
|
||||||
|
return if !defined $obj_idx;
|
||||||
|
my $model_object = $self->{model}->objects->[$obj_idx];
|
||||||
|
my $model_fixed = Slic3r::Model->new;
|
||||||
|
Slic3r::GUI::fix_model_by_win10_sdk_gui($model_object, $self->{print}, $model_fixed);
|
||||||
|
|
||||||
|
my @new_obj_idx = $self->load_model_objects(@{$model_fixed->objects});
|
||||||
|
return if !@new_obj_idx;
|
||||||
|
|
||||||
|
foreach my $new_obj_idx (@new_obj_idx) {
|
||||||
|
my $o = $self->{model}->objects->[$new_obj_idx];
|
||||||
|
$o->clear_instances;
|
||||||
|
$o->add_instance($_) for @{$model_object->instances};
|
||||||
|
#$o->invalidate_bounding_box;
|
||||||
|
|
||||||
|
if ($o->volumes_count == $model_object->volumes_count) {
|
||||||
|
for my $i (0..($o->volumes_count-1)) {
|
||||||
|
$o->get_volume($i)->config->apply($model_object->get_volume($i)->config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#FIXME restore volumes and their configs, layer_height_ranges, layer_height_profile, layer_height_profile_valid,
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->remove($obj_idx);
|
||||||
|
}
|
||||||
|
|
||||||
sub export_amf {
|
sub export_amf {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
return if !@{$self->{objects}};
|
return if !@{$self->{objects}};
|
||||||
|
@ -2178,6 +2206,11 @@ sub object_menu {
|
||||||
$frame->_append_menu_item($menu, L("Export object as STL…"), L('Export this single object as STL file'), sub {
|
$frame->_append_menu_item($menu, L("Export object as STL…"), L('Export this single object as STL file'), sub {
|
||||||
$self->export_object_stl;
|
$self->export_object_stl;
|
||||||
}, undef, 'brick_go.png');
|
}, undef, 'brick_go.png');
|
||||||
|
if (Slic3r::GUI::is_windows10) {
|
||||||
|
$frame->_append_menu_item($menu, L("Fix STL through Netfabb"), L('Fix the model by sending it to a Netfabb cloud service through Windows 10 API'), sub {
|
||||||
|
$self->fix_through_netfabb;
|
||||||
|
}, undef, 'brick_go.png');
|
||||||
|
}
|
||||||
|
|
||||||
return $menu;
|
return $menu;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,13 @@ if(WIN32)
|
||||||
# BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking.
|
# BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking.
|
||||||
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -DBOOST_ALL_NO_LIB)
|
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -DBOOST_ALL_NO_LIB)
|
||||||
# -D_ITERATOR_DEBUG_LEVEL)
|
# -D_ITERATOR_DEBUG_LEVEL)
|
||||||
|
if(WIN10SDK_PATH)
|
||||||
|
message("Building with Win10 Netfabb STL fixing service support")
|
||||||
|
add_definitions(-DHAS_WIN10SDK)
|
||||||
|
include_directories("${WIN10SDK_PATH}/Include")
|
||||||
|
else()
|
||||||
|
message("Building without Win10 Netfabb STL fixing service support")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_definitions(-DwxUSE_UNICODE -D_UNICODE -DUNICODE)
|
add_definitions(-DwxUSE_UNICODE -D_UNICODE -DUNICODE)
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
#ifdef HAS_WIN10SDK
|
#ifdef HAS_WIN10SDK
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
# define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "FixModelByWin10.hpp"
|
#include "FixModelByWin10.hpp"
|
||||||
|
|
||||||
#include <roapi.h>
|
#include <roapi.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <thread>
|
||||||
// for ComPtr
|
// for ComPtr
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
// from C:/Program Files (x86)/Windows Kits/10/Include/10.0.17134.0/
|
// from C:/Program Files (x86)/Windows Kits/10/Include/10.0.17134.0/
|
||||||
|
@ -12,6 +17,18 @@
|
||||||
#include <winrt/windows.storage.provider.h>
|
#include <winrt/windows.storage.provider.h>
|
||||||
#include <winrt/windows.graphics.printing3d.h>
|
#include <winrt/windows.graphics.printing3d.h>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/nowide/convert.hpp>
|
||||||
|
#include <boost/nowide/cstdio.hpp>
|
||||||
|
|
||||||
|
#include "libslic3r/Model.hpp"
|
||||||
|
#include "libslic3r/Print.hpp"
|
||||||
|
#include "libslic3r/Format/3mf.hpp"
|
||||||
|
#include "../GUI/GUI.hpp"
|
||||||
|
#include "../GUI/PresetBundle.hpp"
|
||||||
|
|
||||||
|
#include <wx/progdlg.h>
|
||||||
|
|
||||||
extern "C"{
|
extern "C"{
|
||||||
// from rapi.h
|
// from rapi.h
|
||||||
typedef HRESULT (__stdcall* FunctionRoInitialize)(int);
|
typedef HRESULT (__stdcall* FunctionRoInitialize)(int);
|
||||||
|
@ -23,6 +40,8 @@ extern "C"{
|
||||||
typedef HRESULT (__stdcall* FunctionWindowsDelteString)(HSTRING string);
|
typedef HRESULT (__stdcall* FunctionWindowsDelteString)(HSTRING string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
HMODULE s_hRuntimeObjectLibrary = nullptr;
|
HMODULE s_hRuntimeObjectLibrary = nullptr;
|
||||||
FunctionRoInitialize s_RoInitialize = nullptr;
|
FunctionRoInitialize s_RoInitialize = nullptr;
|
||||||
FunctionRoUninitialize s_RoUninitialize = nullptr;
|
FunctionRoUninitialize s_RoUninitialize = nullptr;
|
||||||
|
@ -178,13 +197,13 @@ bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path
|
||||||
|
|
||||||
if (! winrt_load_runtime_object_library()) {
|
if (! winrt_load_runtime_object_library()) {
|
||||||
printf("Failed to initialize the WinRT library. This should not happen on Windows 10. Exiting.\n");
|
printf("Failed to initialize the WinRT library. This should not happen on Windows 10. Exiting.\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*s_RoInitialize)(RO_INIT_MULTITHREADED);
|
HRESULT hr = (*s_RoInitialize)(RO_INIT_MULTITHREADED);
|
||||||
{
|
{
|
||||||
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IRandomAccessStream> fileStream;
|
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IRandomAccessStream> fileStream;
|
||||||
HRESULT hr = winrt_open_file_stream(L"D:\\3dprint\\bug.3mf", ABI::Windows::Storage::FileAccessMode::FileAccessMode_Read, fileStream.GetAddressOf());
|
hr = winrt_open_file_stream(boost::nowide::widen(path_src), ABI::Windows::Storage::FileAccessMode::FileAccessMode_Read, fileStream.GetAddressOf());
|
||||||
|
|
||||||
Microsoft::WRL::ComPtr<ABI::Windows::Graphics::Printing3D::IPrinting3D3MFPackage> printing3d3mfpackage;
|
Microsoft::WRL::ComPtr<ABI::Windows::Graphics::Printing3D::IPrinting3D3MFPackage> printing3d3mfpackage;
|
||||||
hr = winrt_activate_instance(L"Windows.Graphics.Printing3D.Printing3D3MFPackage", printing3d3mfpackage.GetAddressOf());
|
hr = winrt_activate_instance(L"Windows.Graphics.Printing3D.Printing3D3MFPackage", printing3d3mfpackage.GetAddressOf());
|
||||||
|
@ -198,7 +217,7 @@ bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path
|
||||||
hr = modelAsync->GetResults(model.GetAddressOf());
|
hr = modelAsync->GetResults(model.GetAddressOf());
|
||||||
} else {
|
} else {
|
||||||
printf("Failed loading the input model. Exiting.\n");
|
printf("Failed loading the input model. Exiting.\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IVector<ABI::Windows::Graphics::Printing3D::Printing3DMesh*>> meshes;
|
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IVector<ABI::Windows::Graphics::Printing3D::Printing3DMesh*>> meshes;
|
||||||
|
@ -211,7 +230,7 @@ bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path
|
||||||
status = winrt_async_await(repairAsync);
|
status = winrt_async_await(repairAsync);
|
||||||
if (status != AsyncStatus::Completed) {
|
if (status != AsyncStatus::Completed) {
|
||||||
printf("Mesh repair failed. Exiting.\n");
|
printf("Mesh repair failed. Exiting.\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
printf("Mesh repair finished successfully.\n");
|
printf("Mesh repair finished successfully.\n");
|
||||||
repairAsync->GetResults();
|
repairAsync->GetResults();
|
||||||
|
@ -227,7 +246,7 @@ bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path
|
||||||
status = winrt_async_await(saveToPackageAsync);
|
status = winrt_async_await(saveToPackageAsync);
|
||||||
if (status != AsyncStatus::Completed) {
|
if (status != AsyncStatus::Completed) {
|
||||||
printf("Saving mesh into the 3MF container failed. Exiting.\n");
|
printf("Saving mesh into the 3MF container failed. Exiting.\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
hr = saveToPackageAsync->GetResults();
|
hr = saveToPackageAsync->GetResults();
|
||||||
|
|
||||||
|
@ -236,7 +255,7 @@ bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path
|
||||||
status = winrt_async_await(generatorStreamAsync);
|
status = winrt_async_await(generatorStreamAsync);
|
||||||
if (status != AsyncStatus::Completed) {
|
if (status != AsyncStatus::Completed) {
|
||||||
printf("Saving mesh into the 3MF container failed. Exiting.\n");
|
printf("Saving mesh into the 3MF container failed. Exiting.\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IRandomAccessStream> generatorStream;
|
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IRandomAccessStream> generatorStream;
|
||||||
hr = generatorStreamAsync->GetResults(generatorStream.GetAddressOf());
|
hr = generatorStreamAsync->GetResults(generatorStream.GetAddressOf());
|
||||||
|
@ -251,7 +270,7 @@ bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path
|
||||||
hr = winrt_get_activation_factory(L"Windows.Storage.Streams.Buffer", bufferFactory.GetAddressOf());
|
hr = winrt_get_activation_factory(L"Windows.Storage.Streams.Buffer", bufferFactory.GetAddressOf());
|
||||||
|
|
||||||
// Open the destination file.
|
// Open the destination file.
|
||||||
FILE *fout = ::fopen("D:\\3dprint\\bug-repaired.3mf", "wb");
|
FILE *fout = boost::nowide::fopen(path_dst.c_str(), "wb");
|
||||||
|
|
||||||
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
|
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
|
||||||
byte *buffer_ptr;
|
byte *buffer_ptr;
|
||||||
|
@ -270,7 +289,7 @@ bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path
|
||||||
status = winrt_async_await(asyncRead);
|
status = winrt_async_await(asyncRead);
|
||||||
if (status != AsyncStatus::Completed) {
|
if (status != AsyncStatus::Completed) {
|
||||||
printf("Saving mesh into the 3MF container failed. Exiting.\n");
|
printf("Saving mesh into the 3MF container failed. Exiting.\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
hr = buffer->get_Length(&length);
|
hr = buffer->get_Length(&length);
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
|
@ -281,7 +300,40 @@ bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path
|
||||||
// Here all the COM objects will be released through the ComPtr destructors.
|
// Here all the COM objects will be released through the ComPtr destructors.
|
||||||
}
|
}
|
||||||
(*s_RoUninitialize)();
|
(*s_RoUninitialize)();
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fix_model_by_win10_sdk_gui(const ModelObject &model_object, const Print &print, Model &result)
|
||||||
|
{
|
||||||
|
enum { PROGRESS_RANGE = 1000 };
|
||||||
|
wxProgressDialog progress_dialog(
|
||||||
|
_(L("Model fixing")),
|
||||||
|
_(L("Exporting model...")),
|
||||||
|
PROGRESS_RANGE, nullptr, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
|
||||||
|
progress_dialog.Pulse();
|
||||||
|
|
||||||
|
// Executing the calculation in a background thread, so that the COM context could be created with its own threading model.
|
||||||
|
// (It seems like wxWidgets initialize the COM contex as single threaded and we need a multi-threaded context).
|
||||||
|
auto worker = std::thread([&model_object, &print, &result, &progress_dialog](){
|
||||||
|
boost::filesystem::path path_src = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
|
||||||
|
path_src += ".3mf";
|
||||||
|
Model model;
|
||||||
|
model.add_object(model_object);
|
||||||
|
bool res = Slic3r::store_3mf(path_src.string().c_str(), &model, const_cast<Print*>(&print), false);
|
||||||
|
model.clear_objects();
|
||||||
|
model.clear_materials();
|
||||||
|
|
||||||
|
boost::filesystem::path path_dst = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
|
||||||
|
path_dst += ".3mf";
|
||||||
|
res = fix_model_by_win10_sdk(path_src.string().c_str(), path_dst.string());
|
||||||
|
boost::filesystem::remove(path_src);
|
||||||
|
PresetBundle bundle;
|
||||||
|
res = Slic3r::load_3mf(path_dst.string().c_str(), &bundle, &result);
|
||||||
|
boost::filesystem::remove(path_dst);
|
||||||
|
});
|
||||||
|
worker.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
#endif /* HAS_WIN10SDK */
|
#endif /* HAS_WIN10SDK */
|
||||||
|
|
|
@ -3,16 +3,26 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class Model;
|
||||||
|
class ModelObject;
|
||||||
|
class Print;
|
||||||
|
|
||||||
#ifdef HAS_WIN10SDK
|
#ifdef HAS_WIN10SDK
|
||||||
|
|
||||||
extern bool is_windows10();
|
extern bool is_windows10();
|
||||||
extern bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path_dst);
|
extern bool fix_model_by_win10_sdk(const std::string &path_src, const std::string &path_dst);
|
||||||
|
extern void fix_model_by_win10_sdk_gui(const ModelObject &model_object, const Print &print, Model &result);
|
||||||
|
|
||||||
#else /* HAS_WIN10SDK */
|
#else /* HAS_WIN10SDK */
|
||||||
|
|
||||||
inline bool is_windows10() { return false; }
|
inline bool is_windows10() { return false; }
|
||||||
inline bool fix_model_by_win10_sdk(const std::string &, const std::string &) { return false; }
|
inline bool fix_model_by_win10_sdk(const std::string &, const std::string &) { return false; }
|
||||||
|
inline void fix_model_by_win10_sdk_gui(const ModelObject &, const Print &, Model &) {}
|
||||||
|
|
||||||
#endif /* HAS_WIN10SDK *
|
#endif /* HAS_WIN10SDK */
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
#endif /* slic3r_GUI_Utils_FixModelByWin10_hpp_ */
|
#endif /* slic3r_GUI_Utils_FixModelByWin10_hpp_ */
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <xsinit.h>
|
#include <xsinit.h>
|
||||||
#include "slic3r/GUI/GUI.hpp"
|
#include "slic3r/GUI/GUI.hpp"
|
||||||
#include "slic3r/Utils/ASCIIFolding.hpp"
|
#include "slic3r/Utils/ASCIIFolding.hpp"
|
||||||
|
#include "slic3r/Utils/FixModelByWin10.hpp"
|
||||||
#include "slic3r/Utils/Serial.hpp"
|
#include "slic3r/Utils/Serial.hpp"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -28,6 +29,9 @@ bool debugged()
|
||||||
void break_to_debugger()
|
void break_to_debugger()
|
||||||
%code{% Slic3r::GUI::break_to_debugger(); %};
|
%code{% Slic3r::GUI::break_to_debugger(); %};
|
||||||
|
|
||||||
|
bool is_windows10()
|
||||||
|
%code{% RETVAL=Slic3r::is_windows10(); %};
|
||||||
|
|
||||||
void set_wxapp(SV *ui)
|
void set_wxapp(SV *ui)
|
||||||
%code%{ Slic3r::GUI::set_wxapp((wxApp*)wxPli_sv_2_object(aTHX_ ui, "Wx::App")); %};
|
%code%{ Slic3r::GUI::set_wxapp((wxApp*)wxPli_sv_2_object(aTHX_ ui, "Wx::App")); %};
|
||||||
|
|
||||||
|
@ -98,3 +102,6 @@ int get_export_option(SV *ui)
|
||||||
|
|
||||||
void desktop_open_datadir_folder()
|
void desktop_open_datadir_folder()
|
||||||
%code%{ Slic3r::GUI::desktop_open_datadir_folder(); %};
|
%code%{ Slic3r::GUI::desktop_open_datadir_folder(); %};
|
||||||
|
|
||||||
|
void fix_model_by_win10_sdk_gui(ModelObject *model_object_src, Print *print, Model *model_dst)
|
||||||
|
%code%{ Slic3r::fix_model_by_win10_sdk_gui(*model_object_src, *print, *model_dst); %};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue