1 /* 2 Open Asset Import Library (assimp) 3 ---------------------------------------------------------------------- 4 5 Copyright (c) 2006-2017, assimp team 6 7 All rights reserved. 8 9 Redistribution and use of this software in source and binary forms, 10 with or without modification, are permitted provided that the 11 following conditions are met: 12 13 * Redistributions of source code must retain the above 14 copyright notice, this list of conditions and the 15 following disclaimer. 16 17 * Redistributions in binary form must reproduce the above 18 copyright notice, this list of conditions and the 19 following disclaimer in the documentation and/or other 20 materials provided with the distribution. 21 22 * Neither the name of the assimp team, nor the names of its 23 contributors may be used to endorse or promote products 24 derived from this software without specific prior 25 written permission of the assimp team. 26 27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 39 ---------------------------------------------------------------------- 40 */ 41 42 /** @file DXFHelper.h 43 * @brief Internal utilities for the DXF loader. 44 */ 45 46 #ifndef INCLUDED_DXFHELPER_H 47 #define INCLUDED_DXFHELPER_H 48 49 #include "LineSplitter.h" 50 #include "TinyFormatter.h" 51 #include "StreamReader.h" 52 #include "fast_atof.h" 53 #include <vector> 54 #include <assimp/DefaultLogger.hpp> 55 56 namespace Assimp { 57 namespace DXF { 58 59 60 // read pairs of lines, parse group code and value and provide utilities 61 // to convert the data to the target data type. 62 class LineReader 63 { 64 65 public: 66 LineReader(StreamReaderLE & reader)67 LineReader(StreamReaderLE& reader) 68 // do NOT skip empty lines. In DXF files, they count as valid data. 69 : splitter(reader,false,true) 70 , groupcode( 0 ) 71 , value() 72 , end() 73 { 74 } 75 76 public: 77 78 79 // ----------------------------------------- Is(int gc,const char * what)80 bool Is(int gc, const char* what) const { 81 return groupcode == gc && !strcmp(what,value.c_str()); 82 } 83 84 // ----------------------------------------- Is(int gc)85 bool Is(int gc) const { 86 return groupcode == gc; 87 } 88 89 // ----------------------------------------- GroupCode()90 int GroupCode() const { 91 return groupcode; 92 } 93 94 // ----------------------------------------- Value()95 const std::string& Value() const { 96 return value; 97 } 98 99 // ----------------------------------------- End()100 bool End() const { 101 return !((bool)*this); 102 } 103 104 public: 105 106 // ----------------------------------------- ValueAsUnsignedInt()107 unsigned int ValueAsUnsignedInt() const { 108 return strtoul10(value.c_str()); 109 } 110 111 // ----------------------------------------- ValueAsSignedInt()112 int ValueAsSignedInt() const { 113 return strtol10(value.c_str()); 114 } 115 116 // ----------------------------------------- ValueAsFloat()117 float ValueAsFloat() const { 118 return fast_atof(value.c_str()); 119 } 120 121 public: 122 123 // ----------------------------------------- 124 /** pseudo-iterator increment to advance to the next (groupcode/value) pair */ 125 LineReader& operator++() { 126 if (end) { 127 if (end == 1) { 128 ++end; 129 } 130 return *this; 131 } 132 133 try { 134 groupcode = strtol10(splitter->c_str()); 135 splitter++; 136 137 value = *splitter; 138 splitter++; 139 140 // automatically skip over {} meta blocks (these are for application use 141 // and currently not relevant for Assimp). 142 if (value.length() && value[0] == '{') { 143 144 size_t cnt = 0; 145 for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++); 146 147 splitter++; 148 DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)")); 149 } catch(std::logic_error &)150 } catch(std::logic_error&) { 151 ai_assert(!splitter); 152 } 153 if (!splitter) { 154 end = 1; 155 } 156 return *this; 157 } 158 159 // ----------------------------------------- 160 LineReader& operator++(int) { 161 return ++(*this); 162 } 163 164 165 // ----------------------------------------- 166 operator bool() const { 167 return end <= 1; 168 } 169 170 private: 171 172 LineSplitter splitter; 173 int groupcode; 174 std::string value; 175 int end; 176 }; 177 178 179 180 // represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed. 181 struct PolyLine 182 { PolyLinePolyLine183 PolyLine() 184 : flags() 185 {} 186 187 std::vector<aiVector3D> positions; 188 std::vector<aiColor4D> colors; 189 std::vector<unsigned int> indices; 190 std::vector<unsigned int> counts; 191 unsigned int flags; 192 193 std::string layer; 194 std::string desc; 195 }; 196 197 198 // reference to a BLOCK. Specifies its own coordinate system. 199 struct InsertBlock 200 { InsertBlockInsertBlock201 InsertBlock() 202 : scale(1.f,1.f,1.f) 203 , angle() 204 {} 205 206 aiVector3D pos; 207 aiVector3D scale; 208 float angle; 209 210 std::string name; 211 }; 212 213 214 // keeps track of all geometry in a single BLOCK. 215 struct Block 216 { 217 std::vector< std::shared_ptr<PolyLine> > lines; 218 std::vector<InsertBlock> insertions; 219 220 std::string name; 221 aiVector3D base; 222 }; 223 224 225 struct FileData 226 { 227 // note: the LAST block always contains the stuff from ENTITIES. 228 std::vector<Block> blocks; 229 }; 230 231 232 233 234 235 }} 236 #endif 237