Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::AMFParserContext Struct Reference
+ Collaboration diagram for Slic3r::AMFParserContext:

Classes

struct  Instance
 
struct  Object
 

Public Types

enum  AMFNodeType {
  NODE_TYPE_INVALID = 0 , NODE_TYPE_UNKNOWN , NODE_TYPE_AMF , NODE_TYPE_MATERIAL ,
  NODE_TYPE_OBJECT , NODE_TYPE_LAYER_CONFIG , NODE_TYPE_RANGE , NODE_TYPE_MESH ,
  NODE_TYPE_VERTICES , NODE_TYPE_VERTEX , NODE_TYPE_COORDINATES , NODE_TYPE_COORDINATE_X ,
  NODE_TYPE_COORDINATE_Y , NODE_TYPE_COORDINATE_Z , NODE_TYPE_VOLUME , NODE_TYPE_TRIANGLE ,
  NODE_TYPE_VERTEX1 , NODE_TYPE_VERTEX2 , NODE_TYPE_VERTEX3 , NODE_TYPE_CONSTELLATION ,
  NODE_TYPE_INSTANCE , NODE_TYPE_DELTAX , NODE_TYPE_DELTAY , NODE_TYPE_DELTAZ ,
  NODE_TYPE_RX , NODE_TYPE_RY , NODE_TYPE_RZ , NODE_TYPE_SCALE ,
  NODE_TYPE_SCALEX , NODE_TYPE_SCALEY , NODE_TYPE_SCALEZ , NODE_TYPE_MIRRORX ,
  NODE_TYPE_MIRRORY , NODE_TYPE_MIRRORZ , NODE_TYPE_PRINTABLE , NODE_TYPE_CUSTOM_GCODE ,
  NODE_TYPE_GCODE_PER_HEIGHT , NODE_TYPE_CUSTOM_GCODE_MODE , NODE_TYPE_METADATA
}
 

Public Member Functions

 AMFParserContext (XML_Parser parser, DynamicPrintConfig *config, ConfigSubstitutionContext *config_substitutions, Model *model)
 
void stop (const std::string &msg=std::string())
 
bool error () const
 
const char * error_message () const
 
void startElement (const char *name, const char **atts)
 
void endElement (const char *name)
 
void endDocument ()
 
void characters (const XML_Char *s, int len)
 

Static Public Member Functions

static void XMLCALL startElement (void *userData, const char *name, const char **atts)
 
static void XMLCALL endElement (void *userData, const char *name)
 
static void XMLCALL characters (void *userData, const XML_Char *s, int len)
 
static const char * get_attribute (const char **atts, const char *id)
 

Public Attributes

unsigned int m_version { 0 }
 
XML_Parser m_parser
 
bool m_error { false }
 
std::string m_error_message
 
Modelm_model
 
std::vector< AMFNodeTypem_path
 
ModelObjectm_object { nullptr }
 
std::map< std::string, Objectm_object_instances_map
 
std::vector< Vec3fm_object_vertices
 
ModelVolumem_volume { nullptr }
 
std::vector< Vec3im_volume_facets
 
Transform3d m_volume_transform
 
ModelMaterialm_material { nullptr }
 
Instancem_instance { nullptr }
 
std::string m_value [5]
 
DynamicPrintConfigm_config { nullptr }
 
ConfigSubstitutionContextm_config_substitutions { nullptr }
 

Private Member Functions

AMFParserContextoperator= (AMFParserContext &)
 

Detailed Description

Member Enumeration Documentation

◆ AMFNodeType

Enumerator
NODE_TYPE_INVALID 
NODE_TYPE_UNKNOWN 
NODE_TYPE_AMF 
NODE_TYPE_MATERIAL 
NODE_TYPE_OBJECT 
NODE_TYPE_LAYER_CONFIG 
NODE_TYPE_RANGE 
NODE_TYPE_MESH 
NODE_TYPE_VERTICES 
NODE_TYPE_VERTEX 
NODE_TYPE_COORDINATES 
NODE_TYPE_COORDINATE_X 
NODE_TYPE_COORDINATE_Y 
NODE_TYPE_COORDINATE_Z 
NODE_TYPE_VOLUME 
NODE_TYPE_TRIANGLE 
NODE_TYPE_VERTEX1 
NODE_TYPE_VERTEX2 
NODE_TYPE_VERTEX3 
NODE_TYPE_CONSTELLATION 
NODE_TYPE_INSTANCE 
NODE_TYPE_DELTAX 
NODE_TYPE_DELTAY 
NODE_TYPE_DELTAZ 
NODE_TYPE_RX 
NODE_TYPE_RY 
NODE_TYPE_RZ 
NODE_TYPE_SCALE 
NODE_TYPE_SCALEX 
NODE_TYPE_SCALEY 
NODE_TYPE_SCALEZ 
NODE_TYPE_MIRRORX 
NODE_TYPE_MIRRORY 
NODE_TYPE_MIRRORZ 
NODE_TYPE_PRINTABLE 
NODE_TYPE_CUSTOM_GCODE 
NODE_TYPE_GCODE_PER_HEIGHT 
NODE_TYPE_CUSTOM_GCODE_MODE 
NODE_TYPE_METADATA 
125 {
128 NODE_TYPE_AMF, // amf
129 // amf/metadata
130 NODE_TYPE_MATERIAL, // amf/material
131 // amf/material/metadata
132 NODE_TYPE_OBJECT, // amf/object
133 // amf/object/metadata
134 NODE_TYPE_LAYER_CONFIG, // amf/object/layer_config_ranges
135 NODE_TYPE_RANGE, // amf/object/layer_config_ranges/range
136 // amf/object/layer_config_ranges/range/metadata
137 NODE_TYPE_MESH, // amf/object/mesh
138 NODE_TYPE_VERTICES, // amf/object/mesh/vertices
139 NODE_TYPE_VERTEX, // amf/object/mesh/vertices/vertex
140 NODE_TYPE_COORDINATES, // amf/object/mesh/vertices/vertex/coordinates
141 NODE_TYPE_COORDINATE_X, // amf/object/mesh/vertices/vertex/coordinates/x
142 NODE_TYPE_COORDINATE_Y, // amf/object/mesh/vertices/vertex/coordinates/y
143 NODE_TYPE_COORDINATE_Z, // amf/object/mesh/vertices/vertex/coordinates/z
144 NODE_TYPE_VOLUME, // amf/object/mesh/volume
145 // amf/object/mesh/volume/metadata
146 NODE_TYPE_TRIANGLE, // amf/object/mesh/volume/triangle
147 NODE_TYPE_VERTEX1, // amf/object/mesh/volume/triangle/v1
148 NODE_TYPE_VERTEX2, // amf/object/mesh/volume/triangle/v2
149 NODE_TYPE_VERTEX3, // amf/object/mesh/volume/triangle/v3
150 NODE_TYPE_CONSTELLATION, // amf/constellation
151 NODE_TYPE_INSTANCE, // amf/constellation/instance
152 NODE_TYPE_DELTAX, // amf/constellation/instance/deltax
153 NODE_TYPE_DELTAY, // amf/constellation/instance/deltay
154 NODE_TYPE_DELTAZ, // amf/constellation/instance/deltaz
155 NODE_TYPE_RX, // amf/constellation/instance/rx
156 NODE_TYPE_RY, // amf/constellation/instance/ry
157 NODE_TYPE_RZ, // amf/constellation/instance/rz
158 NODE_TYPE_SCALE, // amf/constellation/instance/scale
159 NODE_TYPE_SCALEX, // amf/constellation/instance/scalex
160 NODE_TYPE_SCALEY, // amf/constellation/instance/scaley
161 NODE_TYPE_SCALEZ, // amf/constellation/instance/scalez
162 NODE_TYPE_MIRRORX, // amf/constellation/instance/mirrorx
163 NODE_TYPE_MIRRORY, // amf/constellation/instance/mirrory
164 NODE_TYPE_MIRRORZ, // amf/constellation/instance/mirrorz
165 NODE_TYPE_PRINTABLE, // amf/constellation/instance/mirrorz
166 NODE_TYPE_CUSTOM_GCODE, // amf/custom_code_per_height
167 NODE_TYPE_GCODE_PER_HEIGHT, // amf/custom_code_per_height/code
168 NODE_TYPE_CUSTOM_GCODE_MODE, // amf/custom_code_per_height/mode
169 NODE_TYPE_METADATA, // anywhere under amf/*/metadata
170 };
@ NODE_TYPE_LAYER_CONFIG
Definition AMF.cpp:134
@ NODE_TYPE_VERTEX
Definition AMF.cpp:139
@ NODE_TYPE_RY
Definition AMF.cpp:156
@ NODE_TYPE_INVALID
Definition AMF.cpp:126
@ NODE_TYPE_GCODE_PER_HEIGHT
Definition AMF.cpp:167
@ NODE_TYPE_VOLUME
Definition AMF.cpp:144
@ NODE_TYPE_MIRRORZ
Definition AMF.cpp:164
@ NODE_TYPE_MIRRORY
Definition AMF.cpp:163
@ NODE_TYPE_CONSTELLATION
Definition AMF.cpp:150
@ NODE_TYPE_COORDINATE_X
Definition AMF.cpp:141
@ NODE_TYPE_PRINTABLE
Definition AMF.cpp:165
@ NODE_TYPE_SCALEY
Definition AMF.cpp:160
@ NODE_TYPE_DELTAX
Definition AMF.cpp:152
@ NODE_TYPE_METADATA
Definition AMF.cpp:169
@ NODE_TYPE_CUSTOM_GCODE
Definition AMF.cpp:166
@ NODE_TYPE_SCALEX
Definition AMF.cpp:159
@ NODE_TYPE_RX
Definition AMF.cpp:155
@ NODE_TYPE_COORDINATE_Y
Definition AMF.cpp:142
@ NODE_TYPE_VERTEX2
Definition AMF.cpp:148
@ NODE_TYPE_OBJECT
Definition AMF.cpp:132
@ NODE_TYPE_COORDINATE_Z
Definition AMF.cpp:143
@ NODE_TYPE_TRIANGLE
Definition AMF.cpp:146
@ NODE_TYPE_MIRRORX
Definition AMF.cpp:162
@ NODE_TYPE_MATERIAL
Definition AMF.cpp:130
@ NODE_TYPE_MESH
Definition AMF.cpp:137
@ NODE_TYPE_DELTAZ
Definition AMF.cpp:154
@ NODE_TYPE_AMF
Definition AMF.cpp:128
@ NODE_TYPE_DELTAY
Definition AMF.cpp:153
@ NODE_TYPE_SCALE
Definition AMF.cpp:158
@ NODE_TYPE_VERTICES
Definition AMF.cpp:138
@ NODE_TYPE_VERTEX3
Definition AMF.cpp:149
@ NODE_TYPE_INSTANCE
Definition AMF.cpp:151
@ NODE_TYPE_RANGE
Definition AMF.cpp:135
@ NODE_TYPE_CUSTOM_GCODE_MODE
Definition AMF.cpp:168
@ NODE_TYPE_RZ
Definition AMF.cpp:157
@ NODE_TYPE_COORDINATES
Definition AMF.cpp:140
@ NODE_TYPE_SCALEZ
Definition AMF.cpp:161
@ NODE_TYPE_VERTEX1
Definition AMF.cpp:147
@ NODE_TYPE_UNKNOWN
Definition AMF.cpp:127

Constructor & Destructor Documentation

◆ AMFParserContext()

Slic3r::AMFParserContext::AMFParserContext ( XML_Parser  parser,
DynamicPrintConfig config,
ConfigSubstitutionContext config_substitutions,
Model model 
)
inline
63 :
64 m_parser(parser),
65 m_model(*model),
66 m_config(config),
67 m_config_substitutions(config_substitutions)
68 {
69 m_path.reserve(12);
70 }
std::vector< AMFNodeType > m_path
Definition AMF.cpp:237
Model & m_model
Definition AMF.cpp:235
DynamicPrintConfig * m_config
Definition AMF.cpp:257
ConfigSubstitutionContext * m_config_substitutions
Definition AMF.cpp:259
XML_Parser m_parser
Definition AMF.cpp:229

References m_path.

Member Function Documentation

◆ characters() [1/2]

void Slic3r::AMFParserContext::characters ( const XML_Char *  s,
int  len 
)
460{
461 if (m_path.back() == NODE_TYPE_METADATA) {
462 m_value[1].append(s, len);
463 }
464 else
465 {
466 switch (m_path.size()) {
467 case 4:
468 if (m_path.back() == NODE_TYPE_DELTAX ||
469 m_path.back() == NODE_TYPE_DELTAY ||
470 m_path.back() == NODE_TYPE_DELTAZ ||
471 m_path.back() == NODE_TYPE_RX ||
472 m_path.back() == NODE_TYPE_RY ||
473 m_path.back() == NODE_TYPE_RZ ||
474 m_path.back() == NODE_TYPE_SCALEX ||
475 m_path.back() == NODE_TYPE_SCALEY ||
476 m_path.back() == NODE_TYPE_SCALEZ ||
477 m_path.back() == NODE_TYPE_SCALE ||
478 m_path.back() == NODE_TYPE_MIRRORX ||
479 m_path.back() == NODE_TYPE_MIRRORY ||
480 m_path.back() == NODE_TYPE_MIRRORZ ||
481 m_path.back() == NODE_TYPE_PRINTABLE)
482 m_value[0].append(s, len);
483 break;
484 case 6:
485 switch (m_path.back()) {
486 case NODE_TYPE_VERTEX1: m_value[0].append(s, len); break;
487 case NODE_TYPE_VERTEX2: m_value[1].append(s, len); break;
488 case NODE_TYPE_VERTEX3: m_value[2].append(s, len); break;
489 default: break;
490 }
491 case 7:
492 switch (m_path.back()) {
493 case NODE_TYPE_COORDINATE_X: m_value[0].append(s, len); break;
494 case NODE_TYPE_COORDINATE_Y: m_value[1].append(s, len); break;
495 case NODE_TYPE_COORDINATE_Z: m_value[2].append(s, len); break;
496 default: break;
497 }
498 default:
499 break;
500 }
501 }
502}
std::string m_value[5]
Definition AMF.cpp:255

References m_path, m_value, NODE_TYPE_COORDINATE_X, NODE_TYPE_COORDINATE_Y, NODE_TYPE_COORDINATE_Z, NODE_TYPE_DELTAX, NODE_TYPE_DELTAY, NODE_TYPE_DELTAZ, NODE_TYPE_METADATA, NODE_TYPE_MIRRORX, NODE_TYPE_MIRRORY, NODE_TYPE_MIRRORZ, NODE_TYPE_PRINTABLE, NODE_TYPE_RX, NODE_TYPE_RY, NODE_TYPE_RZ, NODE_TYPE_SCALE, NODE_TYPE_SCALEX, NODE_TYPE_SCALEY, NODE_TYPE_SCALEZ, NODE_TYPE_VERTEX1, NODE_TYPE_VERTEX2, and NODE_TYPE_VERTEX3.

Referenced by characters(), Slic3r::extract_model_from_archive(), and Slic3r::load_amf_file().

+ Here is the caller graph for this function:

◆ characters() [2/2]

static void XMLCALL Slic3r::AMFParserContext::characters ( void userData,
const XML_Char *  s,
int  len 
)
inlinestatic
109 {
110 AMFParserContext *ctx = (AMFParserContext*)userData;
111 ctx->characters(s, len);
112 }
AMFParserContext(XML_Parser parser, DynamicPrintConfig *config, ConfigSubstitutionContext *config_substitutions, Model *model)
Definition AMF.cpp:63

References characters().

+ Here is the call graph for this function:

◆ endDocument()

void Slic3r::AMFParserContext::endDocument ( )
845{
846 for (const auto &object : m_object_instances_map) {
847 if (object.second.idx == -1) {
848 BOOST_LOG_TRIVIAL(error) << "Undefined object " << object.first.c_str() << " referenced in constellation";
849 continue;
850 }
851 for (const Instance &instance : object.second.instances)
852 if (instance.anything_set()) {
853 ModelInstance *mi = m_model.objects[object.second.idx]->add_instance();
854 mi->set_offset(Vec3d(instance.deltax_set ? (double)instance.deltax : 0.0, instance.deltay_set ? (double)instance.deltay : 0.0, instance.deltaz_set ? (double)instance.deltaz : 0.0));
855 mi->set_rotation(Vec3d(instance.rx_set ? (double)instance.rx : 0.0, instance.ry_set ? (double)instance.ry : 0.0, instance.rz_set ? (double)instance.rz : 0.0));
856 mi->set_scaling_factor(Vec3d(instance.scalex_set ? (double)instance.scalex : 1.0, instance.scaley_set ? (double)instance.scaley : 1.0, instance.scalez_set ? (double)instance.scalez : 1.0));
857 mi->set_mirror(Vec3d(instance.mirrorx_set ? (double)instance.mirrorx : 1.0, instance.mirrory_set ? (double)instance.mirrory : 1.0, instance.mirrorz_set ? (double)instance.mirrorz : 1.0));
858 mi->printable = instance.printable;
859 }
860 }
861}
ModelObjectPtrs objects
Definition Model.hpp:1254
if(!(yy_init))
Definition lexer.c:1190
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:52
std::map< std::string, Object > m_object_instances_map
Definition AMF.cpp:241
bool error() const
Definition AMF.cpp:81

References error(), m_model, m_object_instances_map, Slic3r::Model::objects, Slic3r::ModelInstance::printable, Slic3r::ModelInstance::set_mirror(), Slic3r::ModelInstance::set_offset(), Slic3r::ModelInstance::set_rotation(), and Slic3r::ModelInstance::set_scaling_factor().

Referenced by Slic3r::load_amf_file().

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

◆ endElement() [1/2]

void Slic3r::AMFParserContext::endElement ( const char *  name)
505{
507 switch (m_path.back()) {
508
509 // Constellation transformation:
510 case NODE_TYPE_DELTAX:
511 assert(m_instance);
512 m_instance->deltax = float(atof(m_value[0].c_str()));
513 m_instance->deltax_set = true;
514 m_value[0].clear();
515 break;
516 case NODE_TYPE_DELTAY:
517 assert(m_instance);
518 m_instance->deltay = float(atof(m_value[0].c_str()));
519 m_instance->deltay_set = true;
520 m_value[0].clear();
521 break;
522 case NODE_TYPE_DELTAZ:
523 assert(m_instance);
524 m_instance->deltaz = float(atof(m_value[0].c_str()));
525 m_instance->deltaz_set = true;
526 m_value[0].clear();
527 break;
528 case NODE_TYPE_RX:
529 assert(m_instance);
530 m_instance->rx = float(atof(m_value[0].c_str()));
531 m_instance->rx_set = true;
532 m_value[0].clear();
533 break;
534 case NODE_TYPE_RY:
535 assert(m_instance);
536 m_instance->ry = float(atof(m_value[0].c_str()));
537 m_instance->ry_set = true;
538 m_value[0].clear();
539 break;
540 case NODE_TYPE_RZ:
541 assert(m_instance);
542 m_instance->rz = float(atof(m_value[0].c_str()));
543 m_instance->rz_set = true;
544 m_value[0].clear();
545 break;
546 case NODE_TYPE_SCALE:
547 assert(m_instance);
548 m_instance->scalex = float(atof(m_value[0].c_str()));
549 m_instance->scalex_set = true;
550 m_instance->scaley = float(atof(m_value[0].c_str()));
551 m_instance->scaley_set = true;
552 m_instance->scalez = float(atof(m_value[0].c_str()));
553 m_instance->scalez_set = true;
554 m_value[0].clear();
555 break;
556 case NODE_TYPE_SCALEX:
557 assert(m_instance);
558 m_instance->scalex = float(atof(m_value[0].c_str()));
559 m_instance->scalex_set = true;
560 m_value[0].clear();
561 break;
562 case NODE_TYPE_SCALEY:
563 assert(m_instance);
564 m_instance->scaley = float(atof(m_value[0].c_str()));
565 m_instance->scaley_set = true;
566 m_value[0].clear();
567 break;
568 case NODE_TYPE_SCALEZ:
569 assert(m_instance);
570 m_instance->scalez = float(atof(m_value[0].c_str()));
571 m_instance->scalez_set = true;
572 m_value[0].clear();
573 break;
575 assert(m_instance);
576 m_instance->mirrorx = float(atof(m_value[0].c_str()));
577 m_instance->mirrorx_set = true;
578 m_value[0].clear();
579 break;
581 assert(m_instance);
582 m_instance->mirrory = float(atof(m_value[0].c_str()));
583 m_instance->mirrory_set = true;
584 m_value[0].clear();
585 break;
587 assert(m_instance);
588 m_instance->mirrorz = float(atof(m_value[0].c_str()));
589 m_instance->mirrorz_set = true;
590 m_value[0].clear();
591 break;
593 assert(m_instance);
594 m_instance->printable = bool(atoi(m_value[0].c_str()));
595 m_value[0].clear();
596 break;
597
598 // Object vertices:
599 case NODE_TYPE_VERTEX:
600 assert(m_object);
601 // Parse the vertex data
602 m_object_vertices.emplace_back(float(atof(m_value[0].c_str())), float(atof(m_value[1].c_str())), float(atof(m_value[2].c_str())));
603 m_value[0].clear();
604 m_value[1].clear();
605 m_value[2].clear();
606 break;
607
608 // Faces of the current volume:
610 assert(m_object && m_volume);
611 m_volume_facets.emplace_back(atoi(m_value[0].c_str()), atoi(m_value[1].c_str()), atoi(m_value[2].c_str()));
612 m_value[0].clear();
613 m_value[1].clear();
614 m_value[2].clear();
615 break;
616
617 // Closing the current volume. Create an STL from m_volume_facets pointing to m_object_vertices.
618 case NODE_TYPE_VOLUME:
619 {
620 assert(m_object && m_volume);
621 if (m_volume_facets.empty()) {
622 this->stop("An empty triangle mesh found");
623 return;
624 }
625
626 {
627 // Verify validity of face indices, find the vertex span.
628 int min_id = m_volume_facets.front()[0];
629 int max_id = min_id;
630 for (const Vec3i& face : m_volume_facets) {
631 for (const int tri_id : face) {
632 if (tri_id < 0 || tri_id >= int(m_object_vertices.size())) {
633 this->stop("Malformed triangle mesh");
634 return;
635 }
636 min_id = std::min(min_id, tri_id);
637 max_id = std::max(max_id, tri_id);
638 }
639 }
640
641 // rebase indices to the current vertices list
642 for (Vec3i &face : m_volume_facets)
643 face -= Vec3i(min_id, min_id, min_id);
644
645 indexed_triangle_set its { std::move(m_volume_facets), { m_object_vertices.begin() + min_id, m_object_vertices.begin() + max_id + 1 } };
647 if (its_volume(its) < 0)
649 m_volume->set_mesh(std::move(its));
650 }
651
652 // stores the volume matrix taken from the metadata, if present
653 if (bool has_transform = !m_volume_transform.isApprox(Transform3d::Identity(), 1e-10); has_transform)
655
656 if (m_volume->source.input_file.empty()) {
657 m_volume->source.object_idx = (int)m_model.objects.size() - 1;
658 m_volume->source.volume_idx = (int)m_model.objects.back()->volumes.size() - 1;
660 }
661 else
662 // pass false if the mesh offset has been already taken from the data
664
666 m_volume_facets.clear();
667 m_volume = nullptr;
668 break;
669 }
670
671 case NODE_TYPE_OBJECT:
672 assert(m_object);
673 m_object_vertices.clear();
674 m_object = nullptr;
675 break;
676
678 assert(m_material);
679 m_material = nullptr;
680 break;
681
683 assert(m_instance);
684 m_instance = nullptr;
685 break;
686
688 double print_z = double(atof(m_value[0].c_str()));
689 int extruder = atoi(m_value[1].c_str());
690 const std::string& color= m_value[2];
691 CustomGCode::Type type = static_cast<CustomGCode::Type>(atoi(m_value[3].c_str()));
692 const std::string& extra= m_value[4];
693
694 m_model.custom_gcode_per_print_z.gcodes.push_back(CustomGCode::Item{print_z, type, extruder, color, extra});
695
696 for (std::string& val: m_value)
697 val.clear();
698 break;
699 }
700
702 const std::string& mode = m_value[0];
703
707 for (std::string& val: m_value)
708 val.clear();
709 break;
710 }
711
713 if ((m_config != nullptr) && strncmp(m_value[0].c_str(), SLIC3R_CONFIG_TYPE, strlen(SLIC3R_CONFIG_TYPE)) == 0) {
714 //FIXME Loading a "will be one day a legacy format" of configuration in a form of a G-code comment.
715 // Each config line is prefixed with a semicolon (G-code comment), that is ugly.
716
717 // Replacing the legacy function with load_from_ini_string_commented leads to issues when
718 // parsing 3MFs from before PrusaSlicer 2.0.0 (which can have duplicated entries in the INI.
719 // See https://github.com/prusa3d/PrusaSlicer/issues/7155. We'll revert it for now.
720 //m_config_substitutions->substitutions = m_config->load_from_ini_string_commented(std::move(m_value[1].c_str()), m_config_substitutions->rule);
722 }
723 else if (strncmp(m_value[0].c_str(), "slic3r.", 7) == 0) {
724 const char *opt_key = m_value[0].c_str() + 7;
725 if (print_config_def.options.find(opt_key) != print_config_def.options.end()) {
726 ModelConfig *config = nullptr;
727 if (m_path.size() == 3) {
729 config = &m_material->config;
730 else if (m_path[1] == NODE_TYPE_OBJECT && m_object)
731 config = &m_object->config;
732 }
733 else if (m_path.size() == 5 && m_path[3] == NODE_TYPE_VOLUME && m_volume)
734 config = &m_volume->config;
735 else if (m_path.size() == 5 && m_path[3] == NODE_TYPE_RANGE && m_object && !m_object->layer_config_ranges.empty()) {
736 auto it = --m_object->layer_config_ranges.end();
737 config = &it->second;
738 }
739 if (config)
740 config->set_deserialize(opt_key, m_value[1], *m_config_substitutions);
741 } else if (m_path.size() == 3 && m_path[1] == NODE_TYPE_OBJECT && m_object && strcmp(opt_key, "layer_height_profile") == 0) {
742 // Parse object's layer height profile, a semicolon separated list of floats.
743 char *p = m_value[1].data();
744 std::vector<coordf_t> data;
745 for (;;) {
746 char *end = strchr(p, ';');
747 if (end != nullptr)
748 *end = 0;
749 data.emplace_back(float(atof(p)));
750 if (end == nullptr)
751 break;
752 p = end + 1;
753 }
754 m_object->layer_height_profile.set(std::move(data));
755 }
756 else if (m_path.size() == 3 && m_path[1] == NODE_TYPE_OBJECT && m_object && strcmp(opt_key, "sla_support_points") == 0) {
757 // Parse object's layer height profile, a semicolon separated list of floats.
758 unsigned char coord_idx = 0;
760 char *p = m_value[1].data();
761 for (;;) {
762 char *end = strchr(p, ';');
763 if (end != nullptr)
764 *end = 0;
765
766 point(coord_idx) = float(atof(p));
767 if (++coord_idx == 5) {
768 m_object->sla_support_points.push_back(sla::SupportPoint(point));
769 coord_idx = 0;
770 }
771 if (end == nullptr)
772 break;
773 p = end + 1;
774 }
776 }
777 else if (m_path.size() == 5 && m_path[1] == NODE_TYPE_OBJECT && m_path[3] == NODE_TYPE_RANGE &&
778 m_object && strcmp(opt_key, "layer_height_range") == 0) {
779 // Parse object's layer_height_range, a semicolon separated doubles.
780 char* p = m_value[1].data();
781 char* end = strchr(p, ';');
782 *end = 0;
783
784 const t_layer_height_range range = {double(atof(p)), double(atof(end + 1))};
786 }
787 else if (m_path.size() == 5 && m_path[3] == NODE_TYPE_VOLUME && m_volume) {
788 if (strcmp(opt_key, "modifier") == 0) {
789 // Is this volume a modifier volume?
790 // "modifier" flag comes first in the XML file, so it may be later overwritten by the "type" flag.
792 }
793 else if (strcmp(opt_key, "volume_type") == 0)
795 else if (strcmp(opt_key, "matrix") == 0)
797 else if (strcmp(opt_key, "source_file") == 0)
799 else if (strcmp(opt_key, "source_object_id") == 0)
800 m_volume->source.object_idx = ::atoi(m_value[1].c_str());
801 else if (strcmp(opt_key, "source_volume_id") == 0)
802 m_volume->source.volume_idx = ::atoi(m_value[1].c_str());
803 else if (strcmp(opt_key, "source_offset_x") == 0)
804 m_volume->source.mesh_offset.x() = ::atof(m_value[1].c_str());
805 else if (strcmp(opt_key, "source_offset_y") == 0)
806 m_volume->source.mesh_offset.y() = ::atof(m_value[1].c_str());
807 else if (strcmp(opt_key, "source_offset_z") == 0)
808 m_volume->source.mesh_offset.z() = ::atof(m_value[1].c_str());
809 else if (strcmp(opt_key, "source_in_inches") == 0)
811 else if (strcmp(opt_key, "source_in_meters") == 0)
813 else if (strcmp(opt_key, "source_is_builtin_volume") == 0)
815 }
816 }
817 else if (m_path.size() == 3) {
818 if (m_path[1] == NODE_TYPE_MATERIAL) {
819 if (m_material)
821 }
822 else if (m_path[1] == NODE_TYPE_OBJECT) {
823 if (m_object && m_value[0] == "name")
824 m_object->name = std::move(m_value[1]);
825 }
826 }
827 else if (m_path.size() == 5 && m_path[3] == NODE_TYPE_VOLUME) {
828 if (m_volume && m_value[0] == "name")
829 m_volume->name = std::move(m_value[1]);
830 }
831 else if (strncmp(m_value[0].c_str(), SLIC3RPE_AMF_VERSION, strlen(SLIC3RPE_AMF_VERSION)) == 0) {
832 m_version = (unsigned int)atoi(m_value[1].c_str());
833 }
834
835 m_value[0].clear();
836 m_value[1].clear();
837 break;
838 default:
839 break;
840 }
841 m_path.pop_back();
842}
const char * SLIC3RPE_AMF_VERSION
Definition AMF.cpp:53
const char * SLIC3R_CONFIG_TYPE
Definition AMF.cpp:55
std::pair< coordf_t, coordf_t > t_layer_height_range
Definition UndoRedo.hpp:14
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:180
static size_t load_from_gcode_string_legacy(ConfigBase &config, const char *str, ConfigSubstitutionContext &substitutions)
Definition Config.cpp:804
t_optiondef_map options
Definition Config.hpp:2065
Definition Geometry.hpp:380
void set(const std::vector< coordf_t > &data)
Definition Model.hpp:193
CustomGCode::Info custom_gcode_per_print_z
Definition Model.hpp:1259
ModelConfigObject config
Definition Model.hpp:148
t_model_material_attributes attributes
Definition Model.hpp:146
ModelConfigObject config
Definition Model.hpp:339
std::string name
Definition Model.hpp:330
sla::SupportPoints sla_support_points
Definition Model.hpp:351
sla::PointsStatus sla_points_status
Definition Model.hpp:354
t_layer_config_ranges layer_config_ranges
Definition Model.hpp:341
LayerHeightProfile layer_height_profile
Definition Model.hpp:344
void calculate_convex_hull()
Definition Model.cpp:2098
void set_type(const ModelVolumeType t)
Definition Model.hpp:838
static ModelVolumeType type_from_string(const std::string &s)
Definition Model.cpp:2117
void center_geometry_after_creation(bool update_source_offset=true)
Definition Model.cpp:2082
ModelConfigObject config
Definition Model.hpp:820
void set_mesh(const TriangleMesh &mesh)
Definition Model.hpp:810
std::string name
Definition Model.hpp:755
Source source
Definition Model.hpp:774
static EIGEN_DEVICE_FUNC const Transform Identity()
Returns an identity transformation.
Definition Transform.h:539
EIGEN_DEVICE_FUNC bool isApprox(const Transform &other, const typename NumTraits< Scalar >::Real &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Transform.h:647
static constexpr char SingleExtruderMode[]
Definition CustomGCode.hpp:58
static constexpr char MultiAsSingleMode[]
Definition CustomGCode.hpp:59
@ MultiAsSingle
Definition CustomGCode.hpp:51
@ SingleExtruder
Definition CustomGCode.hpp:50
@ MultiExtruder
Definition CustomGCode.hpp:54
Type
Definition CustomGCode.hpp:14
Transform3d transform3d_from_string(const std::string &transform_str)
Definition Geometry.cpp:679
Eigen::Matrix< int, 3, 1, Eigen::DontAlign > Vec3i
Definition Point.hpp:40
ModelVolumeType
Definition Model.hpp:310
float its_volume(const indexed_triangle_set &its)
Definition TriangleMesh.cpp:1403
auto range(Cont &&cont)
Definition libslic3r.h:356
bool is_decimal_separator_point()
Definition LocalesUtils.cpp:47
const PrintConfigDef print_config_def
Definition PrintConfig.cpp:4288
void its_flip_triangles(indexed_triangle_set &its)
Definition TriangleMesh.cpp:737
int its_compactify_vertices(indexed_triangle_set &its, bool shrink_to_fit)
Definition TriangleMesh.cpp:765
constexpr auto data(C &c) -> decltype(c.data())
Definition span.hpp:195
IGL_INLINE void mode(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &X, const int d, Eigen::Matrix< T, Eigen::Dynamic, 1 > &M)
Definition mode.cpp:14
S::iterator end(S &sh, const PathTag &)
Definition geometry_traits.hpp:620
bool deltaz_set
Definition AMF.cpp:187
float deltax
Definition AMF.cpp:180
bool mirrorx_set
Definition AMF.cpp:206
bool printable
Definition AMF.cpp:212
bool deltay_set
Definition AMF.cpp:184
float scalex
Definition AMF.cpp:198
float rz
Definition AMF.cpp:195
float mirrory
Definition AMF.cpp:207
bool rz_set
Definition AMF.cpp:196
bool mirrory_set
Definition AMF.cpp:208
bool mirrorz_set
Definition AMF.cpp:210
bool deltax_set
Definition AMF.cpp:181
bool scalex_set
Definition AMF.cpp:199
bool scalez_set
Definition AMF.cpp:203
float mirrorz
Definition AMF.cpp:209
float deltay
Definition AMF.cpp:183
float deltaz
Definition AMF.cpp:186
float ry
Definition AMF.cpp:192
bool rx_set
Definition AMF.cpp:190
float scaley
Definition AMF.cpp:200
float scalez
Definition AMF.cpp:202
float rx
Definition AMF.cpp:189
bool scaley_set
Definition AMF.cpp:201
bool ry_set
Definition AMF.cpp:193
float mirrorx
Definition AMF.cpp:205
void stop(const std::string &msg=std::string())
Definition AMF.cpp:72
std::vector< Vec3i > m_volume_facets
Definition AMF.cpp:247
ModelObject * m_object
Definition AMF.cpp:239
unsigned int m_version
Definition AMF.cpp:227
Transform3d m_volume_transform
Definition AMF.cpp:249
ModelMaterial * m_material
Definition AMF.cpp:251
Instance * m_instance
Definition AMF.cpp:253
std::vector< Vec3f > m_object_vertices
Definition AMF.cpp:243
ModelVolume * m_volume
Definition AMF.cpp:245
Mode mode
Definition CustomGCode.hpp:64
std::vector< Item > gcodes
Definition CustomGCode.hpp:65
Geometry::Transformation transform
Definition Model.hpp:763
int object_idx
Definition Model.hpp:760
bool is_from_builtin_objects
Definition Model.hpp:766
Vec3d mesh_offset
Definition Model.hpp:762
std::string input_file
Definition Model.hpp:759
bool is_converted_from_inches
Definition Model.hpp:764
bool is_converted_from_meters
Definition Model.hpp:765
int volume_idx
Definition Model.hpp:761
Definition stl.h:157

References Slic3r::ModelMaterial::attributes, Slic3r::ModelVolume::calculate_convex_hull(), Slic3r::ModelVolume::center_geometry_after_creation(), Slic3r::ModelMaterial::config, Slic3r::ModelObject::config, Slic3r::ModelVolume::config, Slic3r::Model::custom_gcode_per_print_z, Slic3r::AMFParserContext::Instance::deltax, Slic3r::AMFParserContext::Instance::deltax_set, Slic3r::AMFParserContext::Instance::deltay, Slic3r::AMFParserContext::Instance::deltay_set, Slic3r::AMFParserContext::Instance::deltaz, Slic3r::AMFParserContext::Instance::deltaz_set, Slic3r::CustomGCode::Info::gcodes, Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), Slic3r::ModelVolume::Source::input_file, Slic3r::ModelVolume::Source::is_converted_from_inches, Slic3r::ModelVolume::Source::is_converted_from_meters, Slic3r::is_decimal_separator_point(), Slic3r::ModelVolume::Source::is_from_builtin_objects, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::isApprox(), Slic3r::its_compactify_vertices(), Slic3r::its_flip_triangles(), Slic3r::its_volume(), Slic3r::ModelObject::layer_config_ranges, Slic3r::ModelObject::layer_height_profile, Slic3r::ConfigBase::load_from_gcode_string_legacy(), m_config, m_config_substitutions, m_instance, m_material, m_model, m_object, m_object_vertices, m_path, m_value, m_version, m_volume, m_volume_facets, m_volume_transform, Slic3r::ModelVolume::Source::mesh_offset, Slic3r::AMFParserContext::Instance::mirrorx, Slic3r::AMFParserContext::Instance::mirrorx_set, Slic3r::AMFParserContext::Instance::mirrory, Slic3r::AMFParserContext::Instance::mirrory_set, Slic3r::AMFParserContext::Instance::mirrorz, Slic3r::AMFParserContext::Instance::mirrorz_set, Slic3r::CustomGCode::Info::mode, Slic3r::MODEL_PART, Slic3r::CustomGCode::MultiAsSingle, Slic3r::CustomGCode::MultiAsSingleMode, Slic3r::CustomGCode::MultiExtruder, Slic3r::ModelObject::name, Slic3r::ModelVolume::name, NODE_TYPE_CUSTOM_GCODE_MODE, NODE_TYPE_DELTAX, NODE_TYPE_DELTAY, NODE_TYPE_DELTAZ, NODE_TYPE_GCODE_PER_HEIGHT, NODE_TYPE_INSTANCE, NODE_TYPE_MATERIAL, NODE_TYPE_METADATA, NODE_TYPE_MIRRORX, NODE_TYPE_MIRRORY, NODE_TYPE_MIRRORZ, NODE_TYPE_OBJECT, NODE_TYPE_PRINTABLE, NODE_TYPE_RANGE, NODE_TYPE_RX, NODE_TYPE_RY, NODE_TYPE_RZ, NODE_TYPE_SCALE, NODE_TYPE_SCALEX, NODE_TYPE_SCALEY, NODE_TYPE_SCALEZ, NODE_TYPE_TRIANGLE, NODE_TYPE_VERTEX, NODE_TYPE_VOLUME, Slic3r::ModelVolume::Source::object_idx, Slic3r::Model::objects, Slic3r::ConfigDef::options, Slic3r::PARAMETER_MODIFIER, Slic3r::print_config_def, Slic3r::AMFParserContext::Instance::printable, Slic3r::range(), Slic3r::AMFParserContext::Instance::rx, Slic3r::AMFParserContext::Instance::rx_set, Slic3r::AMFParserContext::Instance::ry, Slic3r::AMFParserContext::Instance::ry_set, Slic3r::AMFParserContext::Instance::rz, Slic3r::AMFParserContext::Instance::rz_set, Slic3r::AMFParserContext::Instance::scalex, Slic3r::AMFParserContext::Instance::scalex_set, Slic3r::AMFParserContext::Instance::scaley, Slic3r::AMFParserContext::Instance::scaley_set, Slic3r::AMFParserContext::Instance::scalez, Slic3r::AMFParserContext::Instance::scalez_set, Slic3r::LayerHeightProfile::set(), Slic3r::ModelConfig::set_deserialize(), Slic3r::ModelVolume::set_mesh(), Slic3r::ModelVolume::set_type(), Slic3r::CustomGCode::SingleExtruder, Slic3r::CustomGCode::SingleExtruderMode, Slic3r::ModelObject::sla_points_status, Slic3r::ModelObject::sla_support_points, SLIC3R_CONFIG_TYPE, SLIC3RPE_AMF_VERSION, Slic3r::ModelVolume::source, stop(), Slic3r::ModelVolume::Source::transform, Slic3r::Geometry::transform3d_from_string(), Slic3r::ModelVolume::type_from_string(), Slic3r::sla::UserModified, and Slic3r::ModelVolume::Source::volume_idx.

Referenced by endElement(), Slic3r::extract_model_from_archive(), and Slic3r::load_amf_file().

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

◆ endElement() [2/2]

static void XMLCALL Slic3r::AMFParserContext::endElement ( void userData,
const char *  name 
)
inlinestatic
102 {
103 AMFParserContext *ctx = (AMFParserContext*)userData;
104 ctx->endElement(name);
105 }

References endElement().

+ Here is the call graph for this function:

◆ error()

bool Slic3r::AMFParserContext::error ( ) const
inline
81{ return m_error; }
bool m_error
Definition AMF.cpp:232

References m_error.

Referenced by endDocument(), and Slic3r::load_amf_file().

+ Here is the caller graph for this function:

◆ error_message()

const char * Slic3r::AMFParserContext::error_message ( ) const
inline
82 {
83 return m_error ?
84 // The error was signalled by the user code, not the expat parser.
85 (m_error_message.empty() ? "Invalid AMF format" : m_error_message.c_str()) :
86 // The error was signalled by the expat parser.
87 XML_ErrorString(XML_GetErrorCode(m_parser));
88 }
std::string m_error_message
Definition AMF.cpp:233

References m_error, m_error_message, and m_parser.

Referenced by Slic3r::load_amf_file().

+ Here is the caller graph for this function:

◆ get_attribute()

static const char * Slic3r::AMFParserContext::get_attribute ( const char **  atts,
const char *  id 
)
inlinestatic
114 {
115 if (atts == nullptr)
116 return nullptr;
117 while (*atts != nullptr) {
118 if (strcmp(*(atts ++), id) == 0)
119 return *atts;
120 ++ atts;
121 }
122 return nullptr;
123 }

Referenced by startElement().

+ Here is the caller graph for this function:

◆ operator=()

AMFParserContext & Slic3r::AMFParserContext::operator= ( AMFParserContext )
private

◆ startElement() [1/2]

void Slic3r::AMFParserContext::startElement ( const char *  name,
const char **  atts 
)
266{
267 AMFNodeType node_type_new = NODE_TYPE_UNKNOWN;
268 switch (m_path.size()) {
269 case 0:
270 // An AMF file must start with an <amf> tag.
271 node_type_new = NODE_TYPE_AMF;
272 if (strcmp(name, "amf") != 0)
273 this->stop();
274 break;
275 case 1:
276 if (strcmp(name, "metadata") == 0) {
277 const char *type = get_attribute(atts, "type");
278 if (type != nullptr) {
279 m_value[0] = type;
280 node_type_new = NODE_TYPE_METADATA;
281 }
282 }
283 else if (strcmp(name, "material") == 0) {
284 const char *material_id = get_attribute(atts, "id");
285 m_material = m_model.add_material((material_id == nullptr) ? "_" : material_id);
286 node_type_new = NODE_TYPE_MATERIAL;
287 }
288 else if (strcmp(name, "object") == 0) {
289 const char *object_id = get_attribute(atts, "id");
290 if (object_id == nullptr)
291 this->stop();
292 else {
293 assert(m_object_vertices.empty());
295 m_object->name = std::string(object_id);
296 m_object_instances_map[object_id].idx = int(m_model.objects.size())-1;
297 node_type_new = NODE_TYPE_OBJECT;
298 }
299 }
300 else if (strcmp(name, "constellation") == 0)
301 node_type_new = NODE_TYPE_CONSTELLATION;
302 else if (strcmp(name, "custom_gcodes_per_height") == 0)
303 node_type_new = NODE_TYPE_CUSTOM_GCODE;
304 break;
305 case 2:
306 if (strcmp(name, "metadata") == 0) {
308 m_value[0] = get_attribute(atts, "type");
309 node_type_new = NODE_TYPE_METADATA;
310 }
311 }
312 else if (strcmp(name, "layer_config_ranges") == 0 && m_path[1] == NODE_TYPE_OBJECT)
313 node_type_new = NODE_TYPE_LAYER_CONFIG;
314 else if (strcmp(name, "mesh") == 0) {
315 if (m_path[1] == NODE_TYPE_OBJECT)
316 node_type_new = NODE_TYPE_MESH;
317 }
318 else if (strcmp(name, "instance") == 0) {
320 const char *object_id = get_attribute(atts, "objectid");
321 if (object_id == nullptr)
322 this->stop();
323 else {
324 m_object_instances_map[object_id].instances.push_back(AMFParserContext::Instance());
325 m_instance = &m_object_instances_map[object_id].instances.back();
326 node_type_new = NODE_TYPE_INSTANCE;
327 }
328 }
329 else
330 this->stop();
331 }
332 else if (m_path[1] == NODE_TYPE_CUSTOM_GCODE) {
333 if (strcmp(name, "code") == 0) {
334 node_type_new = NODE_TYPE_GCODE_PER_HEIGHT;
335 m_value[0] = get_attribute(atts, "print_z");
336 m_value[1] = get_attribute(atts, "extruder");
337 m_value[2] = get_attribute(atts, "color");
338 if (get_attribute(atts, "type"))
339 {
340 m_value[3] = get_attribute(atts, "type");
341 m_value[4] = get_attribute(atts, "extra");
342 }
343 else
344 {
345 // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer
346 // read old data ...
347 std::string gcode = get_attribute(atts, "gcode");
348 // ... and interpret them to the new data
350 gcode == "M601" ? CustomGCode::PausePrint :
352 m_value[3] = std::to_string(static_cast<int>(type));
353 m_value[4] = type == CustomGCode::PausePrint ? m_value[2] :
354 type == CustomGCode::Custom ? gcode : "";
355 }
356 }
357 else if (strcmp(name, "mode") == 0) {
358 node_type_new = NODE_TYPE_CUSTOM_GCODE_MODE;
359 m_value[0] = get_attribute(atts, "value");
360 }
361 }
362 break;
363 case 3:
364 if (m_path[2] == NODE_TYPE_MESH) {
365 assert(m_object);
366 if (strcmp(name, "vertices") == 0)
367 node_type_new = NODE_TYPE_VERTICES;
368 else if (strcmp(name, "volume") == 0) {
369 assert(! m_volume);
370 m_volume = m_object->add_volume(TriangleMesh());
372 node_type_new = NODE_TYPE_VOLUME;
373 }
374 } else if (m_path[2] == NODE_TYPE_INSTANCE) {
375 assert(m_instance);
376 if (strcmp(name, "deltax") == 0)
377 node_type_new = NODE_TYPE_DELTAX;
378 else if (strcmp(name, "deltay") == 0)
379 node_type_new = NODE_TYPE_DELTAY;
380 else if (strcmp(name, "deltaz") == 0)
381 node_type_new = NODE_TYPE_DELTAZ;
382 else if (strcmp(name, "rx") == 0)
383 node_type_new = NODE_TYPE_RX;
384 else if (strcmp(name, "ry") == 0)
385 node_type_new = NODE_TYPE_RY;
386 else if (strcmp(name, "rz") == 0)
387 node_type_new = NODE_TYPE_RZ;
388 else if (strcmp(name, "scalex") == 0)
389 node_type_new = NODE_TYPE_SCALEX;
390 else if (strcmp(name, "scaley") == 0)
391 node_type_new = NODE_TYPE_SCALEY;
392 else if (strcmp(name, "scalez") == 0)
393 node_type_new = NODE_TYPE_SCALEZ;
394 else if (strcmp(name, "scale") == 0)
395 node_type_new = NODE_TYPE_SCALE;
396 else if (strcmp(name, "mirrorx") == 0)
397 node_type_new = NODE_TYPE_MIRRORX;
398 else if (strcmp(name, "mirrory") == 0)
399 node_type_new = NODE_TYPE_MIRRORY;
400 else if (strcmp(name, "mirrorz") == 0)
401 node_type_new = NODE_TYPE_MIRRORZ;
402 else if (strcmp(name, "printable") == 0)
403 node_type_new = NODE_TYPE_PRINTABLE;
404 }
405 else if (m_path[2] == NODE_TYPE_LAYER_CONFIG && strcmp(name, "range") == 0) {
406 assert(m_object);
407 node_type_new = NODE_TYPE_RANGE;
408 }
409 break;
410 case 4:
411 if (m_path[3] == NODE_TYPE_VERTICES) {
412 if (strcmp(name, "vertex") == 0)
413 node_type_new = NODE_TYPE_VERTEX;
414 } else if (m_path[3] == NODE_TYPE_VOLUME) {
415 if (strcmp(name, "metadata") == 0) {
416 const char *type = get_attribute(atts, "type");
417 if (type == nullptr)
418 this->stop();
419 else {
420 m_value[0] = type;
421 node_type_new = NODE_TYPE_METADATA;
422 }
423 } else if (strcmp(name, "triangle") == 0)
424 node_type_new = NODE_TYPE_TRIANGLE;
425 }
426 else if (m_path[3] == NODE_TYPE_RANGE && strcmp(name, "metadata") == 0) {
427 m_value[0] = get_attribute(atts, "type");
428 node_type_new = NODE_TYPE_METADATA;
429 }
430 break;
431 case 5:
432 if (strcmp(name, "coordinates") == 0) {
433 if (m_path[4] == NODE_TYPE_VERTEX) {
434 node_type_new = NODE_TYPE_COORDINATES;
435 } else
436 this->stop();
437 } else if (name[0] == 'v' && name[1] >= '1' && name[1] <= '3' && name[2] == 0) {
438 if (m_path[4] == NODE_TYPE_TRIANGLE) {
439 node_type_new = AMFNodeType(NODE_TYPE_VERTEX1 + name[1] - '1');
440 } else
441 this->stop();
442 }
443 break;
444 case 6:
445 if ((name[0] == 'x' || name[0] == 'y' || name[0] == 'z') && name[1] == 0) {
447 node_type_new = AMFNodeType(NODE_TYPE_COORDINATE_X + name[0] - 'x');
448 else
449 this->stop();
450 }
451 break;
452 default:
453 break;
454 }
455
456 m_path.push_back(node_type_new);
457}
ModelMaterial * add_material(t_model_material_id material_id)
Definition Model.cpp:295
ModelObject * add_object()
Definition Model.cpp:189
ModelVolume * add_volume(const TriangleMesh &mesh)
Definition Model.cpp:717
@ PausePrint
Definition CustomGCode.hpp:16
@ ToolChange
Definition CustomGCode.hpp:17
@ Custom
Definition CustomGCode.hpp:19
@ ColorChange
Definition CustomGCode.hpp:15
static const char * get_attribute(const char **atts, const char *id)
Definition AMF.cpp:114
AMFNodeType
Definition AMF.cpp:125

References Slic3r::Model::add_material(), Slic3r::Model::add_object(), Slic3r::ModelObject::add_volume(), Slic3r::CustomGCode::ColorChange, Slic3r::CustomGCode::Custom, get_attribute(), Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), m_instance, m_material, m_model, m_object, m_object_instances_map, m_object_vertices, m_path, m_value, m_volume, m_volume_transform, Slic3r::ModelObject::name, NODE_TYPE_AMF, NODE_TYPE_CONSTELLATION, NODE_TYPE_COORDINATE_X, NODE_TYPE_COORDINATES, NODE_TYPE_CUSTOM_GCODE, NODE_TYPE_CUSTOM_GCODE_MODE, NODE_TYPE_DELTAX, NODE_TYPE_DELTAY, NODE_TYPE_DELTAZ, NODE_TYPE_GCODE_PER_HEIGHT, NODE_TYPE_INSTANCE, NODE_TYPE_LAYER_CONFIG, NODE_TYPE_MATERIAL, NODE_TYPE_MESH, NODE_TYPE_METADATA, NODE_TYPE_MIRRORX, NODE_TYPE_MIRRORY, NODE_TYPE_MIRRORZ, NODE_TYPE_OBJECT, NODE_TYPE_PRINTABLE, NODE_TYPE_RANGE, NODE_TYPE_RX, NODE_TYPE_RY, NODE_TYPE_RZ, NODE_TYPE_SCALE, NODE_TYPE_SCALEX, NODE_TYPE_SCALEY, NODE_TYPE_SCALEZ, NODE_TYPE_TRIANGLE, NODE_TYPE_UNKNOWN, NODE_TYPE_VERTEX, NODE_TYPE_VERTEX1, NODE_TYPE_VERTICES, NODE_TYPE_VOLUME, Slic3r::Model::objects, Slic3r::CustomGCode::PausePrint, stop(), and Slic3r::CustomGCode::ToolChange.

Referenced by Slic3r::extract_model_from_archive(), Slic3r::load_amf_file(), and startElement().

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

◆ startElement() [2/2]

static void XMLCALL Slic3r::AMFParserContext::startElement ( void userData,
const char *  name,
const char **  atts 
)
inlinestatic
96 {
97 AMFParserContext *ctx = (AMFParserContext*)userData;
98 ctx->startElement(name, atts);
99 }

References startElement().

+ Here is the call graph for this function:

◆ stop()

void Slic3r::AMFParserContext::stop ( const std::string &  msg = std::string())
inline
73 {
74 assert(! m_error);
75 assert(m_error_message.empty());
76 m_error = true;
77 m_error_message = msg;
78 XML_StopParser(m_parser, 0);
79 }

References m_error, m_error_message, and m_parser.

Referenced by endElement(), and startElement().

+ Here is the caller graph for this function:

Member Data Documentation

◆ m_config

DynamicPrintConfig* Slic3r::AMFParserContext::m_config { nullptr }

Referenced by endElement().

◆ m_config_substitutions

ConfigSubstitutionContext* Slic3r::AMFParserContext::m_config_substitutions { nullptr }

Referenced by endElement().

◆ m_error

bool Slic3r::AMFParserContext::m_error { false }

Referenced by error(), error_message(), and stop().

◆ m_error_message

std::string Slic3r::AMFParserContext::m_error_message

Referenced by error_message(), and stop().

◆ m_instance

Instance* Slic3r::AMFParserContext::m_instance { nullptr }

Referenced by endElement(), and startElement().

◆ m_material

ModelMaterial* Slic3r::AMFParserContext::m_material { nullptr }

Referenced by endElement(), and startElement().

◆ m_model

Model& Slic3r::AMFParserContext::m_model

◆ m_object

ModelObject* Slic3r::AMFParserContext::m_object { nullptr }

Referenced by endElement(), and startElement().

◆ m_object_instances_map

std::map<std::string, Object> Slic3r::AMFParserContext::m_object_instances_map

Referenced by endDocument(), and startElement().

◆ m_object_vertices

std::vector<Vec3f> Slic3r::AMFParserContext::m_object_vertices

Referenced by endElement(), and startElement().

◆ m_parser

XML_Parser Slic3r::AMFParserContext::m_parser

Referenced by error_message(), and stop().

◆ m_path

std::vector<AMFNodeType> Slic3r::AMFParserContext::m_path

◆ m_value

std::string Slic3r::AMFParserContext::m_value[5]

◆ m_version

unsigned int Slic3r::AMFParserContext::m_version { 0 }

Referenced by endElement().

◆ m_volume

ModelVolume* Slic3r::AMFParserContext::m_volume { nullptr }

Referenced by endElement(), and startElement().

◆ m_volume_facets

std::vector<Vec3i> Slic3r::AMFParserContext::m_volume_facets

Referenced by endElement().

◆ m_volume_transform

Transform3d Slic3r::AMFParserContext::m_volume_transform

Referenced by endElement(), and startElement().


The documentation for this struct was generated from the following file: