Merge branch 'master' of https://github.com/Prusa-Development/PrusaSlicerPrivate into et_sla_switch_view
This commit is contained in:
commit
462bdd134a
@ -131,6 +131,8 @@ set(SLIC3R_SOURCES
|
|||||||
Format/AnycubicSLA.cpp
|
Format/AnycubicSLA.cpp
|
||||||
Format/STEP.hpp
|
Format/STEP.hpp
|
||||||
Format/STEP.cpp
|
Format/STEP.cpp
|
||||||
|
Format/SLAArchiveFormatRegistry.hpp
|
||||||
|
Format/SLAArchiveFormatRegistry.cpp
|
||||||
GCode/ThumbnailData.cpp
|
GCode/ThumbnailData.cpp
|
||||||
GCode/ThumbnailData.hpp
|
GCode/ThumbnailData.hpp
|
||||||
GCode/Thumbnails.cpp
|
GCode/Thumbnails.cpp
|
||||||
|
@ -4,44 +4,14 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "SLAArchiveWriter.hpp"
|
#include "SLAArchiveWriter.hpp"
|
||||||
|
#include "SLAArchiveFormatRegistry.hpp"
|
||||||
|
|
||||||
#include "libslic3r/PrintConfig.hpp"
|
#include "libslic3r/PrintConfig.hpp"
|
||||||
|
|
||||||
#define ANYCUBIC_SLA_FORMAT_VERSION_1 1
|
constexpr uint16_t ANYCUBIC_SLA_FORMAT_VERSION_1 = 1;
|
||||||
#define ANYCUBIC_SLA_FORMAT_VERSION_515 515
|
constexpr uint16_t ANYCUBIC_SLA_FORMAT_VERSION_515 = 515;
|
||||||
#define ANYCUBIC_SLA_FORMAT_VERSION_516 516
|
constexpr uint16_t ANYCUBIC_SLA_FORMAT_VERSION_516 = 516;
|
||||||
#define ANYCUBIC_SLA_FORMAT_VERSION_517 517
|
constexpr uint16_t ANYCUBIC_SLA_FORMAT_VERSION_517 = 517;
|
||||||
|
|
||||||
#define ANYCUBIC_SLA_FORMAT_VERSIONED(FILEFORMAT, NAME, VERSION) \
|
|
||||||
{ FILEFORMAT, { FILEFORMAT, [] (const auto &cfg) { return std::make_unique<AnycubicSLAArchive>(cfg, VERSION); } } }
|
|
||||||
|
|
||||||
#define ANYCUBIC_SLA_FORMAT(FILEFORMAT, NAME) \
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED(FILEFORMAT, NAME, ANYCUBIC_SLA_FORMAT_VERSION_1)
|
|
||||||
|
|
||||||
/**
|
|
||||||
// Supports only ANYCUBIC_SLA_VERSION_1
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pws", "Photon / Photon S", ANYCUBIC_SLA_VERSION_1),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pw0", "Photon Zero", ANYCUBIC_SLA_VERSION_1),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pwx", "Photon X", ANYCUBIC_SLA_VERSION_1),
|
|
||||||
|
|
||||||
// Supports ANYCUBIC_SLA_VERSION_1 and ANYCUBIC_SLA_VERSION_515
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pwmo", "Photon Mono", ANYCUBIC_SLA_VERSION_1),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pwms", "Photon Mono SE", ANYCUBIC_SLA_VERSION_1),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("dlp", "Photon Ultra", ANYCUBIC_SLA_VERSION_1),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pwmx", "Photon Mono X", ANYCUBIC_SLA_VERSION_1),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pmsq", "Photon Mono SQ", ANYCUBIC_SLA_VERSION_1),
|
|
||||||
|
|
||||||
// Supports ANYCUBIC_SLA_VERSION_515 and ANYCUBIC_SLA_VERSION_516
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pwma", "Photon Mono 4K", ANYCUBIC_SLA_VERSION_515),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pm3", "Photon M3", ANYCUBIC_SLA_VERSION_515),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pm3m", "Photon M3 Max", ANYCUBIC_SLA_VERSION_515),
|
|
||||||
|
|
||||||
// Supports NYCUBIC_SLA_VERSION_515 and ANYCUBIC_SLA_VERSION_516 and ANYCUBIC_SLA_VERSION_517
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pwmb", "Photon Mono X 6K / Photon M3 Plus", ANYCUBIC_SLA_VERSION_515),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("dl2p", "Photon Photon D2", ANYCUBIC_SLA_VERSION_515),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pmx2", "Photon Mono X2", ANYCUBIC_SLA_VERSION_515),
|
|
||||||
ANYCUBIC_SLA_FORMAT_VERSIONED("pm3r", "Photon M3 Premium", ANYCUBIC_SLA_VERSION_515),
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
@ -75,6 +45,21 @@ public:
|
|||||||
const std::string &projectname = "") override;
|
const std::string &projectname = "") override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline Slic3r::ArchiveEntry anycubic_sla_format_versioned(const char *fileformat, const char *desc, uint16_t version)
|
||||||
|
{
|
||||||
|
Slic3r::ArchiveEntry entry(fileformat);
|
||||||
|
|
||||||
|
entry.desc = desc;
|
||||||
|
entry.ext = fileformat;
|
||||||
|
entry.wrfactoryfn = [version] (const auto &cfg) { return std::make_unique<AnycubicSLAArchive>(cfg, version); };
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Slic3r::ArchiveEntry anycubic_sla_format(const char *fileformat, const char *desc)
|
||||||
|
{
|
||||||
|
return anycubic_sla_format_versioned(fileformat, desc, ANYCUBIC_SLA_FORMAT_VERSION_1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r::sla
|
} // namespace Slic3r::sla
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "libslic3r/GCode/ThumbnailData.hpp"
|
#include "libslic3r/GCode/ThumbnailData.hpp"
|
||||||
|
|
||||||
#include "SLAArchiveReader.hpp"
|
#include "SLAArchiveReader.hpp"
|
||||||
|
#include "SLAArchiveFormatRegistry.hpp"
|
||||||
#include "ZipperArchiveImport.hpp"
|
#include "ZipperArchiveImport.hpp"
|
||||||
|
|
||||||
#include "libslic3r/MarchingSquares.hpp"
|
#include "libslic3r/MarchingSquares.hpp"
|
||||||
@ -26,6 +27,7 @@
|
|||||||
|
|
||||||
#include "libslic3r/SLA/RasterBase.hpp"
|
#include "libslic3r/SLA/RasterBase.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
147
src/libslic3r/Format/SLAArchiveFormatRegistry.cpp
Normal file
147
src/libslic3r/Format/SLAArchiveFormatRegistry.cpp
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#include <set>
|
||||||
|
#include <mutex>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "SL1.hpp"
|
||||||
|
#include "SL1_SVG.hpp"
|
||||||
|
#include "AnycubicSLA.hpp"
|
||||||
|
|
||||||
|
#include "SLAArchiveFormatRegistry.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
static std::mutex arch_mtx;
|
||||||
|
|
||||||
|
class Registry {
|
||||||
|
static std::unique_ptr<Registry> registry;
|
||||||
|
|
||||||
|
std::set<ArchiveEntry> entries;
|
||||||
|
public:
|
||||||
|
|
||||||
|
Registry ()
|
||||||
|
{
|
||||||
|
entries = {
|
||||||
|
{
|
||||||
|
"SL1", // id
|
||||||
|
L("SL1 archive format"), // description
|
||||||
|
"sl1", // main extension
|
||||||
|
{"sl1s", "zip"}, // extension aliases
|
||||||
|
|
||||||
|
// Writer factory
|
||||||
|
[] (const auto &cfg) { return std::make_unique<SL1Archive>(cfg); },
|
||||||
|
|
||||||
|
// Reader factory
|
||||||
|
[] (const std::string &fname, SLAImportQuality quality, const ProgrFn &progr) {
|
||||||
|
return std::make_unique<SL1Reader>(fname, quality, progr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"SL1SVG",
|
||||||
|
L("SL1SVG archive files"),
|
||||||
|
"sl1_svg",
|
||||||
|
{},
|
||||||
|
[] (const auto &cfg) { return std::make_unique<SL1_SVGArchive>(cfg); },
|
||||||
|
[] (const std::string &fname, SLAImportQuality quality, const ProgrFn &progr) {
|
||||||
|
return std::make_unique<SL1_SVGReader>(fname, quality, progr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"SL2",
|
||||||
|
"",
|
||||||
|
"sl1_svg",
|
||||||
|
{},
|
||||||
|
[] (const auto &cfg) { return std::make_unique<SL1_SVGArchive>(cfg); },
|
||||||
|
nullptr
|
||||||
|
},
|
||||||
|
anycubic_sla_format("pwmo", "Photon Mono"),
|
||||||
|
anycubic_sla_format("pwmx", "Photon Mono X"),
|
||||||
|
anycubic_sla_format("pwms", "Photon Mono SE"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
// Supports only ANYCUBIC_SLA_VERSION_1
|
||||||
|
anycubic_sla_format_versioned("pws", "Photon / Photon S", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
anycubic_sla_format_versioned("pw0", "Photon Zero", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
anycubic_sla_format_versioned("pwx", "Photon X", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
|
||||||
|
// Supports ANYCUBIC_SLA_VERSION_1 and ANYCUBIC_SLA_VERSION_515
|
||||||
|
anycubic_sla_format_versioned("pwmo", "Photon Mono", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
anycubic_sla_format_versioned("pwms", "Photon Mono SE", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
anycubic_sla_format_versioned("dlp", "Photon Ultra", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
anycubic_sla_format_versioned("pwmx", "Photon Mono X", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
anycubic_sla_format_versioned("pmsq", "Photon Mono SQ", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
|
||||||
|
// Supports ANYCUBIC_SLA_VERSION_515 and ANYCUBIC_SLA_VERSION_516
|
||||||
|
anycubic_sla_format_versioned("pwma", "Photon Mono 4K", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
anycubic_sla_format_versioned("pm3", "Photon M3", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
anycubic_sla_format_versioned("pm3m", "Photon M3 Max", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
|
||||||
|
// Supports NYCUBIC_SLA_VERSION_515 and ANYCUBIC_SLA_VERSION_516 and ANYCUBIC_SLA_VERSION_517
|
||||||
|
anycubic_sla_format_versioned("pwmb", "Photon Mono X 6K / Photon M3 Plus", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
anycubic_sla_format_versioned("dl2p", "Photon Photon D2", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
anycubic_sla_format_versioned("pmx2", "Photon Mono X2", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
anycubic_sla_format_versioned("pm3r", "Photon M3 Premium", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static Registry& get_instance()
|
||||||
|
{
|
||||||
|
if (!registry)
|
||||||
|
registry = std::make_unique<Registry>();
|
||||||
|
|
||||||
|
return *registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::set<ArchiveEntry>& get()
|
||||||
|
{
|
||||||
|
return get_instance().entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<ArchiveEntry>& get_entries() { return entries; }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<Registry> Registry::registry = nullptr;
|
||||||
|
|
||||||
|
std::set<ArchiveEntry> registered_sla_archives()
|
||||||
|
{
|
||||||
|
std::lock_guard lk{arch_mtx};
|
||||||
|
|
||||||
|
return Registry::get();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> get_extensions(const ArchiveEntry &entry)
|
||||||
|
{
|
||||||
|
auto ret = reserve_vector<std::string>(entry.ext_aliases.size() + 1);
|
||||||
|
|
||||||
|
ret.emplace_back(entry.ext);
|
||||||
|
for (const char *alias : entry.ext_aliases)
|
||||||
|
ret.emplace_back(alias);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveWriterFactory get_writer_factory(const char *formatid)
|
||||||
|
{
|
||||||
|
std::lock_guard lk{arch_mtx};
|
||||||
|
|
||||||
|
ArchiveWriterFactory ret;
|
||||||
|
auto entry = Registry::get().find(ArchiveEntry{formatid});
|
||||||
|
if (entry != Registry::get().end())
|
||||||
|
ret = entry->wrfactoryfn;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveReaderFactory get_reader_factory(const char *formatid)
|
||||||
|
{
|
||||||
|
std::lock_guard lk{arch_mtx};
|
||||||
|
|
||||||
|
ArchiveReaderFactory ret;
|
||||||
|
auto entry = Registry::get().find(ArchiveEntry{formatid});
|
||||||
|
if (entry != Registry::get().end())
|
||||||
|
ret = entry->rdfactoryfn;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Slic3r::sla
|
71
src/libslic3r/Format/SLAArchiveFormatRegistry.hpp
Normal file
71
src/libslic3r/Format/SLAArchiveFormatRegistry.hpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef SLA_ARCHIVE_FORMAT_REGISTRY_HPP
|
||||||
|
#define SLA_ARCHIVE_FORMAT_REGISTRY_HPP
|
||||||
|
|
||||||
|
#include "SLAArchiveWriter.hpp"
|
||||||
|
#include "SLAArchiveReader.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// Factory function that returns an implementation of SLAArchiveWriter given
|
||||||
|
// a printer configuration.
|
||||||
|
using ArchiveWriterFactory = std::function<
|
||||||
|
std::unique_ptr<SLAArchiveWriter>(const SLAPrinterConfig &)
|
||||||
|
>;
|
||||||
|
|
||||||
|
// Factory function that returns an implementation of SLAArchiveReader
|
||||||
|
using ArchiveReaderFactory = std::function<
|
||||||
|
std::unique_ptr<SLAArchiveReader>(const std::string &fname,
|
||||||
|
SLAImportQuality quality,
|
||||||
|
const ProgrFn & progr)
|
||||||
|
>;
|
||||||
|
|
||||||
|
struct ArchiveEntry {
|
||||||
|
// Main ID for the format, for internal unique identification
|
||||||
|
const char *id;
|
||||||
|
|
||||||
|
// Generic description (usable in GUI) about an archive format. Should only
|
||||||
|
// be marked for localization (macro L).
|
||||||
|
const char *desc = "";
|
||||||
|
|
||||||
|
// Main extension of the format.
|
||||||
|
const char *ext = "zip";
|
||||||
|
|
||||||
|
ArchiveWriterFactory wrfactoryfn;
|
||||||
|
ArchiveReaderFactory rdfactoryfn;
|
||||||
|
|
||||||
|
// Secondary, alias extensions
|
||||||
|
std::vector<const char *> ext_aliases;
|
||||||
|
|
||||||
|
explicit ArchiveEntry(const char *formatid) : id{formatid} {}
|
||||||
|
|
||||||
|
ArchiveEntry(const char *formatid,
|
||||||
|
const char *description,
|
||||||
|
const char *extension,
|
||||||
|
std::initializer_list<const char *> extaliases,
|
||||||
|
const ArchiveWriterFactory &wrfn,
|
||||||
|
const ArchiveReaderFactory &rdfn)
|
||||||
|
: id{formatid}
|
||||||
|
, desc{description}
|
||||||
|
, ext{extension}
|
||||||
|
, ext_aliases{extaliases}
|
||||||
|
, wrfactoryfn{wrfn}
|
||||||
|
, rdfactoryfn{rdfn}
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator <(const ArchiveEntry &other) const
|
||||||
|
{
|
||||||
|
return std::strcmp(id, other.id) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> get_extensions(const ArchiveEntry &entry);
|
||||||
|
|
||||||
|
std::set<ArchiveEntry> registered_sla_archives();
|
||||||
|
|
||||||
|
ArchiveWriterFactory get_writer_factory(const char *formatid);
|
||||||
|
ArchiveReaderFactory get_reader_factory(const char *formatid);
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif // ARCHIVEREGISTRY_HPP
|
@ -8,44 +8,13 @@
|
|||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#include "SLAArchiveFormatRegistry.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// Factory function that returns an implementation of SLAArchiveReader.
|
|
||||||
using ArchiveFactory = std::function<
|
|
||||||
std::unique_ptr<SLAArchiveReader>(const std::string &fname,
|
|
||||||
SLAImportQuality quality,
|
|
||||||
const ProgrFn & progr)>;
|
|
||||||
|
|
||||||
// Entry in the global registry of readable archive formats.
|
|
||||||
struct ArchiveEntry {
|
|
||||||
const char *descr;
|
|
||||||
std::vector<const char *> extensions;
|
|
||||||
ArchiveFactory factoryfn;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is where the readable archive formats are registered.
|
|
||||||
static const std::map<std::string, ArchiveEntry> REGISTERED_ARCHIVES {
|
|
||||||
{
|
|
||||||
"SL1",
|
|
||||||
{ L("SL1 / SL1S archive files"), {"sl1", "sl1s", "zip"},
|
|
||||||
[] (const std::string &fname, SLAImportQuality quality, const ProgrFn &progr) { return std::make_unique<SL1Reader>(fname, quality, progr); } }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"SL1SVG",
|
|
||||||
{ L("SL1SVG archive files"), {"sl1_svg"/*, "zip"*/}, // also a zip but unnecessary hassle to implement single extension for multiple archives
|
|
||||||
[] (const std::string &fname, SLAImportQuality quality, const ProgrFn &progr) { return std::make_unique<SL1_SVGReader>(fname, quality, progr); }}
|
|
||||||
},
|
|
||||||
// TODO: pwmx and future others.
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
std::unique_ptr<SLAArchiveReader> SLAArchiveReader::create(
|
std::unique_ptr<SLAArchiveReader> SLAArchiveReader::create(
|
||||||
const std::string &fname,
|
const std::string &fname,
|
||||||
const std::string &format_id,
|
const std::string &format_id,
|
||||||
@ -64,11 +33,13 @@ std::unique_ptr<SLAArchiveReader> SLAArchiveReader::create(
|
|||||||
|
|
||||||
std::unique_ptr<SLAArchiveReader> ret;
|
std::unique_ptr<SLAArchiveReader> ret;
|
||||||
|
|
||||||
auto arch_from = REGISTERED_ARCHIVES.begin();
|
auto registry = registered_sla_archives();
|
||||||
auto arch_to = REGISTERED_ARCHIVES.end();
|
|
||||||
|
|
||||||
auto arch_it = REGISTERED_ARCHIVES.find(format_id);
|
auto arch_from = registry.begin();
|
||||||
if (arch_it != REGISTERED_ARCHIVES.end()) {
|
auto arch_to = registry.end();
|
||||||
|
|
||||||
|
auto arch_it = registry.find(ArchiveEntry{format_id.c_str()});
|
||||||
|
if (arch_it != registry.end()) {
|
||||||
arch_from = arch_it;
|
arch_from = arch_it;
|
||||||
arch_to = arch_it;
|
arch_to = arch_it;
|
||||||
}
|
}
|
||||||
@ -77,52 +48,23 @@ std::unique_ptr<SLAArchiveReader> SLAArchiveReader::create(
|
|||||||
if (ext.front() == '.')
|
if (ext.front() == '.')
|
||||||
ext.erase(ext.begin());
|
ext.erase(ext.begin());
|
||||||
|
|
||||||
auto extcmp = [&ext](const auto &e) { return e == ext; };
|
for (auto it = arch_from; !ret && it != arch_to; ++it) {
|
||||||
|
const auto &entry = *it;
|
||||||
for (auto it = arch_from; it != arch_to; ++it) {
|
if (entry.rdfactoryfn) {
|
||||||
const auto &[format_id, entry] = *it;
|
auto extensions = get_extensions(entry);
|
||||||
if (std::any_of(entry.extensions.begin(), entry.extensions.end(), extcmp))
|
for (const std::string& supportedext : extensions) {
|
||||||
ret = entry.factoryfn(fname, quality, progr);
|
if (ext == supportedext) {
|
||||||
|
ret = entry.rdfactoryfn(fname, quality, progr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<const char *> &SLAArchiveReader::registered_archives()
|
|
||||||
{
|
|
||||||
static std::vector<const char*> archnames;
|
|
||||||
|
|
||||||
if (archnames.empty()) {
|
|
||||||
archnames.reserve(REGISTERED_ARCHIVES.size());
|
|
||||||
|
|
||||||
for (auto &[name, _] : REGISTERED_ARCHIVES)
|
|
||||||
archnames.emplace_back(name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
return archnames;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const char *> SLAArchiveReader::get_extensions(const char *archtype)
|
|
||||||
{
|
|
||||||
auto it = REGISTERED_ARCHIVES.find(archtype);
|
|
||||||
|
|
||||||
if (it != REGISTERED_ARCHIVES.end())
|
|
||||||
return it->second.extensions;
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *SLAArchiveReader::get_description(const char *archtype)
|
|
||||||
{
|
|
||||||
auto it = REGISTERED_ARCHIVES.find(archtype);
|
|
||||||
|
|
||||||
if (it != REGISTERED_ARCHIVES.end())
|
|
||||||
return it->second.descr;
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SliceParams { double layerh = 0., initial_layerh = 0.; };
|
struct SliceParams { double layerh = 0., initial_layerh = 0.; };
|
||||||
|
|
||||||
static SliceParams get_slice_params(const DynamicPrintConfig &cfg)
|
static SliceParams get_slice_params(const DynamicPrintConfig &cfg)
|
||||||
|
@ -47,15 +47,6 @@ public:
|
|||||||
const std::string &format_id,
|
const std::string &format_id,
|
||||||
SLAImportQuality quality = SLAImportQuality::Balanced,
|
SLAImportQuality quality = SLAImportQuality::Balanced,
|
||||||
const ProgrFn &progr = [](int) { return false; });
|
const ProgrFn &progr = [](int) { return false; });
|
||||||
|
|
||||||
// Get the names of currently known archive reader implementations
|
|
||||||
static const std::vector<const char *> & registered_archives();
|
|
||||||
|
|
||||||
// Get the understood file extensions belonging to an archive format
|
|
||||||
static std::vector<const char *> get_extensions(const char *archtype);
|
|
||||||
|
|
||||||
// Generic description (usable in GUI) about an archive format
|
|
||||||
static const char * get_description(const char *archtype);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Raised in import_sla_archive when a nullptr reader is returned by
|
// Raised in import_sla_archive when a nullptr reader is returned by
|
||||||
|
@ -1,77 +1,18 @@
|
|||||||
#include "SLAArchiveWriter.hpp"
|
#include "SLAArchiveWriter.hpp"
|
||||||
|
#include "SLAArchiveFormatRegistry.hpp"
|
||||||
#include "SL1.hpp"
|
|
||||||
#include "SL1_SVG.hpp"
|
|
||||||
#include "AnycubicSLA.hpp"
|
|
||||||
|
|
||||||
#include "libslic3r/libslic3r.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
using ArchiveFactory = std::function<std::unique_ptr<SLAArchiveWriter>(const SLAPrinterConfig&)>;
|
|
||||||
|
|
||||||
struct ArchiveEntry {
|
|
||||||
const char *ext;
|
|
||||||
ArchiveFactory factoryfn;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const std::map<std::string, ArchiveEntry> REGISTERED_ARCHIVES {
|
|
||||||
{
|
|
||||||
"SL1",
|
|
||||||
{ "sl1", [] (const auto &cfg) { return std::make_unique<SL1Archive>(cfg); } }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"SL1SVG",
|
|
||||||
{ "sl1_svg", [] (const auto &cfg) { return std::make_unique<SL1_SVGArchive>(cfg); } }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"SL2",
|
|
||||||
{ "sl1_svg", [] (const auto &cfg) { return std::make_unique<SL1_SVGArchive>(cfg); } }
|
|
||||||
},
|
|
||||||
ANYCUBIC_SLA_FORMAT("pwmo", "Photon Mono"),
|
|
||||||
ANYCUBIC_SLA_FORMAT("pwmx", "Photon Mono X"),
|
|
||||||
ANYCUBIC_SLA_FORMAT("pwms", "Photon Mono SE"),
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<SLAArchiveWriter>
|
std::unique_ptr<SLAArchiveWriter>
|
||||||
SLAArchiveWriter::create(const std::string &archtype, const SLAPrinterConfig &cfg)
|
SLAArchiveWriter::create(const std::string &archtype, const SLAPrinterConfig &cfg)
|
||||||
{
|
{
|
||||||
auto entry = REGISTERED_ARCHIVES.find(archtype);
|
std::unique_ptr<SLAArchiveWriter> ret;
|
||||||
|
auto factory = get_writer_factory(archtype.c_str());
|
||||||
|
|
||||||
if (entry != REGISTERED_ARCHIVES.end())
|
if (factory)
|
||||||
return entry->second.factoryfn(cfg);
|
ret = factory(cfg);
|
||||||
|
|
||||||
return nullptr;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<const char*>& SLAArchiveWriter::registered_archives()
|
|
||||||
{
|
|
||||||
static std::vector<const char*> archnames;
|
|
||||||
|
|
||||||
if (archnames.empty()) {
|
|
||||||
archnames.reserve(REGISTERED_ARCHIVES.size());
|
|
||||||
|
|
||||||
for (auto &[name, _] : REGISTERED_ARCHIVES)
|
|
||||||
archnames.emplace_back(name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
return archnames;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *SLAArchiveWriter::get_extension(const char *archtype)
|
|
||||||
{
|
|
||||||
constexpr const char* DEFAULT_EXT = "zip";
|
|
||||||
|
|
||||||
auto entry = REGISTERED_ARCHIVES.find(archtype);
|
|
||||||
if (entry != REGISTERED_ARCHIVES.end())
|
|
||||||
return entry->second.ext;
|
|
||||||
|
|
||||||
return DEFAULT_EXT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -53,12 +53,6 @@ public:
|
|||||||
// Factory method to create an archiver instance
|
// Factory method to create an archiver instance
|
||||||
static std::unique_ptr<SLAArchiveWriter> create(
|
static std::unique_ptr<SLAArchiveWriter> create(
|
||||||
const std::string &archtype, const SLAPrinterConfig &);
|
const std::string &archtype, const SLAPrinterConfig &);
|
||||||
|
|
||||||
// Get the names of currently known archiver implementations
|
|
||||||
static const std::vector<const char *> & registered_archives();
|
|
||||||
|
|
||||||
// Get the default file extension belonging to an archive format
|
|
||||||
static const char *get_extension(const char *archtype);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -4558,7 +4558,7 @@ static void draw_branches(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Subtract top contact layer polygons from support base.
|
// Subtract top contact layer polygons from support base.
|
||||||
SupportGeneratorLayer *top_contact_layer = top_contacts[layer_idx];
|
SupportGeneratorLayer *top_contact_layer = top_contacts.empty() ? nullptr : top_contacts[layer_idx];
|
||||||
if (top_contact_layer && ! top_contact_layer->polygons.empty() && ! base_layer_polygons.empty()) {
|
if (top_contact_layer && ! top_contact_layer->polygons.empty() && ! base_layer_polygons.empty()) {
|
||||||
base_layer_polygons = diff(base_layer_polygons, top_contact_layer->polygons);
|
base_layer_polygons = diff(base_layer_polygons, top_contact_layer->polygons);
|
||||||
if (! bottom_contact_polygons.empty())
|
if (! bottom_contact_polygons.empty())
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include "UnsavedChangesDialog.hpp"
|
#include "UnsavedChangesDialog.hpp"
|
||||||
#include "slic3r/Utils/AppUpdater.hpp"
|
#include "slic3r/Utils/AppUpdater.hpp"
|
||||||
#include "slic3r/GUI/I18N.hpp"
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
|
#include "slic3r/Config/Version.hpp"
|
||||||
|
|
||||||
#if defined(__linux__) && defined(__WXGTK3__)
|
#if defined(__linux__) && defined(__WXGTK3__)
|
||||||
#define wxLinux_gtk3 true
|
#define wxLinux_gtk3 true
|
||||||
@ -118,7 +119,7 @@ BundleMap BundleMap::load()
|
|||||||
const auto vendor_dir = (boost::filesystem::path(Slic3r::data_dir()) / "vendor").make_preferred();
|
const auto vendor_dir = (boost::filesystem::path(Slic3r::data_dir()) / "vendor").make_preferred();
|
||||||
const auto archive_dir = (boost::filesystem::path(Slic3r::data_dir()) / "cache" / "vendor").make_preferred();
|
const auto archive_dir = (boost::filesystem::path(Slic3r::data_dir()) / "cache" / "vendor").make_preferred();
|
||||||
const auto rsrc_vendor_dir = (boost::filesystem::path(resources_dir()) / "profiles").make_preferred();
|
const auto rsrc_vendor_dir = (boost::filesystem::path(resources_dir()) / "profiles").make_preferred();
|
||||||
|
const auto cache_dir = boost::filesystem::path(Slic3r::data_dir()) / "cache"; // for Index
|
||||||
// Load Prusa bundle from the datadir/vendor directory or from datadir/cache/vendor (archive) or from resources/profiles.
|
// Load Prusa bundle from the datadir/vendor directory or from datadir/cache/vendor (archive) or from resources/profiles.
|
||||||
auto prusa_bundle_path = (vendor_dir / PresetBundle::PRUSA_BUNDLE).replace_extension(".ini");
|
auto prusa_bundle_path = (vendor_dir / PresetBundle::PRUSA_BUNDLE).replace_extension(".ini");
|
||||||
BundleLocation prusa_bundle_loc = BundleLocation::IN_VENDOR;
|
BundleLocation prusa_bundle_loc = BundleLocation::IN_VENDOR;
|
||||||
@ -138,7 +139,7 @@ BundleMap BundleMap::load()
|
|||||||
|
|
||||||
// Load the other bundles in the datadir/vendor directory
|
// Load the other bundles in the datadir/vendor directory
|
||||||
// and then additionally from datadir/cache/vendor (archive) and resources/profiles.
|
// and then additionally from datadir/cache/vendor (archive) and resources/profiles.
|
||||||
// Should we concider case where archive has older profiles than resources (shouldnt happen)?
|
// Should we concider case where archive has older profiles than resources (shouldnt happen)? -> YES, it happens during re-configuration when running older PS after newer version
|
||||||
typedef std::pair<const fs::path&, BundleLocation> DirData;
|
typedef std::pair<const fs::path&, BundleLocation> DirData;
|
||||||
std::vector<DirData> dir_list { {vendor_dir, BundleLocation::IN_VENDOR}, {archive_dir, BundleLocation::IN_ARCHIVE}, {rsrc_vendor_dir, BundleLocation::IN_RESOURCES} };
|
std::vector<DirData> dir_list { {vendor_dir, BundleLocation::IN_VENDOR}, {archive_dir, BundleLocation::IN_ARCHIVE}, {rsrc_vendor_dir, BundleLocation::IN_RESOURCES} };
|
||||||
for ( auto dir : dir_list) {
|
for ( auto dir : dir_list) {
|
||||||
@ -151,6 +152,42 @@ BundleMap BundleMap::load()
|
|||||||
// Don't load this bundle if we've already loaded it.
|
// Don't load this bundle if we've already loaded it.
|
||||||
if (res.find(id) != res.end()) { continue; }
|
if (res.find(id) != res.end()) { continue; }
|
||||||
|
|
||||||
|
// Fresh index should be in archive_dir, otherwise look for it in cache
|
||||||
|
fs::path idx_path (archive_dir / (id + ".idx"));
|
||||||
|
if (!boost::filesystem::exists(idx_path)) {
|
||||||
|
BOOST_LOG_TRIVIAL(warning) << format("Missing index %1% when loading bundle %2%.", idx_path.string(), id);
|
||||||
|
idx_path = fs::path(cache_dir / (id + ".idx"));
|
||||||
|
}
|
||||||
|
if (!boost::filesystem::exists(idx_path)) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to missing index %1%.", id, idx_path.string());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Slic3r::GUI::Config::Index index;
|
||||||
|
try {
|
||||||
|
index.load(idx_path);
|
||||||
|
}
|
||||||
|
catch (const std::exception& /* err */) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to invalid index %1%.", id, idx_path.string());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto recommended_it = index.recommended();
|
||||||
|
if (recommended_it == index.end()) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to no recommended version in index %2%.", id, idx_path.string());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto recommended = recommended_it->config_version;
|
||||||
|
VendorProfile vp;
|
||||||
|
try {
|
||||||
|
vp = VendorProfile::from_ini(dir_entry, true);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to corrupted profile file %2%. Message: %3%", id, dir_entry.path().string(), e.what());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Don't load
|
||||||
|
if (vp.config_version > recommended)
|
||||||
|
continue;
|
||||||
|
|
||||||
Bundle bundle;
|
Bundle bundle;
|
||||||
if (bundle.load(dir_entry.path(), dir.second))
|
if (bundle.load(dir_entry.path(), dir.second))
|
||||||
res.emplace(std::move(id), std::move(bundle));
|
res.emplace(std::move(id), std::move(bundle));
|
||||||
|
@ -1192,6 +1192,13 @@ void ObjectList::key_event(wxKeyEvent& event)
|
|||||||
|
|
||||||
void ObjectList::OnBeginDrag(wxDataViewEvent &event)
|
void ObjectList::OnBeginDrag(wxDataViewEvent &event)
|
||||||
{
|
{
|
||||||
|
if (m_is_editing_started)
|
||||||
|
m_is_editing_started = false;
|
||||||
|
#ifdef __WXGTK__
|
||||||
|
const auto renderer = dynamic_cast<BitmapTextRenderer*>(GetColumn(colName)->GetRenderer());
|
||||||
|
renderer->FinishEditing();
|
||||||
|
#endif
|
||||||
|
|
||||||
const wxDataViewItem item(event.GetItem());
|
const wxDataViewItem item(event.GetItem());
|
||||||
|
|
||||||
const bool mult_sel = multiple_selection();
|
const bool mult_sel = multiple_selection();
|
||||||
@ -1225,18 +1232,11 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event)
|
|||||||
m_objects_model->GetInstanceIdByItem(item),
|
m_objects_model->GetInstanceIdByItem(item),
|
||||||
type);
|
type);
|
||||||
|
|
||||||
/* Under MSW or OSX, DnD moves an item to the place of another selected item
|
|
||||||
* But under GTK, DnD moves an item between another two items.
|
|
||||||
* And as a result - call EVT_CHANGE_SELECTION to unselect all items.
|
|
||||||
* To prevent such behavior use m_prevent_list_events
|
|
||||||
**/
|
|
||||||
m_prevent_list_events = true;//it's needed for GTK
|
|
||||||
|
|
||||||
/* Under GTK, DnD requires to the wxTextDataObject been initialized with some valid value,
|
/* Under GTK, DnD requires to the wxTextDataObject been initialized with some valid value,
|
||||||
* so set some nonempty string
|
* so set some nonempty string
|
||||||
*/
|
*/
|
||||||
wxTextDataObject* obj = new wxTextDataObject;
|
wxTextDataObject* obj = new wxTextDataObject;
|
||||||
obj->SetText("Some text");//it's needed for GTK
|
obj->SetText(mult_sel ? "SomeText" : m_objects_model->GetItemName(item));//it's needed for GTK
|
||||||
|
|
||||||
event.SetDataObject(obj);
|
event.SetDataObject(obj);
|
||||||
event.SetDragFlags(wxDrag_DefaultMove); // allows both copy and move;
|
event.SetDragFlags(wxDrag_DefaultMove); // allows both copy and move;
|
||||||
@ -1299,11 +1299,8 @@ bool ObjectList::can_drop(const wxDataViewItem& item) const
|
|||||||
void ObjectList::OnDropPossible(wxDataViewEvent &event)
|
void ObjectList::OnDropPossible(wxDataViewEvent &event)
|
||||||
{
|
{
|
||||||
const wxDataViewItem& item = event.GetItem();
|
const wxDataViewItem& item = event.GetItem();
|
||||||
|
if (!can_drop(item))
|
||||||
if (!can_drop(item)) {
|
|
||||||
event.Veto();
|
event.Veto();
|
||||||
m_prevent_list_events = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::OnDrop(wxDataViewEvent &event)
|
void ObjectList::OnDrop(wxDataViewEvent &event)
|
||||||
@ -1317,6 +1314,13 @@ void ObjectList::OnDrop(wxDataViewEvent &event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Under MSW or OSX, DnD moves an item to the place of another selected item
|
||||||
|
* But under GTK, DnD moves an item between another two items.
|
||||||
|
* And as a result - call EVT_CHANGE_SELECTION to unselect all items.
|
||||||
|
* To prevent such behavior use m_prevent_list_events
|
||||||
|
**/
|
||||||
|
m_prevent_list_events = true;//it's needed for GTK
|
||||||
|
|
||||||
if (m_dragged_data.type() == itInstance)
|
if (m_dragged_data.type() == itInstance)
|
||||||
{
|
{
|
||||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(),_(L("Instances to Separated Objects")));
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(),_(L("Instances to Separated Objects")));
|
||||||
@ -4819,6 +4823,9 @@ void ObjectList::sys_color_changed()
|
|||||||
|
|
||||||
void ObjectList::ItemValueChanged(wxDataViewEvent &event)
|
void ObjectList::ItemValueChanged(wxDataViewEvent &event)
|
||||||
{
|
{
|
||||||
|
if (!m_is_editing_started)
|
||||||
|
return;
|
||||||
|
|
||||||
if (event.GetColumn() == colName)
|
if (event.GetColumn() == colName)
|
||||||
update_name_in_model(event.GetItem());
|
update_name_in_model(event.GetItem());
|
||||||
else if (event.GetColumn() == colExtruder) {
|
else if (event.GetColumn() == colExtruder) {
|
||||||
@ -4841,6 +4848,9 @@ void ObjectList::OnEditingStarted(wxDataViewEvent &event)
|
|||||||
|
|
||||||
void ObjectList::OnEditingDone(wxDataViewEvent &event)
|
void ObjectList::OnEditingDone(wxDataViewEvent &event)
|
||||||
{
|
{
|
||||||
|
if (!m_is_editing_started)
|
||||||
|
return;
|
||||||
|
|
||||||
m_is_editing_started = false;
|
m_is_editing_started = false;
|
||||||
if (event.GetColumn() != colName)
|
if (event.GetColumn() != colName)
|
||||||
return;
|
return;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "libslic3r/AppConfig.hpp"
|
#include "libslic3r/AppConfig.hpp"
|
||||||
#include "libslic3r/Format/SLAArchiveReader.hpp"
|
#include "libslic3r/Format/SLAArchiveReader.hpp"
|
||||||
|
#include "libslic3r/Format/SLAArchiveFormatRegistry.hpp"
|
||||||
|
|
||||||
#include "slic3r/GUI/I18N.hpp"
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
|
|
||||||
@ -29,11 +30,16 @@ std::string get_readers_wildcard()
|
|||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
|
||||||
for (const char *archtype : SLAArchiveReader::registered_archives()) {
|
auto registry = registered_sla_archives();
|
||||||
ret += into_u8(_(SLAArchiveReader::get_description(archtype)));
|
|
||||||
|
for (const ArchiveEntry &entry : registry) {
|
||||||
|
if (!entry.rdfactoryfn)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret += into_u8(_(entry.desc));
|
||||||
ret += " (";
|
ret += " (";
|
||||||
auto extensions = SLAArchiveReader::get_extensions(archtype);
|
std::vector<std::string> extensions = get_extensions(entry);
|
||||||
for (const char * ext : extensions) {
|
for (const std::string &ext : extensions) {
|
||||||
ret += "*.";
|
ret += "*.";
|
||||||
ret += ext;
|
ret += ext;
|
||||||
ret += ", ";
|
ret += ", ";
|
||||||
|
@ -1042,6 +1042,16 @@ int ObjectDataViewModel::GetItemIdByLayerRange(const int obj_idx, const t_layer
|
|||||||
return GetLayerIdByItem(item);
|
return GetLayerIdByItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString ObjectDataViewModel::GetItemName(const wxDataViewItem &item) const
|
||||||
|
{
|
||||||
|
if (!item.IsOk())
|
||||||
|
return wxEmptyString;
|
||||||
|
ObjectDataViewModelNode* node = static_cast<ObjectDataViewModelNode*>(item.GetID());
|
||||||
|
if (!node)
|
||||||
|
return wxEmptyString;
|
||||||
|
return node->GetName();
|
||||||
|
}
|
||||||
|
|
||||||
int ObjectDataViewModel::GetIdByItem(const wxDataViewItem& item) const
|
int ObjectDataViewModel::GetIdByItem(const wxDataViewItem& item) const
|
||||||
{
|
{
|
||||||
if(!item.IsOk())
|
if(!item.IsOk())
|
||||||
|
@ -311,6 +311,7 @@ public:
|
|||||||
wxDataViewItem GetItemByLayerId(int obj_idx, int layer_idx);
|
wxDataViewItem GetItemByLayerId(int obj_idx, int layer_idx);
|
||||||
wxDataViewItem GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range);
|
wxDataViewItem GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range);
|
||||||
int GetItemIdByLayerRange(const int obj_idx, const t_layer_height_range& layer_range);
|
int GetItemIdByLayerRange(const int obj_idx, const t_layer_height_range& layer_range);
|
||||||
|
wxString GetItemName(const wxDataViewItem& item) const;
|
||||||
int GetIdByItem(const wxDataViewItem& item) const;
|
int GetIdByItem(const wxDataViewItem& item) const;
|
||||||
int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const;
|
int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const;
|
||||||
int GetObjectIdByItem(const wxDataViewItem& item) const;
|
int GetObjectIdByItem(const wxDataViewItem& item) const;
|
||||||
|
@ -961,7 +961,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version
|
|||||||
BOOST_LOG_TRIVIAL(error) << format("Cannot load the installed index at `%1%`: %2%", bundle_path_idx, err.what());
|
BOOST_LOG_TRIVIAL(error) << format("Cannot load the installed index at `%1%`: %2%", bundle_path_idx, err.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
// Check if the update is already present in a snapshot
|
// Check if the update is already present in a snapshot
|
||||||
if(!current_not_supported)
|
if(!current_not_supported)
|
||||||
{
|
{
|
||||||
@ -974,7 +974,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // 0
|
||||||
updates.updates.emplace_back(std::move(new_update));
|
updates.updates.emplace_back(std::move(new_update));
|
||||||
// 'Install' the index in the vendor directory. This is used to memoize
|
// 'Install' the index in the vendor directory. This is used to memoize
|
||||||
// offered updates and to not offer the same update again if it was cancelled by the user.
|
// offered updates and to not offer the same update again if it was cancelled by the user.
|
||||||
@ -1320,7 +1320,35 @@ bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vector<std::string
|
|||||||
bool is_in_rsrc = fs::exists(path_in_rsrc);
|
bool is_in_rsrc = fs::exists(path_in_rsrc);
|
||||||
bool is_in_cache_vendor = fs::exists(path_in_cache_vendor) && !fs::is_empty(path_in_cache_vendor);
|
bool is_in_cache_vendor = fs::exists(path_in_cache_vendor) && !fs::is_empty(path_in_cache_vendor);
|
||||||
|
|
||||||
// find if in cache vendor is newer version than in resources
|
// Find if in cache vendor is newer version than in resources.
|
||||||
|
// But we also need to mind too new versions - have to read index.
|
||||||
|
|
||||||
|
// Fresh index should be in archive_dir, otherwise look for it in cache
|
||||||
|
fs::path idx_path (path_in_cache_vendor);
|
||||||
|
idx_path.replace_extension(".idx");
|
||||||
|
if (!boost::filesystem::exists(idx_path)) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << GUI::format("Couldn't locate idx file %1% when performing updates.", idx_path.string());
|
||||||
|
idx_path = fs::path(p->cache_path / idx_path.filename());
|
||||||
|
}
|
||||||
|
if (!boost::filesystem::exists(idx_path)) {
|
||||||
|
std::string msg = GUI::format(_L("Couldn't locate index file for vendor %1% when performing updates. The profile will not be installed."), bundle);
|
||||||
|
BOOST_LOG_TRIVIAL(error) << msg;
|
||||||
|
GUI::show_error(nullptr, msg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Slic3r::GUI::Config::Index index;
|
||||||
|
try {
|
||||||
|
index.load(idx_path);
|
||||||
|
}
|
||||||
|
catch (const std::exception& /* err */) {
|
||||||
|
std::string msg = GUI::format(_L("Couldn't load index file for vendor %1% when performing updates. The profile will not be installed. Reason: Corrupted index file %2%."), bundle, idx_path.string());
|
||||||
|
BOOST_LOG_TRIVIAL(error) << msg;
|
||||||
|
GUI::show_error(nullptr, msg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto recommended_it = index.recommended();
|
||||||
|
const auto recommended = recommended_it->config_version;
|
||||||
|
|
||||||
if (is_in_cache_vendor) {
|
if (is_in_cache_vendor) {
|
||||||
Semver version_cache = Semver::zero();
|
Semver version_cache = Semver::zero();
|
||||||
try {
|
try {
|
||||||
@ -1329,13 +1357,11 @@ bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vector<std::string
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
BOOST_LOG_TRIVIAL(error) << format("Corrupted profile file for vendor %1%, message: %2%", path_in_cache_vendor, e.what());
|
BOOST_LOG_TRIVIAL(error) << format("Corrupted profile file for vendor %1%, message: %2%", path_in_cache_vendor, e.what());
|
||||||
// lets use file in resources
|
version_cache = Semver::zero();
|
||||||
if (is_in_rsrc) {
|
|
||||||
updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", "");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
if (version_cache > recommended)
|
||||||
|
version_cache = Semver::zero();
|
||||||
|
|
||||||
Semver version_rsrc = Semver::zero();
|
Semver version_rsrc = Semver::zero();
|
||||||
try {
|
try {
|
||||||
if (is_in_rsrc) {
|
if (is_in_rsrc) {
|
||||||
@ -1345,26 +1371,33 @@ bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vector<std::string
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
BOOST_LOG_TRIVIAL(error) << format("Corrupted profile file for vendor %1%, message: %2%", path_in_rsrc, e.what());
|
BOOST_LOG_TRIVIAL(error) << format("Corrupted profile file for vendor %1%, message: %2%", path_in_rsrc, e.what());
|
||||||
continue;
|
//continue;
|
||||||
|
version_rsrc = Semver::zero();
|
||||||
}
|
}
|
||||||
|
// Should not happen!
|
||||||
|
if (version_rsrc > recommended)
|
||||||
|
version_rsrc = Semver::zero();
|
||||||
|
|
||||||
if (!is_in_rsrc || version_cache > version_rsrc) {
|
if (version_cache == Semver::zero() && version_rsrc == Semver::zero()) {
|
||||||
// in case we are installing from cache / vendor. we should also copy index to cache
|
std::string msg = GUI::format(_L("Couldn't open profile file for vendor %1% when performing updates. The profile will not be installed. This installation might be corrupted."), bundle);
|
||||||
// This needs to be done now bcs the current one would be missing this version on next start
|
BOOST_LOG_TRIVIAL(error) << msg;
|
||||||
// dk: Should we copy it to vendor dir too?
|
GUI::show_error(nullptr, msg);
|
||||||
auto path_idx_cache_vendor(path_in_cache_vendor);
|
continue;
|
||||||
path_idx_cache_vendor.replace_extension(".idx");
|
} else if (version_cache == Semver::zero()) {
|
||||||
auto path_idx_cache = (p->cache_path / bundle).replace_extension(".idx");
|
// cache vendor cannot be used, use resources
|
||||||
// DK: do this during perform_updates() too?
|
updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", "");
|
||||||
if (fs::exists(path_idx_cache_vendor))
|
} else if (version_rsrc == Semver::zero()) {
|
||||||
copy_file_fix(path_idx_cache_vendor, path_idx_cache);
|
// resources cannto be used, use cache vendor
|
||||||
else // Should we dialog this?
|
updates.updates.emplace_back(std::move(path_in_cache_vendor), std::move(path_in_vendors), Version(), "", "");
|
||||||
BOOST_LOG_TRIVIAL(error) << GUI::format(_L("Couldn't locate idx file %1% when performing updates."), path_idx_cache_vendor.string());
|
} else if (version_cache > version_rsrc) {
|
||||||
|
// in case we are installing from cache / vendor. we should also copy index to cache
|
||||||
|
// This needs to be done now bcs the current one would be missing this version on the next start
|
||||||
|
auto path_idx_cache = (p->cache_path / bundle).replace_extension(".idx");
|
||||||
|
if (idx_path != path_idx_cache)
|
||||||
|
copy_file_fix(idx_path, path_idx_cache);
|
||||||
updates.updates.emplace_back(std::move(path_in_cache_vendor), std::move(path_in_vendors), Version(), "", "");
|
updates.updates.emplace_back(std::move(path_in_cache_vendor), std::move(path_in_vendors), Version(), "", "");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (is_in_rsrc)
|
updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", "");
|
||||||
updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", "");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (! is_in_rsrc) {
|
if (! is_in_rsrc) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "libslic3r/SLAPrint.hpp"
|
#include "libslic3r/SLAPrint.hpp"
|
||||||
#include "libslic3r/TriangleMesh.hpp"
|
#include "libslic3r/TriangleMesh.hpp"
|
||||||
|
#include "libslic3r/Format/SLAArchiveFormatRegistry.hpp"
|
||||||
#include "libslic3r/Format/SLAArchiveWriter.hpp"
|
#include "libslic3r/Format/SLAArchiveWriter.hpp"
|
||||||
#include "libslic3r/Format/SLAArchiveReader.hpp"
|
#include "libslic3r/Format/SLAArchiveReader.hpp"
|
||||||
|
|
||||||
@ -11,16 +12,18 @@
|
|||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
|
|
||||||
TEST_CASE("Archive export test", "[sla_archives]") {
|
TEST_CASE("Archive export test", "[sla_archives]") {
|
||||||
|
auto registry = registered_sla_archives();
|
||||||
|
|
||||||
for (const char * pname : {"20mm_cube", "extruder_idler"})
|
for (const char * pname : {"20mm_cube", "extruder_idler"})
|
||||||
for (auto &archname : SLAArchiveWriter::registered_archives()) {
|
for (const ArchiveEntry &entry : registry) {
|
||||||
INFO(std::string("Testing archive type: ") + archname + " -- writing...");
|
INFO(std::string("Testing archive type: ") + entry.id + " -- writing...");
|
||||||
SLAPrint print;
|
SLAPrint print;
|
||||||
SLAFullPrintConfig fullcfg;
|
SLAFullPrintConfig fullcfg;
|
||||||
|
|
||||||
auto m = Model::read_from_file(TEST_DATA_DIR PATH_SEPARATOR + std::string(pname) + ".obj", nullptr);
|
auto m = Model::read_from_file(TEST_DATA_DIR PATH_SEPARATOR + std::string(pname) + ".obj", nullptr);
|
||||||
|
|
||||||
fullcfg.printer_technology.setInt(ptSLA); // FIXME this should be ensured
|
fullcfg.printer_technology.setInt(ptSLA); // FIXME this should be ensured
|
||||||
fullcfg.set("sla_archive_format", archname);
|
fullcfg.set("sla_archive_format", entry.id);
|
||||||
fullcfg.set("supports_enable", false);
|
fullcfg.set("supports_enable", false);
|
||||||
fullcfg.set("pad_enable", false);
|
fullcfg.set("pad_enable", false);
|
||||||
|
|
||||||
@ -32,7 +35,7 @@ TEST_CASE("Archive export test", "[sla_archives]") {
|
|||||||
print.process();
|
print.process();
|
||||||
|
|
||||||
ThumbnailsList thumbnails;
|
ThumbnailsList thumbnails;
|
||||||
auto outputfname = std::string("output_") + pname + "." + SLAArchiveWriter::get_extension(archname);
|
auto outputfname = std::string("output_") + pname + "." + entry.ext;
|
||||||
|
|
||||||
print.export_print(outputfname, thumbnails, pname);
|
print.export_print(outputfname, thumbnails, pname);
|
||||||
|
|
||||||
@ -41,12 +44,8 @@ TEST_CASE("Archive export test", "[sla_archives]") {
|
|||||||
|
|
||||||
double vol_written = m.mesh().volume();
|
double vol_written = m.mesh().volume();
|
||||||
|
|
||||||
auto readable_formats = SLAArchiveReader::registered_archives();
|
if (entry.rdfactoryfn) {
|
||||||
if (std::any_of(readable_formats.begin(), readable_formats.end(),
|
INFO(std::string("Testing archive type: ") + entry.id + " -- reading back...");
|
||||||
[&archname](const std::string &a) { return a == archname; })) {
|
|
||||||
|
|
||||||
INFO(std::string("Testing archive type: ") + archname + " -- reading back...");
|
|
||||||
|
|
||||||
indexed_triangle_set its;
|
indexed_triangle_set its;
|
||||||
DynamicPrintConfig cfg;
|
DynamicPrintConfig cfg;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user