123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- /*
- Open Asset Import Library (assimp)
- ----------------------------------------------------------------------
- Copyright (c) 2006-2020, assimp team
- All rights reserved.
- Redistribution and use of this software in source and binary forms,
- with or without modification, are permitted provided that the
- following conditions are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
- * Neither the name of the assimp team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the assimp team.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ----------------------------------------------------------------------
- */
- /// \file X3DImporter_Geometry2D.cpp
- /// \brief Parsing data from nodes of "Geometry2D" set of X3D.
- /// \date 2015-2016
- /// \author [email protected]
- #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
- #include "X3DImporter.hpp"
- #include "X3DImporter_Node.hpp"
- #include "X3DImporter_Macro.hpp"
- namespace Assimp
- {
- // <Arc2D
- // DEF="" ID
- // USE="" IDREF
- // endAngle="1.570796" SFFloat [initializeOnly]
- // radius="1" SFFloat [initializeOnly]
- // startAngle="0" SFFloat [initializeOnly]
- // />
- // The Arc2D node specifies a linear circular arc whose center is at (0,0) and whose angles are measured starting at the positive x-axis and sweeping
- // towards the positive y-axis. The radius field specifies the radius of the circle of which the arc is a portion. The arc extends from the startAngle
- // counterclockwise to the endAngle. The values of startAngle and endAngle shall be in the range [-2pi, 2pi] radians (or the equivalent if a different
- // angle base unit has been specified). If startAngle and endAngle have the same value, a circle is specified.
- void X3DImporter::ParseNode_Geometry2D_Arc2D()
- {
- std::string def, use;
- float endAngle = AI_MATH_HALF_PI_F;
- float radius = 1;
- float startAngle = 0;
- CX3DImporter_NodeElement* ne( nullptr );
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("endAngle", endAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("startAngle", startAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Arc2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Arc2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
- // create point list of geometry object and convert it to line set.
- std::list<aiVector3D> tlist;
- GeometryHelper_Make_Arc2D(startAngle, endAngle, radius, 10, tlist);///TODO: IME - AI_CONFIG for NumSeg
- GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 2;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Arc2D");
- 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
- }
- // <ArcClose2D
- // DEF="" ID
- // USE="" IDREF
- // closureType="PIE" SFString [initializeOnly], {"PIE", "CHORD"}
- // endAngle="1.570796" SFFloat [initializeOnly]
- // radius="1" SFFloat [initializeOnly]
- // solid="false" SFBool [initializeOnly]
- // startAngle="0" SFFloat [initializeOnly]
- // />
- // The ArcClose node specifies a portion of a circle whose center is at (0,0) and whose angles are measured starting at the positive x-axis and sweeping
- // towards the positive y-axis. The end points of the arc specified are connected as defined by the closureType field. The radius field specifies the radius
- // of the circle of which the arc is a portion. The arc extends from the startAngle counterclockwise to the endAngle. The value of radius shall be greater
- // than zero. The values of startAngle and endAngle shall be in the range [-2pi, 2pi] radians (or the equivalent if a different default angle base unit has
- // been specified). If startAngle and endAngle have the same value, a circle is specified and closureType is ignored. If the absolute difference between
- // startAngle and endAngle is greater than or equal to 2pi, a complete circle is produced with no chord or radial line(s) drawn from the center.
- // A closureType of "PIE" connects the end point to the start point by defining two straight line segments first from the end point to the center and then
- // the center to the start point. A closureType of "CHORD" connects the end point to the start point by defining a straight line segment from the end point
- // to the start point. Textures are applied individually to each face of the ArcClose2D. On the front (+Z) and back (-Z) faces of the ArcClose2D, when
- // viewed from the +Z-axis, the texture is mapped onto each face with the same orientation as if the image were displayed normally in 2D.
- void X3DImporter::ParseNode_Geometry2D_ArcClose2D()
- {
- std::string def, use;
- std::string closureType("PIE");
- float endAngle = AI_MATH_HALF_PI_F;
- float radius = 1;
- bool solid = false;
- float startAngle = 0;
- CX3DImporter_NodeElement* ne( nullptr );
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("closureType", closureType, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("endAngle", endAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("startAngle", startAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_ArcClose2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_ArcClose2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Solid = solid;
- // create point list of geometry object.
- GeometryHelper_Make_Arc2D(startAngle, endAngle, radius, 10, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);///TODO: IME - AI_CONFIG for NumSeg
- // add chord or two radiuses only if not a circle was defined
- if(!((std::fabs(endAngle - startAngle) >= AI_MATH_TWO_PI_F) || (endAngle == startAngle)))
- {
- std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices;// just short alias.
- if((closureType == "PIE") || (closureType == "\"PIE\""))
- vlist.push_back(aiVector3D(0, 0, 0));// center point - first radial line
- else if((closureType != "CHORD") && (closureType != "\"CHORD\""))
- Throw_IncorrectAttrValue("closureType");
- vlist.push_back(*vlist.begin());// arc first point - chord from first to last point of arc(if CHORD) or second radial line(if PIE).
- }
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.size();
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "ArcClose2D");
- 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
- }
- // <Circle2D
- // DEF="" ID
- // USE="" IDREF
- // radius="1" SFFloat [initializeOnly]
- // />
- void X3DImporter::ParseNode_Geometry2D_Circle2D()
- {
- std::string def, use;
- float radius = 1;
- CX3DImporter_NodeElement* ne( nullptr );
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Circle2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Circle2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
- // create point list of geometry object and convert it to line set.
- std::list<aiVector3D> tlist;
- GeometryHelper_Make_Arc2D(0, 0, radius, 10, tlist);///TODO: IME - AI_CONFIG for NumSeg
- GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 2;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Circle2D");
- 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
- }
- // <Disk2D
- // DEF="" ID
- // USE="" IDREF
- // innerRadius="0" SFFloat [initializeOnly]
- // outerRadius="1" SFFloat [initializeOnly]
- // solid="false" SFBool [initializeOnly]
- // />
- // The Disk2D node specifies a circular disk which is centred at (0, 0) in the local coordinate system. The outerRadius field specifies the radius of the
- // outer dimension of the Disk2D. The innerRadius field specifies the inner dimension of the Disk2D. The value of outerRadius shall be greater than zero.
- // The value of innerRadius shall be greater than or equal to zero and less than or equal to outerRadius. If innerRadius is zero, the Disk2D is completely
- // filled. Otherwise, the area within the innerRadius forms a hole in the Disk2D. If innerRadius is equal to outerRadius, a solid circular line shall
- // be drawn using the current line properties. Textures are applied individually to each face of the Disk2D. On the front (+Z) and back (-Z) faces of
- // the Disk2D, when viewed from the +Z-axis, the texture is mapped onto each face with the same orientation as if the image were displayed normally in 2D.
- void X3DImporter::ParseNode_Geometry2D_Disk2D()
- {
- std::string def, use;
- float innerRadius = 0;
- float outerRadius = 1;
- bool solid = false;
- CX3DImporter_NodeElement* ne( nullptr );
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("innerRadius", innerRadius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("outerRadius", outerRadius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Disk2D, ne);
- }
- else
- {
- std::list<aiVector3D> tlist_o, tlist_i;
- if(innerRadius > outerRadius) Throw_IncorrectAttrValue("innerRadius");
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Disk2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
- // create point list of geometry object.
- ///TODO: IME - AI_CONFIG for NumSeg
- GeometryHelper_Make_Arc2D(0, 0, outerRadius, 10, tlist_o);// outer circle
- if(innerRadius == 0.0f)
- {// make filled disk
- // in tlist_o we already have points of circle. just copy it and sign as polygon.
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices = tlist_o;
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = tlist_o.size();
- }
- else if(innerRadius == outerRadius)
- {// make circle
- // in tlist_o we already have points of circle. convert it to line set.
- GeometryHelper_Extend_PointToLine(tlist_o, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 2;
- }
- else
- {// make disk
- std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices;// just short alias.
- GeometryHelper_Make_Arc2D(0, 0, innerRadius, 10, tlist_i);// inner circle
- //
- // create quad list from two point lists
- //
- if(tlist_i.size() < 2) throw DeadlyImportError("Disk2D. Not enough points for creating quad list.");// tlist_i and tlist_o has equal size.
- // add all quads except last
- for(std::list<aiVector3D>::iterator it_i = tlist_i.begin(), it_o = tlist_o.begin(); it_i != tlist_i.end();)
- {
- // do not forget - CCW direction
- vlist.push_back(*it_i++);// 1st point
- vlist.push_back(*it_o++);// 2nd point
- vlist.push_back(*it_o);// 3rd point
- vlist.push_back(*it_i);// 4th point
- }
- // add last quad
- vlist.push_back(*tlist_i.end());// 1st point
- vlist.push_back(*tlist_o.end());// 2nd point
- vlist.push_back(*tlist_o.begin());// 3rd point
- vlist.push_back(*tlist_o.begin());// 4th point
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 4;
- }
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Solid = solid;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Disk2D");
- 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
- }
- // <Polyline2D
- // DEF="" ID
- // USE="" IDREF
- // lineSegments="" MFVec2F [intializeOnly]
- // />
- void X3DImporter::ParseNode_Geometry2D_Polyline2D()
- {
- std::string def, use;
- std::list<aiVector2D> lineSegments;
- CX3DImporter_NodeElement* ne( nullptr );
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("lineSegments", lineSegments, XML_ReadNode_GetAttrVal_AsListVec2f);
- MACRO_ATTRREAD_LOOPEND;
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Polyline2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Polyline2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
- //
- // convert read point list of geometry object to line set.
- //
- std::list<aiVector3D> tlist;
- // convert vec2 to vec3
- for(std::list<aiVector2D>::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); ++it2) tlist.push_back(aiVector3D(it2->x, it2->y, 0));
- // convert point set to line set
- GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 2;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Polyline2D");
- 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
- }
- // <Polypoint2D
- // DEF="" ID
- // USE="" IDREF
- // point="" MFVec2F [inputOutput]
- // />
- void X3DImporter::ParseNode_Geometry2D_Polypoint2D()
- {
- std::string def, use;
- std::list<aiVector2D> point;
- CX3DImporter_NodeElement* ne( nullptr );
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("point", point, XML_ReadNode_GetAttrVal_AsListVec2f);
- MACRO_ATTRREAD_LOOPEND;
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Polypoint2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Polypoint2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
- // convert vec2 to vec3
- for(std::list<aiVector2D>::iterator it2 = point.begin(); it2 != point.end(); ++it2)
- {
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
- }
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 1;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Polypoint2D");
- 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
- }
- // <Rectangle2D
- // DEF="" ID
- // USE="" IDREF
- // size="2 2" SFVec2f [initializeOnly]
- // solid="false" SFBool [initializeOnly]
- // />
- void X3DImporter::ParseNode_Geometry2D_Rectangle2D()
- {
- std::string def, use;
- aiVector2D size(2, 2);
- bool solid = false;
- CX3DImporter_NodeElement* ne( nullptr );
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("size", size, XML_ReadNode_GetAttrVal_AsVec2f);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Rectangle2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Rectangle2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
- float x1 = -size.x / 2.0f;
- float x2 = size.x / 2.0f;
- float y1 = -size.y / 2.0f;
- float y2 = size.y / 2.0f;
- std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices;// just short alias.
- vlist.push_back(aiVector3D(x2, y1, 0));// 1st point
- vlist.push_back(aiVector3D(x2, y2, 0));// 2nd point
- vlist.push_back(aiVector3D(x1, y2, 0));// 3rd point
- vlist.push_back(aiVector3D(x1, y1, 0));// 4th point
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Solid = solid;
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 4;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Rectangle2D");
- 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
- }
- // <TriangleSet2D
- // DEF="" ID
- // USE="" IDREF
- // solid="false" SFBool [initializeOnly]
- // vertices="" MFVec2F [inputOutput]
- // />
- void X3DImporter::ParseNode_Geometry2D_TriangleSet2D()
- {
- std::string def, use;
- bool solid = false;
- std::list<aiVector2D> vertices;
- CX3DImporter_NodeElement* ne( nullptr );
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("vertices", vertices, XML_ReadNode_GetAttrVal_AsListVec2f);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleSet2D, ne);
- }
- else
- {
- if(vertices.size() % 3) throw DeadlyImportError("TriangleSet2D. Not enough points for defining triangle.");
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_TriangleSet2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
- // convert vec2 to vec3
- for(std::list<aiVector2D>::iterator it2 = vertices.begin(); it2 != vertices.end(); ++it2)
- {
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
- }
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Solid = solid;
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 3;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "TriangleSet2D");
- 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
- }
- }// namespace Assimp
- #endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
|