nuclear@0: /* nuclear@0: Open Asset Import Library (assimp) nuclear@0: ---------------------------------------------------------------------- nuclear@0: nuclear@0: Copyright (c) 2006-2012, assimp team nuclear@0: All rights reserved. nuclear@0: nuclear@0: Redistribution and use of this software in source and binary forms, nuclear@0: with or without modification, are permitted provided that the nuclear@0: following conditions are met: nuclear@0: nuclear@0: * Redistributions of source code must retain the above nuclear@0: copyright notice, this list of conditions and the nuclear@0: following disclaimer. nuclear@0: nuclear@0: * Redistributions in binary form must reproduce the above nuclear@0: copyright notice, this list of conditions and the nuclear@0: following disclaimer in the documentation and/or other nuclear@0: materials provided with the distribution. nuclear@0: nuclear@0: * Neither the name of the assimp team, nor the names of its nuclear@0: contributors may be used to endorse or promote products nuclear@0: derived from this software without specific prior nuclear@0: written permission of the assimp team. nuclear@0: nuclear@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS nuclear@0: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT nuclear@0: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR nuclear@0: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT nuclear@0: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, nuclear@0: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT nuclear@0: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, nuclear@0: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY nuclear@0: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT nuclear@0: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE nuclear@0: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. nuclear@0: nuclear@0: ---------------------------------------------------------------------- nuclear@0: */ nuclear@0: nuclear@0: /** @file DXFHelper.h nuclear@0: * @brief Internal utilities for the DXF loader. nuclear@0: */ nuclear@0: nuclear@0: #ifndef INCLUDED_DXFHELPER_H nuclear@0: #define INCLUDED_DXFHELPER_H nuclear@0: nuclear@0: #include "LineSplitter.h" nuclear@0: #include "TinyFormatter.h" nuclear@0: #include "StreamReader.h" nuclear@0: nuclear@0: namespace Assimp { nuclear@0: namespace DXF { nuclear@0: nuclear@0: nuclear@0: // read pairs of lines, parse group code and value and provide utilities nuclear@0: // to convert the data to the target data type. nuclear@0: class LineReader nuclear@0: { nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: LineReader(StreamReaderLE& reader) nuclear@0: // do NOT skip empty lines. In DXF files, they count as valid data. nuclear@0: : splitter(reader,false,true) nuclear@0: , end() nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: bool Is(int gc, const char* what) const { nuclear@0: return groupcode == gc && !strcmp(what,value.c_str()); nuclear@0: } nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: bool Is(int gc) const { nuclear@0: return groupcode == gc; nuclear@0: } nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: int GroupCode() const { nuclear@0: return groupcode; nuclear@0: } nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: const std::string& Value() const { nuclear@0: return value; nuclear@0: } nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: bool End() const { nuclear@0: return !((bool)*this); nuclear@0: } nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: unsigned int ValueAsUnsignedInt() const { nuclear@0: return strtoul10(value.c_str()); nuclear@0: } nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: int ValueAsSignedInt() const { nuclear@0: return strtol10(value.c_str()); nuclear@0: } nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: float ValueAsFloat() const { nuclear@0: return fast_atof(value.c_str()); nuclear@0: } nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: /** pseudo-iterator increment to advance to the next (groupcode/value) pair */ nuclear@0: LineReader& operator++() { nuclear@0: if (end) { nuclear@0: if (end == 1) { nuclear@0: ++end; nuclear@0: } nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: try { nuclear@0: groupcode = strtol10(splitter->c_str()); nuclear@0: splitter++; nuclear@0: nuclear@0: value = *splitter; nuclear@0: splitter++; nuclear@0: nuclear@0: // automatically skip over {} meta blocks (these are for application use nuclear@0: // and currently not relevant for Assimp). nuclear@0: if (value.length() && value[0] == '{') { nuclear@0: nuclear@0: size_t cnt = 0; nuclear@0: for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++); nuclear@0: nuclear@0: splitter++; nuclear@0: DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)")); nuclear@0: } nuclear@0: } catch(std::logic_error&) { nuclear@0: ai_assert(!splitter); nuclear@0: } nuclear@0: if (!splitter) { nuclear@0: end = 1; nuclear@0: } nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: LineReader& operator++(int) { nuclear@0: return ++(*this); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: // ----------------------------------------- nuclear@0: operator bool() const { nuclear@0: return end <= 1; nuclear@0: } nuclear@0: nuclear@0: private: nuclear@0: nuclear@0: LineSplitter splitter; nuclear@0: int groupcode; nuclear@0: std::string value; nuclear@0: int end; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: nuclear@0: // represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed. nuclear@0: struct PolyLine nuclear@0: { nuclear@0: PolyLine() nuclear@0: : flags() nuclear@0: {} nuclear@0: nuclear@0: std::vector positions; nuclear@0: std::vector colors; nuclear@0: std::vector indices; nuclear@0: std::vector counts; nuclear@0: unsigned int flags; nuclear@0: nuclear@0: std::string layer; nuclear@0: std::string desc; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: // reference to a BLOCK. Specifies its own coordinate system. nuclear@0: struct InsertBlock nuclear@0: { nuclear@0: InsertBlock() nuclear@0: : scale(1.f,1.f,1.f) nuclear@0: , angle() nuclear@0: {} nuclear@0: nuclear@0: aiVector3D pos; nuclear@0: aiVector3D scale; nuclear@0: float angle; nuclear@0: nuclear@0: std::string name; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: // keeps track of all geometry in a single BLOCK. nuclear@0: struct Block nuclear@0: { nuclear@0: std::vector< boost::shared_ptr > lines; nuclear@0: std::vector insertions; nuclear@0: nuclear@0: std::string name; nuclear@0: aiVector3D base; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: struct FileData nuclear@0: { nuclear@0: // note: the LAST block always contains the stuff from ENTITIES. nuclear@0: std::vector blocks; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: nuclear@0: nuclear@0: nuclear@0: }} nuclear@0: #endif