OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::_BBS_3MF_Importer Class Reference
Inheritance diagram for Slic3r::_BBS_3MF_Importer:
Collaboration diagram for Slic3r::_BBS_3MF_Importer:

Classes

struct  Component
struct  Geometry
struct  CurrentObject
struct  CurrentConfig
struct  CurrentInstance
struct  Instance
struct  CutObjectInfo
struct  ObjectImporter

Public Member Functions

 _BBS_3MF_Importer ()
 ~_BBS_3MF_Importer ()
bool load_model_from_file (const std::string &filename, Model &model, PlateDataPtrs &plate_data_list, std::vector< Preset * > &project_presets, DynamicPrintConfig &config, ConfigSubstitutionContext &config_substitutions, LoadStrategy strategy, bool *is_bbl_3mf, bool *is_orca_3mf, Semver &file_version, Import3mfProgressFn proFn=nullptr, BBLProject *project=nullptr, int plate_id=0)
bool get_thumbnail (const std::string &filename, std::string &data)
bool load_gcode_3mf_from_stream (std::istream &data, Model &model, PlateDataPtrs &plate_data_list, DynamicPrintConfig &config, Semver &file_version)
unsigned int version () const
void log_errors ()

Protected Member Functions

void add_error (const std::string &error) const
void clear_errors ()

Private Types

typedef std::pair< std::string, int > Id
typedef std::vector< Component > ComponentsList
typedef std::vector< Metadata > MetadataList
typedef std::map< Id, CurrentObject > IdToCurrentObjectMap
typedef std::map< int, std::string > IndexToPathMap
typedef std::map< Id, int > IdToModelObjectMap
typedef std::vector< Instance > InstancesList
typedef std::map< int, ObjectMetadata > IdToMetadataMap
typedef std::map< int, CutObjectInfo > IdToCutObjectInfoMap
typedef std::map< int, std::vector< coordf_t > > IdToLayerHeightsProfileMap
typedef std::map< int, t_layer_config_ranges > IdToLayerConfigRangesMap
typedef std::map< int, BrimPoints > IdToBrimPointsMap
using PathToEmbossShapeFileMap = std::map<std::string, std::shared_ptr<std::string>>

Private Member Functions

void _apply_texture_displacement (ModelVolume &volume, const std::string &json_path)
void _destroy_xml_parser ()
void _stop_xml_parser (const std::string &msg=std::string())
bool parse_error () const
const char * parse_error_message () const
bool _load_model_from_file (std::string filename, Model &model, PlateDataPtrs &plate_data_list, std::vector< Preset * > &project_presets, DynamicPrintConfig &config, ConfigSubstitutionContext &config_substitutions, Import3mfProgressFn proFn=nullptr, BBLProject *project=nullptr, int plate_id=0)
bool _is_published_3mf () const
bool _is_svg_shape_file (const std::string &filename) const
bool _extract_from_archive (mz_zip_archive &archive, std::string const &path, std::function< bool(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)>, bool restore=false)
bool _extract_xml_from_archive (mz_zip_archive &archive, std::string const &path, XML_StartElementHandler start_handler, XML_EndElementHandler end_handler)
bool _extract_xml_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, XML_StartElementHandler start_handler, XML_EndElementHandler end_handler)
bool _extract_model_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
void _extract_cut_information_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, ConfigSubstitutionContext &config_substitutions)
void _extract_layer_heights_profile_config_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
void _extract_layer_config_ranges_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, ConfigSubstitutionContext &config_substitutions)
void _extract_sla_support_points_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
void _extract_sla_drain_holes_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
void _extract_brim_ear_points_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
void _extract_custom_gcode_per_print_z_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
void _extract_filament_sequence_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
void _extract_print_config_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, DynamicPrintConfig &config, ConfigSubstitutionContext &subs_context, const std::string &archive_filename)
void _extract_project_config_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, DynamicPrintConfig &config, ConfigSubstitutionContext &subs_context, Model &model)
void _extract_project_embedded_presets_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, std::vector< Preset * > &project_presets, Model &model, Preset::Type type, bool use_json=true)
void _extract_auxiliary_file_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, Model &model)
void _extract_file_from_archive (mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
void _extract_embossed_svg_shape_file (const std::string &filename, mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
void _handle_start_model_xml_element (const char *name, const char **attributes)
void _handle_end_model_xml_element (const char *name)
void _handle_xml_characters (const XML_Char *s, int len)
void _handle_start_config_xml_element (const char *name, const char **attributes)
void _handle_end_config_xml_element (const char *name)
bool _handle_start_model (const char **attributes, unsigned int num_attributes)
bool _handle_end_model ()
bool _handle_start_resources (const char **attributes, unsigned int num_attributes)
bool _handle_end_resources ()
bool _handle_start_object (const char **attributes, unsigned int num_attributes)
bool _handle_end_object ()
bool _handle_start_color_group (const char **attributes, unsigned int num_attributes)
bool _handle_end_color_group ()
bool _handle_start_color (const char **attributes, unsigned int num_attributes)
bool _handle_end_color ()
bool _handle_start_mesh (const char **attributes, unsigned int num_attributes)
bool _handle_end_mesh ()
bool _handle_start_vertices (const char **attributes, unsigned int num_attributes)
bool _handle_end_vertices ()
bool _handle_start_vertex (const char **attributes, unsigned int num_attributes)
bool _handle_end_vertex ()
bool _handle_start_triangles (const char **attributes, unsigned int num_attributes)
bool _handle_end_triangles ()
bool _handle_start_triangle (const char **attributes, unsigned int num_attributes)
bool _handle_end_triangle ()
bool _handle_start_components (const char **attributes, unsigned int num_attributes)
bool _handle_end_components ()
bool _handle_start_component (const char **attributes, unsigned int num_attributes)
bool _handle_end_component ()
bool _handle_start_build (const char **attributes, unsigned int num_attributes)
bool _handle_end_build ()
bool _handle_start_item (const char **attributes, unsigned int num_attributes)
bool _handle_end_item ()
bool _handle_start_metadata (const char **attributes, unsigned int num_attributes)
bool _handle_end_metadata ()
bool _handle_start_text_configuration (const char **attributes, unsigned int num_attributes)
bool _handle_start_shape_configuration (const char **attributes, unsigned int num_attributes)
bool _create_object_instance (std::string const &path, int object_id, const Transform3d &transform, const bool printable, unsigned int recur_counter)
void _apply_transform (ModelInstance &instance, const Transform3d &transform)
bool _handle_start_config (const char **attributes, unsigned int num_attributes)
bool _handle_end_config ()
bool _handle_start_config_object (const char **attributes, unsigned int num_attributes)
bool _handle_end_config_object ()
bool _handle_start_config_volume (const char **attributes, unsigned int num_attributes)
bool _handle_start_config_volume_mesh (const char **attributes, unsigned int num_attributes)
bool _handle_end_config_volume ()
bool _handle_end_config_volume_mesh ()
bool _handle_start_config_metadata (const char **attributes, unsigned int num_attributes)
bool _handle_end_config_metadata ()
bool _handle_start_config_filament (const char **attributes, unsigned int num_attributes)
bool _handle_start_config_mixed_filament (const char **attributes, unsigned int num_attributes)
bool _handle_end_config_filament ()
bool _handle_start_config_warning (const char **attributes, unsigned int num_attributes)
bool _handle_end_config_warning ()
bool _handle_start_config_nozzle (const char **attributes, unsigned int num_attributes)
bool _handle_end_config_nozzle ()
bool _handle_start_config_plater (const char **attributes, unsigned int num_attributes)
bool _handle_end_config_plater ()
bool _handle_start_config_plater_instance (const char **attributes, unsigned int num_attributes)
bool _handle_end_config_plater_instance ()
bool _handle_start_assemble (const char **attributes, unsigned int num_attributes)
bool _handle_end_assemble ()
bool _handle_start_assemble_item (const char **attributes, unsigned int num_attributes)
bool _handle_end_assemble_item ()
bool _handle_start_text_info_item (const char **attributes, unsigned int num_attributes)
bool _handle_end_text_info_item ()
void _handle_start_relationships_element (const char *name, const char **attributes)
void _handle_end_relationships_element (const char *name)
bool _handle_start_relationship (const char **attributes, unsigned int num_attributes)
bool _generate_current_object_list (std::vector< Component > &sub_objects, Id object_id, IdToCurrentObjectMap &current_objects)
bool _generate_volumes_new (ModelObject &object, const std::vector< Component > &sub_objects, const ObjectMetadata::VolumeMetadataList &volumes, ConfigSubstitutionContext &config_substitutions)

Static Private Member Functions

static void XMLCALL _handle_start_relationships_element (void *userData, const char *name, const char **attributes)
static void XMLCALL _handle_end_relationships_element (void *userData, const char *name)
static void XMLCALL _handle_start_model_xml_element (void *userData, const char *name, const char **attributes)
static void XMLCALL _handle_end_model_xml_element (void *userData, const char *name)
static void XMLCALL _handle_xml_characters (void *userData, const XML_Char *s, int len)
static void XMLCALL _handle_start_config_xml_element (void *userData, const char *name, const char **attributes)
static void XMLCALL _handle_end_config_xml_element (void *userData, const char *name)

Private Attributes

unsigned int m_version
bool m_check_version = false
bool m_load_model = false
bool m_load_aux = false
bool m_load_config = false
bool m_load_restore = false
std::string m_backup_path
std::string m_origin_file
boost::optional< Semver > m_bambuslicer_generator_version
boost::optional< Semver > m_orca_slicer_version
unsigned int m_fdm_supports_painting_version = 0
unsigned int m_seam_painting_version = 0
unsigned int m_mm_painting_version = 0
std::string m_model_id
std::string m_contry_code
std::string m_designer
std::string m_designer_user_id
std::string m_designer_cover
ModelInfo model_info
BBLProject project_info
std::string m_profile_title
std::string m_profile_cover
std::string m_Profile_description
std::string m_profile_user_id
std::string m_profile_user_name
XML_Parser m_xml_parser
bool m_parse_error { false }
std::string m_parse_error_message
Model * m_model
float m_unit_factor
CurrentObject * m_curr_object {nullptr}
IdToCurrentObjectMap m_current_objects
IndexToPathMap m_index_paths
IdToModelObjectMap m_objects
InstancesList m_instances
CurrentConfig m_curr_config
IdToMetadataMap m_objects_metadata
std::set< int > m_items_auto_drop_off
IdToCutObjectInfoMap m_cut_object_infos
IdToLayerHeightsProfileMap m_layer_heights_profiles
IdToLayerConfigRangesMap m_layer_config_ranges
IdToBrimPointsMap m_brim_ear_points
PathToEmbossShapeFileMap m_path_to_emboss_shape_files
std::map< std::string, std::string > m_texture_displacement_files
std::string m_curr_metadata_name
std::string m_curr_characters
std::string m_name
std::string m_sub_model_path
std::string m_start_part_path
std::string m_thumbnail_path
std::string m_thumbnail_middle
std::string m_thumbnail_small
std::vector< std::string > m_sub_model_paths
std::vector< ObjectImporter * > m_object_importers
std::map< int, ModelVolume * > m_shared_meshes
bool m_is_bbl_3mf { false }
bool m_parsing_slice_info { false }
PlateDataMaps m_plater_data
PlateData * m_curr_plater
CurrentInstance m_curr_instance
int m_current_color_group {-1}
std::map< int, std::string > m_group_id_to_color
boost::mutex mutex
std::vector< std::string > m_errors

Detailed Description


Class Documentation

◆ Slic3r::_BBS_3MF_Importer::CurrentConfig

struct Slic3r::_BBS_3MF_Importer::CurrentConfig
Class Members
int object_id {-1}
int volume_id {-1}

◆ Slic3r::_BBS_3MF_Importer::CurrentInstance

struct Slic3r::_BBS_3MF_Importer::CurrentInstance
Class Members
int identify_id
int instance_id
int object_id

◆ Slic3r::_BBS_3MF_Importer::ObjectMetadata

struct Slic3r::_BBS_3MF_Importer::ObjectMetadata
Collaboration diagram for Slic3r::_BBS_3MF_Importer::ObjectMetadata:
Class Members
typedef vector< VolumeMetadata > VolumeMetadataList
Class Members
optional< bool > auto_drop
MetadataList metadata
VolumeMetadataList volumes

◆ Slic3r::_BBS_3MF_Importer::CutObjectInfo

struct Slic3r::_BBS_3MF_Importer::CutObjectInfo
Collaboration diagram for Slic3r::_BBS_3MF_Importer::CutObjectInfo:
Class Members
vector< Connector > connectors
CutObjectBase id

Member Typedef Documentation

◆ ComponentsList

◆ Id

typedef std::pair<std::string, int> Slic3r::_BBS_3MF_Importer::Id
private

◆ IdToBrimPointsMap

◆ IdToCurrentObjectMap

◆ IdToCutObjectInfoMap

◆ IdToLayerConfigRangesMap

◆ IdToLayerHeightsProfileMap

typedef std::map<int, std::vector<coordf_t> > Slic3r::_BBS_3MF_Importer::IdToLayerHeightsProfileMap
private

◆ IdToMetadataMap

◆ IdToModelObjectMap

typedef std::map<Id, int> Slic3r::_BBS_3MF_Importer::IdToModelObjectMap
private

◆ IndexToPathMap

typedef std::map<int, std::string> Slic3r::_BBS_3MF_Importer::IndexToPathMap
private

◆ InstancesList

typedef std::vector<Instance> Slic3r::_BBS_3MF_Importer::InstancesList
private

◆ MetadataList

typedef std::vector<Metadata> Slic3r::_BBS_3MF_Importer::MetadataList
private

◆ PathToEmbossShapeFileMap

using Slic3r::_BBS_3MF_Importer::PathToEmbossShapeFileMap = std::map<std::string, std::shared_ptr<std::string>>
private

Constructor & Destructor Documentation

◆ _BBS_3MF_Importer()

Slic3r::_BBS_3MF_Importer::_BBS_3MF_Importer ( )
1441 : m_version(0)
1442 , m_check_version(false)
1443 , m_xml_parser(nullptr)
1444 , m_model(nullptr)
1445 , m_unit_factor(1.0f)
1447 , m_curr_characters("")
1448 , m_name("")
1449 , m_curr_plater(nullptr)
1450 {
1451 }
std::string m_curr_characters
Definition bbs_3mf.cpp:1225
float m_unit_factor
Definition bbs_3mf.cpp:1200
bool m_check_version
Definition bbs_3mf.cpp:1166
unsigned int m_version
Definition bbs_3mf.cpp:1165
Model * m_model
Definition bbs_3mf.cpp:1199
PlateData * m_curr_plater
Definition bbs_3mf.cpp:1242
std::string m_curr_metadata_name
Definition bbs_3mf.cpp:1224
std::string m_name
Definition bbs_3mf.cpp:1226
XML_Parser m_xml_parser
Definition bbs_3mf.cpp:1194

References m_check_version, m_curr_characters, m_curr_metadata_name, m_curr_plater, m_model, m_name, m_unit_factor, m_version, and m_xml_parser.

Referenced by Slic3r::_BBS_3MF_Importer::ObjectImporter::ObjectImporter(), _extract_model_from_archive(), _handle_end_config_xml_element(), _handle_end_model_xml_element(), _handle_end_relationships_element(), _handle_start_config_xml_element(), _handle_start_model_xml_element(), _handle_start_relationships_element(), and _handle_xml_characters().

Here is the caller graph for this function:

◆ ~_BBS_3MF_Importer()

Slic3r::_BBS_3MF_Importer::~_BBS_3MF_Importer ( )
1454 {
1456 clear_errors();
1457
1458 if (m_curr_object) {
1459 delete m_curr_object;
1460 m_curr_object = nullptr;
1461 }
1462 m_current_objects.clear();
1463 m_index_paths.clear();
1464 m_objects.clear();
1465 m_instances.clear();
1466 m_objects_metadata.clear();
1467 m_items_auto_drop_off.clear();
1468 m_curr_metadata_name.clear();
1469 m_curr_characters.clear();
1470
1471 std::map<int, PlateData*>::iterator it = m_plater_data.begin();
1472 while (it != m_plater_data.end())
1473 {
1474 delete it->second;
1475 it++;
1476 }
1477 m_plater_data.clear();
1478 }
void clear_errors()
Definition bbs_3mf.cpp:817
IdToModelObjectMap m_objects
Definition bbs_3mf.cpp:1204
PlateDataMaps m_plater_data
Definition bbs_3mf.cpp:1241
std::set< int > m_items_auto_drop_off
Definition bbs_3mf.cpp:1211
CurrentObject * m_curr_object
Definition bbs_3mf.cpp:1201
IdToMetadataMap m_objects_metadata
Definition bbs_3mf.cpp:1210
void _destroy_xml_parser()
Definition bbs_3mf.cpp:1775
InstancesList m_instances
Definition bbs_3mf.cpp:1206
IndexToPathMap m_index_paths
Definition bbs_3mf.cpp:1203
IdToCurrentObjectMap m_current_objects
Definition bbs_3mf.cpp:1202

References _destroy_xml_parser(), Slic3r::_BBS_3MF_Base::clear_errors(), m_curr_characters, m_curr_metadata_name, m_curr_object, m_current_objects, m_index_paths, m_instances, m_items_auto_drop_off, m_objects, m_objects_metadata, and m_plater_data.

Here is the call graph for this function:

Member Function Documentation

◆ _apply_texture_displacement()

void Slic3r::_BBS_3MF_Importer::_apply_texture_displacement ( ModelVolume & volume,
const std::string & json_path )
private
3357 {
3358 const auto json = m_texture_displacement_files.find(json_path);
3359 if (json == m_texture_displacement_files.end()) {
3360 add_error("Missing texture displacement data: " + json_path);
3361 return;
3362 }
3363 std::vector<TextureDisplacementLayer> layers;
3364 TextureDisplacementOptions options;
3365 if (!texture_displacement_layers_from_json(json->second, layers, options)) {
3366 add_error("Malformed texture displacement data: " + json_path);
3367 return;
3368 }
3369 // The archive is the only source of a layer's pixels. `path` comes from the project file, so loading
3370 // the project must never read the file it names: that would let whoever made the project pick any
3371 // local (or, on Windows, network) file to read, and the next save would embed it in the archive.
3372 // `path` stays a label of where the texture came from; a layer the archive carries no image for
3373 // loads without one, its settings intact, until the user picks a texture again.
3374 for (TextureDisplacementLayer &layer : layers) {
3375 if (layer.path_in_3mf.empty())
3376 continue;
3377 const auto image = m_texture_displacement_files.find(layer.path_in_3mf);
3378 if (image == m_texture_displacement_files.end()) {
3379 add_error("Missing texture displacement image: " + layer.path_in_3mf);
3380 continue;
3381 }
3382 layer.image_data = std::make_shared<std::vector<unsigned char>>(image->second.begin(), image->second.end());
3383 }
3384 volume.texture_displacement_layers = std::move(layers);
3385 volume.texture_displacement_options = options;
3386 }
void add_error(const std::string &error) const
Definition bbs_3mf.cpp:816
std::map< std::string, std::string > m_texture_displacement_files
Definition bbs_3mf.cpp:1222
nlohmann::json json
Definition AssembleList.cpp:42
bool texture_displacement_layers_from_json(const std::string &text, std::vector< TextureDisplacementLayer > &layers, TextureDisplacementOptions &options)
Definition TextureDisplacement.cpp:5854

References _apply_texture_displacement(), Slic3r::_BBS_3MF_Base::add_error(), m_texture_displacement_files, Slic3r::ModelVolume::texture_displacement_layers, Slic3r::texture_displacement_layers_from_json(), and Slic3r::ModelVolume::texture_displacement_options.

Referenced by _apply_texture_displacement(), and _generate_volumes_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _apply_transform()

void Slic3r::_BBS_3MF_Importer::_apply_transform ( ModelInstance & instance,
const Transform3d & transform )
private
4465 {
4466 // Validate the affine matrix directly. Decomposing a valid mirrored transform to
4467 // rotation and scale is not stable across Eigen versions and may yield a zero diagonal.
4468 if (!transform.matrix().allFinite() || !transform.linear().fullPivLu().isInvertible())
4469 return;
4470
4471 instance.set_transformation(Slic3r::Geometry::Transformation(transform));
4472 }
Linef3 transform(const Linef3 &line, const Transform3d &t)
Definition Line.cpp:15

References _apply_transform(), Slic3r::ModelInstance::set_transformation(), and Slic3r::transform().

Referenced by _apply_transform(), and _handle_end_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _create_object_instance()

bool Slic3r::_BBS_3MF_Importer::_create_object_instance ( std::string const & path,
int object_id,
const Transform3d & transform,
const bool printable,
unsigned int recur_counter )
private
4362 {
4363 static const unsigned int MAX_RECURSIONS = 10;
4364
4365 // escape from circular aliasing
4366 if (recur_counter > MAX_RECURSIONS) {
4367 add_error("Too many recursions");
4368 return false;
4369 }
4370
4371 Id id{path, object_id};
4372 IdToCurrentObjectMap::iterator it = m_current_objects.find(id);
4373 if (it == m_current_objects.end()) {
4374 add_error("can not find object id " + std::to_string(object_id) + " to builditem");
4375 return false;
4376 }
4377
4378 IdToModelObjectMap::iterator object_item = m_objects.find(id);
4379 if (object_item == m_objects.end()) {
4380 //add object
4381 CurrentObject& current_object = it->second;
4382 int object_index = (int)m_model->objects.size();
4383 ModelObject* model_object = m_model->add_object();
4384 if (model_object == nullptr) {
4385 add_error("Unable to create object for builditem, id " + std::to_string(object_id));
4386 return false;
4387 }
4388 m_objects.insert({ id, object_index });
4389 current_object.model_object_idx = object_index;
4390 current_object.object = model_object;
4391
4392 ModelInstance* instance = m_model->objects[object_index]->add_instance();
4393 if (instance == nullptr) {
4394 add_error("error when add object instance for id " + std::to_string(object_id));
4395 return false;
4396 }
4397 instance->printable = printable;
4398
4399 m_instances.emplace_back(instance, transform);
4400
4401 if (m_is_bbl_3mf && boost::ends_with(current_object.uuid, OBJECT_UUID_SUFFIX)) {
4402 std::istringstream iss(current_object.uuid);
4403 int backup_id;
4404 if (iss >> std::hex >> backup_id) {
4405 m_model->set_object_backup_id(*model_object, backup_id);
4406 }
4407 }
4408 /*if (!current_object.geometry.empty()) {
4409 }
4410 else if (!current_object.components.empty()) {
4411 // recursively process nested components
4412 for (const Component& component : it->second) {
4413 if (!_create_object_instance(path, component.object_id, transform * component.transform, printable, recur_counter + 1))
4414 return false;
4415 }
4416 }
4417 else {
4418 add_error("can not construct build items with invalid object, id " + std::to_string(object_id));
4419 return false;
4420 }*/
4421 }
4422 else {
4423 //add instance
4424 ModelInstance* instance = m_model->objects[object_item->second]->add_instance();
4425 if (instance == nullptr) {
4426 add_error("error when add object instance for id " + std::to_string(object_id));
4427 return false;
4428 }
4429 instance->printable = printable;
4430
4431 m_instances.emplace_back(instance, transform);
4432 }
4433
4434 /*if (it->second.size() == 1 && it->second[0].object_id == object_id) {
4435 // aliasing to itself
4436
4437 IdToModelObjectMap::iterator object_item = m_objects.find(id);
4438 if (object_item == m_objects.end() || object_item->second == -1) {
4439 add_error("Found invalid object");
4440 return false;
4441 }
4442 else {
4443 ModelInstance* instance = m_model->objects[object_item->second]->add_instance();
4444 if (instance == nullptr) {
4445 add_error("Unable to add object instance");
4446 return false;
4447 }
4448 instance->printable = printable;
4449
4450 m_instances.emplace_back(instance, transform);
4451 }
4452 }
4453 else {
4454 // recursively process nested components
4455 for (const Component& component : it->second) {
4456 if (!_create_object_instance(path, component.object_id, transform * component.transform, printable, recur_counter + 1))
4457 return false;
4458 }
4459 }*/
4460
4461 return true;
4462 }
static constexpr const char * OBJECT_UUID_SUFFIX
Definition bbs_3mf.cpp:328
bool m_is_bbl_3mf
Definition bbs_3mf.cpp:1239
std::pair< std::string, int > Id
Definition bbs_3mf.cpp:829

References _create_object_instance(), Slic3r::_BBS_3MF_Base::add_error(), m_current_objects, m_instances, m_is_bbl_3mf, m_model, m_objects, Slic3r::_BBS_3MF_Importer::CurrentObject::model_object_idx, Slic3r::_BBS_3MF_Importer::CurrentObject::object, OBJECT_UUID_SUFFIX, Slic3r::ModelInstance::printable, Slic3r::transform(), and Slic3r::_BBS_3MF_Importer::CurrentObject::uuid.

Referenced by _create_object_instance(), and _handle_start_item().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _destroy_xml_parser()

void Slic3r::_BBS_3MF_Importer::_destroy_xml_parser ( )
private
1776 {
1777 if (m_xml_parser != nullptr) {
1778 XML_ParserFree(m_xml_parser);
1779 m_xml_parser = nullptr;
1780 }
1781 }

References m_xml_parser.

Referenced by ~_BBS_3MF_Importer(), _extract_model_from_archive(), and _extract_xml_from_archive().

Here is the caller graph for this function:

◆ _extract_auxiliary_file_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_auxiliary_file_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat,
Model & model )
private
2922 {
2923 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", stat.m_uncomp_size is %1%")%stat.m_uncomp_size;
2924 if (stat.m_uncomp_size > 0) {
2925 std::string dest_file;
2926 if (stat.m_is_utf8) {
2927 dest_file = stat.m_filename;
2928 } else {
2929 std::string extra(1024, 0);
2930 size_t n = mz_zip_reader_get_extra(&archive, stat.m_file_index, extra.data(), extra.size());
2931 dest_file = ZipUnicodePathExtraField::decode(extra.substr(0, n), stat.m_filename);
2932 }
2933 std::string temp_path = model.get_auxiliary_file_temp_path();
2934 //aux directory from model
2935 boost::filesystem::path dir = boost::filesystem::path(temp_path);
2936 std::size_t found = dest_file.find(AUXILIARY_DIR);
2937 if (found != std::string::npos)
2938 dest_file = dest_file.substr(found + AUXILIARY_STR_LEN);
2939 else
2940 return;
2941
2942 if (!is_path_within_root(dest_file, dir)) {
2943 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", path traversal detected in auxiliary file: %1%, skipping") % dest_file;
2944 return;
2945 }
2946
2947 if (dest_file.find('/') != std::string::npos) {
2948 boost::filesystem::path src_path = boost::filesystem::path(dest_file);
2949 boost::filesystem::path parent_path = src_path.parent_path();
2950 std::string temp_path = dir.string() + std::string("/") + parent_path.string();
2951 boost::filesystem::path parent_full_path = boost::filesystem::path(temp_path);
2952 if (!boost::filesystem::exists(parent_full_path))
2953 boost::filesystem::create_directories(parent_full_path);
2954 }
2955 dest_file = dir.string() + std::string("/") + dest_file;
2956 std::string dest_zip_file = encode_path(dest_file.c_str());
2957 mz_bool res = mz_zip_reader_extract_to_file(&archive, stat.m_file_index, dest_zip_file.c_str(), 0);
2958 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", extract %1% from 3mf %2%, ret %3%\n") % dest_file % stat.m_filename % res;
2959 if (res == 0) {
2960 add_error("Error while extract auxiliary file to file");
2961 return;
2962 }
2963 }
2964 }
const unsigned int AUXILIARY_STR_LEN
Definition bbs_3mf.cpp:252
const std::string AUXILIARY_DIR
Definition bbs_3mf.cpp:245
std::string encode_path(const char *src)
Definition utils.cpp:1382
bool is_path_within_root(const std::string &rel_path, const boost::filesystem::path &root)
Definition utils.cpp:1219
static std::string decode(std::string const &extra, std::string const &path={})
Definition bbs_3mf.cpp:147

References _extract_auxiliary_file_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), AUXILIARY_DIR, AUXILIARY_STR_LEN, ZipUnicodePathExtraField::decode(), Slic3r::encode_path(), Slic3r::Model::get_auxiliary_file_temp_path(), and Slic3r::is_path_within_root().

Referenced by _extract_auxiliary_file_from_archive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_brim_ear_points_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_brim_ear_points_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat )
private
3112 {
3113 if (stat.m_uncomp_size > 0) {
3114 std::string buffer((size_t)stat.m_uncomp_size, 0);
3115 mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
3116 if (res == 0) {
3117 add_error("Error while reading brim ear points data to buffer");
3118 return;
3119 }
3120
3121 if (buffer.back() == '\n')
3122 buffer.pop_back();
3123
3124 std::vector<std::string> objects;
3125 boost::split(objects, buffer, boost::is_any_of("\n"), boost::token_compress_off);
3126
3127 // Info on format versioning - see bbs_3mf.hpp
3128 int version = 0;
3129 std::string key("brim_points_format_version=");
3130 if (!objects.empty() && objects[0].find(key) != std::string::npos) {
3131 objects[0].erase(objects[0].begin(), objects[0].begin() + long(key.size())); // removes the string
3132 version = std::stoi(objects[0]);
3133 objects.erase(objects.begin()); // pop the header
3134 }
3135
3136 for (const std::string& object : objects) {
3137 std::vector<std::string> object_data;
3138 boost::split(object_data, object, boost::is_any_of("|"), boost::token_compress_off);
3139
3140 if (object_data.size() != 2) {
3141 add_error("Error while reading object data");
3142 continue;
3143 }
3144
3145 std::vector<std::string> object_data_id;
3146 boost::split(object_data_id, object_data[0], boost::is_any_of("="), boost::token_compress_off);
3147 if (object_data_id.size() != 2) {
3148 add_error("Error while reading object id");
3149 continue;
3150 }
3151
3152 int object_id = std::atoi(object_data_id[1].c_str());
3153 if (object_id == 0) {
3154 add_error("Found invalid object id");
3155 continue;
3156 }
3157
3158 IdToBrimPointsMap::iterator object_item = m_brim_ear_points.find(object_id);
3159 if (object_item != m_brim_ear_points.end()) {
3160 add_error("Found duplicated brim ear points");
3161 continue;
3162 }
3163
3164 std::vector<std::string> object_data_points;
3165 boost::split(object_data_points, object_data[1], boost::is_any_of(" "), boost::token_compress_off);
3166
3167 std::vector<BrimPoint> brim_ear_points;
3168 if (version == 0) {
3169 for (unsigned int i=0; i<object_data_points.size(); i+=4)
3170 brim_ear_points.emplace_back(float(std::atof(object_data_points[i+0].c_str())),
3171 float(std::atof(object_data_points[i+1].c_str())),
3172 float(std::atof(object_data_points[i+2].c_str())),
3173 float(std::atof(object_data_points[i+3].c_str())));
3174 }
3175
3176 if (!brim_ear_points.empty())
3177 m_brim_ear_points.insert({ object_id, brim_ear_points });
3178 }
3179 }
3180 }
IdToBrimPointsMap m_brim_ear_points
Definition bbs_3mf.cpp:1215
unsigned int version() const
Definition bbs_3mf.cpp:1258
T * begin(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:838

References _extract_brim_ear_points_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), m_brim_ear_points, and version().

Referenced by _extract_brim_ear_points_from_archive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_custom_gcode_per_print_z_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_custom_gcode_per_print_z_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat )
private
3415 {
3416 //BBS: add plate tree related logic
3417 if (stat.m_uncomp_size > 0) {
3418 std::string buffer((size_t)stat.m_uncomp_size, 0);
3419 mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
3420 if (res == 0) {
3421 add_error("Error while reading custom Gcodes per height data to buffer");
3422 return;
3423 }
3424
3425 std::istringstream iss(buffer); // wrap returned xml to istringstream
3426 pt::ptree main_tree;
3427 pt::read_xml(iss, main_tree);
3428
3429 if (main_tree.front().first != "custom_gcodes_per_layer")
3430 return;
3431
3432 auto extract_code = [this](int plate_id, pt::ptree code_tree) {
3433 for (const auto& code : code_tree) {
3434 if (code.first == "mode") {
3435 pt::ptree tree = code.second;
3436 std::string mode = tree.get<std::string>("<xmlattr>.value");
3437 m_model->plates_custom_gcodes[plate_id - 1].mode = mode == CustomGCode::SingleExtruderMode ? CustomGCode::Mode::SingleExtruder :
3440 }
3441 if (code.first == "layer") {
3442 pt::ptree tree = code.second;
3443 double print_z = tree.get<double>("<xmlattr>.top_z");
3444 int extruder = tree.get<int>("<xmlattr>.extruder");
3445 std::string color = tree.get<std::string>("<xmlattr>.color");
3446
3447 CustomGCode::Type type;
3448 std::string extra;
3449 pt::ptree attr_tree = tree.find("<xmlattr>")->second;
3450 if (attr_tree.find("type") == attr_tree.not_found()) {
3451 // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer
3452 // read old data ...
3453 std::string gcode = tree.get<std::string>("<xmlattr>.gcode");
3454 // ... and interpret them to the new data
3455 type = gcode == "M600" ? CustomGCode::ColorChange :
3456 gcode == "M601" ? CustomGCode::PausePrint :
3458 extra = type == CustomGCode::PausePrint ? color :
3459 type == CustomGCode::Custom ? gcode : "";
3460 }
3461 else {
3462 type = static_cast<CustomGCode::Type>(tree.get<int>("<xmlattr>.type"));
3463 extra = tree.get<std::string>("<xmlattr>.extra");
3464 }
3465 m_model->plates_custom_gcodes[plate_id - 1].gcodes.push_back(CustomGCode::Item{ print_z, type, extruder, color, extra });
3466 }
3467 }
3468 };
3469
3470 m_model->plates_custom_gcodes.clear();
3471
3472 bool has_plate_info = false;
3473 for (const auto& element : main_tree.front().second) {
3474 if (element.first == "plate") {
3475 has_plate_info = true;
3476
3477 int plate_id = -1;
3478 pt::ptree code_tree = element.second;
3479 for (const auto& code : code_tree) {
3480 if (code.first == "plate_info") {
3481 plate_id = code.second.get<int>("<xmlattr>.id");
3482 }
3483
3484 }
3485 if (plate_id == -1)
3486 continue;
3487
3488 extract_code(plate_id, code_tree);
3489 }
3490 }
3491
3492 if (!has_plate_info) {
3493 int plate_id = 1;
3494 pt::ptree code_tree = main_tree.front().second;
3495 extract_code(plate_id, code_tree);
3496 }
3497 }
3498 }
static constexpr char SingleExtruderMode[]
Definition CustomGCode.hpp:64
static constexpr char MultiAsSingleMode[]
Definition CustomGCode.hpp:65
@ MultiAsSingle
Definition CustomGCode.hpp:57
@ SingleExtruder
Definition CustomGCode.hpp:56
@ MultiExtruder
Definition CustomGCode.hpp:60
Type
Definition CustomGCode.hpp:18
@ PausePrint
Definition CustomGCode.hpp:20
@ ToolChange
Definition CustomGCode.hpp:21
@ Custom
Definition CustomGCode.hpp:23
@ ColorChange
Definition CustomGCode.hpp:19
@ gcode
Definition Time.hpp:14

References _extract_custom_gcode_per_print_z_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::CustomGCode::ColorChange, Slic3r::CustomGCode::Custom, m_model, Slic3r::CustomGCode::MultiAsSingle, Slic3r::CustomGCode::MultiAsSingleMode, Slic3r::CustomGCode::MultiExtruder, Slic3r::CustomGCode::PausePrint, Slic3r::CustomGCode::SingleExtruder, Slic3r::CustomGCode::SingleExtruderMode, and Slic3r::CustomGCode::ToolChange.

Referenced by _extract_custom_gcode_per_print_z_from_archive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_cut_information_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_cut_information_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat,
ConfigSubstitutionContext & config_substitutions )
private
2719 {
2720 if (stat.m_uncomp_size > 0) {
2721 std::string buffer((size_t)stat.m_uncomp_size, 0);
2722 mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void *) buffer.data(), (size_t) stat.m_uncomp_size, 0);
2723 if (res == 0) {
2724 add_error("Error while reading cut information data to buffer");
2725 return;
2726 }
2727
2728 std::istringstream iss(buffer); // wrap returned xml to istringstream
2729 pt::ptree objects_tree;
2730 pt::read_xml(iss, objects_tree);
2731
2732 for (const auto& object : objects_tree.get_child("objects")) {
2733 pt::ptree object_tree = object.second;
2734 int obj_idx = object_tree.get<int>("<xmlattr>.id", -1);
2735 if (obj_idx <= 0) {
2736 add_error("Found invalid object id");
2737 continue;
2738 }
2739
2740 IdToCutObjectInfoMap::iterator object_item = m_cut_object_infos.find(obj_idx);
2741 if (object_item != m_cut_object_infos.end()) {
2742 add_error("Found duplicated cut_object_id");
2743 continue;
2744 }
2745
2746 CutObjectBase cut_id;
2747 std::vector<CutObjectInfo::Connector> connectors;
2748
2749 for (const auto& obj_cut_info : object_tree) {
2750 if (obj_cut_info.first == "cut_id") {
2751 pt::ptree cut_id_tree = obj_cut_info.second;
2752 cut_id = CutObjectBase(ObjectID( cut_id_tree.get<size_t>("<xmlattr>.id")),
2753 cut_id_tree.get<size_t>("<xmlattr>.check_sum"),
2754 cut_id_tree.get<size_t>("<xmlattr>.connectors_cnt"));
2755 }
2756 if (obj_cut_info.first == "connectors") {
2757 pt::ptree cut_connectors_tree = obj_cut_info.second;
2758 for (const auto& cut_connector : cut_connectors_tree) {
2759 if (cut_connector.first != "connector")
2760 continue;
2761 pt::ptree connector_tree = cut_connector.second;
2762 CutObjectInfo::Connector connector = {connector_tree.get<int>("<xmlattr>.volume_id"),
2763 connector_tree.get<int>("<xmlattr>.type"),
2764 connector_tree.get<float>("<xmlattr>.r_tolerance"),
2765 connector_tree.get<float>("<xmlattr>.h_tolerance")};
2766 connectors.emplace_back(connector);
2767 }
2768 }
2769 }
2770
2771 CutObjectInfo cut_info {cut_id, connectors};
2772 m_cut_object_infos.insert({ obj_idx, cut_info });
2773 }
2774 }
2775 }
IdToCutObjectInfoMap m_cut_object_infos
Definition bbs_3mf.cpp:1212

References _extract_cut_information_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), and m_cut_object_infos.

Referenced by _extract_cut_information_from_archive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_embossed_svg_shape_file()

void Slic3r::_BBS_3MF_Importer::_extract_embossed_svg_shape_file ( const std::string & filename,
mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat )
private
3388 {
3389 assert(m_path_to_emboss_shape_files.find(filename) == m_path_to_emboss_shape_files.end());
3390 auto file = std::make_unique<std::string>(stat.m_uncomp_size, '\0');
3391 mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void *) file->data(), stat.m_uncomp_size, 0);
3392 if (res == 0) {
3393 add_error("Error while reading svg shape for emboss");
3394 return;
3395 }
3396
3397 // store for case svg is loaded before volume
3398 m_path_to_emboss_shape_files[filename] = std::move(file);
3399
3400 // find embossed volume, for case svg is loaded after volume
3401 for (const ModelObject* object : m_model->objects)
3402 for (ModelVolume *volume : object->volumes) {
3403 std::optional<EmbossShape> &es = volume->emboss_shape;
3404 if (!es.has_value())
3405 continue;
3406 std::optional<EmbossShape::SvgFile> &svg = es->svg_file;
3407 if (!svg.has_value())
3408 continue;
3409 if (filename.compare(svg->path_in_3mf) == 0)
3410 svg->file_data = m_path_to_emboss_shape_files[filename];
3411 }
3412 }
PathToEmbossShapeFileMap m_path_to_emboss_shape_files
Definition bbs_3mf.cpp:1218

References _extract_embossed_svg_shape_file(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::ModelVolume::emboss_shape, m_model, m_path_to_emboss_shape_files, and Slic3r::ModelObject::volumes.

Referenced by _extract_embossed_svg_shape_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_filament_sequence_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_filament_sequence_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat )
private
3501 {
3502 if (stat.m_uncomp_size == 0) {
3503 add_error("Error while reading filament sequence data to buffer");
3504 return;
3505 }
3506
3507 std::string buffer((size_t) stat.m_uncomp_size, 0);
3508 mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*) buffer.data(), (size_t) stat.m_uncomp_size, 0);
3509 if (res == 0) {
3510 add_error("Error while reading filament sequence data to buffer");
3511 return;
3512 }
3513
3514 try {
3515 const nlohmann::json sequence_json = nlohmann::json::parse(buffer);
3516 for (auto& elem : m_plater_data) {
3517 const std::string plate_key = "plate_" + std::to_string(elem.first);
3518 auto plate_it = sequence_json.find(plate_key);
3519 if (plate_it == sequence_json.end() || !plate_it->is_object())
3520 continue;
3521
3522 auto filament_it = plate_it->find("filament_sequence");
3523 if (filament_it == plate_it->end())
3524 filament_it = plate_it->find("sequence");
3525
3526 auto nozzle_it = plate_it->find("nozzle_sequence");
3527 if (filament_it == plate_it->end() || !filament_it->is_array() || nozzle_it == plate_it->end() || !nozzle_it->is_array())
3528 continue;
3529
3530 std::vector<unsigned int> filament_sequence;
3531 std::vector<unsigned int> nozzle_sequence;
3532 std::vector<int> optimal_assignment;
3533 for (const auto& item : *filament_it) {
3534 const unsigned int filament_id = item.get<unsigned int>();
3535 filament_sequence.push_back(filament_id > 0 ? filament_id - 1 : 0);
3536 }
3537 for (const auto& item : *nozzle_it)
3538 nozzle_sequence.push_back(item.get<unsigned int>());
3539
3540 auto optimal_assignment_it = plate_it->find("optimal_assignment");
3541 if (optimal_assignment_it != plate_it->end() && optimal_assignment_it->is_array()) {
3542 for (const auto& item : *optimal_assignment_it)
3543 optimal_assignment.emplace_back(item.get<int>());
3544 }
3545
3546 elem.second->filament_change_sequence = std::move(filament_sequence);
3547 elem.second->nozzle_change_sequence = std::move(nozzle_sequence);
3548 if (!optimal_assignment.empty())
3549 elem.second->optimal_assignment = std::move(optimal_assignment);
3550 }
3551 } catch (const std::exception& e) {
3552 add_error(std::string("Error while parsing filament sequence JSON: ") + e.what());
3553 }
3554 }

References _extract_filament_sequence_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), and m_plater_data.

Referenced by _extract_filament_sequence_from_archive(), and load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_file_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_file_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat )
private
2967 {
2968 if (stat.m_uncomp_size > 0) {
2969 std::string src_file = decode_path(stat.m_filename);
2970
2971 boost::filesystem::path backup_root(m_backup_path);
2972 if (!is_path_within_root(src_file, backup_root)) {
2973 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", path traversal detected in file: %1%, skipping") % src_file;
2974 return;
2975 }
2976
2977 // BBS: use backup path
2978 //aux directory from model
2979 boost::filesystem::path dest_path = boost::filesystem::path(m_backup_path + "/" + src_file);
2980 std::string dest_zip_file = encode_path(dest_path.string().c_str());
2981 mz_bool res = mz_zip_reader_extract_to_file(&archive, stat.m_file_index, dest_zip_file.c_str(), 0);
2982 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", extract %1% from 3mf %2%, ret %3%\n") % dest_path % stat.m_filename % res;
2983 if (res == 0) {
2984 add_error("Error while extract file to temp directory");
2985 return;
2986 }
2987 }
2988 return;
2989 }
std::string m_backup_path
Definition bbs_3mf.cpp:1172
std::string decode_path(const char *src)
Definition utils.cpp:1401

References _extract_file_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::decode_path(), Slic3r::encode_path(), Slic3r::is_path_within_root(), and m_backup_path.

Referenced by _extract_file_from_archive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_from_archive()

bool Slic3r::_BBS_3MF_Importer::_extract_from_archive ( mz_zip_archive & archive,
std::string const & path,
std::function< bool(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)> extract,
bool restore = false )
private
2534 {
2535 mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
2536 mz_zip_archive_file_stat stat;
2537 std::string path2 = path;
2538 if (path2.front() == '/') path2 = path2.substr(1);
2539 // try utf8 encoding
2540 int index = mz_zip_reader_locate_file(&archive, path2.c_str(), nullptr, 0);
2541 if (index < 0) {
2542 // try native encoding
2543 std::string native_path = encode_path(path2.c_str());
2544 index = mz_zip_reader_locate_file(&archive, native_path.c_str(), nullptr, 0);
2545 }
2546 if (index < 0) {
2547 // try unicode path extra
2548 std::string extra(1024, 0);
2549 for (mz_uint i = 0; i < archive.m_total_files; ++i) {
2550 size_t n = mz_zip_reader_get_extra(&archive, i, extra.data(), extra.size());
2551 if (n > 0 && path2 == ZipUnicodePathExtraField::decode(extra.substr(0, n))) {
2552 index = i;
2553 break;
2554 }
2555 }
2556 }
2557 if (index < 0 || !mz_zip_reader_file_stat(&archive, index, &stat)) {
2558 if (restore) {
2559 std::vector<std::string> paths = {m_backup_path + path};
2560 if (!m_origin_file.empty()) paths.push_back(m_origin_file);
2561 for (auto & path2 : paths) {
2562 bool result = false;
2563 if (boost::filesystem::exists(path2)) {
2564 mz_zip_archive archive;
2565 mz_zip_zero_struct(&archive);
2566 if (open_zip_reader(&archive, path2)) {
2567 result = _extract_from_archive(archive, path, extract);
2568 close_zip_reader(&archive);
2569 }
2570 }
2571 if (result) return result;
2572 }
2573 }
2574 char error_buf[1024];
2575 ::snprintf(error_buf, 1024, "File %s not found from archive", path.c_str());
2576 add_error(error_buf);
2577 return false;
2578 }
2579 try
2580 {
2581 if (!extract(archive, stat)) {
2582 return false;
2583 }
2584 }
2585 catch (const std::exception& e)
2586 {
2587 // ensure the zip archive is closed and rethrow the exception
2588 add_error(e.what());
2589 return false;
2590 }
2591 return true;
2592 }
std::string m_origin_file
Definition bbs_3mf.cpp:1173
bool _extract_from_archive(mz_zip_archive &archive, std::string const &path, std::function< bool(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)>, bool restore=false)
Definition bbs_3mf.cpp:2533
bool open_zip_reader(mz_zip_archive *zip, const std::string &fname)
Definition miniz_extension.cpp:119
bool close_zip_reader(mz_zip_archive *zip)
Definition miniz_extension.cpp:129

References _extract_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::close_zip_reader(), ZipUnicodePathExtraField::decode(), Slic3r::encode_path(), m_backup_path, m_origin_file, and Slic3r::open_zip_reader().

Referenced by _extract_from_archive(), _extract_xml_from_archive(), _load_model_from_file(), get_thumbnail(), and load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_layer_config_ranges_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_layer_config_ranges_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat,
ConfigSubstitutionContext & config_substitutions )
private
3054 {
3055 if (stat.m_uncomp_size > 0) {
3056 std::string buffer((size_t)stat.m_uncomp_size, 0);
3057 mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
3058 if (res == 0) {
3059 add_error("Error while reading layer config ranges data to buffer");
3060 return;
3061 }
3062
3063 std::istringstream iss(buffer); // wrap returned xml to istringstream
3064 pt::ptree objects_tree;
3065 pt::read_xml(iss, objects_tree);
3066
3067 for (const auto& object : objects_tree.get_child("objects")) {
3068 pt::ptree object_tree = object.second;
3069 int obj_idx = object_tree.get<int>("<xmlattr>.id", -1);
3070 if (obj_idx <= 0) {
3071 add_error("Found invalid object id");
3072 continue;
3073 }
3074
3075 IdToLayerConfigRangesMap::iterator object_item = m_layer_config_ranges.find(obj_idx);
3076 if (object_item != m_layer_config_ranges.end()) {
3077 add_error("Found duplicated layer config range");
3078 continue;
3079 }
3080
3081 t_layer_config_ranges config_ranges;
3082
3083 for (const auto& range : object_tree) {
3084 if (range.first != "range")
3085 continue;
3086 pt::ptree range_tree = range.second;
3087 double min_z = range_tree.get<double>("<xmlattr>.min_z");
3088 double max_z = range_tree.get<double>("<xmlattr>.max_z");
3089
3090 // get Z range information
3091 DynamicPrintConfig config;
3092
3093 for (const auto& option : range_tree) {
3094 if (option.first != "option")
3095 continue;
3096 std::string opt_key = option.second.get<std::string>("<xmlattr>.opt_key");
3097 std::string value = option.second.data();
3098
3099 config.set_deserialize(opt_key, value, config_substitutions);
3100 }
3101
3102 config_ranges[{ min_z, max_z }].assign_config(std::move(config));
3103 }
3104
3105 if (!config_ranges.empty())
3106 m_layer_config_ranges.insert({ obj_idx, std::move(config_ranges) });
3107 }
3108 }
3109 }
IdToLayerConfigRangesMap m_layer_config_ranges
Definition bbs_3mf.cpp:1214
auto range(Cont &&cont)
Definition libslic3r.h:405
std::map< t_layer_height_range, ModelConfig > t_layer_config_ranges
Definition Slicing.hpp:160

References _extract_layer_config_ranges_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), m_layer_config_ranges, and Slic3r::range().

Referenced by _extract_layer_config_ranges_from_archive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_layer_heights_profile_config_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_layer_heights_profile_config_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat )
private
2992 {
2993 if (stat.m_uncomp_size > 0) {
2994 std::string buffer((size_t)stat.m_uncomp_size, 0);
2995 mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
2996 if (res == 0) {
2997 add_error("Error while reading layer heights profile data to buffer");
2998 return;
2999 }
3000
3001 if (buffer.back() == '\n')
3002 buffer.pop_back();
3003
3004 std::vector<std::string> objects;
3005 boost::split(objects, buffer, boost::is_any_of("\n"), boost::token_compress_off);
3006
3007 for (const std::string& object : objects) {
3008 std::vector<std::string> object_data;
3009 boost::split(object_data, object, boost::is_any_of("|"), boost::token_compress_off);
3010 if (object_data.size() != 2) {
3011 add_error("Error while reading object data");
3012 continue;
3013 }
3014
3015 std::vector<std::string> object_data_id;
3016 boost::split(object_data_id, object_data[0], boost::is_any_of("="), boost::token_compress_off);
3017 if (object_data_id.size() != 2) {
3018 add_error("Error while reading object id");
3019 continue;
3020 }
3021
3022 int object_id = std::atoi(object_data_id[1].c_str());
3023 if (object_id == 0) {
3024 add_error("Found invalid object id");
3025 continue;
3026 }
3027
3028 IdToLayerHeightsProfileMap::iterator object_item = m_layer_heights_profiles.find(object_id);
3029 if (object_item != m_layer_heights_profiles.end()) {
3030 add_error("Found duplicated layer heights profile");
3031 continue;
3032 }
3033
3034 std::vector<std::string> object_data_profile;
3035 boost::split(object_data_profile, object_data[1], boost::is_any_of(";"), boost::token_compress_off);
3036 if (object_data_profile.size() <= 4 || object_data_profile.size() % 2 != 0) {
3037 add_error("Found invalid layer heights profile");
3038 continue;
3039 }
3040
3041 std::vector<coordf_t> profile;
3042 profile.reserve(object_data_profile.size());
3043
3044 for (const std::string& value : object_data_profile) {
3045 profile.push_back((coordf_t)std::atof(value.c_str()));
3046 }
3047
3048 m_layer_heights_profiles.insert({ object_id, profile });
3049 }
3050 }
3051 }
IdToLayerHeightsProfileMap m_layer_heights_profiles
Definition bbs_3mf.cpp:1213
double coordf_t
Definition GUI_ObjectList.hpp:46

References _extract_layer_heights_profile_config_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), and m_layer_heights_profiles.

Referenced by _extract_layer_heights_profile_config_from_archive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_model_from_archive()

bool Slic3r::_BBS_3MF_Importer::_extract_model_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat )
private
2652 {
2653 if (stat.m_uncomp_size == 0) {
2654 add_error("Found invalid size");
2655 return false;
2656 }
2657
2659
2660 m_xml_parser = XML_ParserCreate(nullptr);
2661 if (m_xml_parser == nullptr) {
2662 add_error("Unable to create parser");
2663 return false;
2664 }
2665
2666 XML_SetUserData(m_xml_parser, (void*)this);
2668 XML_SetCharacterDataHandler(m_xml_parser, _BBS_3MF_Importer::_handle_xml_characters);
2669 XML_SetEntityDeclHandler(m_xml_parser, nullptr);
2670 XML_SetExternalEntityRefHandler(m_xml_parser, nullptr);
2671
2672 struct CallbackData
2673 {
2674 XML_Parser& parser;
2675 _BBS_3MF_Importer& importer;
2676 const mz_zip_archive_file_stat& stat;
2677
2678 CallbackData(XML_Parser& parser, _BBS_3MF_Importer& importer, const mz_zip_archive_file_stat& stat) : parser(parser), importer(importer), stat(stat) {}
2679 };
2680
2681 CallbackData data(m_xml_parser, *this, stat);
2682
2683 mz_bool res = 0;
2684
2685 try
2686 {
2687 mz_file_write_func callback = [](void* pOpaque, mz_uint64 file_ofs, const void* pBuf, size_t n)->size_t {
2688 CallbackData* data = (CallbackData*)pOpaque;
2689 if (!XML_Parse(data->parser, (const char*)pBuf, (int)n, (file_ofs + n == data->stat.m_uncomp_size) ? 1 : 0) || data->importer.parse_error()) {
2690 char error_buf[1024];
2691 ::snprintf(error_buf, 1024, "Error (%s) while parsing '%s' at line %d", data->importer.parse_error_message(), data->stat.m_filename, (int)XML_GetCurrentLineNumber(data->parser));
2692 throw Slic3r::FileIOError(error_buf);
2693 }
2694 return n;
2695 };
2696 void* opaque = &data;
2697 res = mz_zip_reader_extract_to_callback(&archive, stat.m_file_index, callback, opaque, 0);
2698 }
2699 catch (const version_error& e)
2700 {
2701 // rethrow the exception
2702 throw Slic3r::FileIOError(e.what());
2703 }
2704 catch (std::exception& e)
2705 {
2706 add_error(e.what());
2707 return false;
2708 }
2709
2710 if (res == 0) {
2711 add_error("Error while extracting model data from zip archive");
2712 return false;
2713 }
2714
2715 return true;
2716 }
void _handle_start_model_xml_element(const char *name, const char **attributes)
Definition bbs_3mf.cpp:3556
void _handle_xml_characters(const XML_Char *s, int len)
Definition bbs_3mf.cpp:3641
void _handle_end_model_xml_element(const char *name)
Definition bbs_3mf.cpp:3599

References _BBS_3MF_Importer(), _destroy_xml_parser(), _extract_model_from_archive(), _handle_end_model_xml_element(), _handle_start_model_xml_element(), _handle_xml_characters(), Slic3r::_BBS_3MF_Base::add_error(), and m_xml_parser.

Referenced by _extract_model_from_archive(), _load_model_from_file(), and load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_print_config_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_print_config_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat,
DynamicPrintConfig & config,
ConfigSubstitutionContext & subs_context,
const std::string & archive_filename )
private
2778 {
2779 if (stat.m_uncomp_size > 0) {
2780 std::string buffer((size_t)stat.m_uncomp_size, 0);
2781 mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
2782 if (res == 0) {
2783 add_error("Error while reading config data to buffer");
2784 return;
2785 }
2786 ConfigBase::load_from_gcode_string_legacy(config, buffer.data(), config_substitutions);
2787 }
2788 }
static size_t load_from_gcode_string_legacy(ConfigBase &config, const char *str, ConfigSubstitutionContext &substitutions)
Definition Config.cpp:1264

References _extract_print_config_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), and Slic3r::ConfigBase::load_from_gcode_string_legacy().

Referenced by _extract_print_config_from_archive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_project_config_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_project_config_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat,
DynamicPrintConfig & config,
ConfigSubstitutionContext & subs_context,
Model & model )
private
2792 {
2793 if (stat.m_uncomp_size > 0) {
2794 const std::string& temp_path = model.get_backup_path();
2795
2796 std::string dest_file = temp_path + std::string("/") + "_temp_3.config";;
2797 std::string dest_zip_file = encode_path(dest_file.c_str());
2798 mz_bool res = mz_zip_reader_extract_to_file(&archive, stat.m_file_index, dest_zip_file.c_str(), 0);
2799 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", extract %1% from 3mf %2%, ret %3%\n") % dest_file % stat.m_filename % res;
2800 if (res == 0) {
2801 add_error("Error while extract project config file to file");
2802 return;
2803 }
2804 std::map<std::string, std::string> key_values;
2805 std::string reason;
2806 int ret = config.load_from_json(dest_file, config_substitutions, true, key_values, reason);
2807 if (ret) {
2808 add_error("Error load config from json:"+reason);
2809 return;
2810 }
2811 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", load project config file successfully from %1%\n") %dest_file;
2812
2813 // Heal any gradient-curve slots corrupted by the legacy "|" separator collision
2814 // (see FilamentMixer::sanitize_mixed_gradient_curve_array). The 3MF JSON itself
2815 // is safe (";" + C-style escape), but older projects saved through the buggy
2816 // export_selections/load_selections path may already carry single-point entries
2817 // that fail MakerWorld's "curve needs >= 2 points" check.
2818 if (auto* curve_opt = config.option<ConfigOptionStrings>("filament_mixed_gradient_curve"))
2820 }
2821 }
void sanitize_mixed_gradient_curve_array(std::vector< std::string > &vals)
Definition FilamentMixer.cpp:616

References _extract_project_config_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::encode_path(), Slic3r::Model::get_backup_path(), Slic3r::ConfigBase::load_from_json(), Slic3r::ConfigBase::option(), and Slic3r::sanitize_mixed_gradient_curve_array().

Referenced by _extract_project_config_from_archive(), and load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_project_embedded_presets_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_project_embedded_presets_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat,
std::vector< Preset * > & project_presets,
Model & model,
Preset::Type type,
bool use_json = true )
private
2825 {
2826 if (stat.m_uncomp_size > 0) {
2827 /*std::string src_file = decode_path(stat.m_filename);
2828 std::size_t found = src_file.find(METADATA_DIR);
2829 if (found != std::string::npos)
2830 src_file = src_file.substr(found + METADATA_STR_LEN);
2831 else
2832 return;*/
2833 std::string dest_file = m_backup_path + std::string("/") + "_temp_2.config";;
2834 std::string dest_zip_file = encode_path(dest_file.c_str());
2835 mz_bool res = mz_zip_reader_extract_to_file(&archive, stat.m_file_index, dest_zip_file.c_str(), 0);
2836 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", extract %1% from 3mf %2%, ret %3%\n") % dest_file % stat.m_filename % res;
2837 if (res == 0) {
2838 add_error("Error while extract auxiliary file to file");
2839 return;
2840 }
2841 //load presets
2842 DynamicPrintConfig config;
2843 //ConfigSubstitutions config_substitutions = config.load_from_ini(dest_file, Enable);
2844 std::map<std::string, std::string> key_values;
2845 std::string reason;
2846 ConfigSubstitutions config_substitutions = use_json? config.load_from_json(dest_file, Enable, key_values, reason) : config.load_from_ini(dest_file, Enable);
2847 if (!reason.empty()) {
2848 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", load project embedded config from %1% failed\n") % dest_file;
2849 //skip this file
2850 return;
2851 }
2852 ConfigOptionString* print_name;
2853 ConfigOptionStrings* filament_names;
2854 std::string preset_name;
2855 if (type == Preset::TYPE_PRINT) {
2856 print_name = dynamic_cast < ConfigOptionString* > (config.option("print_settings_id"));
2857 if (!print_name) {
2858 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", can not found print_settings_id from %1%\n") % dest_file;
2859 //skip this file
2860 return;
2861 }
2862 preset_name = print_name->value;
2863 }
2864 else if (type == Preset::TYPE_FILAMENT) {
2865 filament_names = dynamic_cast < ConfigOptionStrings* > (config.option("filament_settings_id"));
2866 if (!filament_names) {
2867 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", can not found filament_settings_id from %1%\n") % dest_file;
2868 //skip this file
2869 return;
2870 }
2871 preset_name = filament_names->values[0];
2872 }
2873 else if (type == Preset::TYPE_PRINTER) {
2874 print_name = dynamic_cast < ConfigOptionString* > (config.option("printer_settings_id"));
2875 if (!print_name) {
2876 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", can not found printer_settings_id from %1%\n") % dest_file;
2877 //skip this file
2878 return;
2879 }
2880 preset_name = print_name->value;
2881 }
2882 else {
2883 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", invalid type %1% from file %2%\n")% Preset::get_type_string(type) % dest_file;
2884 //skip this file
2885 return;
2886 }
2887
2888 Preset *preset = new Preset(type, preset_name, false);
2889 preset->file = dest_file;
2890 preset->config = std::move(config);
2891 preset->loaded = true;
2892 preset->is_project_embedded = true;
2893 preset->is_external = true;
2894 preset->is_dirty = false;
2895
2896 std::string version_str = key_values[BBL_JSON_KEY_VERSION];
2897 boost::optional<Semver> version = Semver::parse(version_str);
2898 if (version) {
2899 preset->version = *version;
2900 }
2901 else
2902 preset->version = this->m_bambuslicer_generator_version?*this->m_bambuslicer_generator_version: Semver();
2903 /*for (int i = 0; i < config_substitutions.size(); i++)
2904 {
2905 //ConfigSubstitution config_substitution;
2906 //config_substitution.opt_def = optdef;
2907 //config_substitution.old_value = value;
2908 //config_substitution.new_value = ConfigOptionUniquePtr(opt->clone());
2909 preset->loading_substitutions.emplace_back(std::move(config_substitutions[i]));
2910 }*/
2911 if (!config_substitutions.empty()) {
2912 preset->loading_substitutions = new ConfigSubstitutions();
2913 *(preset->loading_substitutions) = std::move(config_substitutions);
2914 }
2915
2916 project_presets.push_back(preset);
2917 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", create one project embedded preset: %1% from %2%, type %3%\n") % preset_name % dest_file %Preset::get_type_string(type);
2918 }
2919 }
#define BBL_JSON_KEY_VERSION
Definition Preset.hpp:55
static std::string get_type_string(Preset::Type type)
Definition Preset.cpp:590
@ TYPE_PRINTER
Definition Preset.hpp:250
@ TYPE_PRINT
Definition Preset.hpp:246
@ TYPE_FILAMENT
Definition Preset.hpp:248
static boost::optional< Semver > parse(const std::string &str)
Definition Semver.hpp:63
boost::optional< Semver > m_bambuslicer_generator_version
Definition bbs_3mf.cpp:1175
@ Enable
Definition Config.hpp:245
std::vector< ConfigSubstitution > ConfigSubstitutions
Definition Config.hpp:269
@ Preset
Definition calib.hpp:39
zaa_minimize_perimeter_height ConfigOptionString
Definition PrintConfig.hpp:1702

References _extract_project_embedded_presets_from_archive(), Slic3r::_BBS_3MF_Base::add_error(), BBL_JSON_KEY_VERSION, Slic3r::Preset::config, Slic3r::Enable, Slic3r::encode_path(), Slic3r::Preset::file, Slic3r::Preset::get_type_string(), Slic3r::Preset::is_dirty, Slic3r::Preset::is_external, Slic3r::Preset::is_project_embedded, Slic3r::ConfigBase::load_from_ini(), Slic3r::ConfigBase::load_from_json(), Slic3r::Preset::loaded, Slic3r::Preset::loading_substitutions, m_backup_path, Slic3r::ConfigBase::option(), Slic3r::Semver::parse(), Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, Slic3r::Preset::TYPE_PRINTER, Slic3r::ConfigOptionSingle< T >::value, Slic3r::ConfigOptionVector< T >::values, version(), and Slic3r::Preset::version.

Referenced by _extract_project_embedded_presets_from_archive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_sla_drain_holes_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_sla_drain_holes_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat )
private

References Slic3r::transform().

Here is the call graph for this function:

◆ _extract_sla_support_points_from_archive()

void Slic3r::_BBS_3MF_Importer::_extract_sla_support_points_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat )
private

◆ _extract_xml_from_archive() [1/2]

bool Slic3r::_BBS_3MF_Importer::_extract_xml_from_archive ( mz_zip_archive & archive,
const mz_zip_archive_file_stat & stat,
XML_StartElementHandler start_handler,
XML_EndElementHandler end_handler )
private
2602 {
2603 if (stat.m_uncomp_size == 0) {
2604 add_error("Found invalid size");
2605 return false;
2606 }
2607
2609
2610 m_xml_parser = XML_ParserCreate(nullptr);
2611 if (m_xml_parser == nullptr) {
2612 add_error("Unable to create parser");
2613 return false;
2614 }
2615
2616 XML_SetUserData(m_xml_parser, (void*)this);
2617 XML_SetElementHandler(m_xml_parser, start_handler, end_handler);
2618 XML_SetCharacterDataHandler(m_xml_parser, _BBS_3MF_Importer::_handle_xml_characters);
2619 XML_SetEntityDeclHandler(m_xml_parser, nullptr);
2620 XML_SetExternalEntityRefHandler(m_xml_parser, nullptr);
2621
2622 // expat sizes its buffer with an int, so a larger entry cannot be parsed in one piece.
2623 if (stat.m_uncomp_size > static_cast<mz_uint64>(std::numeric_limits<int>::max())) {
2624 add_error("Found invalid size");
2625 return false;
2626 }
2627 const int xml_size = static_cast<int>(stat.m_uncomp_size);
2628
2629 void* parser_buffer = XML_GetBuffer(m_xml_parser, xml_size);
2630 if (parser_buffer == nullptr) {
2631 add_error("Unable to create buffer");
2632 return false;
2633 }
2634
2635 mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, static_cast<size_t>(xml_size), 0);
2636 if (res == 0) {
2637 add_error("Error while reading config data to buffer");
2638 return false;
2639 }
2640
2641 if (!XML_ParseBuffer(m_xml_parser, xml_size, 1)) {
2642 char error_buf[1024];
2643 ::snprintf(error_buf, 1024, "Error (%s) while parsing xml file at line %d", XML_ErrorString(XML_GetErrorCode(m_xml_parser)), (int)XML_GetCurrentLineNumber(m_xml_parser));
2644 add_error(error_buf);
2645 return false;
2646 }
2647
2648 return true;
2649 }

References _destroy_xml_parser(), _extract_xml_from_archive(), _handle_xml_characters(), Slic3r::_BBS_3MF_Base::add_error(), and m_xml_parser.

Here is the call graph for this function:

◆ _extract_xml_from_archive() [2/2]

bool Slic3r::_BBS_3MF_Importer::_extract_xml_from_archive ( mz_zip_archive & archive,
std::string const & path,
XML_StartElementHandler start_handler,
XML_EndElementHandler end_handler )
private
2595 {
2596 return _extract_from_archive(archive, path, [this, start_handler, end_handler](mz_zip_archive& archive, const mz_zip_archive_file_stat& stat) {
2597 return _extract_xml_from_archive(archive, stat, start_handler, end_handler);
2598 });
2599 }
bool _extract_xml_from_archive(mz_zip_archive &archive, std::string const &path, XML_StartElementHandler start_handler, XML_EndElementHandler end_handler)
Definition bbs_3mf.cpp:2594

References _extract_from_archive(), and _extract_xml_from_archive().

Referenced by _extract_xml_from_archive(), _extract_xml_from_archive(), _load_model_from_file(), get_thumbnail(), and load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _generate_current_object_list()

bool Slic3r::_BBS_3MF_Importer::_generate_current_object_list ( std::vector< Component > & sub_objects,
Id object_id,
IdToCurrentObjectMap & current_objects )
private
5172 {
5173 // A cycle in the component graph would expand forever, and an acyclic graph can still expand
5174 // exponentially, so bound the number of component references queued. Checking before they are
5175 // queued bounds the work list itself, whatever the fan-out. A valid file over the budget is
5176 // rejected too, but the budget is way above the component references of any real object.
5177 static constexpr size_t max_components = 100000;
5178
5179 std::list<std::pair<Component, Transform3d>> id_list;
5180 id_list.push_back(std::make_pair(Component(object_id, Transform3d::Identity()), Transform3d::Identity()));
5181
5182 size_t num_components = 0;
5183 while (!id_list.empty())
5184 {
5185 auto current_item = id_list.front();
5186 Component current_id = current_item.first;
5187 id_list.pop_front();
5188 IdToCurrentObjectMap::iterator current_object = current_objects.find(current_id.object_id);
5189 if (current_object != current_objects.end()) {
5190 //found one
5191 if (!current_object->second.components.empty()) {
5192 num_components += current_object->second.components.size();
5193 if (num_components > max_components) {
5194 add_error("invalid 3mf: cyclic or too many component references");
5195 sub_objects.clear();
5196 return false;
5197 }
5198 for (const Component &comp : current_object->second.components) {
5199 id_list.push_back(std::pair(comp, current_item.second * comp.transform));
5200 }
5201 }
5202 else if (!(current_object->second.geometry.empty())) {
5203 //CurrentObject* ptr = &(current_objects[current_id]);
5204 //CurrentObject* ptr2 = &(current_object->second);
5205 sub_objects.push_back({ current_object->first, current_item.second});
5206 }
5207 }
5208 }
5209 return true;
5210 }
Definition bbs_3mf.cpp:832

References _generate_current_object_list(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::_BBS_3MF_Importer::Component::object_id, and Slic3r::_BBS_3MF_Importer::Component::transform.

Referenced by _generate_current_object_list().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _generate_volumes_new()

bool Slic3r::_BBS_3MF_Importer::_generate_volumes_new ( ModelObject & object,
const std::vector< Component > & sub_objects,
const ObjectMetadata::VolumeMetadataList & volumes,
ConfigSubstitutionContext & config_substitutions )
private
5213 {
5214 if (!object.volumes.empty()) {
5215 add_error("object already built with parts");
5216 return false;
5217 }
5218
5219 //unsigned int geo_tri_count = (unsigned int)geometry.triangles.size();
5220 unsigned int renamed_volumes_count = 0;
5221
5222 for (unsigned int index = 0; index < sub_objects.size(); index++)
5223 {
5224 //find the volume metadata firstly
5225 Component sub_comp = sub_objects[index];
5226 Id object_id = sub_comp.object_id;
5227 IdToCurrentObjectMap::iterator current_object = m_current_objects.find(object_id);
5228 if (current_object == m_current_objects.end()) {
5229 add_error("sub_objects can not be found, id=" + std::to_string(object_id.second));
5230 return false;
5231 }
5232 CurrentObject* sub_object = &(current_object->second);
5233
5234 const ObjectMetadata::VolumeMetadata* volume_data = nullptr;
5235 ObjectMetadata::VolumeMetadata default_volume_data(sub_object->id);
5236 if (index < volumes.size() && volumes[index].subobject_id == sub_object->id)
5237 volume_data = &volumes[index];
5238 else for (const ObjectMetadata::VolumeMetadata& volume_iter : volumes) {
5239 if (volume_iter.subobject_id == sub_object->id) {
5240 volume_data = &volume_iter;
5241 break;
5242 }
5243 }
5244
5245 Transform3d volume_matrix_to_object = Transform3d::Identity();
5246 bool has_transform = false;
5247 int shared_mesh_id = object_id.second;
5248 if (volume_data)
5249 {
5250 int found_count = 0;
5251 // extract the volume transformation from the volume's metadata, if present
5252 for (const Metadata& metadata : volume_data->metadata) {
5253 if (metadata.key == MATRIX_KEY) {
5254 volume_matrix_to_object = Slic3r::Geometry::transform3d_from_string(metadata.value);
5255 has_transform = ! volume_matrix_to_object.isApprox(Transform3d::Identity(), 1e-10);
5256 found_count++;
5257 }
5258 else if (metadata.key == MESH_SHARED_KEY){
5259 //add the shared mesh logic
5260 shared_mesh_id = ::atoi(metadata.value.c_str());
5261 found_count++;
5262 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": line %1%, shared_mesh_id %2%")%__LINE__%shared_mesh_id;
5263 }
5264
5265 if (found_count >= 2)
5266 break;
5267 }
5268 }
5269 else {
5270 //create a volume_data
5271 volume_data = &default_volume_data;
5272 }
5273
5274 ModelVolume* volume = nullptr;
5275 ModelVolume *shared_volume = nullptr;
5276 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": line %1%, subobject_id %2%, shared_mesh_id %3%")%__LINE__ %sub_object->id %shared_mesh_id;
5277 if (shared_mesh_id != -1) {
5278 std::map<int, ModelVolume*>::iterator iter = m_shared_meshes.find(shared_mesh_id);
5279 if (iter != m_shared_meshes.end()) {
5280 shared_volume = iter->second;
5281 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": line %1%, found shared mesh, id %2%, mesh %3%")%__LINE__%shared_mesh_id%shared_volume;
5282 }
5283 }
5284 else {
5285 //for some cases, object point to this shared mesh already loaded, treat that one as the root
5286 std::map<int, ModelVolume*>::iterator iter = m_shared_meshes.find(sub_object->id);
5287 if (iter != m_shared_meshes.end()) {
5288 shared_volume = iter->second;
5289 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": line %1%, already loaded copy-share mesh before, id %2%, mesh %3%")%__LINE__%sub_object->id%shared_volume;
5290 }
5291 }
5292
5293 const size_t triangles_count = sub_object->geometry.triangles.size();
5294 if (triangles_count == 0) {
5295 add_error("found no trianges in the object " + std::to_string(sub_object->id));
5296 return false;
5297 }
5298 if (!shared_volume){
5299 // splits volume out of imported geometry
5300 indexed_triangle_set its;
5301 its.indices.assign(sub_object->geometry.triangles.begin(), sub_object->geometry.triangles.end());
5302 //const size_t triangles_count = its.indices.size();
5303 //if (triangles_count == 0) {
5304 // add_error("found no trianges in the object " + std::to_string(sub_object->id));
5305 // return false;
5306 //}
5307 for (const Vec3i32& face : its.indices) {
5308 for (const int tri_id : face) {
5309 if (tri_id < 0 || tri_id >= int(sub_object->geometry.vertices.size())) {
5310 add_error("invalid vertex id in object " + std::to_string(sub_object->id));
5311 return false;
5312 }
5313 }
5314 }
5315
5316 for (const Vec3f &v : sub_object->geometry.vertices)
5317 if (! v.allFinite()) { // Qhull cannot take a NaN vertex
5318 add_error("invalid (non-finite) vertex in object " + std::to_string(sub_object->id));
5319 return false;
5320 }
5321 its.vertices.assign(sub_object->geometry.vertices.begin(), sub_object->geometry.vertices.end());
5322
5323 // BBS
5324 for (const std::string& prop_str : sub_object->geometry.face_properties) {
5325 FaceProperty face_prop;
5326 face_prop.from_string(prop_str);
5327 its.properties.push_back(face_prop);
5328 }
5329
5330 TriangleMesh triangle_mesh(std::move(its), volume_data->mesh_stats);
5331
5332 // BBS: no need to multiply the instance matrix into the volume
5333 //if (!m_is_bbl_3mf) {
5334 // // if the 3mf was not produced by BambuStudio and there is only one instance,
5335 // // bake the transformation into the geometry to allow the reload from disk command
5336 // // to work properly
5337 // if (object.instances.size() == 1) {
5338 // triangle_mesh.transform(object.instances.front()->get_transformation().get_matrix(), false);
5339 // object.instances.front()->set_transformation(Slic3r::Geometry::Transformation());
5340 // //FIXME do the mesh fixing?
5341 // }
5342 //}
5343 if (triangle_mesh.volume() < 0)
5344 triangle_mesh.flip_triangles();
5345
5346 volume = object.add_volume(std::move(triangle_mesh));
5347
5348 if (shared_mesh_id != -1)
5349 //for some cases the shared mesh is in other plate and not loaded in cli slicing
5350 //we need to use the first one in the same plate instead
5351 m_shared_meshes[shared_mesh_id] = volume;
5352 else
5353 m_shared_meshes[sub_object->id] = volume;
5354 }
5355 else {
5356 //create volume to use shared mesh
5357 volume = object.add_volume_with_shared_mesh(*shared_volume);
5358 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": line %1%, create volume using shared_mesh %2%")%__LINE__%shared_volume;
5359 }
5360 // stores the volume matrix taken from the metadata, if present
5361 if (has_transform)
5362 volume->source.transform = Slic3r::Geometry::Transformation(volume_matrix_to_object);
5363
5364 volume->calculate_convex_hull();
5365
5366 //set transform from 3mf
5367 Slic3r::Geometry::Transformation comp_transformatino(sub_comp.transform);
5368 volume->set_transformation(comp_transformatino * volume->get_transformation());
5369 if (shared_volume) {
5370 const TriangleMesh& trangle_mesh = volume->mesh();
5371 Vec3d shift = trangle_mesh.get_init_shift();
5372 if (!shift.isApprox(Vec3d::Zero()))
5373 volume->translate(shift);
5374 }
5375
5376 // recreate custom supports, seam and mmu segmentation from previously loaded attribute
5377 {
5378 volume->supported_facets.reserve(triangles_count);
5379 volume->seam_facets.reserve(triangles_count);
5380 volume->mmu_segmentation_facets.reserve(triangles_count);
5381 volume->fuzzy_skin_facets.reserve(triangles_count);
5382 for (size_t i=0; i<triangles_count; ++i) {
5383 assert(i < sub_object->geometry.custom_supports.size());
5384 assert(i < sub_object->geometry.custom_seam.size());
5385 assert(i < sub_object->geometry.mmu_segmentation.size());
5386 assert(i < sub_object->geometry.fuzzy_skin.size());
5387 if (! sub_object->geometry.custom_supports[i].empty())
5388 volume->supported_facets.set_triangle_from_string(i, sub_object->geometry.custom_supports[i]);
5389 if (! sub_object->geometry.custom_seam[i].empty())
5390 volume->seam_facets.set_triangle_from_string(i, sub_object->geometry.custom_seam[i]);
5391 if (! sub_object->geometry.mmu_segmentation[i].empty())
5392 volume->mmu_segmentation_facets.set_triangle_from_string(i, sub_object->geometry.mmu_segmentation[i]);
5393 if (!sub_object->geometry.fuzzy_skin[i].empty())
5394 volume->fuzzy_skin_facets.set_triangle_from_string(i, sub_object->geometry.fuzzy_skin[i]);
5395 }
5396 volume->supported_facets.shrink_to_fit();
5397 volume->seam_facets.shrink_to_fit();
5398 volume->mmu_segmentation_facets.shrink_to_fit();
5399 volume->mmu_segmentation_facets.touch();
5400 volume->fuzzy_skin_facets.shrink_to_fit();
5401 volume->fuzzy_skin_facets.touch();
5402 for (int slot = 0; slot < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++slot) {
5403 const std::vector<std::string> &mask = sub_object->geometry.texture_displacement[slot];
5404 if (mask.empty())
5405 continue; // no triangle painted on this slot
5406 FacetsAnnotation &facets = volume->texture_displacement_facet(slot);
5407 facets.reserve(triangles_count);
5408 for (size_t i = 0; i < triangles_count && i < mask.size(); ++i)
5409 if (!mask[i].empty())
5410 facets.set_triangle_from_string(i, mask[i]);
5411 facets.shrink_to_fit();
5412 facets.touch();
5413 }
5414 }
5415
5416 volume->set_type(volume_data->part_type);
5417
5418 if (auto &es = volume_data->shape_configuration; es.has_value())
5419 volume->emboss_shape = std::move(es);
5420 if (auto &tc = volume_data->text_configuration; tc.has_value())
5421 volume->text_configuration = std::move(tc);
5422
5423 // Apply the seam mode after all base-type metadata, regardless of XML key order.
5424 ModelVolumeType precise_seam_type = ModelVolumeType::INVALID;
5425 // apply the remaining volume's metadata
5426 for (const Metadata& metadata : volume_data->metadata) {
5427 if (metadata.key == NAME_KEY)
5428 volume->name = metadata.value;
5429 else if (metadata.key == TEXTURE_DISPLACEMENT_KEY)
5430 _apply_texture_displacement(*volume, metadata.value);
5431 //else if ((metadata.key == MODIFIER_KEY) && (metadata.value == "1"))
5432 // volume->set_type(ModelVolumeType::PARAMETER_MODIFIER);
5433 //for old format
5434 else if ((metadata.key == VOLUME_TYPE_KEY) || (metadata.key == PART_TYPE_KEY))
5435 volume->set_type(ModelVolume::type_from_string(metadata.value));
5436 else if (metadata.key == PRECISE_SEAM_TYPE_KEY)
5437 precise_seam_type = ModelVolume::type_from_string(metadata.value);
5438 else if (boost::starts_with(metadata.key, PRECISE_SEAM_CONFIG_PREFIX))
5439 continue; // Restore dormant settings only after the final volume type is known.
5440 else if (metadata.key == SOURCE_FILE_KEY)
5441 volume->source.input_file = metadata.value;
5442 else if (metadata.key == SOURCE_OBJECT_ID_KEY)
5443 volume->source.object_idx = ::atoi(metadata.value.c_str());
5444 else if (metadata.key == SOURCE_VOLUME_ID_KEY)
5445 volume->source.volume_idx = ::atoi(metadata.value.c_str());
5446 else if (metadata.key == SOURCE_OFFSET_X_KEY)
5447 volume->source.mesh_offset(0) = ::atof(metadata.value.c_str());
5448 else if (metadata.key == SOURCE_OFFSET_Y_KEY)
5449 volume->source.mesh_offset(1) = ::atof(metadata.value.c_str());
5450 else if (metadata.key == SOURCE_OFFSET_Z_KEY)
5451 volume->source.mesh_offset(2) = ::atof(metadata.value.c_str());
5452 else if (metadata.key == SOURCE_IN_INCHES)
5453 volume->source.is_converted_from_inches = metadata.value == "1";
5454 else if (metadata.key == SOURCE_IN_METERS)
5455 volume->source.is_converted_from_meters = metadata.value == "1";
5456 else if ((metadata.key == MATRIX_KEY) || (metadata.key == MESH_SHARED_KEY))
5457 continue;
5458 else
5459 volume->config.set_deserialize(metadata.key, metadata.value, config_substitutions);
5460 }
5461
5462 // Missing or unknown seam modes retain the ordinary modifier fallback.
5463 // Ignore seam metadata on other base types; legacy inline seam types still load above.
5464 if (volume->is_modifier() && is_precise_seam(precise_seam_type))
5465 volume->set_type(precise_seam_type);
5466
5467 // Unknown seam modes must remain inert modifiers, even when dormant settings are present.
5468 if (volume->is_precise_seam()) {
5469 for (const Metadata& metadata : volume_data->metadata) {
5470 if (boost::starts_with(metadata.key, PRECISE_SEAM_CONFIG_PREFIX)) {
5471 const std::string key = metadata.key.substr(sizeof(PRECISE_SEAM_CONFIG_PREFIX) - 1);
5472 if (!key.empty())
5473 volume->config.set_deserialize(key, metadata.value, config_substitutions);
5474 }
5475 }
5476 }
5477
5478 // this may happen for 3mf saved by 3rd part softwares
5479 if (volume->name.empty()) {
5480 volume->name = object.name;
5481 if (renamed_volumes_count > 0)
5482 volume->name += "_" + std::to_string(renamed_volumes_count + 1);
5483 ++renamed_volumes_count;
5484 }
5485 }
5486
5487 return true;
5488 }
static constexpr const char * SOURCE_VOLUME_ID_KEY
Definition 3mf.cpp:163
static constexpr const char * NAME_KEY
Definition 3mf.cpp:153
static constexpr const char * SOURCE_IN_METERS
Definition 3mf.cpp:168
static constexpr const char * SOURCE_OFFSET_Z_KEY
Definition 3mf.cpp:166
static constexpr const char * SOURCE_OFFSET_X_KEY
Definition 3mf.cpp:164
static constexpr const char * SOURCE_IN_INCHES
Definition 3mf.cpp:167
static constexpr const char * SOURCE_OBJECT_ID_KEY
Definition 3mf.cpp:162
static constexpr char PRECISE_SEAM_CONFIG_PREFIX[]
Definition 3mf.cpp:159
static constexpr const char * SOURCE_OFFSET_Y_KEY
Definition 3mf.cpp:165
static constexpr const char * MATRIX_KEY
Definition 3mf.cpp:160
static constexpr const char * SOURCE_FILE_KEY
Definition 3mf.cpp:161
static constexpr const char * VOLUME_TYPE_KEY
Definition 3mf.cpp:155
static constexpr const char * PRECISE_SEAM_TYPE_KEY
Definition 3mf.cpp:157
static constexpr const char * MESH_SHARED_KEY
Definition bbs_3mf.cpp:441
static constexpr const char * PART_TYPE_KEY
Definition bbs_3mf.cpp:426
static constexpr const char * TEXTURE_DISPLACEMENT_KEY
Definition bbs_3mf.cpp:364
static ModelVolumeType type_from_string(const std::string &s)
Definition Model.cpp:2910
std::map< int, ModelVolume * > m_shared_meshes
Definition bbs_3mf.cpp:1236
void _apply_texture_displacement(ModelVolume &volume, const std::string &json_path)
Definition bbs_3mf.cpp:3356
Transform3d transform3d_from_string(const std::string &transform_str)
Definition Geometry.cpp:732
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:96
ModelVolumeType
Definition Model.hpp:355
@ INVALID
Definition Model.hpp:356
static constexpr size_t TEXTURE_DISPLACEMENT_MAX_LAYERS
Definition TextureDisplacement.hpp:44
Eigen::Matrix< float, 3, 1, Eigen::DontAlign > Vec3f
Definition Point.hpp:65
Eigen::Matrix< int32_t, 3, 1, Eigen::DontAlign > Vec3i32
Definition Point.hpp:59
bool empty(const BoundingBoxBase< PointType, PointsType > &bb)
Definition BoundingBox.hpp:273
bool is_precise_seam(ModelVolumeType t)
Definition Model.hpp:373
Definition bbs_3mf.cpp:944

References _apply_texture_displacement(), _generate_volumes_new(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::ModelVolume::calculate_convex_hull(), Slic3r::ModelVolume::config, Slic3r::_BBS_3MF_Importer::Geometry::custom_seam, Slic3r::_BBS_3MF_Importer::Geometry::custom_supports, Slic3r::ModelVolume::emboss_shape, Slic3r::empty(), Slic3r::_BBS_3MF_Importer::Geometry::face_properties, Slic3r::TriangleMesh::flip_triangles(), Slic3r::_BBS_3MF_Importer::Geometry::fuzzy_skin, Slic3r::ModelVolume::fuzzy_skin_facets, Slic3r::_BBS_3MF_Importer::CurrentObject::geometry, Slic3r::TriangleMesh::get_init_shift(), Slic3r::ModelVolume::get_transformation(), Slic3r::_BBS_3MF_Importer::CurrentObject::id, Slic3r::ModelVolume::Source::input_file, Slic3r::INVALID, Slic3r::ModelVolume::Source::is_converted_from_inches, Slic3r::ModelVolume::Source::is_converted_from_meters, Slic3r::ModelVolume::is_modifier(), Slic3r::is_precise_seam(), Slic3r::ModelVolume::is_precise_seam(), Slic3r::_BBS_3MF_Importer::Metadata::key, m_current_objects, m_shared_meshes, MATRIX_KEY, Slic3r::ModelVolume::mesh(), Slic3r::ModelVolume::Source::mesh_offset, MESH_SHARED_KEY, Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::mesh_stats, Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::metadata, Slic3r::_BBS_3MF_Importer::Geometry::mmu_segmentation, Slic3r::ModelVolume::mmu_segmentation_facets, Slic3r::ModelVolume::name, NAME_KEY, Slic3r::_BBS_3MF_Importer::Component::object_id, Slic3r::ModelVolume::Source::object_idx, Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::part_type, PART_TYPE_KEY, PRECISE_SEAM_CONFIG_PREFIX, PRECISE_SEAM_TYPE_KEY, Slic3r::FacetsAnnotation::reserve(), Slic3r::ModelVolume::seam_facets, Slic3r::ModelConfig::set_deserialize(), Slic3r::ModelVolume::set_transformation(), Slic3r::FacetsAnnotation::set_triangle_from_string(), Slic3r::ModelVolume::set_type(), Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::shape_configuration, Slic3r::FacetsAnnotation::shrink_to_fit(), Slic3r::ModelVolume::source, SOURCE_FILE_KEY, SOURCE_IN_INCHES, SOURCE_IN_METERS, SOURCE_OBJECT_ID_KEY, SOURCE_OFFSET_X_KEY, SOURCE_OFFSET_Y_KEY, SOURCE_OFFSET_Z_KEY, SOURCE_VOLUME_ID_KEY, Slic3r::ModelVolume::supported_facets, Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::text_configuration, Slic3r::ModelVolume::text_configuration, Slic3r::_BBS_3MF_Importer::Geometry::texture_displacement, Slic3r::ModelVolume::texture_displacement_facet(), TEXTURE_DISPLACEMENT_KEY, Slic3r::TEXTURE_DISPLACEMENT_MAX_LAYERS, Slic3r::ObjectWithTimestamp::touch(), Slic3r::_BBS_3MF_Importer::Component::transform, Slic3r::ModelVolume::Source::transform, Slic3r::Geometry::transform3d_from_string(), Slic3r::ModelVolume::translate(), Slic3r::_BBS_3MF_Importer::Geometry::triangles, Slic3r::ModelVolume::type_from_string(), Slic3r::_BBS_3MF_Importer::Metadata::value, Slic3r::_BBS_3MF_Importer::Geometry::vertices, Slic3r::TriangleMesh::volume(), Slic3r::ModelVolume::Source::volume_idx, and VOLUME_TYPE_KEY.

Referenced by _generate_volumes_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_assemble()

bool Slic3r::_BBS_3MF_Importer::_handle_end_assemble ( )
private
5014 {
5015 //do nothing
5016 return true;
5017 }

References _handle_end_assemble().

Referenced by _handle_end_assemble(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_assemble_item()

bool Slic3r::_BBS_3MF_Importer::_handle_end_assemble_item ( )
private
5051 {
5052 return true;
5053 }

References _handle_end_assemble_item().

Referenced by _handle_end_assemble_item(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_build()

bool Slic3r::_BBS_3MF_Importer::_handle_end_build ( )
private
4113 {
4114 // do nothing
4115 return true;
4116 }

References _handle_end_build().

Referenced by _handle_end_build(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_color()

bool Slic3r::_BBS_3MF_Importer::_handle_end_color ( )
private
3951 {
3952 // do nothing
3953 return true;
3954 }

References _handle_end_color().

Referenced by _handle_end_color(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_color_group()

bool Slic3r::_BBS_3MF_Importer::_handle_end_color_group ( )
private
3938 {
3939 // do nothing
3940 return true;
3941 }

References _handle_end_color_group().

Referenced by _handle_end_color_group(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_component()

bool Slic3r::_BBS_3MF_Importer::_handle_end_component ( )
private
4101 {
4102 // do nothing
4103 return true;
4104 }

References _handle_end_component().

Referenced by _handle_end_component(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_components()

bool Slic3r::_BBS_3MF_Importer::_handle_end_components ( )
private
4071 {
4072 // do nothing
4073 return true;
4074 }

References _handle_end_components().

Referenced by _handle_end_components(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config ( )
private
4481 {
4482 // do nothing
4483 return true;
4484 }

References _handle_end_config().

Referenced by _handle_end_config(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_filament()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config_filament ( )
private
4889 {
4890 // do nothing
4891 return true;
4892 }

References _handle_end_config_filament().

Referenced by _handle_end_config_filament(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_metadata()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config_metadata ( )
private
4835 {
4836 // do nothing
4837 return true;
4838 }

References _handle_end_config_metadata().

Referenced by _handle_end_config_metadata(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_nozzle()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config_nozzle ( )
private
4924 {
4925 // do nothing
4926 return true;
4927 }

References _handle_end_config_nozzle().

Referenced by _handle_end_config_nozzle(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_object()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config_object ( )
private
4509 {
4510 m_curr_config.object_id = -1;
4511 return true;
4512 }
CurrentConfig m_curr_config
Definition bbs_3mf.cpp:1209

References _handle_end_config_object(), and m_curr_config.

Referenced by _handle_end_config_object(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_plater()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config_plater ( )
private
4963 {
4964 if (!m_curr_plater)
4965 {
4966 add_error("_handle_end_config_plater: don't find plate created before");
4967 return false;
4968 }
4969 m_plater_data.emplace(m_curr_plater->plate_index, m_curr_plater);
4970 m_curr_plater = nullptr;
4971 return true;
4972 }

References _handle_end_config_plater(), Slic3r::_BBS_3MF_Base::add_error(), m_curr_plater, and m_plater_data.

Referenced by _handle_end_config_plater(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_plater_instance()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config_plater_instance ( )
private
4987 {
4988 if (!m_curr_plater)
4989 {
4990 add_error("_handle_end_config_plater_instance: don't find plate created before");
4991 return false;
4992 }
4993 if ((m_curr_instance.object_id == -1) || (m_curr_instance.instance_id == -1))
4994 {
4995 //add_error("invalid object id/instance id");
4996 //skip this instance
4997 m_curr_instance.object_id = m_curr_instance.instance_id = -1;
4998 m_curr_instance.identify_id = 0;
4999 return true;
5000 }
5001
5002 m_curr_plater->obj_inst_map.emplace(m_curr_instance.object_id, std::make_pair(m_curr_instance.instance_id, m_curr_instance.identify_id));
5003 m_curr_instance.object_id = m_curr_instance.instance_id = -1;
5004 m_curr_instance.identify_id = 0;
5005 return true;
5006 }
CurrentInstance m_curr_instance
Definition bbs_3mf.cpp:1243

References _handle_end_config_plater_instance(), Slic3r::_BBS_3MF_Base::add_error(), m_curr_instance, and m_curr_plater.

Referenced by _handle_end_config_plater_instance(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_volume()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config_volume ( )
private
4566 {
4567 m_curr_config.volume_id = -1;
4568 return true;
4569 }

References _handle_end_config_volume(), and m_curr_config.

Referenced by _handle_end_config_volume(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_volume_mesh()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config_volume_mesh ( )
private
4572 {
4573 // do nothing
4574 return true;
4575 }

References _handle_end_config_volume_mesh().

Referenced by _handle_end_config_volume_mesh(), and _handle_end_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_warning()

bool Slic3r::_BBS_3MF_Importer::_handle_end_config_warning ( )
private
4948 {
4949 // do nothing
4950 return true;
4951 }

References _handle_end_config_warning().

Referenced by _handle_end_config_warning().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_xml_element() [1/2]

void Slic3r::_BBS_3MF_Importer::_handle_end_config_xml_element ( const char * name)
private
3694 {
3695 if (m_xml_parser == nullptr)
3696 return;
3697
3698 bool res = true;
3699
3700 if (::strcmp(CONFIG_TAG, name) == 0)
3701 res = _handle_end_config();
3702 else if (::strcmp(OBJECT_TAG, name) == 0)
3704 else if (::strcmp(VOLUME_TAG, name) == 0)
3706 else if (::strcmp(PART_TAG, name) == 0)
3708 else if (::strcmp(MESH_STAT_TAG, name) == 0)
3710 else if (::strcmp(METADATA_TAG, name) == 0)
3712 else if (::strcmp(PLATE_TAG, name) == 0)
3714 else if (::strcmp(FILAMENT_TAG, name) == 0)
3716 else if (::strcmp(NOZZLE_TAG, name) == 0)
3718 else if (::strcmp(INSTANCE_TAG, name) == 0)
3720 else if (::strcmp(ASSEMBLE_TAG, name) == 0)
3721 res = _handle_end_assemble();
3722 else if (::strcmp(ASSEMBLE_ITEM_TAG, name) == 0)
3724
3725 if (!res)
3727 }
static constexpr const char * VOLUME_TAG
Definition 3mf.cpp:124
static constexpr const char * CONFIG_TAG
Definition 3mf.cpp:123
static constexpr const char * METADATA_TAG
Definition 3mf.cpp:121
static constexpr const char * OBJECT_TAG
Definition 3mf.cpp:111
static constexpr const char * MESH_STAT_TAG
Definition bbs_3mf.cpp:262
static constexpr const char * PART_TAG
Definition bbs_3mf.cpp:295
static constexpr const char * INSTANCE_TAG
Definition bbs_3mf.cpp:297
static constexpr const char * ASSEMBLE_ITEM_TAG
Definition bbs_3mf.cpp:300
static constexpr const char * PLATE_TAG
Definition bbs_3mf.cpp:296
static constexpr const char * NOZZLE_TAG
Definition bbs_3mf.cpp:287
static constexpr const char * FILAMENT_TAG
Definition bbs_3mf.cpp:272
static constexpr const char * ASSEMBLE_TAG
Definition bbs_3mf.cpp:299
void _stop_xml_parser(const std::string &msg=std::string())
Definition bbs_3mf.cpp:1783
bool _handle_end_assemble_item()
Definition bbs_3mf.cpp:5050
bool _handle_end_config_object()
Definition bbs_3mf.cpp:4508
bool _handle_end_config_nozzle()
Definition bbs_3mf.cpp:4923
bool _handle_end_config_volume_mesh()
Definition bbs_3mf.cpp:4571
bool _handle_end_config_plater()
Definition bbs_3mf.cpp:4962
bool _handle_end_config()
Definition bbs_3mf.cpp:4480
bool _handle_end_assemble()
Definition bbs_3mf.cpp:5013
bool _handle_end_config_volume()
Definition bbs_3mf.cpp:4565
bool _handle_end_config_filament()
Definition bbs_3mf.cpp:4888
bool _handle_end_config_metadata()
Definition bbs_3mf.cpp:4834
bool _handle_end_config_plater_instance()
Definition bbs_3mf.cpp:4986

References _handle_end_assemble(), _handle_end_assemble_item(), _handle_end_config(), _handle_end_config_filament(), _handle_end_config_metadata(), _handle_end_config_nozzle(), _handle_end_config_object(), _handle_end_config_plater(), _handle_end_config_plater_instance(), _handle_end_config_volume(), _handle_end_config_volume_mesh(), _handle_end_config_xml_element(), _stop_xml_parser(), ASSEMBLE_ITEM_TAG, ASSEMBLE_TAG, CONFIG_TAG, FILAMENT_TAG, INSTANCE_TAG, m_xml_parser, MESH_STAT_TAG, METADATA_TAG, NOZZLE_TAG, OBJECT_TAG, PART_TAG, PLATE_TAG, and VOLUME_TAG.

Referenced by _handle_end_config_xml_element(), _handle_end_config_xml_element(), and load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_config_xml_element() [2/2]

void XMLCALL Slic3r::_BBS_3MF_Importer::_handle_end_config_xml_element ( void * userData,
const char * name )
staticprivate
5683 {
5684 _BBS_3MF_Importer* importer = (_BBS_3MF_Importer*)userData;
5685 if (importer != nullptr)
5686 importer->_handle_end_config_xml_element(name);
5687 }
_BBS_3MF_Importer()
Definition bbs_3mf.cpp:1440

References _BBS_3MF_Importer(), and _handle_end_config_xml_element().

Here is the call graph for this function:

◆ _handle_end_item()

bool Slic3r::_BBS_3MF_Importer::_handle_end_item ( )
private
4137 {
4138 // do nothing
4139 return true;
4140 }

References _handle_end_item().

Referenced by _handle_end_item(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_mesh()

bool Slic3r::_BBS_3MF_Importer::_handle_end_mesh ( )
private
3965 {
3966 // do nothing
3967 return true;
3968 }

References _handle_end_mesh().

Referenced by _handle_end_mesh(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_metadata()

bool Slic3r::_BBS_3MF_Importer::_handle_end_metadata ( )
private
4161 {
4163 //m_is_bbl_3mf = true;
4164 m_version = (unsigned int)atoi(m_curr_characters.c_str());
4165 /*if (m_check_version && (m_version > VERSION_BBS_3MF_COMPATIBLE)) {
4166 // std::string msg = _(L("The selected 3mf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible."));
4167 // throw version_error(msg.c_str());
4168 const std::string msg = (boost::format(_(L("The selected 3mf file has been saved with a newer version of %1% and is not compatible."))) % std::string(SLIC3R_APP_NAME)).str();
4169 throw version_error(msg);
4170 }*/
4172 // Generator application of the 3MF.
4173 // SLIC3R_APP_KEY - SoftFever_VERSION
4174 if (boost::starts_with(m_curr_characters, "BambuStudio-")) {
4175 m_is_bbl_3mf = true;
4177 }
4178 else if (boost::starts_with(m_curr_characters, "OrcaSlicer-")) {
4179 m_is_bbl_3mf = true;
4181 }
4182 } else if (m_curr_metadata_name == ORCASLICER_TAG) {
4183 // OrcaSlicer version tag (written from OrcaSlicer 2.3.2 onwards)
4186 m_is_bbl_3mf = true;
4187 }
4188 //TODO: currently use version 0, no need to load&&save this string
4189 /*} else if (m_curr_metadata_name == BBS_FDM_SUPPORTS_PAINTING_VERSION) {
4190 m_fdm_supports_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
4191 check_painting_version(m_fdm_supports_painting_version, FDM_SUPPORTS_PAINTING_VERSION,
4192 _(L("The selected 3MF contains FDM supports painted object using a newer version of OrcaSlicer and is not compatible.")));
4193 } else if (m_curr_metadata_name == BBS_SEAM_PAINTING_VERSION) {
4194 m_seam_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
4195 check_painting_version(m_seam_painting_version, SEAM_PAINTING_VERSION,
4196 _(L("The selected 3MF contains seam painted object using a newer version of OrcaSlicer and is not compatible.")));
4197 } else if (m_curr_metadata_name == BBS_MM_PAINTING_VERSION) {
4198 m_mm_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
4199 check_painting_version(m_mm_painting_version, MM_PAINTING_VERSION,
4200 _(L("The selected 3MF contains multi-material painted object using a newer version of OrcaSlicer and is not compatible.")));*/
4201 } else if (m_curr_metadata_name == BBL_MODEL_ID_TAG) {
4204 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found model name = " << m_curr_characters;
4206 } else if (m_curr_metadata_name == BBL_ORIGIN_TAG) {
4207 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found model name = " << m_curr_characters;
4209 } else if (m_curr_metadata_name == BBL_DESIGNER_TAG) {
4210 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found designer = " << m_curr_characters;
4213 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found designer_user_id = " << m_curr_characters;
4216 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found designer_cover = " << m_curr_characters;
4219 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found description = " << m_curr_characters;
4221 } else if (m_curr_metadata_name == BBL_LICENSE_TAG) {
4222 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found license = " << m_curr_characters;
4225 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found CopyRight = " << m_curr_characters;
4228 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found Copyright = " << m_curr_characters;
4230 } else if (m_curr_metadata_name == BBL_REGION_TAG) {
4231 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found region = " << m_curr_characters;
4234 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found profile_title = " << m_curr_characters;
4237 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found profile_cover = " << m_curr_characters;
4240 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found profile_description = " << m_curr_characters;
4243 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found profile_user_id = " << m_curr_characters;
4246 BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found profile_user_name = " << m_curr_characters;
4249 ;
4251 ;
4252 } else {
4253 ;
4254 }
4255 if (!m_curr_metadata_name.empty()) {
4256 BOOST_LOG_TRIVIAL(info) << "load_3mf found metadata key = " << m_curr_metadata_name << ", value = " << xml_unescape(m_curr_characters);
4258 }
4259
4260 return true;
4261 }
const std::string ORCASLICER_TAG
Definition bbs_3mf.cpp:199
const std::string BBL_DESIGNER_TAG
Definition bbs_3mf.cpp:186
const std::string BBL_MODEL_NAME_TAG
Definition bbs_3mf.cpp:184
const char * BBS_3MF_VERSION1
Definition bbs_3mf.cpp:172
const std::string BBL_PROFILE_USER_NAME_TAG
Definition bbs_3mf.cpp:208
const std::string BBL_PROFILE_DESCRIPTION_TAG
Definition bbs_3mf.cpp:206
const std::string BBL_DESIGNER_USER_ID_TAG
Definition bbs_3mf.cpp:187
const std::string BBL_CREATION_DATE_TAG
Definition bbs_3mf.cpp:195
const std::string BBL_APPLICATION_TAG
Definition bbs_3mf.cpp:197
const std::string BBL_PROFILE_USER_ID_TAG
Definition bbs_3mf.cpp:207
const std::string BBL_MODIFICATION_TAG
Definition bbs_3mf.cpp:194
const char * BBS_3MF_VERSION
Definition bbs_3mf.cpp:173
const std::string BBL_REGION_TAG
Definition bbs_3mf.cpp:193
const std::string BBL_COPYRIGHT_NORMATIVE_TAG
Definition bbs_3mf.cpp:191
const std::string BBL_DESIGNER_COVER_FILE_TAG
Definition bbs_3mf.cpp:188
const std::string BBL_MODEL_ID_TAG
Definition bbs_3mf.cpp:183
const std::string BBL_LICENSE_TAG
Definition bbs_3mf.cpp:192
const std::string BBL_ORIGIN_TAG
Definition bbs_3mf.cpp:185
const std::string BBL_PROFILE_TITLE_TAG
Definition bbs_3mf.cpp:204
const std::string BBL_DESCRIPTION_TAG
Definition bbs_3mf.cpp:189
const std::string BBL_COPYRIGHT_TAG
Definition bbs_3mf.cpp:190
const std::string BBL_PROFILE_COVER_TAG
Definition bbs_3mf.cpp:205
boost::optional< Semver > m_orca_slicer_version
Definition bbs_3mf.cpp:1177
std::string m_designer_user_id
Definition bbs_3mf.cpp:1184
ModelInfo model_info
Definition bbs_3mf.cpp:1186
std::string m_model_id
Definition bbs_3mf.cpp:1181
std::string m_profile_user_name
Definition bbs_3mf.cpp:1192
std::string m_designer
Definition bbs_3mf.cpp:1183
std::string m_Profile_description
Definition bbs_3mf.cpp:1190
std::string m_profile_cover
Definition bbs_3mf.cpp:1189
std::string m_profile_title
Definition bbs_3mf.cpp:1188
std::string m_contry_code
Definition bbs_3mf.cpp:1182
std::string m_profile_user_id
Definition bbs_3mf.cpp:1191
void trace(unsigned int level, const char *message)
Definition utils.cpp:247
std::string xml_unescape(std::string s)
Definition utils.cpp:1641

References _handle_end_metadata(), BBL_APPLICATION_TAG, BBL_COPYRIGHT_NORMATIVE_TAG, BBL_COPYRIGHT_TAG, BBL_CREATION_DATE_TAG, BBL_DESCRIPTION_TAG, BBL_DESIGNER_COVER_FILE_TAG, BBL_DESIGNER_TAG, BBL_DESIGNER_USER_ID_TAG, BBL_LICENSE_TAG, BBL_MODEL_ID_TAG, BBL_MODEL_NAME_TAG, BBL_MODIFICATION_TAG, BBL_ORIGIN_TAG, BBL_PROFILE_COVER_TAG, BBL_PROFILE_DESCRIPTION_TAG, BBL_PROFILE_TITLE_TAG, BBL_PROFILE_USER_ID_TAG, BBL_PROFILE_USER_NAME_TAG, BBL_REGION_TAG, BBS_3MF_VERSION, BBS_3MF_VERSION1, m_bambuslicer_generator_version, m_contry_code, m_curr_characters, m_curr_metadata_name, m_designer, m_designer_user_id, m_is_bbl_3mf, m_model_id, m_orca_slicer_version, m_profile_cover, m_Profile_description, m_profile_title, m_profile_user_id, m_profile_user_name, m_version, model_info, ORCASLICER_TAG, Slic3r::Semver::parse(), Slic3r::trace(), and Slic3r::xml_unescape().

Referenced by _handle_end_metadata(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_model()

bool Slic3r::_BBS_3MF_Importer::_handle_end_model ( )
private
3737 {
3738 // BBS: Production Extension
3739 if (!m_sub_model_path.empty())
3740 return true;
3741
3742 // deletes all non-built or non-instanced objects
3743 for (const IdToModelObjectMap::value_type& object : m_objects) {
3744 if (object.second >= int(m_model->objects.size())) {
3745 add_error("Unable to find object");
3746 return false;
3747 }
3748 ModelObject *model_object = m_model->objects[object.second];
3749 if (model_object != nullptr && model_object->instances.size() == 0)
3750 m_model->delete_object(model_object);
3751 }
3752
3753 //construct the index maps
3754 for (const IdToCurrentObjectMap::value_type& object : m_current_objects) {
3755 m_index_paths.insert({ object.first.second, object.first.first});
3756 }
3757
3758 if (!m_is_bbl_3mf && !_is_published_3mf()) {
3759 // if the 3mf was not produced by OrcaSlicer and there is only one object,
3760 // set the object name to match the filename
3761 if (m_model->objects.size() == 1)
3762 m_model->objects.front()->name = m_name;
3763 }
3764
3765 // applies instances' matrices
3766 for (Instance& instance : m_instances) {
3767 if (instance.instance != nullptr && instance.instance->get_object() != nullptr)
3768 // apply the transform to the instance
3769 _apply_transform(*instance.instance, instance.transform);
3770 }
3771
3772 return true;
3773 }
std::string m_sub_model_path
Definition bbs_3mf.cpp:1227
void _apply_transform(ModelInstance &instance, const Transform3d &transform)
Definition bbs_3mf.cpp:4464
bool _is_published_3mf() const
Definition bbs_3mf.cpp:1286
Definition bbs_3mf.cpp:932

References _apply_transform(), _handle_end_model(), _is_published_3mf(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::ModelObject::instances, m_current_objects, m_index_paths, m_instances, m_is_bbl_3mf, m_model, m_name, m_objects, and m_sub_model_path.

Referenced by _handle_end_model(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_model_xml_element() [1/2]

void Slic3r::_BBS_3MF_Importer::_handle_end_model_xml_element ( const char * name)
private
3600 {
3601 if (m_xml_parser == nullptr)
3602 return;
3603
3604 bool res = true;
3605
3606 if (::strcmp(MODEL_TAG, name) == 0)
3607 res = _handle_end_model();
3608 else if (::strcmp(RESOURCES_TAG, name) == 0)
3609 res = _handle_end_resources();
3610 else if (::strcmp(OBJECT_TAG, name) == 0)
3611 res = _handle_end_object();
3612 else if (::strcmp(COLOR_GROUP_TAG, name) == 0)
3614 else if (::strcmp(COLOR_TAG, name) == 0)
3615 res = _handle_end_color();
3616 else if (::strcmp(MESH_TAG, name) == 0)
3617 res = _handle_end_mesh();
3618 else if (::strcmp(VERTICES_TAG, name) == 0)
3619 res = _handle_end_vertices();
3620 else if (::strcmp(VERTEX_TAG, name) == 0)
3621 res = _handle_end_vertex();
3622 else if (::strcmp(TRIANGLES_TAG, name) == 0)
3623 res = _handle_end_triangles();
3624 else if (::strcmp(TRIANGLE_TAG, name) == 0)
3625 res = _handle_end_triangle();
3626 else if (::strcmp(COMPONENTS_TAG, name) == 0)
3627 res = _handle_end_components();
3628 else if (::strcmp(COMPONENT_TAG, name) == 0)
3629 res = _handle_end_component();
3630 else if (::strcmp(BUILD_TAG, name) == 0)
3631 res = _handle_end_build();
3632 else if (::strcmp(ITEM_TAG, name) == 0)
3633 res = _handle_end_item();
3634 else if (::strcmp(METADATA_TAG, name) == 0)
3635 res = _handle_end_metadata();
3636
3637 if (!res)
3639 }
static constexpr const char * BUILD_TAG
Definition 3mf.cpp:119
static constexpr const char * TRIANGLES_TAG
Definition 3mf.cpp:115
static constexpr const char * RESOURCES_TAG
Definition 3mf.cpp:110
static constexpr const char * VERTEX_TAG
Definition 3mf.cpp:114
static constexpr const char * MESH_TAG
Definition 3mf.cpp:112
static constexpr const char * ITEM_TAG
Definition 3mf.cpp:120
static constexpr const char * COMPONENTS_TAG
Definition 3mf.cpp:117
static constexpr const char * COMPONENT_TAG
Definition 3mf.cpp:118
static constexpr const char * MODEL_TAG
Definition 3mf.cpp:109
static constexpr const char * VERTICES_TAG
Definition 3mf.cpp:113
static constexpr const char * TRIANGLE_TAG
Definition 3mf.cpp:116
static constexpr const char * COLOR_GROUP_TAG
Definition bbs_3mf.cpp:258
static constexpr const char * COLOR_TAG
Definition bbs_3mf.cpp:259
bool _handle_end_triangles()
Definition bbs_3mf.cpp:4017
bool _handle_end_triangle()
Definition bbs_3mf.cpp:4056
bool _handle_end_resources()
Definition bbs_3mf.cpp:3781
bool _handle_end_color_group()
Definition bbs_3mf.cpp:3937
bool _handle_end_components()
Definition bbs_3mf.cpp:4070
bool _handle_end_build()
Definition bbs_3mf.cpp:4112
bool _handle_end_vertices()
Definition bbs_3mf.cpp:3978
bool _handle_end_metadata()
Definition bbs_3mf.cpp:4160
bool _handle_end_vertex()
Definition bbs_3mf.cpp:4003
bool _handle_end_item()
Definition bbs_3mf.cpp:4136
bool _handle_end_object()
Definition bbs_3mf.cpp:3822
bool _handle_end_color()
Definition bbs_3mf.cpp:3950
bool _handle_end_component()
Definition bbs_3mf.cpp:4100
bool _handle_end_mesh()
Definition bbs_3mf.cpp:3964
bool _handle_end_model()
Definition bbs_3mf.cpp:3736

References _handle_end_build(), _handle_end_color(), _handle_end_color_group(), _handle_end_component(), _handle_end_components(), _handle_end_item(), _handle_end_mesh(), _handle_end_metadata(), _handle_end_model(), _handle_end_model_xml_element(), _handle_end_object(), _handle_end_resources(), _handle_end_triangle(), _handle_end_triangles(), _handle_end_vertex(), _handle_end_vertices(), _stop_xml_parser(), BUILD_TAG, COLOR_GROUP_TAG, COLOR_TAG, COMPONENT_TAG, COMPONENTS_TAG, ITEM_TAG, m_xml_parser, MESH_TAG, METADATA_TAG, MODEL_TAG, OBJECT_TAG, RESOURCES_TAG, TRIANGLE_TAG, TRIANGLES_TAG, VERTEX_TAG, and VERTICES_TAG.

Referenced by _extract_model_from_archive(), _handle_end_model_xml_element(), and _handle_end_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_model_xml_element() [2/2]

void XMLCALL Slic3r::_BBS_3MF_Importer::_handle_end_model_xml_element ( void * userData,
const char * name )
staticprivate
5662 {
5663 _BBS_3MF_Importer* importer = (_BBS_3MF_Importer*)userData;
5664 if (importer != nullptr)
5665 importer->_handle_end_model_xml_element(name);
5666 }

References _BBS_3MF_Importer(), and _handle_end_model_xml_element().

Here is the call graph for this function:

◆ _handle_end_object()

bool Slic3r::_BBS_3MF_Importer::_handle_end_object ( )
private
3823 {
3824 if (!m_load_model) {
3825 delete m_curr_object;
3826 m_curr_object = nullptr;
3827 return true;
3828 }
3829 if (!m_curr_object || (m_curr_object->id == -1)) {
3830 add_error("Found invalid object");
3831 return false;
3832 }
3833 else {
3834 if (m_is_bbl_3mf && boost::ends_with(m_curr_object->uuid, OBJECT_UUID_SUFFIX) && m_load_restore) {
3835 // Adjust backup object/volume id
3836 std::istringstream iss(m_curr_object->uuid);
3837 int backup_id;
3838 bool need_replace = false;
3839 if (iss >> std::hex >> backup_id) {
3840 need_replace = (m_curr_object->id != backup_id);
3841 m_curr_object->id = backup_id;
3842 }
3843 if (!m_curr_object->components.empty())
3844 {
3845 Id first_id = m_curr_object->components.front().object_id;
3846 first_id.second = 0;
3847 IdToCurrentObjectMap::iterator current_object = m_current_objects.lower_bound(first_id);
3848 IdToCurrentObjectMap new_map;
3849 for (int index = 0; index < m_curr_object->components.size(); index++)
3850 {
3851 Component& component = m_curr_object->components[index];
3852 Id new_id = component.object_id;
3853 new_id.second = (index + 1) << 16 | backup_id;
3854 if (current_object != m_current_objects.end()
3855 && (new_id.first.empty() || new_id.first == current_object->first.first)) {
3856 current_object->second.id = new_id.second;
3857 new_map.insert({new_id, std::move(current_object->second)});
3858 current_object = m_current_objects.erase(current_object);
3859 }
3860 else {
3861 add_error("can not find object for component, id=" + std::to_string(component.object_id.second));
3862 delete m_curr_object;
3863 m_curr_object = nullptr;
3864 return false;
3865 }
3866 component.object_id.second = new_id.second;
3867 }
3868 for (auto & obj : new_map)
3869 m_current_objects.insert({obj.first, std::move(obj.second)});
3870 }
3871 }
3872
3873 Id id = std::make_pair(m_sub_model_path, m_curr_object->id);
3874 if (m_current_objects.find(id) == m_current_objects.end()) {
3875 m_current_objects.insert({ id, std::move(*m_curr_object) });
3876 delete m_curr_object;
3877 m_curr_object = nullptr;
3878 }
3879 else {
3880 add_error("Found object with duplicate id");
3881 delete m_curr_object;
3882 m_curr_object = nullptr;
3883 return false;
3884 }
3885 }
3886
3887 /*if (m_curr_object.object != nullptr) {
3888 if (m_curr_object.id != -1) {
3889 if (m_curr_object.geometry.empty()) {
3890 // no geometry defined
3891 // remove the object from the model
3892 m_model->delete_object(m_curr_object.object);
3893
3894 if (m_curr_object.components.empty()) {
3895 // no components defined -> invalid object, delete it
3896 IdToModelObjectMap::iterator object_item = m_objects.find(id);
3897 if (object_item != m_objects.end())
3898 m_objects.erase(object_item);
3899
3900 IdToAliasesMap::iterator alias_item = m_objects_aliases.find(id);
3901 if (alias_item != m_objects_aliases.end())
3902 m_objects_aliases.erase(alias_item);
3903 }
3904 else
3905 // adds components to aliases
3906 m_objects_aliases.insert({ id, m_curr_object.components });
3907 }
3908 else {
3909 // geometry defined, store it for later use
3910 m_geometries.insert({ id, std::move(m_curr_object.geometry) });
3911
3912 // stores the object for later use
3913 if (m_objects.find(id) == m_objects.end()) {
3914 m_objects.insert({ id, m_curr_object.model_object_idx });
3915 m_objects_aliases.insert({ id, { 1, Component(m_curr_object.id) } }); // aliases itself
3916 }
3917 else {
3918 add_error("Found object with duplicate id");
3919 return false;
3920 }
3921 }
3922 }
3923 else {
3924 //sub objects
3925 }
3926 }*/
3927
3928 return true;
3929 }
std::map< Id, CurrentObject > IdToCurrentObjectMap
Definition bbs_3mf.cpp:1009
bool m_load_model
Definition bbs_3mf.cpp:1167
bool m_load_restore
Definition bbs_3mf.cpp:1171

References _handle_end_object(), Slic3r::_BBS_3MF_Base::add_error(), m_curr_object, m_current_objects, m_is_bbl_3mf, m_load_model, m_load_restore, m_sub_model_path, Slic3r::_BBS_3MF_Importer::Component::object_id, and OBJECT_UUID_SUFFIX.

Referenced by _handle_end_model_xml_element(), and _handle_end_object().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_relationships_element() [1/2]

void Slic3r::_BBS_3MF_Importer::_handle_end_relationships_element ( const char * name)
private
5143 {
5144 if (m_xml_parser == nullptr)
5145 return;
5146
5147 bool res = true;
5148
5149 if (!res)
5151 }

References _handle_end_relationships_element(), _stop_xml_parser(), and m_xml_parser.

Here is the call graph for this function:

◆ _handle_end_relationships_element() [2/2]

void XMLCALL Slic3r::_BBS_3MF_Importer::_handle_end_relationships_element ( void * userData,
const char * name )
staticprivate
5120 {
5121 _BBS_3MF_Importer* importer = (_BBS_3MF_Importer*)userData;
5122 if (importer != nullptr)
5123 importer->_handle_end_relationships_element(name);
5124 }

References _BBS_3MF_Importer(), and _handle_end_relationships_element().

Referenced by _handle_end_relationships_element(), _handle_end_relationships_element(), _load_model_from_file(), get_thumbnail(), and load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_resources()

bool Slic3r::_BBS_3MF_Importer::_handle_end_resources ( )
private
3782 {
3783 // do nothing
3784 return true;
3785 }

References _handle_end_resources().

Referenced by _handle_end_model_xml_element(), and _handle_end_resources().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_text_info_item()

bool Slic3r::_BBS_3MF_Importer::_handle_end_text_info_item ( )
private
5108 {
5109 return true;
5110 }

References _handle_end_text_info_item().

Referenced by _handle_end_text_info_item().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_triangle()

bool Slic3r::_BBS_3MF_Importer::_handle_end_triangle ( )
private
4057 {
4058 // do nothing
4059 return true;
4060 }

References _handle_end_triangle().

Referenced by _handle_end_model_xml_element(), and _handle_end_triangle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_triangles()

bool Slic3r::_BBS_3MF_Importer::_handle_end_triangles ( )
private
4018 {
4019 // do nothing
4020 return true;
4021 }

References _handle_end_triangles().

Referenced by _handle_end_model_xml_element(), and _handle_end_triangles().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_vertex()

bool Slic3r::_BBS_3MF_Importer::_handle_end_vertex ( )
private
4004 {
4005 // do nothing
4006 return true;
4007 }

References _handle_end_vertex().

Referenced by _handle_end_model_xml_element(), and _handle_end_vertex().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_end_vertices()

bool Slic3r::_BBS_3MF_Importer::_handle_end_vertices ( )
private
3979 {
3980 // do nothing
3981 return true;
3982 }

References _handle_end_vertices().

Referenced by _handle_end_model_xml_element(), and _handle_end_vertices().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_assemble()

bool Slic3r::_BBS_3MF_Importer::_handle_start_assemble ( const char ** attributes,
unsigned int num_attributes )
private
5009 {
5010 return true;
5011 }

References _handle_start_assemble().

Referenced by _handle_start_assemble(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_assemble_item()

bool Slic3r::_BBS_3MF_Importer::_handle_start_assemble_item ( const char ** attributes,
unsigned int num_attributes )
private
5020 {
5021 if (!m_load_model) return true;
5022
5023 int object_id = bbs_get_attribute_value_int(attributes, num_attributes, OBJECT_ID_ATTR);
5024 int instance_id = bbs_get_attribute_value_int(attributes, num_attributes, INSTANCEID_ATTR);
5025
5026 IndexToPathMap::iterator index_iter = m_index_paths.find(object_id);
5027 if (index_iter == m_index_paths.end()) {
5028 add_error("can not find object for assemble item, id= " + std::to_string(object_id));
5029 return false;
5030 }
5031 Id temp_id = std::make_pair(index_iter->second, index_iter->first);
5032 IdToModelObjectMap::iterator object_item = m_objects.find(temp_id);
5033 if (object_item == m_objects.end()) {
5034 add_error("can not find object for assemble item, id= " + std::to_string(object_id));
5035 return false;
5036 }
5037 object_id = object_item->second;
5038
5041 if (object_id < m_model->objects.size()) {
5042 if (instance_id < m_model->objects[object_id]->instances.size()) {
5043 m_model->objects[object_id]->instances[instance_id]->set_assemble_from_transform(transform);
5044 m_model->objects[object_id]->instances[instance_id]->set_offset_to_assembly(ofs2ass);
5045 }
5046 }
5047 return true;
5048 }
static constexpr const char * TRANSFORM_ATTR
Definition 3mf.cpp:137
static constexpr const char * OBJECT_ID_ATTR
Definition bbs_3mf.cpp:398
Slic3r::Transform3d bbs_get_transform_from_3mf_specs_string(const std::string &mat_str)
Definition bbs_3mf.cpp:637
Slic3r::Vec3d bbs_get_offset_from_3mf_specs_string(const std::string &vec_str)
Definition bbs_3mf.cpp:666
static constexpr const char * INSTANCEID_ATTR
Definition bbs_3mf.cpp:399
int bbs_get_attribute_value_int(const char **attributes, unsigned int attributes_size, const char *attribute_key)
Definition bbs_3mf.cpp:552
std::string bbs_get_attribute_value_string(const char **attributes, unsigned int attributes_size, const char *attribute_key)
Definition bbs_3mf.cpp:538
static constexpr const char * OFFSET_ATTR
Definition bbs_3mf.cpp:351

References _handle_start_assemble_item(), Slic3r::_BBS_3MF_Base::add_error(), bbs_get_attribute_value_int(), bbs_get_attribute_value_string(), bbs_get_offset_from_3mf_specs_string(), bbs_get_transform_from_3mf_specs_string(), INSTANCEID_ATTR, m_index_paths, m_load_model, m_model, m_objects, OBJECT_ID_ATTR, OFFSET_ATTR, Slic3r::transform(), and TRANSFORM_ATTR.

Referenced by _handle_start_assemble_item(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_build()

bool Slic3r::_BBS_3MF_Importer::_handle_start_build ( const char ** attributes,
unsigned int num_attributes )
private
4107 {
4108 // do nothing
4109 return true;
4110 }

References _handle_start_build().

Referenced by _handle_start_build(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_color()

bool Slic3r::_BBS_3MF_Importer::_handle_start_color ( const char ** attributes,
unsigned int num_attributes )
private
3944 {
3945 std::string color = bbs_get_attribute_value_string(attributes, num_attributes, COLOR_ATTR);
3947 return true;
3948 }
static constexpr const char * COLOR_ATTR
Definition bbs_3mf.cpp:339
int m_current_color_group
Definition bbs_3mf.cpp:1245
std::map< int, std::string > m_group_id_to_color
Definition bbs_3mf.cpp:1246

References _handle_start_color(), bbs_get_attribute_value_string(), COLOR_ATTR, m_current_color_group, and m_group_id_to_color.

Referenced by _handle_start_color(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_color_group()

bool Slic3r::_BBS_3MF_Importer::_handle_start_color_group ( const char ** attributes,
unsigned int num_attributes )
private
3932 {
3933 m_current_color_group = bbs_get_attribute_value_int(attributes, num_attributes, ID_ATTR);
3934 return true;
3935 }
static constexpr const char * ID_ATTR
Definition 3mf.cpp:129

References _handle_start_color_group(), bbs_get_attribute_value_int(), ID_ATTR, and m_current_color_group.

Referenced by _handle_start_color_group(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_component()

bool Slic3r::_BBS_3MF_Importer::_handle_start_component ( const char ** attributes,
unsigned int num_attributes )
private
4077 {
4078 std::string path = xml_unescape(bbs_get_attribute_value_string(attributes, num_attributes, PPATH_ATTR));
4079 int object_id = bbs_get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR);
4081
4082 /*Id id = std::make_pair(m_sub_model_path, object_id);
4083 IdToModelObjectMap::iterator object_item = m_objects.find(id);
4084 if (object_item == m_objects.end()) {
4085 IdToAliasesMap::iterator alias_item = m_objects_aliases.find(id);
4086 if (alias_item == m_objects_aliases.end()) {
4087 add_error("Found component with invalid object id");
4088 return false;
4089 }
4090 }*/
4091
4092 if (m_curr_object) {
4093 Id id = std::make_pair(m_sub_model_path.empty() ? path : m_sub_model_path, object_id);
4094 m_curr_object->components.emplace_back(id, transform);
4095 }
4096
4097 return true;
4098 }
static constexpr const char * OBJECTID_ATTR
Definition 3mf.cpp:136
static constexpr const char * PPATH_ATTR
Definition bbs_3mf.cpp:327

References _handle_start_component(), bbs_get_attribute_value_int(), bbs_get_attribute_value_string(), bbs_get_transform_from_3mf_specs_string(), m_curr_object, m_sub_model_path, OBJECTID_ATTR, PPATH_ATTR, Slic3r::transform(), TRANSFORM_ATTR, and Slic3r::xml_unescape().

Referenced by _handle_start_component(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_components()

bool Slic3r::_BBS_3MF_Importer::_handle_start_components ( const char ** attributes,
unsigned int num_attributes )
private
4063 {
4064 // reset current components
4065 if (m_curr_object)
4066 m_curr_object->components.clear();
4067 return true;
4068 }

References _handle_start_components(), and m_curr_object.

Referenced by _handle_start_components(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config ( const char ** attributes,
unsigned int num_attributes )
private
4475 {
4476 // do nothing
4477 return true;
4478 }

References _handle_start_config().

Referenced by _handle_start_config(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_filament()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_filament ( const char ** attributes,
unsigned int num_attributes )
private
4841 {
4842 if (m_curr_plater) {
4843 std::string id = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_ID_TAG);
4844 std::string type = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_TYPE_TAG);
4845 std::string color = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_COLOR_TAG);
4846 std::string used_m = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_USED_M_TAG);
4847 std::string used_g = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_USED_G_TAG);
4848 std::string filament_id = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_TRAY_INFO_ID_TAG);
4849 std::string used_for_object = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_USED_FOR_OBJECT);
4850 std::string used_for_support = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_USED_FOR_SUPPORT);
4851 std::string group_id = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_NOZZLE_GROUP_ID_TAG);
4852 std::string nozzle_diameter = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_NOZZLE_DIAMETER_TAG);
4853 std::string volume_type = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_NOZZLE_VOLUME_TYPE_TAG);
4854 FilamentInfo filament_info;
4855 filament_info.id = atoi(id.c_str()) - 1;
4856 filament_info.type = type;
4857 filament_info.color = color;
4858 filament_info.used_m = atof(used_m.c_str());
4859 filament_info.used_g = atof(used_g.c_str());
4860 filament_info.filament_id = filament_id;
4861 std::istringstream(used_for_object) >> std::boolalpha >> filament_info.used_for_object;
4862 std::istringstream(used_for_support) >> std::boolalpha >> filament_info.used_for_support;
4863 filament_info.group_id = parse_int_list(group_id);
4864 filament_info.nozzle_diameter = atof(nozzle_diameter.c_str());
4865 filament_info.nozzle_volume_type = volume_type;
4866 m_curr_plater->slice_filaments_info.push_back(filament_info);
4867 }
4868 return true;
4869 }
static constexpr const char * FILAMENT_ID_TAG
Definition bbs_3mf.cpp:277
static constexpr const char * FILAMENT_USED_FOR_OBJECT
Definition bbs_3mf.cpp:283
static constexpr const char * FILAMENT_NOZZLE_GROUP_ID_TAG
Definition bbs_3mf.cpp:284
static constexpr const char * FILAMENT_USED_G_TAG
Definition bbs_3mf.cpp:281
static constexpr const char * FILAMENT_TYPE_TAG
Definition bbs_3mf.cpp:278
static constexpr const char * FILAMENT_NOZZLE_VOLUME_TYPE_TAG
Definition bbs_3mf.cpp:286
static constexpr const char * FILAMENT_COLOR_TAG
Definition bbs_3mf.cpp:279
static constexpr const char * FILAMENT_NOZZLE_DIAMETER_TAG
Definition bbs_3mf.cpp:285
std::vector< int > parse_int_list(const std::string &value)
Definition bbs_3mf.cpp:585
static constexpr const char * FILAMENT_USED_M_TAG
Definition bbs_3mf.cpp:280
static constexpr const char * FILAMENT_TRAY_INFO_ID_TAG
Definition bbs_3mf.cpp:288
static constexpr const char * FILAMENT_USED_FOR_SUPPORT
Definition bbs_3mf.cpp:282
zaa_minimize_perimeter_height nozzle_diameter((ConfigOptionBool, reduce_infill_retraction))((ConfigOptionBool
uint32_t group_id(std::vector< Bridge > &bridges, uint32_t src_id)
Definition LayerRegion.cpp:214

References _handle_start_config_filament(), bbs_get_attribute_value_string(), Slic3r::FilamentGroupUtils::FilamentInfo::color, FILAMENT_COLOR_TAG, FILAMENT_ID_TAG, FILAMENT_NOZZLE_DIAMETER_TAG, FILAMENT_NOZZLE_GROUP_ID_TAG, FILAMENT_NOZZLE_VOLUME_TYPE_TAG, FILAMENT_TRAY_INFO_ID_TAG, FILAMENT_TYPE_TAG, FILAMENT_USED_FOR_OBJECT, FILAMENT_USED_FOR_SUPPORT, FILAMENT_USED_G_TAG, FILAMENT_USED_M_TAG, Slic3r::group_id(), m_curr_plater, Slic3r::nozzle_diameter(), parse_int_list(), and Slic3r::FilamentGroupUtils::FilamentInfo::type.

Referenced by _handle_start_config_filament(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_metadata()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_metadata ( const char ** attributes,
unsigned int num_attributes )
private
4578 {
4579 //std::string type = bbs_get_attribute_value_string(attributes, num_attributes, TYPE_ATTR);
4580 std::string key = bbs_get_attribute_value_string(attributes, num_attributes, KEY_ATTR);
4581 std::string value = bbs_get_attribute_value_string(attributes, num_attributes, VALUE_ATTR);
4582 if (key.empty())
4583 return true;
4584
4585 auto get_vector_from_string = [](const std::string& str) -> std::vector<int> {
4586 std::stringstream stream(str);
4587 int value;
4588 std::vector<int> results;
4589 while (stream >> value) {
4590 results.push_back(value);
4591 }
4592 return results;
4593 };
4594
4595 auto get_vector_array_from_string = [get_vector_from_string](const std::string &str) -> std::vector<std::vector<int>> {
4596 std::vector<std::string> sub_strs;
4597 size_t pos = 0;
4598 size_t found = 0;
4599 while ((found = str.find('#', pos)) != std::string::npos) {
4600 std::string sub_str = str.substr(pos, found - pos);
4601 sub_strs.push_back(sub_str);
4602 pos = found + 1;
4603 }
4604
4605 std::vector<std::vector<int>> results;
4606 for (std::string sub_str : sub_strs) {
4607 results.emplace_back(get_vector_from_string(sub_str));
4608 }
4609
4610 return results;
4611 };
4612
4613 if ((m_curr_plater == nullptr)&&!m_parsing_slice_info)
4614 {
4615 IdToMetadataMap::iterator object = m_objects_metadata.find(m_curr_config.object_id);
4616 if (object == m_objects_metadata.end()) {
4617 add_error("Cannot find object for metadata, id " + std::to_string(m_curr_config.object_id));
4618 return false;
4619 }
4620 if (m_curr_config.volume_id == -1)
4621 object->second.metadata.emplace_back(key, value);
4622 else {
4623 if (size_t(m_curr_config.volume_id) < object->second.volumes.size())
4624 object->second.volumes[m_curr_config.volume_id].metadata.emplace_back(key, value);
4625 }
4626 }
4627 else
4628 {
4629 //plater
4630 if (key == PLATERID_ATTR)
4631 {
4632 m_curr_plater->plate_index = atoi(value.c_str());
4633 }
4634 else if (key == PLATER_NAME_ATTR) {
4635 m_curr_plater->plate_name = xml_unescape(value.c_str());
4636 }
4637 else if (key == LOCK_ATTR)
4638 {
4639 std::istringstream(value) >> std::boolalpha >> m_curr_plater->locked;
4640 }
4641 else if (key == BED_TYPE_ATTR)
4642 {
4643 BedType bed_type = BedType::btPC;
4644 const std::string bed_type_value = value == "SuperTack Plate" ? "Supertack Plate" : value;
4645 ConfigOptionEnum<BedType>::from_string(bed_type_value, bed_type);
4646 m_curr_plater->config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type));
4647 }
4648 else if (key == PRINT_SEQUENCE_ATTR)
4649 {
4652 m_curr_plater->config.set_key_value("print_sequence", new ConfigOptionEnum<PrintSequence>(print_sequence));
4653 }
4654 else if (key == FIRST_LAYER_PRINT_SEQUENCE_ATTR) {
4655 m_curr_plater->config.set_key_value("first_layer_print_sequence", new ConfigOptionInts(get_vector_from_string(value)));
4656 }
4657 else if (key == OTHER_LAYERS_PRINT_SEQUENCE_ATTR) {
4658 m_curr_plater->config.set_key_value("other_layers_print_sequence", new ConfigOptionInts(get_vector_from_string(value)));
4659 }
4660 else if (key == OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR) {
4661 m_curr_plater->config.set_key_value("other_layers_print_sequence_nums", new ConfigOptionInt(stoi(value)));
4662 }
4663 else if (key == SPIRAL_VASE_MODE) {
4664 bool spiral_mode = false;
4665 std::istringstream(value) >> std::boolalpha >> spiral_mode;
4666 m_curr_plater->config.set_key_value("spiral_mode", new ConfigOptionBool(spiral_mode));
4667 }
4668 else if (key == IMEX_PARALLEL_MODE_ATTR || key == IXEX_PARALLEL_MODE_ATTR_LEGACY) {
4669 m_curr_plater->config.set_key_value("imex_parallel_mode", new ConfigOptionString(value));
4670 }
4671 else if (key == IMEX_HEAD_FILAMENT_MAP_ATTR) {
4672 m_curr_plater->config.set_key_value("imex_head_filament_map", new ConfigOptionString(value));
4673 }
4674 else if (key == FILAMENT_MAP_MODE_ATTR)
4675 {
4677 // handle old versions, only load manual params
4678 if (value != "Auto") {
4680 m_curr_plater->config.set_key_value("filament_map_mode", new ConfigOptionEnum<FilamentMapMode>(map_mode));
4681 }
4682 }
4683 else if (key == FILAMENT_MAP_ATTR) {
4684 if (m_curr_plater){
4685 auto filament_map = get_vector_from_string(value);
4686 for (size_t idx = 0; idx < filament_map.size(); ++idx) {
4687 if (filament_map[idx] < 1) {
4688 filament_map[idx] = 1;
4689 }
4690 }
4691 m_curr_plater->filament_maps = filament_map;
4692 m_curr_plater->config.set_key_value("filament_map", new ConfigOptionInts(filament_map));
4693 }
4694 }
4695 else if (key == FILAMENT_VOL_MAP_ATTR) {
4696 if (m_curr_plater){
4697 auto filament_volume_map = get_vector_from_string(value);
4698 for (size_t idx = 0; idx < filament_volume_map.size(); ++idx) {
4699 // The map feeds per-filament slot resolution and grouping. Clamp any
4700 // higher volume-type back to Standard(0) on load: Hybrid(2) is only an
4701 // in-memory grouping seed that is never persisted, and TPU High Flow(3)
4702 // is clamped with the same information loss on every load.
4703 if (filament_volume_map[idx] > 1) {
4704 filament_volume_map[idx] = 0;
4705 }
4706 }
4707 m_curr_plater->config.set_key_value("filament_volume_map", new ConfigOptionInts(filament_volume_map));
4708 }
4709 }
4710 else if (key == GCODE_FILE_ATTR)
4711 {
4712 m_curr_plater->gcode_file = value;
4713 }
4714 else if (key == THUMBNAIL_FILE_ATTR)
4715 {
4716 m_curr_plater->thumbnail_file = value;
4717 }
4718 else if (key == NO_LIGHT_THUMBNAIL_FILE_ATTR)
4719 {
4720 m_curr_plater->no_light_thumbnail_file = value;
4721 }
4722 else if (key == TOP_FILE_ATTR)
4723 {
4724 m_curr_plater->top_file = value;
4725 }
4726 else if (key == PICK_FILE_ATTR)
4727 {
4728 m_curr_plater->pick_file = value;
4729 }
4730 //else if (key == PATTERN_FILE_ATTR)
4731 //{
4732 // m_curr_plater->pattern_file = value;
4733 //}
4734 else if (key == PATTERN_BBOX_FILE_ATTR)
4735 {
4736 m_curr_plater->pattern_bbox_file = value;
4737 }
4738 else if (key == INSTANCEID_ATTR)
4739 {
4740 m_curr_instance.instance_id = atoi(value.c_str());
4741 }
4742 else if (key == IDENTIFYID_ATTR)
4743 {
4744 m_curr_instance.identify_id = atoi(value.c_str());
4745 }
4746 else if (key == OBJECT_ID_ATTR)
4747 {
4748 m_curr_instance.object_id = atoi(value.c_str());
4749 /*int obj_id = atoi(value.c_str());
4750 m_curr_instance.object_id = -1;
4751 IndexToPathMap::iterator index_iter = m_index_paths.find(obj_id);
4752 if (index_iter == m_index_paths.end()) {
4753 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__
4754 << boost::format(", can not find object for plate's item, id=%1%, skip this object")%obj_id;
4755 return true;
4756 }
4757 Id temp_id = std::make_pair(index_iter->second, index_iter->first);
4758 IdToModelObjectMap::iterator object_item = m_objects.find(temp_id);
4759 if (object_item == m_objects.end()) {
4760 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__
4761 << boost::format(", can not find object for plate's item, ID <%1%, %2%>, skip this object")%index_iter->second %index_iter->first;
4762 return true;
4763 }
4764 m_curr_instance.object_id = object_item->second;*/
4765 }
4766 else if (key == PLATE_IDX_ATTR)
4767 {
4768 int plate_index = atoi(value.c_str());
4769 std::map<int, PlateData*>::iterator it = m_plater_data.find(plate_index);
4770 if (it != m_plater_data.end())
4771 m_curr_plater = it->second;
4772 }
4773 else if (key == SLICE_PREDICTION_ATTR)
4774 {
4775 if (m_curr_plater)
4776 m_curr_plater->gcode_prediction = value;
4777 }
4778 else if (key == SLICE_WEIGHT_ATTR)
4779 {
4780 if (m_curr_plater)
4781 m_curr_plater->gcode_weight = value;
4782 }
4783 else if (key == OUTSIDE_ATTR)
4784 {
4785 if (m_curr_plater)
4786 std::istringstream(value) >> std::boolalpha >> m_curr_plater->toolpath_outside;
4787 }
4788 else if (key == SUPPORT_USED_ATTR)
4789 {
4790 if (m_curr_plater)
4791 std::istringstream(value) >> std::boolalpha >> m_curr_plater->is_support_used;
4792 }
4793 else if (key == LABEL_OBJECT_ENABLED_ATTR)
4794 {
4795 if (m_curr_plater)
4796 std::istringstream(value) >> std::boolalpha >> m_curr_plater->is_label_object_enabled;
4797 }
4798 else if (key == ENABLE_FILAMENT_DYNAMIC_MAP_ATTR)
4799 {
4800 if (m_curr_plater) {
4801 bool enable_filament_dynamic_map = false;
4802 std::istringstream(value) >> std::boolalpha >> enable_filament_dynamic_map;
4803 m_curr_plater->config.set_key_value("enable_filament_dynamic_map", new ConfigOptionBool(enable_filament_dynamic_map));
4804 }
4805 }
4806 else if (key == HAS_FILAMENT_SWITCHER_ATTR)
4807 {
4808 if (m_curr_plater) {
4809 bool has_filament_switcher = false;
4810 std::istringstream(value) >> std::boolalpha >> has_filament_switcher;
4811 m_curr_plater->config.set_key_value("has_filament_switcher", new ConfigOptionBool(has_filament_switcher));
4812 }
4813 }
4814 else if (key == PRINTER_MODEL_ID_ATTR)
4815 {
4816 if (m_curr_plater)
4817 m_curr_plater->printer_model_id = value;
4818 }
4819 else if (key == NOZZLE_VOLUME_TYPE_ATTR)
4820 {
4821 if (m_curr_plater)
4822 m_curr_plater->nozzle_volume_types = value;
4823 }
4824 else if (key == NOZZLE_DIAMETERS_ATTR)
4825 {
4826 if (m_curr_plater)
4827 m_curr_plater->nozzle_diameters = value;
4828 }
4829 }
4830
4831 return true;
4832 }
static constexpr const char * VALUE_ATTR
Definition 3mf.cpp:146
static constexpr const char * KEY_ATTR
Definition 3mf.cpp:145
static constexpr const char * PATTERN_BBOX_FILE_ATTR
Definition bbs_3mf.cpp:397
static constexpr const char * PLATERID_ATTR
Definition bbs_3mf.cpp:401
static constexpr const char * LABEL_OBJECT_ENABLED_ATTR
Definition bbs_3mf.cpp:415
static constexpr const char * FILAMENT_MAP_ATTR
Definition bbs_3mf.cpp:388
static constexpr const char * SUPPORT_USED_ATTR
Definition bbs_3mf.cpp:414
static constexpr const char * IMEX_HEAD_FILAMENT_MAP_ATTR
Definition bbs_3mf.cpp:386
static constexpr const char * PICK_FILE_ATTR
Definition bbs_3mf.cpp:395
static constexpr const char * THUMBNAIL_FILE_ATTR
Definition bbs_3mf.cpp:392
static constexpr const char * GCODE_FILE_ATTR
Definition bbs_3mf.cpp:391
static constexpr const char * PLATER_NAME_ATTR
Definition bbs_3mf.cpp:402
static constexpr const char * PRINTER_MODEL_ID_ATTR
Definition bbs_3mf.cpp:404
static constexpr const char * ENABLE_FILAMENT_DYNAMIC_MAP_ATTR
Definition bbs_3mf.cpp:416
static constexpr const char * IXEX_PARALLEL_MODE_ATTR_LEGACY
Definition bbs_3mf.cpp:385
static constexpr const char * PRINT_SEQUENCE_ATTR
Definition bbs_3mf.cpp:376
static constexpr const char * FIRST_LAYER_PRINT_SEQUENCE_ATTR
Definition bbs_3mf.cpp:377
static constexpr const char * TOP_FILE_ATTR
Definition bbs_3mf.cpp:394
static constexpr const char * SPIRAL_VASE_MODE
Definition bbs_3mf.cpp:380
static constexpr const char * PLATE_IDX_ATTR
Definition bbs_3mf.cpp:403
static constexpr const char * OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR
Definition bbs_3mf.cpp:379
static constexpr const char * NO_LIGHT_THUMBNAIL_FILE_ATTR
Definition bbs_3mf.cpp:393
static constexpr const char * FILAMENT_MAP_MODE_ATTR
Definition bbs_3mf.cpp:387
static constexpr const char * NOZZLE_DIAMETERS_ATTR
Definition bbs_3mf.cpp:408
static constexpr const char * BED_TYPE_ATTR
Definition bbs_3mf.cpp:375
static constexpr const char * HAS_FILAMENT_SWITCHER_ATTR
Definition bbs_3mf.cpp:417
static constexpr const char * SLICE_PREDICTION_ATTR
Definition bbs_3mf.cpp:409
static constexpr const char * IMEX_PARALLEL_MODE_ATTR
Definition bbs_3mf.cpp:381
static constexpr const char * SLICE_WEIGHT_ATTR
Definition bbs_3mf.cpp:410
static constexpr const char * OTHER_LAYERS_PRINT_SEQUENCE_ATTR
Definition bbs_3mf.cpp:378
static constexpr const char * OUTSIDE_ATTR
Definition bbs_3mf.cpp:413
static constexpr const char * FILAMENT_VOL_MAP_ATTR
Definition bbs_3mf.cpp:389
static constexpr const char * IDENTIFYID_ATTR
Definition bbs_3mf.cpp:400
static constexpr const char * NOZZLE_VOLUME_TYPE_ATTR
Definition bbs_3mf.cpp:406
static constexpr const char * LOCK_ATTR
Definition bbs_3mf.cpp:374
static bool from_string(const std::string &str, T &value)
Definition Config.hpp:2132
bool m_parsing_slice_info
Definition bbs_3mf.cpp:1240
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:16
zaa_minimize_perimeter_height print_sequence((ConfigOptionEnum< PrintOrder >, print_order))((ConfigOptionInts
BedType
Definition PrintConfig.hpp:507
@ btPC
Definition PrintConfig.hpp:509
zaa_minimize_perimeter_height filament_map((ConfigOptionInts, filament_volume_map))((ConfigOptionInts
PrintSequence
Definition PrintConfig.hpp:310
@ ByLayer
Definition PrintConfig.hpp:311
ConfigOptionIntsTempl< false > ConfigOptionInts
Definition Config.hpp:1154
FilamentMapMode
Definition PrintConfig.hpp:632
@ fmmAutoForFlush
Definition PrintConfig.hpp:633

References _handle_start_config_metadata(), Slic3r::_BBS_3MF_Base::add_error(), bbs_get_attribute_value_string(), BED_TYPE_ATTR, Slic3r::btPC, Slic3r::ByLayer, ENABLE_FILAMENT_DYNAMIC_MAP_ATTR, Slic3r::filament_map(), FILAMENT_MAP_ATTR, FILAMENT_MAP_MODE_ATTR, FILAMENT_VOL_MAP_ATTR, FIRST_LAYER_PRINT_SEQUENCE_ATTR, Slic3r::fmmAutoForFlush, Slic3r::ConfigOptionEnum< T >::from_string(), GCODE_FILE_ATTR, HAS_FILAMENT_SWITCHER_ATTR, IDENTIFYID_ATTR, IMEX_HEAD_FILAMENT_MAP_ATTR, IMEX_PARALLEL_MODE_ATTR, INSTANCEID_ATTR, IXEX_PARALLEL_MODE_ATTR_LEGACY, KEY_ATTR, LABEL_OBJECT_ENABLED_ATTR, LOCK_ATTR, m_curr_config, m_curr_instance, m_curr_plater, m_objects_metadata, m_parsing_slice_info, m_plater_data, NO_LIGHT_THUMBNAIL_FILE_ATTR, NOZZLE_DIAMETERS_ATTR, NOZZLE_VOLUME_TYPE_ATTR, OBJECT_ID_ATTR, OTHER_LAYERS_PRINT_SEQUENCE_ATTR, OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR, OUTSIDE_ATTR, PATTERN_BBOX_FILE_ATTR, PICK_FILE_ATTR, PLATE_IDX_ATTR, PLATER_NAME_ATTR, PLATERID_ATTR, Slic3r::print_sequence(), PRINT_SEQUENCE_ATTR, PRINTER_MODEL_ID_ATTR, SLICE_PREDICTION_ATTR, SLICE_WEIGHT_ATTR, SPIRAL_VASE_MODE, SUPPORT_USED_ATTR, THUMBNAIL_FILE_ATTR, TOP_FILE_ATTR, VALUE_ATTR, and Slic3r::xml_unescape().

Referenced by _handle_start_config_metadata(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_mixed_filament()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_mixed_filament ( const char ** attributes,
unsigned int num_attributes )
private
4872 {
4873 if (m_curr_plater) {
4874 std::string id = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_ID_TAG);
4875 std::string type = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_TYPE_TAG);
4876 std::string color = bbs_get_attribute_value_string(attributes, num_attributes, FILAMENT_COLOR_TAG);
4877 std::string components = bbs_get_attribute_value_string(attributes, num_attributes, MIXED_FILAMENT_COMPONENTS_TAG);
4878 PlateMixedFilamentInfo mixed_info;
4879 mixed_info.id = atoi(id.c_str());
4880 mixed_info.type = type;
4881 mixed_info.color = color;
4882 mixed_info.components = components;
4883 m_curr_plater->mixed_filaments_info.push_back(mixed_info);
4884 }
4885 return true;
4886 }
static constexpr const char * MIXED_FILAMENT_COMPONENTS_TAG
Definition bbs_3mf.cpp:274

References _handle_start_config_mixed_filament(), bbs_get_attribute_value_string(), Slic3r::PlateMixedFilamentInfo::color, Slic3r::PlateMixedFilamentInfo::components, FILAMENT_COLOR_TAG, FILAMENT_ID_TAG, FILAMENT_TYPE_TAG, Slic3r::PlateMixedFilamentInfo::id, m_curr_plater, MIXED_FILAMENT_COMPONENTS_TAG, and Slic3r::PlateMixedFilamentInfo::type.

Referenced by _handle_start_config_mixed_filament(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_nozzle()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_nozzle ( const char ** attributes,
unsigned int num_attributes )
private
4895 {
4896 // Read the per-plate <nozzle> tags. Older 3mf without <nozzle> tags leave nozzles_info
4897 // empty; load_nozzle_infos_with_compatibility then rebuilds the list from the per-filament
4898 // group_id / filament_map on the device side.
4899 if (m_curr_plater) {
4900 // id="0" extruder_id="1" nozzle_diameter="0.4" volume_type="Standard"
4901 std::string id = bbs_get_attribute_value_string(attributes, num_attributes, "id");
4902 std::string extruder_id = bbs_get_attribute_value_string(attributes, num_attributes, "extruder_id");
4903 std::string nozzle_diameter= bbs_get_attribute_value_string(attributes, num_attributes, "nozzle_diameter");
4904 std::string volume_type = bbs_get_attribute_value_string(attributes, num_attributes, "volume_type");
4905
4906 auto volume_type_str_to_enum = ConfigOptionEnum<NozzleVolumeType>::get_enum_values();
4907
4908 MultiNozzleUtils::NozzleInfo nozzle_info;
4909 nozzle_info.group_id = atoi(id.c_str());
4910 nozzle_info.extruder_id = atoi(extruder_id.c_str()) - 1;
4911 nozzle_info.diameter = nozzle_diameter;
4912
4913 if (volume_type_str_to_enum.count(volume_type))
4914 nozzle_info.volume_type = NozzleVolumeType(volume_type_str_to_enum.at(volume_type));
4915 else
4916 nozzle_info.volume_type = NozzleVolumeType::nvtStandard;
4917
4918 m_curr_plater->nozzles_info.push_back(nozzle_info);
4919 }
4920 return true;
4921 }
static const t_config_enum_values & get_enum_values()
NozzleVolumeType
Definition PrintConfig.hpp:618
@ nvtStandard
Definition PrintConfig.hpp:619

References _handle_start_config_nozzle(), bbs_get_attribute_value_string(), Slic3r::MultiNozzleUtils::NozzleInfo::diameter, Slic3r::MultiNozzleUtils::NozzleInfo::extruder_id, Slic3r::ConfigOptionEnum< T >::get_enum_values(), Slic3r::MultiNozzleUtils::NozzleInfo::group_id, m_curr_plater, Slic3r::nozzle_diameter(), Slic3r::nvtStandard, and Slic3r::MultiNozzleUtils::NozzleInfo::volume_type.

Referenced by _handle_start_config_nozzle(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_object()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_object ( const char ** attributes,
unsigned int num_attributes )
private
4487 {
4489 return true;
4490 int object_id = bbs_get_attribute_value_int(attributes, num_attributes, ID_ATTR);
4491 IdToMetadataMap::iterator object_item = m_objects_metadata.find(object_id);
4492 if (object_item != m_objects_metadata.end()) {
4493 add_error("Duplicated object id: " + std::to_string(object_id) + " in model_settings.config");
4494 return false;
4495 }
4496
4497 // Added because of github #3435, currently not used by PrusaSlicer
4498 // int instances_count_id = bbs_get_attribute_value_int(attributes, num_attributes, INSTANCESCOUNT_ATTR);
4499
4500 ObjectMetadata metadata;
4501 if (bbs_get_attribute_value_charptr(attributes, num_attributes, AUTO_DROP_ATTR) != nullptr)
4502 metadata.auto_drop = bbs_get_attribute_value_bool(attributes, num_attributes, AUTO_DROP_ATTR);
4503 m_objects_metadata.insert({ object_id, std::move(metadata) });
4504 m_curr_config.object_id = object_id;
4505 return true;
4506 }
bool bbs_get_attribute_value_bool(const char **attributes, unsigned int attributes_size, const char *attribute_key)
Definition bbs_3mf.cpp:560
const char * bbs_get_attribute_value_charptr(const char **attributes, unsigned int attributes_size, const char *attribute_key)
Definition bbs_3mf.cpp:525
static constexpr const char * AUTO_DROP_ATTR
Definition bbs_3mf.cpp:353
std::optional< bool > auto_drop
Definition bbs_3mf.cpp:991

References _handle_start_config_object(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::_BBS_3MF_Importer::ObjectMetadata::auto_drop, AUTO_DROP_ATTR, bbs_get_attribute_value_bool(), bbs_get_attribute_value_charptr(), bbs_get_attribute_value_int(), ID_ATTR, m_curr_config, m_objects_metadata, and m_parsing_slice_info.

Referenced by _handle_start_config_object(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_plater()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_plater ( const char ** attributes,
unsigned int num_attributes )
private
4954 {
4955 if (!m_parsing_slice_info) {
4956 m_curr_plater = new PlateData();
4957 }
4958
4959 return true;
4960 }

References _handle_start_config_plater(), m_curr_plater, and m_parsing_slice_info.

Referenced by _handle_start_config_plater(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_plater_instance()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_plater_instance ( const char ** attributes,
unsigned int num_attributes )
private
4975 {
4976 if (!m_curr_plater)
4977 {
4978 add_error("_handle_start_config_plater_instance: don't find plate created before");
4979 return false;
4980 }
4981
4982 //do nothing
4983 return true;
4984 }

References _handle_start_config_plater_instance(), Slic3r::_BBS_3MF_Base::add_error(), and m_curr_plater.

Referenced by _handle_start_config_plater_instance(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_volume()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_volume ( const char ** attributes,
unsigned int num_attributes )
private
4515 {
4516 IdToMetadataMap::iterator object = m_objects_metadata.find(m_curr_config.object_id);
4517 if (object == m_objects_metadata.end()) {
4518 add_error("can not find object for part, id " + std::to_string(m_curr_config.object_id) );
4519 return false;
4520 }
4521
4522 m_curr_config.volume_id = (int)object->second.volumes.size();
4523
4524 unsigned int first_triangle_id = (unsigned int)bbs_get_attribute_value_int(attributes, num_attributes, FIRST_TRIANGLE_ID_ATTR);
4525 unsigned int last_triangle_id = (unsigned int)bbs_get_attribute_value_int(attributes, num_attributes, LAST_TRIANGLE_ID_ATTR);
4526
4527 //BBS: refine the part type logic
4528 std::string subtype_str = bbs_get_attribute_value_string(attributes, num_attributes, SUBTYPE_ATTR);
4530
4531 int subbject_id = bbs_get_attribute_value_int(attributes, num_attributes, ID_ATTR);
4532
4533 if (last_triangle_id > 0)
4534 object->second.volumes.emplace_back(first_triangle_id, last_triangle_id, type);
4535 else
4536 object->second.volumes.emplace_back(subbject_id, type);
4537 return true;
4538 }
static constexpr const char * FIRST_TRIANGLE_ID_ATTR
Definition 3mf.cpp:147
static constexpr const char * LAST_TRIANGLE_ID_ATTR
Definition 3mf.cpp:148
static constexpr const char * SUBTYPE_ATTR
Definition bbs_3mf.cpp:373

References _handle_start_config_volume(), Slic3r::_BBS_3MF_Base::add_error(), bbs_get_attribute_value_int(), bbs_get_attribute_value_string(), FIRST_TRIANGLE_ID_ATTR, ID_ATTR, LAST_TRIANGLE_ID_ATTR, m_curr_config, m_objects_metadata, SUBTYPE_ATTR, and Slic3r::ModelVolume::type_from_string().

Referenced by _handle_start_config_volume(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_volume_mesh()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_volume_mesh ( const char ** attributes,
unsigned int num_attributes )
private
4541 {
4542 IdToMetadataMap::iterator object = m_objects_metadata.find(m_curr_config.object_id);
4543 if (object == m_objects_metadata.end()) {
4544 add_error("can not find object for mesh_stats, id " + std::to_string(m_curr_config.object_id) );
4545 return false;
4546 }
4547 if ((m_curr_config.volume_id == -1) || ((object->second.volumes.size() - 1) < m_curr_config.volume_id)) {
4548 add_error("can not find part for mesh_stats");
4549 return false;
4550 }
4551
4552 ObjectMetadata::VolumeMetadata& volume = object->second.volumes[m_curr_config.volume_id];
4553
4554 int edges_fixed = bbs_get_attribute_value_int(attributes, num_attributes, MESH_STAT_EDGES_FIXED );
4555 int degenerate_facets = bbs_get_attribute_value_int(attributes, num_attributes, MESH_STAT_DEGENERATED_FACETS);
4556 int facets_removed = bbs_get_attribute_value_int(attributes, num_attributes, MESH_STAT_FACETS_REMOVED );
4557 int facets_reversed = bbs_get_attribute_value_int(attributes, num_attributes, MESH_STAT_FACETS_RESERVED );
4558 int backwards_edges = bbs_get_attribute_value_int(attributes, num_attributes, MESH_STAT_BACKWARDS_EDGES );
4559
4560 volume.mesh_stats = { edges_fixed, degenerate_facets, facets_removed, facets_reversed, backwards_edges };
4561
4562 return true;
4563 }
static constexpr const char * MESH_STAT_BACKWARDS_EDGES
Definition 3mf.cpp:174
static constexpr const char * MESH_STAT_EDGES_FIXED
Definition 3mf.cpp:170
static constexpr const char * MESH_STAT_FACETS_RESERVED
Definition 3mf.cpp:173
static constexpr const char * MESH_STAT_FACETS_REMOVED
Definition 3mf.cpp:172
static constexpr const char * MESH_STAT_DEGENERATED_FACETS
Definition 3mf.cpp:171

References _handle_start_config_volume_mesh(), Slic3r::_BBS_3MF_Base::add_error(), bbs_get_attribute_value_int(), m_curr_config, m_objects_metadata, MESH_STAT_BACKWARDS_EDGES, MESH_STAT_DEGENERATED_FACETS, MESH_STAT_EDGES_FIXED, MESH_STAT_FACETS_REMOVED, MESH_STAT_FACETS_RESERVED, and Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::mesh_stats.

Referenced by _handle_start_config_volume_mesh(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_warning()

bool Slic3r::_BBS_3MF_Importer::_handle_start_config_warning ( const char ** attributes,
unsigned int num_attributes )
private
4930 {
4931 if (m_curr_plater) {
4932 std::string msg = bbs_get_attribute_value_string(attributes, num_attributes, WARNING_MSG_TAG);
4933 std::string lvl_str = bbs_get_attribute_value_string(attributes, num_attributes, "level");
4934 GCodeProcessorResult::SliceWarning sw;
4935 sw.msg = msg;
4936 try {
4937 sw.level = atoi(lvl_str.c_str());
4938 }
4939 catch(...) {
4940 };
4941
4942 m_curr_plater->warnings.push_back(sw);
4943 }
4944 return true;
4945 }
static constexpr const char * WARNING_MSG_TAG
Definition bbs_3mf.cpp:276

References _handle_start_config_warning(), bbs_get_attribute_value_string(), Slic3r::GCodeProcessorResult::SliceWarning::level, m_curr_plater, Slic3r::GCodeProcessorResult::SliceWarning::msg, and WARNING_MSG_TAG.

Referenced by _handle_start_config_warning(), and _handle_start_config_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_xml_element() [1/2]

void Slic3r::_BBS_3MF_Importer::_handle_start_config_xml_element ( const char * name,
const char ** attributes )
private
3647 {
3648 if (m_xml_parser == nullptr)
3649 return;
3650
3651 bool res = true;
3652 unsigned int num_attributes = (unsigned int)XML_GetSpecifiedAttributeCount(m_xml_parser);
3653
3654 if (::strcmp(CONFIG_TAG, name) == 0)
3655 res = _handle_start_config(attributes, num_attributes);
3656 else if (::strcmp(OBJECT_TAG, name) == 0)
3657 res = _handle_start_config_object(attributes, num_attributes);
3658 else if (::strcmp(VOLUME_TAG, name) == 0)
3659 res = _handle_start_config_volume(attributes, num_attributes);
3660 else if (::strcmp(PART_TAG, name) == 0)
3661 res = _handle_start_config_volume(attributes, num_attributes);
3662 else if (::strcmp(MESH_STAT_TAG, name) == 0)
3663 res = _handle_start_config_volume_mesh(attributes, num_attributes);
3664 else if (::strcmp(METADATA_TAG, name) == 0)
3665 res = _handle_start_config_metadata(attributes, num_attributes);
3666 else if (::strcmp(SHAPE_TAG, name) == 0)
3667 res = _handle_start_shape_configuration(attributes, num_attributes);
3668 else if (::strcmp(TEXT_TAG, name) == 0)
3669 res = _handle_start_text_configuration(attributes, num_attributes);
3670 else if (::strcmp(PLATE_TAG, name) == 0)
3671 res = _handle_start_config_plater(attributes, num_attributes);
3672 else if (::strcmp(INSTANCE_TAG, name) == 0)
3673 res = _handle_start_config_plater_instance(attributes, num_attributes);
3674 else if (::strcmp(FILAMENT_TAG, name) == 0)
3675 res = _handle_start_config_filament(attributes, num_attributes);
3676 else if (::strcmp(MIXED_FILAMENT_TAG, name) == 0)
3677 res = _handle_start_config_mixed_filament(attributes, num_attributes);
3678 else if (::strcmp(SLICE_WARNING_TAG, name) == 0)
3679 res = _handle_start_config_warning(attributes, num_attributes);
3680 else if (::strcmp(NOZZLE_TAG, name) == 0)
3681 res = _handle_start_config_nozzle(attributes, num_attributes);
3682 else if (::strcmp(ASSEMBLE_TAG, name) == 0)
3683 res = _handle_start_assemble(attributes, num_attributes);
3684 else if (::strcmp(ASSEMBLE_ITEM_TAG, name) == 0)
3685 res = _handle_start_assemble_item(attributes, num_attributes);
3686 else if (::strcmp(TEXT_INFO_TAG, name) == 0)
3687 res = _handle_start_text_info_item(attributes, num_attributes);
3688
3689 if (!res)
3691 }
static constexpr const char * TEXT_TAG
Definition bbs_3mf.cpp:450
static constexpr const char * SHAPE_TAG
Definition bbs_3mf.cpp:474
static constexpr const char * TEXT_INFO_TAG
Definition bbs_3mf.cpp:305
static constexpr const char * SLICE_WARNING_TAG
Definition bbs_3mf.cpp:275
static constexpr const char * MIXED_FILAMENT_TAG
Definition bbs_3mf.cpp:273
bool _handle_start_config_volume_mesh(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4540
bool _handle_start_config_metadata(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4577
bool _handle_start_config_volume(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4514
bool _handle_start_assemble(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:5008
bool _handle_start_config_nozzle(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4894
bool _handle_start_config_filament(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4840
bool _handle_start_text_info_item(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:5055
bool _handle_start_shape_configuration(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4327
bool _handle_start_config_object(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4486
bool _handle_start_config_plater_instance(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4974
bool _handle_start_config_warning(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4929
bool _handle_start_assemble_item(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:5019
bool _handle_start_config(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4474
bool _handle_start_config_plater(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4953
bool _handle_start_config_mixed_filament(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4871
bool _handle_start_text_configuration(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4298

References _handle_start_assemble(), _handle_start_assemble_item(), _handle_start_config(), _handle_start_config_filament(), _handle_start_config_metadata(), _handle_start_config_mixed_filament(), _handle_start_config_nozzle(), _handle_start_config_object(), _handle_start_config_plater(), _handle_start_config_plater_instance(), _handle_start_config_volume(), _handle_start_config_volume_mesh(), _handle_start_config_warning(), _handle_start_config_xml_element(), _handle_start_shape_configuration(), _handle_start_text_configuration(), _handle_start_text_info_item(), _stop_xml_parser(), ASSEMBLE_ITEM_TAG, ASSEMBLE_TAG, CONFIG_TAG, FILAMENT_TAG, INSTANCE_TAG, m_xml_parser, MESH_STAT_TAG, METADATA_TAG, MIXED_FILAMENT_TAG, NOZZLE_TAG, OBJECT_TAG, PART_TAG, PLATE_TAG, SHAPE_TAG, SLICE_WARNING_TAG, TEXT_INFO_TAG, TEXT_TAG, and VOLUME_TAG.

Referenced by _handle_start_config_xml_element(), _handle_start_config_xml_element(), and load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_config_xml_element() [2/2]

void XMLCALL Slic3r::_BBS_3MF_Importer::_handle_start_config_xml_element ( void * userData,
const char * name,
const char ** attributes )
staticprivate
5676 {
5677 _BBS_3MF_Importer* importer = (_BBS_3MF_Importer*)userData;
5678 if (importer != nullptr)
5679 importer->_handle_start_config_xml_element(name, attributes);
5680 }

References _BBS_3MF_Importer(), and _handle_start_config_xml_element().

Here is the call graph for this function:

◆ _handle_start_item()

bool Slic3r::_BBS_3MF_Importer::_handle_start_item ( const char ** attributes,
unsigned int num_attributes )
private
4119 {
4120 // we are ignoring the following attributes
4121 // thumbnail
4122 // partnumber
4123 // pid
4124 // pindex
4125 // see specifications
4126
4127 int object_id = bbs_get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR);
4128 std::string path = bbs_get_attribute_value_string(attributes, num_attributes, PPATH_ATTR);
4130 int printable = bbs_get_attribute_value_bool(attributes, num_attributes, PRINTABLE_ATTR);
4131 if (const char* auto_drop = bbs_get_attribute_value_charptr(attributes, num_attributes, AUTO_DROP_ATTR); auto_drop != nullptr && !::atoi(auto_drop))
4132 m_items_auto_drop_off.insert(object_id);
4133 return !m_load_model || _create_object_instance(path, object_id, transform, printable, 1);
4134 }
static constexpr const char * PRINTABLE_ATTR
Definition 3mf.cpp:138
bool _create_object_instance(std::string const &path, int object_id, const Transform3d &transform, const bool printable, unsigned int recur_counter)
Definition bbs_3mf.cpp:4361

References _create_object_instance(), _handle_start_item(), AUTO_DROP_ATTR, bbs_get_attribute_value_bool(), bbs_get_attribute_value_charptr(), bbs_get_attribute_value_int(), bbs_get_attribute_value_string(), bbs_get_transform_from_3mf_specs_string(), m_items_auto_drop_off, m_load_model, OBJECTID_ATTR, PPATH_ATTR, PRINTABLE_ATTR, Slic3r::transform(), and TRANSFORM_ATTR.

Referenced by _handle_start_item(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_mesh()

bool Slic3r::_BBS_3MF_Importer::_handle_start_mesh ( const char ** attributes,
unsigned int num_attributes )
private
3957 {
3958 // reset current geometry
3959 if (m_curr_object)
3960 m_curr_object->geometry.reset();
3961 return true;
3962 }

References _handle_start_mesh(), and m_curr_object.

Referenced by _handle_start_mesh(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_metadata()

bool Slic3r::_BBS_3MF_Importer::_handle_start_metadata ( const char ** attributes,
unsigned int num_attributes )
private
4143 {
4144 m_curr_characters.clear();
4145
4146 std::string name = bbs_get_attribute_value_string(attributes, num_attributes, NAME_ATTR);
4147 if (!name.empty()) {
4148 m_curr_metadata_name = name;
4149 }
4150
4151 return true;
4152 }
static constexpr const char * NAME_ATTR
Definition 3mf.cpp:127

References _handle_start_metadata(), bbs_get_attribute_value_string(), m_curr_characters, m_curr_metadata_name, and NAME_ATTR.

Referenced by _handle_start_metadata(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_model()

bool Slic3r::_BBS_3MF_Importer::_handle_start_model ( const char ** attributes,
unsigned int num_attributes )
private
3730 {
3732
3733 return true;
3734 }
static constexpr const char * UNIT_ATTR
Definition 3mf.cpp:126
float bbs_get_unit_factor(const std::string &unit)
Definition bbs_3mf.cpp:689

References _handle_start_model(), bbs_get_attribute_value_string(), bbs_get_unit_factor(), m_unit_factor, and UNIT_ATTR.

Referenced by _handle_start_model(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_model_xml_element() [1/2]

void Slic3r::_BBS_3MF_Importer::_handle_start_model_xml_element ( const char * name,
const char ** attributes )
private
3557 {
3558 if (m_xml_parser == nullptr)
3559 return;
3560
3561 bool res = true;
3562 unsigned int num_attributes = (unsigned int)XML_GetSpecifiedAttributeCount(m_xml_parser);
3563
3564 if (::strcmp(MODEL_TAG, name) == 0)
3565 res = _handle_start_model(attributes, num_attributes);
3566 else if (::strcmp(RESOURCES_TAG, name) == 0)
3567 res = _handle_start_resources(attributes, num_attributes);
3568 else if (::strcmp(OBJECT_TAG, name) == 0)
3569 res = _handle_start_object(attributes, num_attributes);
3570 else if (::strcmp(COLOR_GROUP_TAG, name) == 0)
3571 res = _handle_start_color_group(attributes, num_attributes);
3572 else if (::strcmp(COLOR_TAG, name) == 0)
3573 res = _handle_start_color(attributes, num_attributes);
3574 else if (::strcmp(MESH_TAG, name) == 0)
3575 res = _handle_start_mesh(attributes, num_attributes);
3576 else if (::strcmp(VERTICES_TAG, name) == 0)
3577 res = _handle_start_vertices(attributes, num_attributes);
3578 else if (::strcmp(VERTEX_TAG, name) == 0)
3579 res = _handle_start_vertex(attributes, num_attributes);
3580 else if (::strcmp(TRIANGLES_TAG, name) == 0)
3581 res = _handle_start_triangles(attributes, num_attributes);
3582 else if (::strcmp(TRIANGLE_TAG, name) == 0)
3583 res = _handle_start_triangle(attributes, num_attributes);
3584 else if (::strcmp(COMPONENTS_TAG, name) == 0)
3585 res = _handle_start_components(attributes, num_attributes);
3586 else if (::strcmp(COMPONENT_TAG, name) == 0)
3587 res = _handle_start_component(attributes, num_attributes);
3588 else if (::strcmp(BUILD_TAG, name) == 0)
3589 res = _handle_start_build(attributes, num_attributes);
3590 else if (::strcmp(ITEM_TAG, name) == 0)
3591 res = _handle_start_item(attributes, num_attributes);
3592 else if (::strcmp(METADATA_TAG, name) == 0)
3593 res = _handle_start_metadata(attributes, num_attributes);
3594
3595 if (!res)
3597 }
bool _handle_start_vertices(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:3970
bool _handle_start_resources(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:3775
bool _handle_start_triangle(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4023
bool _handle_start_vertex(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:3984
bool _handle_start_color_group(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:3931
bool _handle_start_object(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:3787
bool _handle_start_mesh(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:3956
bool _handle_start_component(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4076
bool _handle_start_model(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:3729
bool _handle_start_item(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4118
bool _handle_start_color(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:3943
bool _handle_start_build(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4106
bool _handle_start_components(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4062
bool _handle_start_metadata(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4142
bool _handle_start_triangles(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:4009

References _handle_start_build(), _handle_start_color(), _handle_start_color_group(), _handle_start_component(), _handle_start_components(), _handle_start_item(), _handle_start_mesh(), _handle_start_metadata(), _handle_start_model(), _handle_start_model_xml_element(), _handle_start_object(), _handle_start_resources(), _handle_start_triangle(), _handle_start_triangles(), _handle_start_vertex(), _handle_start_vertices(), _stop_xml_parser(), BUILD_TAG, COLOR_GROUP_TAG, COLOR_TAG, COMPONENT_TAG, COMPONENTS_TAG, ITEM_TAG, m_xml_parser, MESH_TAG, METADATA_TAG, MODEL_TAG, OBJECT_TAG, RESOURCES_TAG, TRIANGLE_TAG, TRIANGLES_TAG, VERTEX_TAG, and VERTICES_TAG.

Referenced by _extract_model_from_archive(), _handle_start_model_xml_element(), and _handle_start_model_xml_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_model_xml_element() [2/2]

void XMLCALL Slic3r::_BBS_3MF_Importer::_handle_start_model_xml_element ( void * userData,
const char * name,
const char ** attributes )
staticprivate
5655 {
5656 _BBS_3MF_Importer* importer = (_BBS_3MF_Importer*)userData;
5657 if (importer != nullptr)
5658 importer->_handle_start_model_xml_element(name, attributes);
5659 }

References _BBS_3MF_Importer(), and _handle_start_model_xml_element().

Here is the call graph for this function:

◆ _handle_start_object()

bool Slic3r::_BBS_3MF_Importer::_handle_start_object ( const char ** attributes,
unsigned int num_attributes )
private
3788 {
3789 // reset current object data
3790 if (m_curr_object) {
3791 delete m_curr_object;
3792 m_curr_object = nullptr;
3793 }
3794
3795 std::string object_type = bbs_get_attribute_value_string(attributes, num_attributes, TYPE_ATTR);
3796
3797 if (bbs_is_valid_object_type(object_type)) {
3798 if (!m_curr_object) {
3800 // create new object (it may be removed later if no instances are generated from it)
3801 /*m_curr_object->model_object_idx = (int)m_model->objects.size();
3802 m_curr_object.object = m_model->add_object();
3803 if (m_curr_object.object == nullptr) {
3804 add_error("Unable to create object");
3805 return false;
3806 }*/
3807 }
3808
3809 m_curr_object->id = bbs_get_attribute_value_int(attributes, num_attributes, ID_ATTR);
3810 m_curr_object->name = bbs_get_attribute_value_string(attributes, num_attributes, NAME_ATTR);
3811
3812 m_curr_object->uuid = bbs_get_attribute_value_string(attributes, num_attributes, PUUID_ATTR);
3813 if (m_curr_object->uuid.empty()) {
3814 m_curr_object->uuid = bbs_get_attribute_value_string(attributes, num_attributes, PUUID_LOWER_ATTR);
3815 }
3816 m_curr_object->pid = bbs_get_attribute_value_int(attributes, num_attributes, PID_ATTR);
3817 }
3818
3819 return true;
3820 }
static constexpr const char * TYPE_ATTR
Definition 3mf.cpp:128
bool bbs_is_valid_object_type(const std::string &type)
Definition bbs_3mf.cpp:708
static constexpr const char * PUUID_LOWER_ATTR
Definition bbs_3mf.cpp:326
static constexpr const char * PID_ATTR
Definition bbs_3mf.cpp:324
static constexpr const char * PUUID_ATTR
Definition bbs_3mf.cpp:325

References _handle_start_object(), bbs_get_attribute_value_int(), bbs_get_attribute_value_string(), bbs_is_valid_object_type(), ID_ATTR, m_curr_object, NAME_ATTR, PID_ATTR, PUUID_ATTR, PUUID_LOWER_ATTR, and TYPE_ATTR.

Referenced by _handle_start_model_xml_element(), and _handle_start_object().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_relationship()

bool Slic3r::_BBS_3MF_Importer::_handle_start_relationship ( const char ** attributes,
unsigned int num_attributes )
private
5154 {
5155 std::string path = bbs_get_attribute_value_string(attributes, num_attributes, TARGET_ATTR);
5156 std::string type = bbs_get_attribute_value_string(attributes, num_attributes, RELS_TYPE_ATTR);
5157 if (boost::starts_with(type, "http://schemas.microsoft.com/3dmanufacturing/") && boost::ends_with(type, "3dmodel")) {
5158 if (m_start_part_path.empty()) m_start_part_path = path;
5159 else m_sub_model_paths.push_back(path);
5160 } else if (boost::starts_with(type, "http://schemas.openxmlformats.org/") && boost::ends_with(type, "thumbnail")) {
5161 if (boost::algorithm::ends_with(path, ".png"))
5162 m_thumbnail_path = path;
5163 } else if (boost::starts_with(type, "http://schemas.bambulab.com/") && boost::ends_with(type, "cover-thumbnail-middle")) {
5164 m_thumbnail_middle = path;
5165 } else if (boost::starts_with(type, "http://schemas.bambulab.com/") && boost::ends_with(type, "cover-thumbnail-small")) {
5166 m_thumbnail_small = path;
5167 }
5168 return true;
5169 }
static constexpr const char * RELS_TYPE_ATTR
Definition bbs_3mf.cpp:335
static constexpr const char * TARGET_ATTR
Definition bbs_3mf.cpp:334
std::string m_thumbnail_path
Definition bbs_3mf.cpp:1230
std::string m_thumbnail_middle
Definition bbs_3mf.cpp:1231
std::string m_thumbnail_small
Definition bbs_3mf.cpp:1232
std::vector< std::string > m_sub_model_paths
Definition bbs_3mf.cpp:1233
std::string m_start_part_path
Definition bbs_3mf.cpp:1229

References _handle_start_relationship(), bbs_get_attribute_value_string(), m_start_part_path, m_sub_model_paths, m_thumbnail_middle, m_thumbnail_path, m_thumbnail_small, RELS_TYPE_ATTR, and TARGET_ATTR.

Referenced by _handle_start_relationship(), and _handle_start_relationships_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_relationships_element() [1/2]

void Slic3r::_BBS_3MF_Importer::_handle_start_relationships_element ( const char * name,
const char ** attributes )
private
5127 {
5128 if (m_xml_parser == nullptr)
5129 return;
5130
5131 bool res = true;
5132 unsigned int num_attributes = (unsigned int)XML_GetSpecifiedAttributeCount(m_xml_parser);
5133
5134 if (::strcmp(RELATIONSHIP_TAG, name) == 0)
5135 res = _handle_start_relationship(attributes, num_attributes);
5136
5137 m_curr_characters.clear();
5138 if (!res)
5140 }
static constexpr const char * RELATIONSHIP_TAG
Definition bbs_3mf.cpp:323
bool _handle_start_relationship(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:5153

References _handle_start_relationship(), _handle_start_relationships_element(), _stop_xml_parser(), m_curr_characters, m_xml_parser, and RELATIONSHIP_TAG.

Here is the call graph for this function:

◆ _handle_start_relationships_element() [2/2]

void XMLCALL Slic3r::_BBS_3MF_Importer::_handle_start_relationships_element ( void * userData,
const char * name,
const char ** attributes )
staticprivate
5113 {
5114 _BBS_3MF_Importer* importer = (_BBS_3MF_Importer*)userData;
5115 if (importer != nullptr)
5116 importer->_handle_start_relationships_element(name, attributes);
5117 }

References _BBS_3MF_Importer(), and _handle_start_relationships_element().

Referenced by _handle_start_relationships_element(), _handle_start_relationships_element(), _load_model_from_file(), get_thumbnail(), and load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_resources()

bool Slic3r::_BBS_3MF_Importer::_handle_start_resources ( const char ** attributes,
unsigned int num_attributes )
private
3776 {
3777 // do nothing
3778 return true;
3779 }

References _handle_start_resources().

Referenced by _handle_start_model_xml_element(), and _handle_start_resources().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_shape_configuration()

bool Slic3r::_BBS_3MF_Importer::_handle_start_shape_configuration ( const char ** attributes,
unsigned int num_attributes )
private
4328 {
4329 IdToMetadataMap::iterator object = m_objects_metadata.find(m_curr_config.object_id);
4330 if (object == m_objects_metadata.end()) {
4331 add_error("Can not assign volume mesh to a valid object");
4332 return false;
4333 }
4334 auto &volumes = object->second.volumes;
4335 if (volumes.empty()) {
4336 add_error("Can not assign mesh to a valid volume");
4337 return false;
4338 }
4339 ObjectMetadata::VolumeMetadata &volume = volumes.back();
4340 volume.shape_configuration = read_emboss_shape(attributes, num_attributes);
4341 if (!volume.shape_configuration.has_value())
4342 return false;
4343
4344 // Fill svg file content into shape_configuration
4345 std::optional<EmbossShape::SvgFile> &svg = volume.shape_configuration->svg_file;
4346 if (!svg.has_value())
4347 return true; // do not contain svg file
4348
4349 const std::string &path = svg->path_in_3mf;
4350 if (path.empty())
4351 return true; // do not contain svg file
4352
4353 auto it = m_path_to_emboss_shape_files.find(path);
4354 if (it == m_path_to_emboss_shape_files.end())
4355 return true; // svg file is not loaded yet
4356
4357 svg->file_data = it->second;
4358 return true;
4359 }
static std::optional< EmbossShape > read_emboss_shape(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:10162
std::optional< EmbossShape > shape_configuration
Definition bbs_3mf.cpp:969

References _handle_start_shape_configuration(), Slic3r::_BBS_3MF_Base::add_error(), m_curr_config, m_objects_metadata, m_path_to_emboss_shape_files, Slic3r::read_emboss_shape(), and Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::shape_configuration.

Referenced by _handle_start_config_xml_element(), and _handle_start_shape_configuration().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_text_configuration()

bool Slic3r::_BBS_3MF_Importer::_handle_start_text_configuration ( const char ** attributes,
unsigned int num_attributes )
private
4299 {
4300 IdToMetadataMap::iterator object = m_objects_metadata.find(m_curr_config.object_id);
4301 if (object == m_objects_metadata.end()) {
4302 add_error("Can not assign volume mesh to a valid object");
4303 return false;
4304 }
4305 if (object->second.volumes.empty()) {
4306 add_error("Can not assign mesh to a valid volume");
4307 return false;
4308 }
4309 ObjectMetadata::VolumeMetadata& volume = object->second.volumes.back();
4310 volume.text_configuration = TextConfigurationSerialization::read(attributes, num_attributes);
4311 if (!volume.text_configuration.has_value())
4312 return false;
4313
4314 // Is 3mf version with shapes?
4315 if (volume.shape_configuration.has_value())
4316 return true;
4317
4318 // Back compatibility for 3mf version without shapes
4319 volume.shape_configuration = TextConfigurationSerialization::read_old(attributes, num_attributes);
4320 return true;
4321 }
static EmbossShape read_old(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:10049
static std::optional< TextConfiguration > read(const char **attributes, unsigned int num_attributes)
Definition bbs_3mf.cpp:10005
std::optional< TextConfiguration > text_configuration
Definition bbs_3mf.cpp:968

References _handle_start_text_configuration(), Slic3r::_BBS_3MF_Base::add_error(), m_curr_config, m_objects_metadata, Slic3r::TextConfigurationSerialization::read(), Slic3r::TextConfigurationSerialization::read_old(), Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::shape_configuration, and Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::text_configuration.

Referenced by _handle_start_config_xml_element(), and _handle_start_text_configuration().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_text_info_item()

bool Slic3r::_BBS_3MF_Importer::_handle_start_text_info_item ( const char ** attributes,
unsigned int num_attributes )
private
5056 {
5057 IdToMetadataMap::iterator object = m_objects_metadata.find(m_curr_config.object_id);
5058 if (object == m_objects_metadata.end()) {
5059 add_error("can not find object for text_info, id " + std::to_string(m_curr_config.object_id));
5060 return false;
5061 }
5062 if ((m_curr_config.volume_id == -1) || ((object->second.volumes.size() - 1) < m_curr_config.volume_id)) {
5063 add_error("can not find part for text_info");
5064 return false;
5065 }
5066
5067 ObjectMetadata::VolumeMetadata &volume = object->second.volumes[m_curr_config.volume_id];
5068
5069 if (volume.text_configuration.has_value()) {
5070 add_error("Both text_info and text_configuration found, ignore legacy text_info");
5071 return true;
5072 }
5073
5074 // TODO: Orca: support legacy text info
5075 /*
5076 TextInfo text_info;
5077 text_info.m_text = xml_unescape(bbs_get_attribute_value_string(attributes, num_attributes, TEXT_ATTR));
5078 text_info.m_font_name = bbs_get_attribute_value_string(attributes, num_attributes, FONT_NAME_ATTR);
5079
5080 text_info.m_curr_font_idx = bbs_get_attribute_value_int(attributes, num_attributes, FONT_INDEX_ATTR);
5081
5082 text_info.m_font_size = bbs_get_attribute_value_float(attributes, num_attributes, FONT_SIZE_ATTR);
5083 text_info.m_thickness = bbs_get_attribute_value_float(attributes, num_attributes, THICKNESS_ATTR);
5084 text_info.m_embeded_depth = bbs_get_attribute_value_float(attributes, num_attributes, EMBEDED_DEPTH_ATTR);
5085 text_info.m_rotate_angle = bbs_get_attribute_value_float(attributes, num_attributes, ROTATE_ANGLE_ATTR);
5086 text_info.m_text_gap = bbs_get_attribute_value_float(attributes, num_attributes, TEXT_GAP_ATTR);
5087
5088 text_info.m_bold = bbs_get_attribute_value_int(attributes, num_attributes, BOLD_ATTR);
5089 text_info.m_italic = bbs_get_attribute_value_int(attributes, num_attributes, ITALIC_ATTR);
5090 text_info.m_is_surface_text = bbs_get_attribute_value_int(attributes, num_attributes, SURFACE_TEXT_ATTR);
5091 text_info.m_keep_horizontal = bbs_get_attribute_value_int(attributes, num_attributes, KEEP_HORIZONTAL_ATTR);
5092
5093 text_info.m_rr.mesh_id = bbs_get_attribute_value_int(attributes, num_attributes, HIT_MESH_ATTR);
5094
5095 std::string hit_pos = bbs_get_attribute_value_string(attributes, num_attributes, HIT_POSITION_ATTR);
5096 if (!hit_pos.empty())
5097 text_info.m_rr.hit = get_vec3_from_string(hit_pos);
5098
5099 std::string hit_normal = bbs_get_attribute_value_string(attributes, num_attributes, HIT_NORMAL_ATTR);
5100 if (!hit_normal.empty())
5101 text_info.m_rr.normal = get_vec3_from_string(hit_normal);
5102
5103 volume.text_info = text_info;*/
5104 return true;
5105 }

References _handle_start_text_info_item(), Slic3r::_BBS_3MF_Base::add_error(), m_curr_config, m_objects_metadata, and Slic3r::_BBS_3MF_Importer::ObjectMetadata::VolumeMetadata::text_configuration.

Referenced by _handle_start_config_xml_element(), and _handle_start_text_info_item().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_triangle()

bool Slic3r::_BBS_3MF_Importer::_handle_start_triangle ( const char ** attributes,
unsigned int num_attributes )
private
4024 {
4025 // we are ignoring the following attributes:
4026 // p1
4027 // p2
4028 // p3
4029 // pid
4030 // see specifications
4031
4032 // appends the triangle's vertices indices
4033 // missing values are set equal to ZERO
4034 if (m_curr_object) {
4035 m_curr_object->geometry.triangles.emplace_back(
4036 bbs_get_attribute_value_int(attributes, num_attributes, V1_ATTR),
4037 bbs_get_attribute_value_int(attributes, num_attributes, V2_ATTR),
4038 bbs_get_attribute_value_int(attributes, num_attributes, V3_ATTR));
4039
4040 m_curr_object->geometry.custom_supports.push_back(bbs_get_attribute_value_string(attributes, num_attributes, CUSTOM_SUPPORTS_ATTR));
4041 m_curr_object->geometry.custom_seam.push_back(bbs_get_attribute_value_string(attributes, num_attributes, CUSTOM_SEAM_ATTR));
4042 m_curr_object->geometry.mmu_segmentation.push_back(bbs_get_attribute_value_string(attributes, num_attributes, MMU_SEGMENTATION_ATTR));
4043 m_curr_object->geometry.fuzzy_skin.push_back(bbs_get_attribute_value_string(attributes, num_attributes, CUSTOM_FUZZY_SKIN_ATTR));
4044 for (int slot = 0; slot < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++slot)
4045 if (const char *paint = bbs_get_attribute_value_charptr(attributes, num_attributes, TEXTURE_DISPLACEMENT_ATTRS[slot])) {
4046 std::vector<std::string> &mask = m_curr_object->geometry.texture_displacement[slot];
4047 mask.resize(m_curr_object->geometry.triangles.size());
4048 mask.back() = paint;
4049 }
4050 // BBS
4051 m_curr_object->geometry.face_properties.push_back(bbs_get_attribute_value_string(attributes, num_attributes, FACE_PROPERTY_ATTR));
4052 }
4053 return true;
4054 }
static constexpr const char * MMU_SEGMENTATION_ATTR
Definition 3mf.cpp:142
static constexpr const char * CUSTOM_SEAM_ATTR
Definition 3mf.cpp:141
static constexpr const char * CUSTOM_SUPPORTS_ATTR
Definition 3mf.cpp:140
static constexpr const char * V3_ATTR
Definition 3mf.cpp:135
static constexpr const char * V1_ATTR
Definition 3mf.cpp:133
static constexpr const char * V2_ATTR
Definition 3mf.cpp:134
static constexpr const char * TEXTURE_DISPLACEMENT_ATTRS[Slic3r::TEXTURE_DISPLACEMENT_MAX_LAYERS]
Definition bbs_3mf.cpp:361
static constexpr const char * CUSTOM_FUZZY_SKIN_ATTR
Definition bbs_3mf.cpp:356
static constexpr const char * FACE_PROPERTY_ATTR
Definition bbs_3mf.cpp:367

References _handle_start_triangle(), bbs_get_attribute_value_charptr(), bbs_get_attribute_value_int(), bbs_get_attribute_value_string(), CUSTOM_FUZZY_SKIN_ATTR, CUSTOM_SEAM_ATTR, CUSTOM_SUPPORTS_ATTR, FACE_PROPERTY_ATTR, m_curr_object, MMU_SEGMENTATION_ATTR, TEXTURE_DISPLACEMENT_ATTRS, Slic3r::TEXTURE_DISPLACEMENT_MAX_LAYERS, V1_ATTR, V2_ATTR, and V3_ATTR.

Referenced by _handle_start_model_xml_element(), and _handle_start_triangle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_triangles()

bool Slic3r::_BBS_3MF_Importer::_handle_start_triangles ( const char ** attributes,
unsigned int num_attributes )
private
4010 {
4011 // reset current triangles
4012 if (m_curr_object)
4013 m_curr_object->geometry.triangles.clear();
4014 return true;
4015 }

References _handle_start_triangles(), and m_curr_object.

Referenced by _handle_start_model_xml_element(), and _handle_start_triangles().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_vertex()

bool Slic3r::_BBS_3MF_Importer::_handle_start_vertex ( const char ** attributes,
unsigned int num_attributes )
private
3985 {
3986 // appends the vertex coordinates
3987 // missing values are set equal to ZERO
3988 if (m_curr_object) {
3989 const Vec3f v(m_unit_factor * bbs_get_attribute_value_float(attributes, num_attributes, X_ATTR),
3990 m_unit_factor * bbs_get_attribute_value_float(attributes, num_attributes, Y_ATTR),
3991 m_unit_factor * bbs_get_attribute_value_float(attributes, num_attributes, Z_ATTR));
3992 // A non-finite coordinate ("nan", "inf") used to be accepted and crashed
3993 // qhull in ModelVolume's convex hull while the file was still loading. Refuse the file.
3994 if (! v.allFinite()) {
3995 _stop_xml_parser("Invalid vertex coordinate: not a finite number");
3996 return true; // the parser is stopped; returning false would overwrite the message
3997 }
3998 m_curr_object->geometry.vertices.emplace_back(v);
3999 }
4000 return true;
4001 }
static constexpr const char * X_ATTR
Definition 3mf.cpp:130
static constexpr const char * Y_ATTR
Definition 3mf.cpp:131
static constexpr const char * Z_ATTR
Definition 3mf.cpp:132
float bbs_get_attribute_value_float(const char **attributes, unsigned int attributes_size, const char *attribute_key)
Definition bbs_3mf.cpp:544

References _handle_start_vertex(), _stop_xml_parser(), bbs_get_attribute_value_float(), m_curr_object, m_unit_factor, X_ATTR, Y_ATTR, and Z_ATTR.

Referenced by _handle_start_model_xml_element(), and _handle_start_vertex().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_start_vertices()

bool Slic3r::_BBS_3MF_Importer::_handle_start_vertices ( const char ** attributes,
unsigned int num_attributes )
private
3971 {
3972 // reset current vertices
3973 if (m_curr_object)
3974 m_curr_object->geometry.vertices.clear();
3975 return true;
3976 }

References _handle_start_vertices(), and m_curr_object.

Referenced by _handle_start_model_xml_element(), and _handle_start_vertices().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_xml_characters() [1/2]

void Slic3r::_BBS_3MF_Importer::_handle_xml_characters ( const XML_Char * s,
int len )
private
3642 {
3643 m_curr_characters.append(s, len);
3644 }

References _handle_xml_characters(), and m_curr_characters.

Referenced by _extract_model_from_archive(), _extract_xml_from_archive(), _handle_xml_characters(), and _handle_xml_characters().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _handle_xml_characters() [2/2]

void XMLCALL Slic3r::_BBS_3MF_Importer::_handle_xml_characters ( void * userData,
const XML_Char * s,
int len )
staticprivate
5669 {
5670 _BBS_3MF_Importer* importer = (_BBS_3MF_Importer*)userData;
5671 if (importer != nullptr)
5672 importer->_handle_xml_characters(s, len);
5673 }

References _BBS_3MF_Importer(), and _handle_xml_characters().

Here is the call graph for this function:

◆ _is_published_3mf()

bool Slic3r::_BBS_3MF_Importer::_is_published_3mf ( ) const
inlineprivate
1286 {
1287 const auto it = this->model_info.metadata_items.find(ORCA_PUBLISHED_TAG);
1288 return it != this->model_info.metadata_items.end() && is_published_3mf_flag(it->second);
1289 }
constexpr const char * ORCA_PUBLISHED_TAG
Definition bbs_3mf.hpp:192
bool is_published_3mf_flag(const std::string &value)
Definition bbs_3mf.cpp:724

References Slic3r::is_published_3mf_flag(), Slic3r::ModelInfo::metadata_items, and Slic3r::ORCA_PUBLISHED_TAG.

Referenced by _handle_end_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _is_svg_shape_file()

bool Slic3r::_BBS_3MF_Importer::_is_svg_shape_file ( const std::string & filename) const
private
2529 {
2530 return boost::starts_with(name, MODEL_FOLDER) && boost::ends_with(name, ".svg");
2531 }
const std::string MODEL_FOLDER
Definition 3mf.cpp:95

References _is_svg_shape_file(), and MODEL_FOLDER.

Referenced by _is_svg_shape_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _load_model_from_file()

bool Slic3r::_BBS_3MF_Importer::_load_model_from_file ( std::string filename,
Model & model,
PlateDataPtrs & plate_data_list,
std::vector< Preset * > & project_presets,
DynamicPrintConfig & config,
ConfigSubstitutionContext & config_substitutions,
Import3mfProgressFn proFn = nullptr,
BBLProject * project = nullptr,
int plate_id = 0 )
private
1804 {
1805 bool cb_cancel = false;
1806 //BBS progress point
1807 // prepare restore
1808 if (m_load_restore) {
1809 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_RESTORE\n");
1810 if (proFn) {
1811 proFn(IMPORT_STAGE_RESTORE, 0, 1, cb_cancel);
1812 if (cb_cancel)
1813 return false;
1814 }
1815 }
1816
1817 //BBS progress point
1818 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_OPEN, m_load_restore=%1%\n")%m_load_restore;
1819 if (proFn) {
1820 proFn(IMPORT_STAGE_OPEN, 0, 1, cb_cancel);
1821 if (cb_cancel)
1822 return false;
1823 }
1824
1825 mz_zip_archive archive;
1826 mz_zip_zero_struct(&archive);
1827
1828 struct close_lock
1829 {
1830 mz_zip_archive * archive;
1831 void close() {
1832 if (archive) {
1833 close_zip_reader(archive);
1834 archive = nullptr;
1835 }
1836 }
1837 ~close_lock() {
1838 close();
1839 }
1840 } lock{ &archive };
1841
1842 if (!open_zip_reader(&archive, filename)) {
1843 add_error("Unable to open the file"+filename);
1844 return false;
1845 }
1846
1847 mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
1848
1849 mz_zip_archive_file_stat stat;
1850
1851 m_name = boost::filesystem::path(filename).stem().string();
1852
1853 //BBS progress point
1854 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_READ_FILES\n");
1855 if (proFn) {
1856 proFn(IMPORT_STAGE_READ_FILES, 0, 3, cb_cancel);
1857 if (cb_cancel)
1858 return false;
1859 }
1860 // BBS: load relationships
1862 return false;
1863 if (m_start_part_path.empty())
1864 return false;
1865 // BBS: load sub models (Production Extension)
1866 std::string sub_rels = m_start_part_path;
1867 sub_rels.insert(boost::find_last(sub_rels, "/").end() - sub_rels.begin(), "_rels/");
1868 sub_rels.append(".rels");
1869 if (sub_rels.front() == '/') sub_rels = sub_rels.substr(1);
1870
1871 //check whether sub relation file is exist or not
1872 int sub_index = mz_zip_reader_locate_file(&archive, sub_rels.c_str(), nullptr, 0);
1873 if (sub_index == -1) {
1874 //no submodule files found, use only one 3dmodel.model
1875 }
1876 else {
1878 int index = 0;
1879
1880#if 0
1881 for (auto path : m_sub_model_paths) {
1882 if (proFn) {
1883 proFn(IMPORT_STAGE_READ_FILES, ++index, 3 + m_sub_model_paths.size(), cb_cancel);
1884 if (cb_cancel)
1885 return false;
1886 }
1887 else
1888 ++index;
1889 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", read %1%th sub model file %2%\n")%index %path;
1890 m_sub_model_path = path;
1891 if (!_extract_from_archive(archive, path, [this] (mz_zip_archive& archive, const mz_zip_archive_file_stat& stat) {
1892 return _extract_model_from_archive(archive, stat);
1893 }, m_load_restore)) {
1894 add_error("Archive does not contain a valid model");
1895 return false;
1896 }
1897 m_sub_model_path.clear();
1898 }
1899#else
1900 for (auto path : m_sub_model_paths) {
1901 ObjectImporter *object_importer = new ObjectImporter(this, filename, path);
1902 m_object_importers.push_back(object_importer);
1903 }
1904
1905 bool object_load_result = true;
1906 boost::mutex mutex;
1907 tbb::parallel_for(
1908 tbb::blocked_range<size_t>(0, m_object_importers.size()),
1909 [this, &mutex, &object_load_result](const tbb::blocked_range<size_t>& importer_range) {
1910 CNumericLocalesSetter locales_setter;
1911 for (size_t object_index = importer_range.begin(); object_index < importer_range.end(); ++ object_index) {
1912 bool result = m_object_importers[object_index]->extract_object_model();
1913 {
1914 boost::unique_lock l(mutex);
1915 object_load_result &= result;
1916 }
1917 }
1918 }
1919 );
1920
1921 if (!object_load_result) {
1922 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", loading sub-objects error\n");
1923 return false;
1924 }
1925
1926 //merge these objects into one
1927 for (auto obj_importer : m_object_importers) {
1928 for (const IdToCurrentObjectMap::value_type& obj : obj_importer->object_list)
1929 m_current_objects.insert({ std::move(obj.first), std::move(obj.second)});
1930 for (auto group_color : obj_importer->object_group_id_to_color)
1931 m_group_id_to_color.insert(std::move(group_color));
1932
1933 delete obj_importer;
1934 }
1935 m_object_importers.clear();
1936#endif
1937 // BBS: load root model
1938 if (proFn) {
1939 proFn(IMPORT_STAGE_READ_FILES, 2, 3, cb_cancel);
1940 if (cb_cancel)
1941 return false;
1942 }
1943 }
1944
1945 //extract model files
1946 if (!_extract_from_archive(archive, m_start_part_path, [this] (mz_zip_archive& archive, const mz_zip_archive_file_stat& stat) {
1947 return _extract_model_from_archive(archive, stat);
1948 })) {
1949 add_error("Archive does not contain a valid model");
1950 return false;
1951 }
1952
1953 if (!m_designer.empty()) {
1954 m_model->design_info = std::make_shared<ModelDesignInfo>();
1955 m_model->design_info->DesignerUserId = m_designer_user_id;
1956 m_model->design_info->Designer = m_designer;
1957 }
1958
1959 m_model->profile_info = std::make_shared<ModelProfileInfo>();
1960 m_model->profile_info->ProfileTile = m_profile_title;
1961 m_model->profile_info->ProfileCover = m_profile_cover;
1962 m_model->profile_info->ProfileDescription = m_Profile_description;
1963 m_model->profile_info->ProfileUserId = m_profile_user_id;
1964 m_model->profile_info->ProfileUserName = m_profile_user_name;
1965
1966
1967 m_model->model_info = std::make_shared<ModelInfo>();
1968 m_model->model_info->load(model_info);
1969 if (!m_thumbnail_small.empty()) m_model->model_info->metadata_items.emplace("Thumbnail_Small", m_thumbnail_small);
1970 if (!m_thumbnail_middle.empty()) m_model->model_info->metadata_items.emplace("Thumbnail_Middle", m_thumbnail_middle);
1971
1972 //got project id
1973 if (project) {
1974 project->project_model_id = m_model_id;
1975 project->project_country_code = m_contry_code;
1976 }
1977
1978 // Orca: skip version check
1979 bool dont_load_config = !m_load_config;
1980 // if (m_bambuslicer_generator_version) {
1981 // Semver app_version = *(Semver::parse(SoftFever_VERSION));
1982 // Semver file_version = *m_bambuslicer_generator_version;
1983 // if (file_version.maj() != app_version.maj())
1984 // dont_load_config = true;
1985 // }
1986 // else {
1987 // m_bambuslicer_generator_version = Semver::parse("0.0.0.0");
1988 // dont_load_config = true;
1989 // }
1990
1991 // we then loop again the entries to read other files stored in the archive
1992 for (mz_uint i = 0; i < num_entries; ++i) {
1993 if (mz_zip_reader_file_stat(&archive, i, &stat)) {
1994
1995 //BBS progress point
1996 if (proFn) {
1997 proFn(IMPORT_STAGE_EXTRACT, i, num_entries, cb_cancel);
1998 if (cb_cancel)
1999 return false;
2000 }
2001
2002 std::string name(stat.m_filename);
2003 std::replace(name.begin(), name.end(), '\\', '/');
2004
2005 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("extract %1%th file %2%, total=%3%")%(i+1)%name%num_entries;
2006
2007 if (name.find("/../") != std::string::npos ||
2008 name.find("../") == 0 ||
2009 (name.length() >= 3 && name.compare(name.length() - 3, 3, "/..") == 0) ||
2010 name == "..") {
2011 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", find file path including path traversal, not valid, skip it\n");
2012 continue;
2013 }
2014
2015 if (boost::algorithm::iequals(name, BBS_LAYER_HEIGHTS_PROFILE_FILE)) {
2016 // extract slic3r layer heights profile file
2018 }
2019 else
2020 if (boost::algorithm::iequals(name, LAYER_CONFIG_RANGES_FILE)) {
2021 // extract slic3r layer config ranges file
2022 _extract_layer_config_ranges_from_archive(archive, stat, config_substitutions);
2023 }
2024 else if (boost::algorithm::iequals(name, BRIM_EAR_POINTS_FILE)) {
2025 // extract slic3r config file
2027 }
2028 //BBS: disable SLA related files currently
2029 /*else if (boost::algorithm::iequals(name, SLA_SUPPORT_POINTS_FILE)) {
2030 // extract sla support points file
2031 _extract_sla_support_points_from_archive(archive, stat);
2032 }
2033 else if (boost::algorithm::iequals(name, SLA_DRAIN_HOLES_FILE)) {
2034 // extract sla support points file
2035 _extract_sla_drain_holes_from_archive(archive, stat);
2036 }*/
2037 //BBS: project setting file
2038 //if (!dont_load_config && boost::algorithm::iequals(name, BBS_PRINT_CONFIG_FILE)) {
2039 // extract slic3r print config file
2040 // _extract_print_config_from_archive(archive, stat, config, config_substitutions, filename);
2041 //} else
2042 if (!dont_load_config && boost::algorithm::iequals(name, BBS_PROJECT_CONFIG_FILE)) {
2043 // extract slic3r print config file
2044 _extract_project_config_from_archive(archive, stat, config, config_substitutions, model);
2045 }
2046 else if (boost::algorithm::iequals(name, ORCA_CAD_RECIPE_FILE)
2047 || boost::algorithm::iequals(name, LEGACY_CAD_RECIPE_FILE)) {
2048 // Restore the editable CAD recipe (optional; absent in non-CAD projects).
2049 // The current name wins over the legacy one whichever the archive lists
2050 // first, and the size the archive claims is capped before it is allocated.
2051 constexpr mz_uint64 kMaxCadRecipe = mz_uint64(1) << 30; // 1 GiB
2052 const bool legacy = boost::algorithm::iequals(name, LEGACY_CAD_RECIPE_FILE);
2053 if (stat.m_uncomp_size > kMaxCadRecipe) {
2054 BOOST_LOG_TRIVIAL(error) << "3MF: CAD recipe of " << stat.m_uncomp_size
2055 << " bytes exceeds the limit; not loaded";
2056 } else if (stat.m_uncomp_size > 0 && !(legacy && !model.cad_recipe.empty())) {
2057 std::string buf((size_t)stat.m_uncomp_size, '\0');
2058 if (mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, buf.data(), buf.size(), 0))
2059 model.cad_recipe = std::move(buf);
2060 }
2061 }
2062 else if (boost::algorithm::iequals(name, CUT_INFORMATION_FILE)) {
2063 // extract object cut info
2064 _extract_cut_information_from_archive(archive, stat, config_substitutions);
2065 }
2066 //BBS: project embedded presets
2067 else if (!dont_load_config && boost::algorithm::istarts_with(name, PROJECT_EMBEDDED_PRINT_PRESETS_FILE)) {
2068 // extract slic3r layer config ranges file
2069 _extract_project_embedded_presets_from_archive(archive, stat, project_presets, model, Preset::TYPE_PRINT, false);
2070 }
2071 else if (!dont_load_config && boost::algorithm::istarts_with(name, PROJECT_EMBEDDED_SLICE_PRESETS_FILE)) {
2072 // extract slic3r layer config ranges file
2073 _extract_project_embedded_presets_from_archive(archive, stat, project_presets, model, Preset::TYPE_PRINT);
2074 }
2075 else if (!dont_load_config && boost::algorithm::istarts_with(name, PROJECT_EMBEDDED_FILAMENT_PRESETS_FILE)) {
2076 // extract slic3r layer config ranges file
2077 _extract_project_embedded_presets_from_archive(archive, stat, project_presets, model, Preset::TYPE_FILAMENT);
2078 }
2079 else if (!dont_load_config && boost::algorithm::istarts_with(name, PROJECT_EMBEDDED_PRINTER_PRESETS_FILE)) {
2080 // extract slic3r layer config ranges file
2081 _extract_project_embedded_presets_from_archive(archive, stat, project_presets, model, Preset::TYPE_PRINTER);
2082 }
2083 else if (!dont_load_config && boost::algorithm::iequals(name, CUSTOM_GCODE_PER_PRINT_Z_FILE)) {
2084 // extract slic3r layer config ranges file
2086 }
2087 else if (boost::algorithm::iequals(name, BBS_MODEL_CONFIG_FILE)) {
2088 // extract slic3r model config file
2090 if (m_is_bbl_3mf) {
2091 add_error("Archive does not contain a valid model config");
2092 return false;
2093 }
2094 }
2095 }
2096 else if (_is_svg_shape_file(name)) {
2097 _extract_embossed_svg_shape_file(name, archive, stat);
2098 }
2099 else if (boost::algorithm::istarts_with(name, TEXTURE_DISPLACEMENT_DIR)) {
2100 std::string contents(stat.m_uncomp_size, '\0');
2101 if (mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, contents.data(), stat.m_uncomp_size, 0))
2102 m_texture_displacement_files.emplace(name, std::move(contents));
2103 else
2104 add_error("Error while reading texture displacement data");
2105 }
2106 else if (!dont_load_config && boost::algorithm::iequals(name, SLICE_INFO_CONFIG_FILE)) {
2107 m_parsing_slice_info = true;
2108 //extract slice info from archive
2110 m_parsing_slice_info = false;
2111 }
2112 else if (!dont_load_config && boost::algorithm::iequals(name, FILAMENT_SEQUENCE_FILE)) {
2114 }
2115 else if (boost::algorithm::istarts_with(name, AUXILIARY_DIR)) {
2116 // extract auxiliary directory to temp directory, do nothing for restore
2117 if (m_load_aux && !m_load_restore)
2118 _extract_auxiliary_file_from_archive(archive, stat, model);
2119 }
2120 else if (!dont_load_config && boost::algorithm::istarts_with(name, METADATA_DIR) && boost::algorithm::iends_with(name, GCODE_EXTENSION)) {
2121 //load gcode files
2122 _extract_file_from_archive(archive, stat);
2123 }
2124 else if (!dont_load_config && boost::algorithm::istarts_with(name, METADATA_DIR) && boost::algorithm::iends_with(name, THUMBNAIL_EXTENSION)) {
2125 //BBS parsing pattern thumbnail and plate thumbnails
2126 _extract_file_from_archive(archive, stat);
2127 }
2128 else if (!dont_load_config && boost::algorithm::istarts_with(name, METADATA_DIR) && boost::algorithm::iends_with(name, CALIBRATION_INFO_EXTENSION)) {
2129 //BBS parsing pattern config files
2130 _extract_file_from_archive(archive, stat);
2131 }
2132 else {
2133 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", %1% skipped, already parsed or a directory or not supported\n")%name;
2134 }
2135 }
2136 }
2137
2138 lock.close();
2139
2140 if (!m_is_bbl_3mf && !_is_published_3mf()) {
2141 // if the 3mf was not produced by OrcaSlicer and there is more than one instance,
2142 // split the object in as many objects as instances
2143 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", found 3mf from other vendor, split as instance");
2144 for (const IdToModelObjectMap::value_type& object : m_objects) {
2145 if (object.second >= int(m_model->objects.size())) {
2146 add_error("3rd 3mf, invalid object, id: "+std::to_string(object.first.second));
2147 return false;
2148 }
2149 ModelObject* model_object = m_model->objects[object.second];
2150 if (model_object->instances.size() > 1) {
2151 IdToCurrentObjectMap::const_iterator current_object = m_current_objects.find(object.first);
2152 if (current_object == m_current_objects.end()) {
2153 add_error("3rd 3mf, can not find object, id " + std::to_string(object.first.second));
2154 return false;
2155 }
2156 std::vector<Component> object_id_list;
2157 if (!_generate_current_object_list(object_id_list, object.first, m_current_objects))
2158 return false;
2159
2161 ObjectMetadata::VolumeMetadataList* volumes_ptr = nullptr;
2162
2163 for (int k = 0; k < object_id_list.size(); k++)
2164 {
2165 Id object_id = object_id_list[k].object_id;
2166 volumes.emplace_back(object_id.second);
2167 }
2168
2169 // select as volumes
2170 volumes_ptr = &volumes;
2171
2172 // for each instance after the 1st, create a new model object containing only that instance
2173 // and copy into it the geometry
2174 while (model_object->instances.size() > 1) {
2175 ModelObject* new_model_object = m_model->add_object(*model_object);
2176 new_model_object->clear_instances();
2177 new_model_object->add_instance(*model_object->instances.back());
2178 model_object->delete_last_instance();
2179 if (!_generate_volumes_new(*new_model_object, object_id_list, *volumes_ptr, config_substitutions))
2180 return false;
2181 }
2182 }
2183 }
2184 }
2185
2186 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", process group colors, size %1%\n")%m_group_id_to_color.size();
2187 std::map<int, int> color_group_id_to_extruder_id_map;
2188 std::map<std::string, int> color_to_extruder_id_map;
2189 int extruder_id = 0;
2190 for (auto group_iter = m_group_id_to_color.begin(); group_iter != m_group_id_to_color.end(); ++group_iter) {
2191 auto color_iter = color_to_extruder_id_map.find(group_iter->second);
2192 if (color_iter == color_to_extruder_id_map.end()) {
2193 ++extruder_id;
2194 color_to_extruder_id_map[group_iter->second] = extruder_id;
2195 color_group_id_to_extruder_id_map[group_iter->first] = extruder_id;
2196 } else {
2197 color_group_id_to_extruder_id_map[group_iter->first] = color_iter->second;
2198 }
2199 }
2200
2201 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", begin to assemble objects, size %1%\n")%m_objects.size();
2202 //only load objects in plate_id
2203 PlateData* current_plate_data = nullptr;
2204 if ((plate_id > 0) && (plate_id <= m_plater_data.size())) {
2205 std::map<int, PlateData*>::iterator it =m_plater_data.find(plate_id);
2206 if (it != m_plater_data.end()) {
2207 current_plate_data = it->second;
2208 }
2209 }
2210 for (const IdToModelObjectMap::value_type& object : m_objects) {
2211 if (object.second >= int(m_model->objects.size())) {
2212 add_error("invalid object, id: "+std::to_string(object.first.second));
2213 return false;
2214 }
2215 if (current_plate_data) {
2216 std::map<int, std::pair<int, int>>::iterator it = current_plate_data->obj_inst_map.find(object.first.second);
2217 if (it == current_plate_data->obj_inst_map.end()) {
2218 //not in current plate, skip
2219 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", could not find object %1% in plate %2%, skip it\n")%object.first.second %plate_id;
2220 continue;
2221 }
2222 }
2223 ModelObject* model_object = m_model->objects[object.second];
2224 /*IdToGeometryMap::const_iterator obj_geometry = m_geometries.find(object.first);
2225 if (obj_geometry == m_geometries.end()) {
2226 add_error("Unable to find object geometry");
2227 return false;
2228 }*/
2229
2230 // m_layer_heights_profiles are indexed by a 1 based model object index.
2231 IdToLayerHeightsProfileMap::iterator obj_layer_heights_profile = m_layer_heights_profiles.find(object.second + 1);
2232 if (obj_layer_heights_profile != m_layer_heights_profiles.end())
2233 model_object->layer_height_profile.set(std::move(obj_layer_heights_profile->second));
2234
2235 // m_layer_config_ranges are indexed by a 1 based model object index.
2236 IdToLayerConfigRangesMap::iterator obj_layer_config_ranges = m_layer_config_ranges.find(object.second + 1);
2237 if (obj_layer_config_ranges != m_layer_config_ranges.end())
2238 model_object->layer_config_ranges = std::move(obj_layer_config_ranges->second);
2239
2240 IdToBrimPointsMap::iterator obj_brim_points = m_brim_ear_points.find(object.second + 1);
2241 if (obj_brim_points != m_brim_ear_points.end())
2242 model_object->brim_points = std::move(obj_brim_points->second);
2243
2244 // m_sla_support_points are indexed by a 1 based model object index.
2245 /*IdToSlaSupportPointsMap::iterator obj_sla_support_points = m_sla_support_points.find(object.second + 1);
2246 if (obj_sla_support_points != m_sla_support_points.end() && !obj_sla_support_points->second.empty()) {
2247 model_object->sla_support_points = std::move(obj_sla_support_points->second);
2248 model_object->sla_points_status = sla::PointsStatus::UserModified;
2249 }
2250
2251 IdToSlaDrainHolesMap::iterator obj_drain_holes = m_sla_drain_holes.find(object.second + 1);
2252 if (obj_drain_holes != m_sla_drain_holes.end() && !obj_drain_holes->second.empty()) {
2253 model_object->sla_drain_holes = std::move(obj_drain_holes->second);
2254 }*/
2255
2256 std::vector<Component> object_id_list;
2257 if (!_generate_current_object_list(object_id_list, object.first, m_current_objects))
2258 return false;
2259
2261 ObjectMetadata::VolumeMetadataList* volumes_ptr = nullptr;
2262
2263 // 2.4.x stored auto_drop on build items, shared by all instances of an object; any "off" wins
2264 const bool legacy_auto_drop = !m_items_auto_drop_off.count(object.first.second);
2265
2266 IdToMetadataMap::iterator obj_metadata = m_objects_metadata.find(object.first.second);
2267 if (obj_metadata != m_objects_metadata.end()) {
2268 // config data has been found, this model was saved using slic3r pe
2269
2270 model_object->auto_drop = obj_metadata->second.auto_drop.value_or(legacy_auto_drop);
2271
2272 // apply object's name and config data
2273 for (const Metadata& metadata : obj_metadata->second.metadata) {
2274 if (metadata.key == "name")
2275 model_object->name = metadata.value;
2276 //BBS: add module name
2277 else if (metadata.key == "module")
2278 model_object->module_name = metadata.value;
2279 else
2280 model_object->config.set_deserialize(metadata.key, metadata.value, config_substitutions);
2281 }
2282
2283 // select object's detected volumes
2284 volumes_ptr = &obj_metadata->second.volumes;
2285 }
2286 else {
2287 // config data not found, this model was not saved using slic3r pe
2288 model_object->auto_drop = legacy_auto_drop;
2289
2290 // add the entire geometry as the single volume to generate
2291 //volumes.emplace_back(0, (int)obj_geometry->second.triangles.size() - 1);
2292 for (int k = 0; k < object_id_list.size(); k++)
2293 {
2294 Id object_id = object_id_list[k].object_id;
2295 volumes.emplace_back(object_id.second);
2296 }
2297
2298 IdToCurrentObjectMap::const_iterator current_object = m_current_objects.find(object.first);
2299 if (current_object != m_current_objects.end()) {
2300 // get name
2301 if (!current_object->second.name.empty())
2302 model_object->name = current_object->second.name;
2303 else
2304 model_object->name = "Object_"+std::to_string(object.second+1);
2305
2306 // get color
2307 auto extruder_itor = color_group_id_to_extruder_id_map.find(current_object->second.pid);
2308 if (extruder_itor != color_group_id_to_extruder_id_map.end()) {
2309 model_object->config.set_key_value("extruder", new ConfigOptionInt(extruder_itor->second));
2310 }
2311 }
2312
2313 // select as volumes
2314 volumes_ptr = &volumes;
2315 }
2316
2317 if (!_generate_volumes_new(*model_object, object_id_list, *volumes_ptr, config_substitutions))
2318 return false;
2319
2320 // Apply cut information for object if any was loaded
2321 // m_cut_object_ids are indexed by a 1 based model object index.
2322 IdToCutObjectInfoMap::iterator cut_object_info = m_cut_object_infos.find(object.second + 1);
2323 if (cut_object_info != m_cut_object_infos.end()) {
2324 model_object->cut_id = cut_object_info->second.id;
2325 int vol_cnt = int(model_object->volumes.size());
2326 for (auto connector : cut_object_info->second.connectors) {
2327 if (connector.volume_id < 0 || connector.volume_id >= vol_cnt) {
2328 add_error("Invalid connector is found");
2329 continue;
2330 }
2331 model_object->volumes[connector.volume_id]->cut_info =
2332 ModelVolume::CutInfo(CutConnectorType(connector.type), connector.r_tolerance, connector.h_tolerance, true);
2333 }
2334 }
2335 }
2336
2337 // If instances contain a single volume, the volume offset should be 0,0,0
2338 // This equals to say that instance world position and volume world position should match
2339 // Correct all instances/volumes for which this does not hold
2340 for (int obj_id = 0; obj_id < int(model.objects.size()); ++obj_id) {
2341 ModelObject *o = model.objects[obj_id];
2342 if (o->volumes.size() == 1) {
2343 ModelVolume * v = o->volumes.front();
2344 const Slic3r::Geometry::Transformation &first_inst_trafo = o->instances.front()->get_transformation();
2345 const Vec3d world_vol_offset = (first_inst_trafo * v->get_transformation()).get_offset();
2346 const Vec3d world_inst_offset = first_inst_trafo.get_offset();
2347
2348 if (!world_vol_offset.isApprox(world_inst_offset)) {
2349 const Slic3r::Geometry::Transformation &vol_trafo = v->get_transformation();
2350 for (int inst_id = 0; inst_id < int(o->instances.size()); ++inst_id) {
2351 ModelInstance * i = o->instances[inst_id];
2352 const Slic3r::Geometry::Transformation &inst_trafo = i->get_transformation();
2353 i->set_offset((inst_trafo * vol_trafo).get_offset());
2354 }
2355 v->set_offset(Vec3d::Zero());
2356 }
2357 }
2358 }
2359
2360 int object_idx = 0;
2361 for (ModelObject* o : model.objects) {
2362 int volume_idx = 0;
2363 for (ModelVolume* v : o->volumes) {
2364 if (v->source.input_file.empty() && v->type() == ModelVolumeType::MODEL_PART) {
2365 v->source.input_file = filename;
2366 if (v->source.volume_idx == -1)
2367 v->source.volume_idx = volume_idx;
2368 if (v->source.object_idx == -1)
2369 v->source.object_idx = object_idx;
2370 }
2371 ++volume_idx;
2372 }
2373 ++object_idx;
2374 }
2375
2376 const ConfigOptionStrings* filament_ids_opt = config.option<ConfigOptionStrings>("filament_settings_id");
2377 int max_filament_id = filament_ids_opt ? filament_ids_opt->size() : std::numeric_limits<int>::max();
2378 for (ModelObject* mo : m_model->objects) {
2379 const ConfigOptionInt* extruder_opt = dynamic_cast<const ConfigOptionInt*>(mo->config.option("extruder"));
2380 int extruder_id = 0;
2381 if (extruder_opt != nullptr)
2382 extruder_id = extruder_opt->getInt();
2383
2384 if (extruder_id == 0 || extruder_id > max_filament_id)
2385 mo->config.set_key_value("extruder", new ConfigOptionInt(1));
2386
2387 if (mo->volumes.size() == 1) {
2388 mo->volumes[0]->config.erase("extruder");
2389 }
2390 else {
2391 for (ModelVolume* mv : mo->volumes) {
2392 const ConfigOptionInt* vol_extruder_opt = dynamic_cast<const ConfigOptionInt*>(mv->config.option("extruder"));
2393 if (vol_extruder_opt == nullptr)
2394 continue;
2395
2396 if (vol_extruder_opt->getInt() == 0)
2397 mv->config.erase("extruder");
2398 else if (vol_extruder_opt->getInt() > max_filament_id)
2399 mv->config.set_key_value("extruder", new ConfigOptionInt(1));
2400 }
2401 }
2402 }
2403
2404// // fixes the min z of the model if negative
2405// model.adjust_min_z();
2406
2407 //BBS progress point
2408 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_LOADING_PLATES, m_plater_data size %1%, m_backup_path %2%\n")%m_plater_data.size() %m_backup_path;
2409 if (proFn) {
2410 proFn(IMPORT_STAGE_LOADING_PLATES, 0, 1, cb_cancel);
2411 if (cb_cancel)
2412 return false;
2413 }
2414
2415 //BBS: load the plate info into plate_data_list
2416 std::map<int, PlateData*>::iterator it = m_plater_data.begin();
2417 plate_data_list.clear();
2418 plate_data_list.reserve(m_plater_data.size());
2419 for (unsigned int i = 0; i < m_plater_data.size(); i++)
2420 {
2421 PlateData* plate = new PlateData();
2422 plate_data_list.push_back(plate);
2423 }
2424 while (it != m_plater_data.end())
2425 {
2426 if (it->first <= 0 || static_cast<size_t>(it->first) > m_plater_data.size())
2427 {
2428 add_error("invalid plate index");
2429 return false;
2430 }
2431 plate_data_list[it->first-1]->locked = it->second->locked;
2432 plate_data_list[it->first-1]->plate_index = it->second->plate_index-1;
2433 plate_data_list[it->first-1]->plate_name = it->second->plate_name;
2434 plate_data_list[it->first-1]->obj_inst_map = it->second->obj_inst_map;
2435 plate_data_list[it->first-1]->gcode_file = (m_load_restore || it->second->gcode_file.empty()) ? it->second->gcode_file : m_backup_path + "/" + it->second->gcode_file;
2436 plate_data_list[it->first-1]->gcode_prediction = it->second->gcode_prediction;
2437 plate_data_list[it->first-1]->gcode_weight = it->second->gcode_weight;
2438 plate_data_list[it->first-1]->toolpath_outside = it->second->toolpath_outside;
2439 plate_data_list[it->first-1]->is_support_used = it->second->is_support_used;
2440 plate_data_list[it->first-1]->is_label_object_enabled = it->second->is_label_object_enabled;
2441 plate_data_list[it->first-1]->slice_filaments_info = it->second->slice_filaments_info;
2442 plate_data_list[it->first-1]->nozzles_info = it->second->nozzles_info;
2443 plate_data_list[it->first-1]->skipped_objects = it->second->skipped_objects;
2444 plate_data_list[it->first-1]->printer_model_id = it->second->printer_model_id;
2445 plate_data_list[it->first-1]->nozzle_diameters = it->second->nozzle_diameters;
2446 plate_data_list[it->first-1]->nozzle_volume_types = it->second->nozzle_volume_types;
2447 plate_data_list[it->first-1]->filament_maps = it->second->filament_maps;
2448 plate_data_list[it->first-1]->filament_change_sequence = it->second->filament_change_sequence;
2449 plate_data_list[it->first-1]->nozzle_change_sequence = it->second->nozzle_change_sequence;
2450 plate_data_list[it->first-1]->optimal_assignment = it->second->optimal_assignment;
2451 plate_data_list[it->first-1]->warnings = it->second->warnings;
2452 plate_data_list[it->first-1]->thumbnail_file = (m_load_restore || it->second->thumbnail_file.empty()) ? it->second->thumbnail_file : m_backup_path + "/" + it->second->thumbnail_file;
2453 //plate_data_list[it->first-1]->pattern_file = (m_load_restore || it->second->pattern_file.empty()) ? it->second->pattern_file : m_backup_path + "/" + it->second->pattern_file;
2454 plate_data_list[it->first-1]->no_light_thumbnail_file = (m_load_restore || it->second->no_light_thumbnail_file.empty()) ? it->second->no_light_thumbnail_file : m_backup_path + "/" + it->second->no_light_thumbnail_file;
2455 plate_data_list[it->first-1]->top_file = (m_load_restore || it->second->top_file.empty()) ? it->second->top_file : m_backup_path + "/" + it->second->top_file;
2456 plate_data_list[it->first-1]->pick_file = (m_load_restore || it->second->pick_file.empty()) ? it->second->pick_file : m_backup_path + "/" + it->second->pick_file;
2457 plate_data_list[it->first-1]->pattern_bbox_file = (m_load_restore || it->second->pattern_bbox_file.empty()) ? it->second->pattern_bbox_file : m_backup_path + "/" + it->second->pattern_bbox_file;
2458 plate_data_list[it->first-1]->config = it->second->config;
2459
2460 current_plate_data = plate_data_list[it->first - 1];
2461 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", plate %1%, thumbnail_file=%2%, no_light_thumbnail_file=%3%")%it->first %plate_data_list[it->first-1]->thumbnail_file %plate_data_list[it->first-1]->no_light_thumbnail_file;
2462 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", top_thumbnail_file=%1%, pick_thumbnail_file=%2%")%plate_data_list[it->first-1]->top_file %plate_data_list[it->first-1]->pick_file;
2463 it++;
2464
2465 //update the arrange order
2466 std::map<int, std::pair<int, int>>::iterator map_it = current_plate_data->obj_inst_map.begin();
2467 while (map_it != current_plate_data->obj_inst_map.end()) {
2468 int obj_index, obj_id = map_it->first, inst_index = map_it->second.first;
2469 IndexToPathMap::iterator index_iter = m_index_paths.find(obj_id);
2470 if (index_iter == m_index_paths.end()) {
2471 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__
2472 << boost::format(", can not find object from plate's obj_map, id=%1%, skip this object")%obj_id;
2473 map_it++;
2474 continue;
2475 }
2476 Id temp_id = std::make_pair(index_iter->second, index_iter->first);
2477 IdToModelObjectMap::iterator object_item = m_objects.find(temp_id);
2478 if (object_item == m_objects.end()) {
2479 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__
2480 << boost::format(", can not find object from plate's obj_map, ID <%1%, %2%>, skip this object")%index_iter->second %index_iter->first;
2481 map_it++;
2482 continue;
2483 }
2484 obj_index = object_item->second;
2485
2486 if (obj_index >= m_model->objects.size()) {
2487 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__ << boost::format("invalid object id %1%\n")%obj_index;
2488 map_it++;
2489 continue;
2490 }
2491 ModelObject* obj = m_model->objects[obj_index];
2492 if (inst_index >= obj->instances.size()) {
2493 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__ << boost::format("invalid instance id %1%\n")%inst_index;
2494 map_it++;
2495 continue;
2496 }
2497 ModelInstance* inst = obj->instances[inst_index];
2498 inst->loaded_id = map_it->second.second;
2499 map_it++;
2500 }
2501 }
2502
2503 if ((plate_id > 0) && (plate_id <= m_plater_data.size())) {
2504 //remove the no need objects
2505 std::vector<size_t> delete_ids;
2506 for (int index = 0; index < m_model->objects.size(); index++) {
2507 ModelObject* obj = m_model->objects[index];
2508 if (obj->volumes.size() == 0) {
2509 //remove this model objects
2510 delete_ids.push_back(index);
2511 }
2512 }
2513
2514 for (int index = delete_ids.size() - 1; index >= 0; index--)
2515 m_model->delete_object(delete_ids[index]);
2516 }
2517
2518 //BBS progress point
2519 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_FINISH\n");
2520 if (proFn) {
2521 proFn(IMPORT_STAGE_FINISH, 0, 1, cb_cancel);
2522 if (cb_cancel)
2523 return false;
2524 }
2525
2526 return true;
2527 }
const std::string LAYER_CONFIG_RANGES_FILE
Definition 3mf.cpp:104
const std::string CUSTOM_GCODE_PER_PRINT_Z_FILE
Definition 3mf.cpp:107
const std::string RELATIONSHIPS_FILE
Definition 3mf.cpp:99
const std::string LEGACY_CAD_RECIPE_FILE
Definition bbs_3mf.cpp:239
const std::string CALIBRATION_INFO_EXTENSION
Definition bbs_3mf.cpp:219
const std::string PROJECT_EMBEDDED_PRINT_PRESETS_FILE
Definition bbs_3mf.cpp:246
const std::string PROJECT_EMBEDDED_SLICE_PRESETS_FILE
Definition bbs_3mf.cpp:247
const std::string BBS_LAYER_HEIGHTS_PROFILE_FILE
Definition bbs_3mf.cpp:235
const std::string BBS_MODEL_CONFIG_FILE
Definition bbs_3mf.cpp:231
const std::string GCODE_EXTENSION
Definition bbs_3mf.cpp:217
const std::string FILAMENT_SEQUENCE_FILE
Definition bbs_3mf.cpp:234
const std::string THUMBNAIL_EXTENSION
Definition bbs_3mf.cpp:218
const std::string SLICE_INFO_CONFIG_FILE
Definition bbs_3mf.cpp:233
const std::string METADATA_DIR
Definition bbs_3mf.cpp:215
static constexpr const char * TEXTURE_DISPLACEMENT_DIR
Definition bbs_3mf.cpp:365
const std::string PROJECT_EMBEDDED_FILAMENT_PRESETS_FILE
Definition bbs_3mf.cpp:248
const std::string BBS_PROJECT_CONFIG_FILE
Definition bbs_3mf.cpp:230
const std::string CUT_INFORMATION_FILE
Definition bbs_3mf.cpp:250
const std::string BRIM_EAR_POINTS_FILE
Definition bbs_3mf.cpp:241
const std::string ORCA_CAD_RECIPE_FILE
Definition bbs_3mf.cpp:236
const std::string PROJECT_EMBEDDED_PRINTER_PRESETS_FILE
Definition bbs_3mf.cpp:249
Vec3d get_offset() const
Definition Geometry.hpp:426
boost::mutex mutex
Definition bbs_3mf.cpp:812
void _extract_layer_config_ranges_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, ConfigSubstitutionContext &config_substitutions)
Definition bbs_3mf.cpp:3053
bool m_load_aux
Definition bbs_3mf.cpp:1168
bool _generate_current_object_list(std::vector< Component > &sub_objects, Id object_id, IdToCurrentObjectMap &current_objects)
Definition bbs_3mf.cpp:5171
void _extract_auxiliary_file_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, Model &model)
Definition bbs_3mf.cpp:2921
void _extract_layer_heights_profile_config_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
Definition bbs_3mf.cpp:2991
static void XMLCALL _handle_start_relationships_element(void *userData, const char *name, const char **attributes)
Definition bbs_3mf.cpp:5112
void _extract_brim_ear_points_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
Definition bbs_3mf.cpp:3111
std::vector< VolumeMetadata > VolumeMetadataList
Definition bbs_3mf.cpp:987
bool _extract_model_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
Definition bbs_3mf.cpp:2651
void _extract_custom_gcode_per_print_z_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
Definition bbs_3mf.cpp:3414
void _extract_project_config_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, DynamicPrintConfig &config, ConfigSubstitutionContext &subs_context, Model &model)
Definition bbs_3mf.cpp:2791
static void XMLCALL _handle_end_relationships_element(void *userData, const char *name)
Definition bbs_3mf.cpp:5119
void _extract_embossed_svg_shape_file(const std::string &filename, mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
Definition bbs_3mf.cpp:3388
bool m_load_config
Definition bbs_3mf.cpp:1169
bool _is_svg_shape_file(const std::string &filename) const
Definition bbs_3mf.cpp:2529
void _extract_cut_information_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, ConfigSubstitutionContext &config_substitutions)
Definition bbs_3mf.cpp:2718
void _extract_filament_sequence_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
Definition bbs_3mf.cpp:3500
void _extract_file_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat)
Definition bbs_3mf.cpp:2966
void _extract_project_embedded_presets_from_archive(mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, std::vector< Preset * > &project_presets, Model &model, Preset::Type type, bool use_json=true)
Definition bbs_3mf.cpp:2824
void _handle_start_config_xml_element(const char *name, const char **attributes)
Definition bbs_3mf.cpp:3646
std::vector< ObjectImporter * > m_object_importers
Definition bbs_3mf.cpp:1234
bool _generate_volumes_new(ModelObject &object, const std::vector< Component > &sub_objects, const ObjectMetadata::VolumeMetadataList &volumes, ConfigSubstitutionContext &config_substitutions)
Definition bbs_3mf.cpp:5212
void _handle_end_config_xml_element(const char *name)
Definition bbs_3mf.cpp:3693
T * end(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:841
const int IMPORT_STAGE_OPEN
Definition bbs_3mf.hpp:260
@ MODEL_PART
Definition Model.hpp:357
const int IMPORT_STAGE_READ_FILES
Definition bbs_3mf.hpp:261
const int IMPORT_STAGE_FINISH
Definition bbs_3mf.hpp:265
CutConnectorType
Definition Model.hpp:262
const int IMPORT_STAGE_EXTRACT
Definition bbs_3mf.hpp:262
const int IMPORT_STAGE_RESTORE
Definition bbs_3mf.hpp:259
const int IMPORT_STAGE_LOADING_PLATES
Definition bbs_3mf.hpp:264
@ lock
Definition GLGizmoEmboss.cpp:209

References _extract_from_archive(), _extract_model_from_archive(), _extract_xml_from_archive(), _handle_end_relationships_element(), _handle_start_relationships_element(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::close_zip_reader(), Slic3r::IMPORT_STAGE_OPEN, Slic3r::IMPORT_STAGE_READ_FILES, Slic3r::IMPORT_STAGE_RESTORE, m_current_objects, m_group_id_to_color, m_load_restore, m_name, m_object_importers, m_start_part_path, m_sub_model_path, m_sub_model_paths, Slic3r::_BBS_3MF_Base::mutex, Slic3r::open_zip_reader(), and RELATIONSHIPS_FILE.

Referenced by load_model_from_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _stop_xml_parser()

void Slic3r::_BBS_3MF_Importer::_stop_xml_parser ( const std::string & msg = std::string())
private
1784 {
1785 assert(! m_parse_error);
1786 assert(m_parse_error_message.empty());
1787 assert(m_xml_parser != nullptr);
1788 m_parse_error = true;
1790 XML_StopParser(m_xml_parser, false);
1791 }
std::string m_parse_error_message
Definition bbs_3mf.cpp:1198
bool m_parse_error
Definition bbs_3mf.cpp:1197

References m_parse_error, m_parse_error_message, and m_xml_parser.

Referenced by _handle_end_config_xml_element(), _handle_end_model_xml_element(), _handle_end_relationships_element(), _handle_start_config_xml_element(), _handle_start_model_xml_element(), _handle_start_relationships_element(), and _handle_start_vertex().

Here is the caller graph for this function:

◆ add_error()

void Slic3r::_BBS_3MF_Base::add_error ( const std::string & error) const
inlineprotectedinherited
816{ boost::unique_lock l(mutex); m_errors.push_back(error); }
std::vector< std::string > m_errors
Definition bbs_3mf.cpp:813

References m_errors, and mutex.

Referenced by Slic3r::_BBS_3MF_Exporter::_add_bbox_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_brim_ear_points_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_cad_recipe_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_content_types_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_cut_information_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_filament_sequence_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_layer_config_ranges_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_layer_height_profile_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_mesh_to_object_stream(), Slic3r::_BBS_3MF_Exporter::_add_model_config_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_model_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_object_to_model_stream(), Slic3r::_BBS_3MF_Exporter::_add_print_config_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_relationships_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_slice_info_config_file_to_archive(), Slic3r::_BBS_3MF_Exporter::_add_thumbnail_file_to_archive(), Slic3r::_BBS_3MF_Importer::_apply_texture_displacement(), Slic3r::_BBS_3MF_Importer::_create_object_instance(), Slic3r::_BBS_3MF_Importer::_extract_auxiliary_file_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_brim_ear_points_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_custom_gcode_per_print_z_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_cut_information_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_embossed_svg_shape_file(), Slic3r::_BBS_3MF_Importer::_extract_filament_sequence_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_file_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_layer_config_ranges_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_layer_heights_profile_config_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_model_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_print_config_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_project_config_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_project_embedded_presets_from_archive(), Slic3r::_BBS_3MF_Importer::_extract_xml_from_archive(), Slic3r::_BBS_3MF_Importer::_generate_current_object_list(), Slic3r::_BBS_3MF_Importer::_generate_volumes_new(), Slic3r::_BBS_3MF_Importer::_handle_end_config_plater(), Slic3r::_BBS_3MF_Importer::_handle_end_config_plater_instance(), Slic3r::_BBS_3MF_Importer::_handle_end_model(), Slic3r::_BBS_3MF_Importer::_handle_end_object(), Slic3r::_BBS_3MF_Importer::_handle_start_assemble_item(), Slic3r::_BBS_3MF_Importer::_handle_start_config_metadata(), Slic3r::_BBS_3MF_Importer::_handle_start_config_object(), Slic3r::_BBS_3MF_Importer::_handle_start_config_plater_instance(), Slic3r::_BBS_3MF_Importer::_handle_start_config_volume(), Slic3r::_BBS_3MF_Importer::_handle_start_config_volume_mesh(), Slic3r::_BBS_3MF_Importer::_handle_start_shape_configuration(), Slic3r::_BBS_3MF_Importer::_handle_start_text_configuration(), Slic3r::_BBS_3MF_Importer::_handle_start_text_info_item(), Slic3r::_BBS_3MF_Importer::_load_model_from_file(), Slic3r::_BBS_3MF_Exporter::_save_model_to_file(), Slic3r::_BBS_3MF_Importer::get_thumbnail(), Slic3r::_BBS_3MF_Importer::load_gcode_3mf_from_stream(), Slic3r::_BBS_3MF_Exporter::save_model_to_file(), and Slic3r::_BBS_3MF_Exporter::save_object_mesh().

◆ clear_errors()

void Slic3r::_BBS_3MF_Base::clear_errors ( )
inlineprotectedinherited
817{ m_errors.clear(); }

References m_errors.

Referenced by Slic3r::_BBS_3MF_Importer::~_BBS_3MF_Importer(), Slic3r::_BBS_3MF_Importer::load_model_from_file(), and Slic3r::_BBS_3MF_Exporter::save_model_to_file().

Here is the caller graph for this function:

◆ get_thumbnail()

bool Slic3r::_BBS_3MF_Importer::get_thumbnail ( const std::string & filename,
std::string & data )
1562 {
1563 mz_zip_archive archive;
1564 mz_zip_zero_struct(&archive);
1565
1566 struct close_lock
1567 {
1568 mz_zip_archive *archive;
1569 void close()
1570 {
1571 if (archive) {
1572 close_zip_reader(archive);
1573 archive = nullptr;
1574 }
1575 }
1576 ~close_lock() { close(); }
1577 } lock{&archive};
1578
1579 if (!open_zip_reader(&archive, filename)) {
1580 add_error("Unable to open the file"+filename);
1581 return false;
1582 }
1583
1584 // BBS: load relationships
1586 return false;
1588 if (!m_thumbnail_middle.empty()) {
1589 return _extract_from_archive(archive, m_thumbnail_middle, [&data](auto &archive, auto const &stat) -> bool {
1590 data.resize(stat.m_uncomp_size);
1591 return mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, data.data(), data.size(), 0);
1592 });
1593 }
1594 return _extract_from_archive(archive, THUMBNAIL_FILE, [&data](auto &archive, auto const &stat) -> bool {
1595 data.resize(stat.m_uncomp_size);
1596 return mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, data.data(), data.size(), 0);
1597 });
1598 }
const std::string THUMBNAIL_FILE
Definition 3mf.cpp:100

References _extract_from_archive(), _extract_xml_from_archive(), _handle_end_relationships_element(), _handle_start_relationships_element(), Slic3r::_BBS_3MF_Base::add_error(), Slic3r::close_zip_reader(), m_thumbnail_middle, m_thumbnail_path, Slic3r::open_zip_reader(), RELATIONSHIPS_FILE, and THUMBNAIL_FILE.

Referenced by Slic3r::bbs_3mf_get_thumbnail().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_gcode_3mf_from_stream()

bool Slic3r::_BBS_3MF_Importer::load_gcode_3mf_from_stream ( std::istream & data,
Model & model,
PlateDataPtrs & plate_data_list,
DynamicPrintConfig & config,
Semver & file_version )
1611 {
1612 mz_zip_archive archive;
1613 mz_zip_zero_struct(&archive);
1614 archive.m_pRead = mz_zip_read_istream;
1615 archive.m_pIO_opaque = &data;
1616
1617 data.seekg(0, std::istream::end);
1618 mz_uint64 size = data.tellg();
1619 data.seekg(0, std::istream::beg);
1620 if (!mz_zip_reader_init(&archive, size, 0))
1621 return false;
1622
1623 struct close_lock
1624 {
1625 mz_zip_archive *archive;
1626 void close()
1627 {
1628 if (archive) {
1629 mz_zip_reader_end(archive);
1630 archive = nullptr;
1631 }
1632 }
1633 ~close_lock() { close(); }
1634 } lock{&archive};
1635
1636 // BBS: load relationships
1638 return false;
1639 if (m_start_part_path.empty())
1640 return false;
1641
1642 //extract model files
1643 m_model = &model;
1644 if (!_extract_from_archive(archive, m_start_part_path, [this] (mz_zip_archive& archive, const mz_zip_archive_file_stat& stat) {
1645 return _extract_model_from_archive(archive, stat);
1646 })) {
1647 add_error("Archive does not contain a valid model");
1648 return false;
1649 }
1650
1651 if (!m_designer.empty()) {
1652 m_model->design_info = std::make_shared<ModelDesignInfo>();
1653 m_model->design_info->DesignerUserId = m_designer_user_id;
1654 m_model->design_info->Designer = m_designer;
1655 }
1656
1657 m_model->profile_info = std::make_shared<ModelProfileInfo>();
1658 m_model->profile_info->ProfileTile = m_profile_title;
1659 m_model->profile_info->ProfileCover = m_profile_cover;
1660 m_model->profile_info->ProfileDescription = m_Profile_description;
1661 m_model->profile_info->ProfileUserId = m_profile_user_id;
1662 m_model->profile_info->ProfileUserName = m_profile_user_name;
1663
1664 m_model->model_info = std::make_shared<ModelInfo>();
1665 m_model->model_info->load(model_info);
1666
1669 if (!m_thumbnail_small.empty() && m_thumbnail_small.front() == '/')
1670 m_thumbnail_small.erase(m_thumbnail_small.begin());
1671 if (!m_thumbnail_middle.empty() && m_thumbnail_middle.front() == '/')
1673 m_model->model_info->metadata_items.emplace("Thumbnail", m_thumbnail_middle);
1674 m_model->model_info->metadata_items.emplace("Poster", m_thumbnail_middle);
1675
1676 // we then loop again the entries to read other files stored in the archive
1677 mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
1678 mz_zip_archive_file_stat stat;
1679 for (mz_uint i = 0; i < num_entries; ++i) {
1680 if (mz_zip_reader_file_stat(&archive, i, &stat)) {
1681 std::string name(stat.m_filename);
1682 std::replace(name.begin(), name.end(), '\\', '/');
1683
1684 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("extract %1%th file %2%, total=%3%\n")%(i+1)%name%num_entries;
1685
1686 if (boost::algorithm::iequals(name, BBS_PROJECT_CONFIG_FILE)) {
1687 // extract slic3r print config file
1688 ConfigSubstitutionContext config_substitutions(ForwardCompatibilitySubstitutionRule::Disable);
1689 _extract_project_config_from_archive(archive, stat, config, config_substitutions, model);
1690 }
1691 else if (boost::algorithm::iequals(name, BBS_MODEL_CONFIG_FILE)) {
1692 // extract slic3r model config file
1694 add_error("Archive does not contain a valid model config");
1695 return false;
1696 }
1697 }
1698 else if (boost::algorithm::iequals(name, SLICE_INFO_CONFIG_FILE)) {
1699 m_parsing_slice_info = true;
1700 //extract slice info from archive
1702 m_parsing_slice_info = false;
1703 }
1704 else if (boost::algorithm::iequals(name, FILAMENT_SEQUENCE_FILE)) {
1706 }
1707 }
1708 }
1709
1710 //BBS: load the plate info into plate_data_list
1711 std::map<int, PlateData*>::iterator it = m_plater_data.begin();
1712 plate_data_list.clear();
1713 plate_data_list.reserve(m_plater_data.size());
1714 for (unsigned int i = 0; i < m_plater_data.size(); i++)
1715 {
1716 PlateData* plate = new PlateData();
1717 plate_data_list.push_back(plate);
1718 }
1719 while (it != m_plater_data.end())
1720 {
1721 if (it->first <= 0 || static_cast<size_t>(it->first) > m_plater_data.size())
1722 {
1723 add_error("invalid plate index");
1724 return false;
1725 }
1726 PlateData * plate = plate_data_list[it->first-1];
1727 plate->locked = it->second->locked;
1728 plate->plate_index = it->second->plate_index-1;
1729 plate->obj_inst_map = it->second->obj_inst_map;
1730 plate->gcode_file = it->second->gcode_file;
1731 plate->gcode_prediction = it->second->gcode_prediction;
1732 plate->gcode_weight = it->second->gcode_weight;
1733 plate->toolpath_outside = it->second->toolpath_outside;
1734 plate->is_support_used = it->second->is_support_used;
1735 plate->is_label_object_enabled = it->second->is_label_object_enabled;
1736 plate->skipped_objects = it->second->skipped_objects;
1737 plate->slice_filaments_info = it->second->slice_filaments_info;
1738 plate->nozzles_info = it->second->nozzles_info;
1739 plate->printer_model_id = it->second->printer_model_id;
1740 plate->nozzle_diameters = it->second->nozzle_diameters;
1741 plate->nozzle_volume_types = it->second->nozzle_volume_types;
1742 plate->filament_maps = it->second->filament_maps;
1743 plate->filament_change_sequence = it->second->filament_change_sequence;
1744 plate->nozzle_change_sequence = it->second->nozzle_change_sequence;
1745 plate->optimal_assignment = it->second->optimal_assignment;
1746 plate->warnings = it->second->warnings;
1747 plate->thumbnail_file = it->second->thumbnail_file;
1748 if (plate->thumbnail_file.empty()) {
1749 plate->thumbnail_file = plate->gcode_file;
1750 boost::algorithm::replace_all(plate->thumbnail_file, ".gcode", ".png");
1751 }
1752 //plate->pattern_file = it->second->pattern_file;
1753 plate->no_light_thumbnail_file = it->second->no_light_thumbnail_file;
1754 plate->top_file = it->second->top_file;
1755 plate->pick_file = it->second->pick_file;
1756 plate->pattern_bbox_file = it->second->pattern_bbox_file;
1757 plate->config = it->second->config;
1758
1759 if (!plate->thumbnail_file.empty())
1760 _extract_from_archive(archive, plate->thumbnail_file, [&pixels = plate_data_list[it->first - 1]->plate_thumbnail.pixels](auto &archive, auto const &stat) -> bool {
1761 pixels.resize(stat.m_uncomp_size);
1762 return mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, pixels.data(), pixels.size(), 0);
1763 });
1764
1765 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", plate %1%, thumbnail_file=%2%, no_light_thumbnail_file=%3%")%it->first %plate->thumbnail_file %plate->no_light_thumbnail_file;
1766 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", top_thumbnail_file=%1%, pick_thumbnail_file=%2%")%plate->top_file %plate->pick_file;
1767 it++;
1768 }
1769
1770 lock.close();
1771
1772 return true;
1773 }
@ Disable
Definition Config.hpp:243
static size_t mz_zip_read_istream(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
Definition bbs_3mf.cpp:1600

References _extract_filament_sequence_from_archive(), _extract_from_archive(), _extract_model_from_archive(), _extract_project_config_from_archive(), _extract_xml_from_archive(), _handle_end_config_xml_element(), _handle_end_relationships_element(), _handle_start_config_xml_element(), _handle_start_relationships_element(), Slic3r::_BBS_3MF_Base::add_error(), BBS_MODEL_CONFIG_FILE, BBS_PROJECT_CONFIG_FILE, Slic3r::PlateData::config, Slic3r::Disable, Slic3r::PlateData::filament_change_sequence, Slic3r::PlateData::filament_maps, FILAMENT_SEQUENCE_FILE, Slic3r::PlateData::gcode_file, Slic3r::PlateData::gcode_prediction, Slic3r::PlateData::gcode_weight, Slic3r::PlateData::is_label_object_enabled, Slic3r::PlateData::is_support_used, Slic3r::PlateData::locked, m_designer, m_designer_user_id, m_model, m_parsing_slice_info, m_plater_data, m_profile_cover, m_Profile_description, m_profile_title, m_profile_user_id, m_profile_user_name, m_start_part_path, m_thumbnail_middle, m_thumbnail_path, m_thumbnail_small, model_info, Slic3r::mz_zip_read_istream(), Slic3r::PlateData::no_light_thumbnail_file, Slic3r::PlateData::nozzle_change_sequence, Slic3r::PlateData::nozzle_diameters, Slic3r::PlateData::nozzle_volume_types, Slic3r::PlateData::nozzles_info, Slic3r::PlateData::obj_inst_map, Slic3r::PlateData::optimal_assignment, Slic3r::PlateData::pattern_bbox_file, Slic3r::PlateData::pick_file, Slic3r::PlateData::plate_index, Slic3r::PlateData::printer_model_id, RELATIONSHIPS_FILE, Slic3r::PlateData::skipped_objects, Slic3r::PlateData::slice_filaments_info, SLICE_INFO_CONFIG_FILE, Slic3r::PlateData::thumbnail_file, Slic3r::PlateData::toolpath_outside, Slic3r::PlateData::top_file, and Slic3r::PlateData::warnings.

Referenced by Slic3r::load_gcode_3mf_from_stream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_model_from_file()

bool Slic3r::_BBS_3MF_Importer::load_model_from_file ( const std::string & filename,
Model & model,
PlateDataPtrs & plate_data_list,
std::vector< Preset * > & project_presets,
DynamicPrintConfig & config,
ConfigSubstitutionContext & config_substitutions,
LoadStrategy strategy,
bool * is_bbl_3mf,
bool * is_orca_3mf,
Semver & file_version,
Import3mfProgressFn proFn = nullptr,
BBLProject * project = nullptr,
int plate_id = 0 )
1484 {
1485 m_version = 0;
1490 //BBS: auxiliary data
1495 m_model = &model;
1496 m_unit_factor = 1.0f;
1497 m_curr_object = nullptr;
1498 m_current_objects.clear();
1499 m_index_paths.clear();
1500 m_objects.clear();
1501 //m_objects_aliases.clear();
1502 m_instances.clear();
1503 //m_geometries.clear();
1504 m_curr_config.object_id = -1;
1505 m_curr_config.volume_id = -1;
1506 m_objects_metadata.clear();
1507 m_items_auto_drop_off.clear();
1509 m_layer_config_ranges.clear();
1510 m_brim_ear_points.clear();
1511 //m_sla_support_points.clear();
1512 m_curr_metadata_name.clear();
1513 m_curr_characters.clear();
1514 //BBS: plater data init
1515 m_plater_data.clear();
1516 m_curr_instance.object_id = -1;
1517 m_curr_instance.instance_id = -1;
1518 m_curr_instance.identify_id = 0;
1519 clear_errors();
1520
1521 // restore
1522 if (m_load_restore) {
1523 m_backup_path = filename.substr(0, filename.size() - 5);
1524 model.set_backup_path(m_backup_path);
1525 try {
1526 if (boost::filesystem::exists(model.get_backup_path() + "/origin.txt"))
1527 load_string_file(model.get_backup_path() + "/origin.txt", m_origin_file);
1528 } catch (...) {}
1530 model.get_backup_path() + "/lock.txt",
1531 boost::lexical_cast<std::string>(get_current_pid()));
1532 }
1533 else {
1534 m_backup_path = model.get_backup_path();
1535 }
1536 bool result = _load_model_from_file(filename, model, plate_data_list, project_presets, config, config_substitutions, proFn, project, plate_id);
1537 if (is_bbl_3mf) {
1538 *is_bbl_3mf = m_is_bbl_3mf;
1539 }
1540 // If the OrcaSlicer tag is present, use it as file_version (ignoring the Bambu Application version).
1541 // Otherwise fall back to the version parsed from the Application tag.
1543 file_version = *m_orca_slicer_version;
1544 if (is_orca_3mf)
1545 *is_orca_3mf = true;
1546 } else {
1548 file_version = *m_bambuslicer_generator_version;
1549 if (is_orca_3mf)
1550 *is_orca_3mf = false;
1551 }
1552 // save for restore
1553 if (result && m_load_aux && !m_load_restore) {
1554 save_string_file(model.get_backup_path() + "/origin.txt", filename);
1555 }
1556 if (m_load_restore && !result) // not clear failed backup data for later analyze
1557 model.set_backup_path("detach");
1558 return result;
1559 }
unsigned int m_mm_painting_version
Definition bbs_3mf.cpp:1180
bool _load_model_from_file(std::string filename, Model &model, PlateDataPtrs &plate_data_list, std::vector< Preset * > &project_presets, DynamicPrintConfig &config, ConfigSubstitutionContext &config_substitutions, Import3mfProgressFn proFn=nullptr, BBLProject *project=nullptr, int plate_id=0)
Definition bbs_3mf.cpp:1794
unsigned int m_fdm_supports_painting_version
Definition bbs_3mf.cpp:1178
unsigned int m_seam_painting_version
Definition bbs_3mf.cpp:1179
void save_string_file(const boost::filesystem::path &p, const std::string &str)
Definition utils.cpp:2156
unsigned get_current_pid()
Definition utils.cpp:1480
void load_string_file(const boost::filesystem::path &p, std::string &str)
Definition utils.cpp:2164
@ LoadModel
Definition bbs_3mf.hpp:222
@ Restore
Definition bbs_3mf.hpp:228
@ LoadConfig
Definition bbs_3mf.hpp:223
@ CheckVersion
Definition bbs_3mf.hpp:221
@ LoadAuxiliary
Definition bbs_3mf.hpp:224

References _load_model_from_file(), Slic3r::CheckVersion, Slic3r::_BBS_3MF_Base::clear_errors(), Slic3r::Model::get_backup_path(), Slic3r::get_current_pid(), Slic3r::load_string_file(), Slic3r::LoadAuxiliary, Slic3r::LoadConfig, Slic3r::LoadModel, m_backup_path, m_bambuslicer_generator_version, m_brim_ear_points, m_check_version, m_curr_characters, m_curr_config, m_curr_instance, m_curr_metadata_name, m_curr_object, m_current_objects, m_fdm_supports_painting_version, m_index_paths, m_instances, m_is_bbl_3mf, m_items_auto_drop_off, m_layer_config_ranges, m_layer_heights_profiles, m_load_aux, m_load_config, m_load_model, m_load_restore, m_mm_painting_version, m_model, m_objects, m_objects_metadata, m_orca_slicer_version, m_origin_file, m_plater_data, m_seam_painting_version, m_unit_factor, m_version, Slic3r::Restore, Slic3r::save_string_file(), and Slic3r::Model::set_backup_path().

Referenced by Slic3r::load_bbs_3mf().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ log_errors()

void Slic3r::_BBS_3MF_Base::log_errors ( )
inlineinherited
821 {
822 for (const std::string& error : m_errors)
823 BOOST_LOG_TRIVIAL(error) << error;
824 }

References m_errors.

Referenced by Slic3r::bbs_3mf_get_thumbnail(), Slic3r::load_bbs_3mf(), Slic3r::load_gcode_3mf_from_stream(), and Slic3r::store_bbs_3mf().

Here is the caller graph for this function:

◆ parse_error()

bool Slic3r::_BBS_3MF_Importer::parse_error ( ) const
inlineprivate
1264{ return m_parse_error; }

References m_parse_error.

◆ parse_error_message()

const char * Slic3r::_BBS_3MF_Importer::parse_error_message ( ) const
inlineprivate
1265 {
1266 return m_parse_error ?
1267 // The error was signalled by the user code, not the expat parser.
1268 (m_parse_error_message.empty() ? "Invalid 3MF format" : m_parse_error_message.c_str()) :
1269 // The error was signalled by the expat parser.
1270 XML_ErrorString(XML_GetErrorCode(m_xml_parser));
1271 }

References m_parse_error, m_parse_error_message, and m_xml_parser.

◆ version()

unsigned int Slic3r::_BBS_3MF_Importer::version ( ) const
inline
1258{ return m_version; }

References m_version.

Referenced by _extract_brim_ear_points_from_archive(), and _extract_project_embedded_presets_from_archive().

Here is the caller graph for this function:

Member Data Documentation

◆ m_backup_path

std::string Slic3r::_BBS_3MF_Importer::m_backup_path
private

◆ m_bambuslicer_generator_version

boost::optional<Semver> Slic3r::_BBS_3MF_Importer::m_bambuslicer_generator_version
private

◆ m_brim_ear_points

IdToBrimPointsMap Slic3r::_BBS_3MF_Importer::m_brim_ear_points
private

◆ m_check_version

bool Slic3r::_BBS_3MF_Importer::m_check_version = false
private

◆ m_contry_code

std::string Slic3r::_BBS_3MF_Importer::m_contry_code
private

Referenced by _handle_end_metadata().

◆ m_curr_characters

◆ m_curr_config

◆ m_curr_instance

CurrentInstance Slic3r::_BBS_3MF_Importer::m_curr_instance
private

◆ m_curr_metadata_name

std::string Slic3r::_BBS_3MF_Importer::m_curr_metadata_name
private

◆ m_curr_object

◆ m_curr_plater

◆ m_current_color_group

int Slic3r::_BBS_3MF_Importer::m_current_color_group {-1}
private
1245{-1};

Referenced by _handle_start_color(), and _handle_start_color_group().

◆ m_current_objects

◆ m_cut_object_infos

IdToCutObjectInfoMap Slic3r::_BBS_3MF_Importer::m_cut_object_infos
private

◆ m_designer

std::string Slic3r::_BBS_3MF_Importer::m_designer
private

◆ m_designer_cover

std::string Slic3r::_BBS_3MF_Importer::m_designer_cover
private

◆ m_designer_user_id

std::string Slic3r::_BBS_3MF_Importer::m_designer_user_id
private

◆ m_errors

std::vector<std::string> Slic3r::_BBS_3MF_Base::m_errors
mutableprivateinherited

Referenced by add_error(), clear_errors(), and log_errors().

◆ m_fdm_supports_painting_version

unsigned int Slic3r::_BBS_3MF_Importer::m_fdm_supports_painting_version = 0
private

Referenced by load_model_from_file().

◆ m_group_id_to_color

std::map<int, std::string> Slic3r::_BBS_3MF_Importer::m_group_id_to_color
private

◆ m_index_paths

IndexToPathMap Slic3r::_BBS_3MF_Importer::m_index_paths
private

◆ m_instances

InstancesList Slic3r::_BBS_3MF_Importer::m_instances
private

◆ m_is_bbl_3mf

bool Slic3r::_BBS_3MF_Importer::m_is_bbl_3mf { false }
private

◆ m_items_auto_drop_off

std::set<int> Slic3r::_BBS_3MF_Importer::m_items_auto_drop_off
private

◆ m_layer_config_ranges

IdToLayerConfigRangesMap Slic3r::_BBS_3MF_Importer::m_layer_config_ranges
private

◆ m_layer_heights_profiles

IdToLayerHeightsProfileMap Slic3r::_BBS_3MF_Importer::m_layer_heights_profiles
private

◆ m_load_aux

bool Slic3r::_BBS_3MF_Importer::m_load_aux = false
private

Referenced by load_model_from_file().

◆ m_load_config

bool Slic3r::_BBS_3MF_Importer::m_load_config = false
private

Referenced by load_model_from_file().

◆ m_load_model

bool Slic3r::_BBS_3MF_Importer::m_load_model = false
private

◆ m_load_restore

bool Slic3r::_BBS_3MF_Importer::m_load_restore = false
private

◆ m_mm_painting_version

unsigned int Slic3r::_BBS_3MF_Importer::m_mm_painting_version = 0
private

Referenced by load_model_from_file().

◆ m_model

◆ m_model_id

std::string Slic3r::_BBS_3MF_Importer::m_model_id
private

Referenced by _handle_end_metadata().

◆ m_name

std::string Slic3r::_BBS_3MF_Importer::m_name
private

◆ m_object_importers

std::vector<ObjectImporter*> Slic3r::_BBS_3MF_Importer::m_object_importers
private

Referenced by _load_model_from_file().

◆ m_objects

◆ m_objects_metadata

◆ m_orca_slicer_version

boost::optional<Semver> Slic3r::_BBS_3MF_Importer::m_orca_slicer_version
private

◆ m_origin_file

std::string Slic3r::_BBS_3MF_Importer::m_origin_file
private

◆ m_parse_error

bool Slic3r::_BBS_3MF_Importer::m_parse_error { false }
private
1197{ false };

Referenced by _stop_xml_parser(), parse_error(), and parse_error_message().

◆ m_parse_error_message

std::string Slic3r::_BBS_3MF_Importer::m_parse_error_message
private

◆ m_parsing_slice_info

bool Slic3r::_BBS_3MF_Importer::m_parsing_slice_info { false }
private

◆ m_path_to_emboss_shape_files

PathToEmbossShapeFileMap Slic3r::_BBS_3MF_Importer::m_path_to_emboss_shape_files
private

◆ m_plater_data

◆ m_profile_cover

std::string Slic3r::_BBS_3MF_Importer::m_profile_cover
private

◆ m_Profile_description

std::string Slic3r::_BBS_3MF_Importer::m_Profile_description
private

◆ m_profile_title

std::string Slic3r::_BBS_3MF_Importer::m_profile_title
private

◆ m_profile_user_id

std::string Slic3r::_BBS_3MF_Importer::m_profile_user_id
private

◆ m_profile_user_name

std::string Slic3r::_BBS_3MF_Importer::m_profile_user_name
private

◆ m_seam_painting_version

unsigned int Slic3r::_BBS_3MF_Importer::m_seam_painting_version = 0
private

Referenced by load_model_from_file().

◆ m_shared_meshes

std::map<int, ModelVolume*> Slic3r::_BBS_3MF_Importer::m_shared_meshes
private

Referenced by _generate_volumes_new().

◆ m_start_part_path

std::string Slic3r::_BBS_3MF_Importer::m_start_part_path
private

◆ m_sub_model_path

std::string Slic3r::_BBS_3MF_Importer::m_sub_model_path
private

◆ m_sub_model_paths

std::vector<std::string> Slic3r::_BBS_3MF_Importer::m_sub_model_paths
private

◆ m_texture_displacement_files

std::map<std::string, std::string> Slic3r::_BBS_3MF_Importer::m_texture_displacement_files
private

◆ m_thumbnail_middle

std::string Slic3r::_BBS_3MF_Importer::m_thumbnail_middle
private

◆ m_thumbnail_path

std::string Slic3r::_BBS_3MF_Importer::m_thumbnail_path
private

◆ m_thumbnail_small

std::string Slic3r::_BBS_3MF_Importer::m_thumbnail_small
private

◆ m_unit_factor

float Slic3r::_BBS_3MF_Importer::m_unit_factor
private

◆ m_version

unsigned int Slic3r::_BBS_3MF_Importer::m_version
private

◆ m_xml_parser

◆ model_info

ModelInfo Slic3r::_BBS_3MF_Importer::model_info
private

◆ mutex

boost::mutex Slic3r::_BBS_3MF_Base::mutex
mutableprivateinherited

◆ project_info

BBLProject Slic3r::_BBS_3MF_Importer::project_info
private

The documentation for this class was generated from the following file:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Format/bbs_3mf.cpp