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 | |
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 | // ----------------------------------------- |
80 | bool Is(int gc, const char* what) const { |
81 | return groupcode == gc && !strcmp(what,value.c_str()); |
82 | } |
83 | |
84 | // ----------------------------------------- |
85 | bool Is(int gc) const { |
86 | return groupcode == gc; |
87 | } |
88 | |
89 | // ----------------------------------------- |
90 | int GroupCode() const { |
91 | return groupcode; |
92 | } |
93 | |
94 | // ----------------------------------------- |
95 | const std::string& Value() const { |
96 | return value; |
97 | } |
98 | |
99 | // ----------------------------------------- |
100 | bool End() const { |
101 | return !((bool)*this); |
102 | } |
103 | |
104 | public: |
105 | |
106 | // ----------------------------------------- |
107 | unsigned int ValueAsUnsignedInt() const { |
108 | return strtoul10(value.c_str()); |
109 | } |
110 | |
111 | // ----------------------------------------- |
112 | int ValueAsSignedInt() const { |
113 | return strtol10(value.c_str()); |
114 | } |
115 | |
116 | // ----------------------------------------- |
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 | } |
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 | { |
183 | 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 | { |
201 | 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 | |