// <mesh> // </mesh> // A 3D mesh hull. // Multi elements - Yes. // Parent element - <object>. void AMFImporter::ParseNode_Mesh() { CAMFImporter_NodeElement* ne; // create new mesh object. ne = new CAMFImporter_NodeElement_Mesh(mNodeElement_Cur); // Check for child nodes if(!mReader->isEmptyElement()) { bool vert_read = false; ParseHelper_Node_Enter(ne); MACRO_NODECHECK_LOOPBEGIN("mesh"); if(XML_CheckNode_NameEqual("vertices")) { // Check if data already defined. if(vert_read) Throw_MoreThanOnceDefined("vertices", "Only one vertices set can be defined for <mesh>."); // read data and set flag about it ParseNode_Vertices(); vert_read = true; continue; } if(XML_CheckNode_NameEqual("volume")) { ParseNode_Volume(); continue; } MACRO_NODECHECK_LOOPEND("mesh"); ParseHelper_Node_Exit(); }// if(!mReader->isEmptyElement()) else { mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element }// if(!mReader->isEmptyElement()) else mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. }
// <coordinates> // </coordinates> // Specifies the 3D location of this vertex. // Multi elements - No. // Parent element - <vertex>. // // Children elements: // <x>, <y>, <z> // Multi elements - No. // X, Y, or Z coordinate, respectively, of a vertex position in space. void AMFImporter::ParseNode_Coordinates() { CAMFImporter_NodeElement* ne; // create new color object. ne = new CAMFImporter_NodeElement_Coordinates(mNodeElement_Cur); CAMFImporter_NodeElement_Coordinates& als = *((CAMFImporter_NodeElement_Coordinates*)ne);// alias for convenience // Check for child nodes if(!mReader->isEmptyElement()) { bool read_flag[3] = { false, false, false }; ParseHelper_Node_Enter(ne); MACRO_NODECHECK_LOOPBEGIN("coordinates"); MACRO_NODECHECK_READCOMP_F("x", read_flag[0], als.Coordinate.x); MACRO_NODECHECK_READCOMP_F("y", read_flag[1], als.Coordinate.y); MACRO_NODECHECK_READCOMP_F("z", read_flag[2], als.Coordinate.z); MACRO_NODECHECK_LOOPEND("coordinates"); ParseHelper_Node_Exit(); // check that all components was defined if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined."); }// if(!mReader->isEmptyElement()) else { mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element }// if(!mReader->isEmptyElement()) else mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. }
// <volume // materialid="" - Which material to use. // type="" - What this volume describes can be “region” or “support”. If none specified, “object” is assumed. If support, then the geometric // requirements 1-8 listed in section 5 do not need to be maintained. // > // </volume> // Defines a volume from the established vertex list. // Multi elements - Yes. // Parent element - <mesh>. void AMFImporter::ParseNode_Volume() { std::string materialid; std::string type; CAMFImporter_NodeElement* ne; // Read attributes for node <color>. MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue); MACRO_ATTRREAD_LOOPEND; // create new object. ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur); // and assign read data ((CAMFImporter_NodeElement_Volume*)ne)->MaterialID = materialid; ((CAMFImporter_NodeElement_Volume*)ne)->Type = type; // Check for child nodes if(!mReader->isEmptyElement()) { bool col_read = false; ParseHelper_Node_Enter(ne); MACRO_NODECHECK_LOOPBEGIN("volume"); if(XML_CheckNode_NameEqual("color")) { // Check if data already defined. if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <volume>."); // read data and set flag about it ParseNode_Color(); col_read = true; continue; } if(XML_CheckNode_NameEqual("triangle")) { ParseNode_Triangle(); continue; } if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } MACRO_NODECHECK_LOOPEND("volume"); ParseHelper_Node_Exit(); }// if(!mReader->isEmptyElement()) else { mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element }// if(!mReader->isEmptyElement()) else mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. }
// <Appearance // DEF="" ID // USE="" IDREF // > // <!-- AppearanceChildContentModel --> // "Child-node content model corresponding to X3DAppearanceChildNode. Appearance can contain FillProperties, LineProperties, Material, any Texture node and // any TextureTransform node, in any order. No more than one instance of these nodes is allowed. Appearance may also contain multiple shaders (ComposedShader, // PackagedShader, ProgramShader). // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model." // </Appearance> void X3DImporter::ParseNode_Shape_Appearance() { std::string use, def; CX3DImporter_NodeElement* ne( nullptr ); MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_LOOPEND; // if "USE" defined then find already defined element. if(!use.empty()) { MACRO_USE_CHECKANDAPPLY(def, use, ENET_Appearance, ne); } else { // create and if needed - define new geometry object. ne = new CX3DImporter_NodeElement_Appearance(NodeElement_Cur); if(!def.empty()) ne->ID = def; // check for child nodes if(!mReader->isEmptyElement()) { ParseHelper_Node_Enter(ne); MACRO_NODECHECK_LOOPBEGIN("Appearance"); if(XML_CheckNode_NameEqual("Material")) { ParseNode_Shape_Material(); continue; } if(XML_CheckNode_NameEqual("ImageTexture")) { ParseNode_Texturing_ImageTexture(); continue; } if(XML_CheckNode_NameEqual("TextureTransform")) { ParseNode_Texturing_TextureTransform(); continue; } // check for X3DMetadataObject if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Appearance"); MACRO_NODECHECK_LOOPEND("Appearance"); ParseHelper_Node_Exit(); }// if(!mReader->isEmptyElement()) else { NodeElement_Cur->Child.push_back(ne);// add made object as child to current element } NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph }// if(!use.empty()) else }
// <vertices> // </vertices> // The list of vertices to be used in defining triangles. // Multi elements - No. // Parent element - <mesh>. void AMFImporter::ParseNode_Vertices() { CAMFImporter_NodeElement* ne; // create new mesh object. ne = new CAMFImporter_NodeElement_Vertices(mNodeElement_Cur); // Check for child nodes if(!mReader->isEmptyElement()) { ParseHelper_Node_Enter(ne); MACRO_NODECHECK_LOOPBEGIN("vertices"); if(XML_CheckNode_NameEqual("vertex")) { ParseNode_Vertex(); continue; } MACRO_NODECHECK_LOOPEND("vertices"); ParseHelper_Node_Exit(); }// if(!mReader->isEmptyElement()) else { mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element }// if(!mReader->isEmptyElement()) else mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. }
void X3DImporter::ParseNode_Metadata(CX3DImporter_NodeElement* pParentElement, const std::string& /*pNodeName*/) { ParseHelper_Node_Enter(pParentElement); MACRO_NODECHECK_METADATA(mReader->getNodeName()); ParseHelper_Node_Exit(); }
// <Shape // DEF="" ID // USE="" IDREF // bboxCenter="0 0 0" SFVec3f [initializeOnly] // bboxSize="-1 -1 -1" SFVec3f [initializeOnly] // > // <!-- ShapeChildContentModel --> // "ShapeChildContentModel is the child-node content model corresponding to X3DShapeNode. ShapeChildContentModel can contain a single Appearance node and a // single geometry node, in any order. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model." // </Shape> // A Shape node is unlit if either of the following is true: // The shape's appearance field is NULL (default). // The material field in the Appearance node is NULL (default). // NOTE Geometry nodes that represent lines or points do not support lighting. void X3DImporter::ParseNode_Shape_Shape() { std::string use, def; CX3DImporter_NodeElement* ne( nullptr ); MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use); MACRO_ATTRREAD_LOOPEND; // if "USE" defined then find already defined element. if(!use.empty()) { MACRO_USE_CHECKANDAPPLY(def, use, ENET_Shape, ne); } else { // create and if needed - define new geometry object. ne = new CX3DImporter_NodeElement_Shape(NodeElement_Cur); if(!def.empty()) ne->ID = def; // check for child nodes if(!mReader->isEmptyElement()) { ParseHelper_Node_Enter(ne); MACRO_NODECHECK_LOOPBEGIN("Shape"); // check for appearance node if(XML_CheckNode_NameEqual("Appearance")) { ParseNode_Shape_Appearance(); continue; } // check for X3DGeometryNodes if(XML_CheckNode_NameEqual("Arc2D")) { ParseNode_Geometry2D_Arc2D(); continue; } if(XML_CheckNode_NameEqual("ArcClose2D")) { ParseNode_Geometry2D_ArcClose2D(); continue; } if(XML_CheckNode_NameEqual("Circle2D")) { ParseNode_Geometry2D_Circle2D(); continue; } if(XML_CheckNode_NameEqual("Disk2D")) { ParseNode_Geometry2D_Disk2D(); continue; } if(XML_CheckNode_NameEqual("Polyline2D")) { ParseNode_Geometry2D_Polyline2D(); continue; } if(XML_CheckNode_NameEqual("Polypoint2D")) { ParseNode_Geometry2D_Polypoint2D(); continue; } if(XML_CheckNode_NameEqual("Rectangle2D")) { ParseNode_Geometry2D_Rectangle2D(); continue; } if(XML_CheckNode_NameEqual("TriangleSet2D")) { ParseNode_Geometry2D_TriangleSet2D(); continue; } if(XML_CheckNode_NameEqual("Box")) { ParseNode_Geometry3D_Box(); continue; } if(XML_CheckNode_NameEqual("Cone")) { ParseNode_Geometry3D_Cone(); continue; } if(XML_CheckNode_NameEqual("Cylinder")) { ParseNode_Geometry3D_Cylinder(); continue; } if(XML_CheckNode_NameEqual("ElevationGrid")) { ParseNode_Geometry3D_ElevationGrid(); continue; } if(XML_CheckNode_NameEqual("Extrusion")) { ParseNode_Geometry3D_Extrusion(); continue; } if(XML_CheckNode_NameEqual("IndexedFaceSet")) { ParseNode_Geometry3D_IndexedFaceSet(); continue; } if(XML_CheckNode_NameEqual("Sphere")) { ParseNode_Geometry3D_Sphere(); continue; } if(XML_CheckNode_NameEqual("IndexedLineSet")) { ParseNode_Rendering_IndexedLineSet(); continue; } if(XML_CheckNode_NameEqual("LineSet")) { ParseNode_Rendering_LineSet(); continue; } if(XML_CheckNode_NameEqual("PointSet")) { ParseNode_Rendering_PointSet(); continue; } if(XML_CheckNode_NameEqual("IndexedTriangleFanSet")) { ParseNode_Rendering_IndexedTriangleFanSet(); continue; } if(XML_CheckNode_NameEqual("IndexedTriangleSet")) { ParseNode_Rendering_IndexedTriangleSet(); continue; } if(XML_CheckNode_NameEqual("IndexedTriangleStripSet")) { ParseNode_Rendering_IndexedTriangleStripSet(); continue; } if(XML_CheckNode_NameEqual("TriangleFanSet")) { ParseNode_Rendering_TriangleFanSet(); continue; } if(XML_CheckNode_NameEqual("TriangleSet")) { ParseNode_Rendering_TriangleSet(); continue; } if(XML_CheckNode_NameEqual("TriangleStripSet")) { ParseNode_Rendering_TriangleStripSet(); continue; } // check for X3DMetadataObject if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Shape"); MACRO_NODECHECK_LOOPEND("Shape"); ParseHelper_Node_Exit(); }// if(!mReader->isEmptyElement()) else { NodeElement_Cur->Child.push_back(ne);// add made object as child to current element } NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph }// if(!use.empty()) else }
// <triangle> // </triangle> // Defines a 3D triangle from three vertices, according to the right-hand rule (counter-clockwise when looking from the outside). // Multi elements - Yes. // Parent element - <volume>. // // Children elements: // <v1>, <v2>, <v3> // Multi elements - No. // Index of the desired vertices in a triangle or edge. void AMFImporter::ParseNode_Triangle() { CAMFImporter_NodeElement* ne; // create new color object. ne = new CAMFImporter_NodeElement_Triangle(mNodeElement_Cur); CAMFImporter_NodeElement_Triangle& als = *((CAMFImporter_NodeElement_Triangle*)ne);// alias for convenience // Check for child nodes if(!mReader->isEmptyElement()) { bool col_read = false, tex_read = false; bool read_flag[3] = { false, false, false }; ParseHelper_Node_Enter(ne); MACRO_NODECHECK_LOOPBEGIN("triangle"); if(XML_CheckNode_NameEqual("color")) { // Check if data already defined. if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <triangle>."); // read data and set flag about it ParseNode_Color(); col_read = true; continue; } if(XML_CheckNode_NameEqual("texmap"))// new name of node: "texmap". { // Check if data already defined. if(tex_read) Throw_MoreThanOnceDefined("texmap", "Only one texture coordinate can be defined for <triangle>."); // read data and set flag about it ParseNode_TexMap(); tex_read = true; continue; } else if(XML_CheckNode_NameEqual("map"))// old name of node: "map". { // Check if data already defined. if(tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for <triangle>."); // read data and set flag about it ParseNode_TexMap(true); tex_read = true; continue; } MACRO_NODECHECK_READCOMP_U32("v1", read_flag[0], als.V[0]); MACRO_NODECHECK_READCOMP_U32("v2", read_flag[1], als.V[1]); MACRO_NODECHECK_READCOMP_U32("v3", read_flag[2], als.V[2]); MACRO_NODECHECK_LOOPEND("triangle"); ParseHelper_Node_Exit(); // check that all components was defined if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined."); }// if(!mReader->isEmptyElement()) else { mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element }// if(!mReader->isEmptyElement()) else mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. }