/src/assimp/code/AssetLib/DXF/DXFLoader.cpp
Line | Count | Source |
1 | | /* |
2 | | --------------------------------------------------------------------------- |
3 | | Open Asset Import Library (assimp) |
4 | | --------------------------------------------------------------------------- |
5 | | |
6 | | Copyright (c) 2006-2025, assimp team |
7 | | |
8 | | All rights reserved. |
9 | | |
10 | | Redistribution and use of this software in source and binary forms, |
11 | | with or without modification, are permitted provided that the following |
12 | | conditions are met: |
13 | | |
14 | | * Redistributions of source code must retain the above |
15 | | copyright notice, this list of conditions and the |
16 | | following disclaimer. |
17 | | |
18 | | * Redistributions in binary form must reproduce the above |
19 | | copyright notice, this list of conditions and the |
20 | | following disclaimer in the documentation and/or other |
21 | | materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the assimp team, nor the names of its |
24 | | contributors may be used to endorse or promote products |
25 | | derived from this software without specific prior |
26 | | written permission of the assimp team. |
27 | | |
28 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
29 | | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
30 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
31 | | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
32 | | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
33 | | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
34 | | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
35 | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
36 | | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
37 | | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
38 | | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
39 | | --------------------------------------------------------------------------- |
40 | | */ |
41 | | |
42 | | /** @file DXFLoader.cpp |
43 | | * @brief Implementation of the DXF importer class |
44 | | */ |
45 | | |
46 | | #ifndef ASSIMP_BUILD_NO_DXF_IMPORTER |
47 | | |
48 | | #include "DXFLoader.h" |
49 | | #include "DXFHelper.h" |
50 | | #include "PostProcessing/ConvertToLHProcess.h" |
51 | | |
52 | | #include <assimp/ParsingUtils.h> |
53 | | #include <assimp/fast_atof.h> |
54 | | #include <assimp/IOSystem.hpp> |
55 | | #include <assimp/scene.h> |
56 | | #include <assimp/importerdesc.h> |
57 | | |
58 | | #include <numeric> |
59 | | #include <utility> |
60 | | |
61 | | using namespace Assimp; |
62 | | |
63 | | // AutoCAD Binary DXF<CR><LF><SUB><NULL> |
64 | | static constexpr char AI_DXF_BINARY_IDENT[] = "AutoCAD Binary DXF\r\n\x1a"; |
65 | | static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT; |
66 | | |
67 | | // default vertex color that all uncolored vertices will receive |
68 | | static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f)); |
69 | | |
70 | | // color indices for DXF - 256 are supported, the table is |
71 | | // taken directly from the AutoCad Index (ACI) table |
72 | | // https://gohtx.com/acadcolors.php |
73 | | //STH 2024-0126 |
74 | | static const aiColor4D g_aclrDxfIndexColors[256] = { |
75 | | aiColor4D (0.0f, 0.0f ,0.0f, 1.0f), //dxf color code 0 |
76 | | aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 1 |
77 | | aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 2 |
78 | | aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 3 |
79 | | aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 4 |
80 | | aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 5 |
81 | | aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 6 |
82 | | aiColor4D (1.0f, 1.0f ,1.0f, 1.0f), //dxf color code 7 |
83 | | aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 8 |
84 | | aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 9 |
85 | | aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 10 |
86 | | aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 11 |
87 | | aiColor4D (0.7f, 0.0f ,0.0f, 1.0f), //dxf color code 12 |
88 | | aiColor4D (0.7f, 0.5f ,0.5f, 1.0f), //dxf color code 13 |
89 | | aiColor4D (0.5f, 0.0f ,0.0f, 1.0f), //dxf color code 14 |
90 | | aiColor4D (0.5f, 0.3f ,0.3f, 1.0f), //dxf color code 15 |
91 | | aiColor4D (0.4f, 0.0f ,0.0f, 1.0f), //dxf color code 16 |
92 | | aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 17 |
93 | | aiColor4D (0.3f, 0.0f ,0.0f, 1.0f), //dxf color code 18 |
94 | | aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 19 |
95 | | aiColor4D (1.0f, 0.2f ,0.0f, 1.0f), //dxf color code 20 |
96 | | aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 21 |
97 | | aiColor4D (0.7f, 0.2f ,0.0f, 1.0f), //dxf color code 22 |
98 | | aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 23 |
99 | | aiColor4D (0.5f, 0.1f ,0.0f, 1.0f), //dxf color code 24 |
100 | | aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 25 |
101 | | aiColor4D (0.4f, 0.1f ,0.0f, 1.0f), //dxf color code 26 |
102 | | aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 27 |
103 | | aiColor4D (0.3f, 0.1f ,0.0f, 1.0f), //dxf color code 28 |
104 | | aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 29 |
105 | | aiColor4D (1.0f, 0.5f ,0.0f, 1.0f), //dxf color code 30 |
106 | | aiColor4D (1.0f, 0.8f ,0.7f, 1.0f), //dxf color code 31 |
107 | | aiColor4D (0.7f, 0.4f ,0.0f, 1.0f), //dxf color code 32 |
108 | | aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 33 |
109 | | aiColor4D (0.5f, 0.3f ,0.0f, 1.0f), //dxf color code 34 |
110 | | aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 35 |
111 | | aiColor4D (0.4f, 0.2f ,0.0f, 1.0f), //dxf color code 36 |
112 | | aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 37 |
113 | | aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 38 |
114 | | aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 39 |
115 | | aiColor4D (1.0f, 0.7f ,0.0f, 1.0f), //dxf color code 40 |
116 | | aiColor4D (1.0f, 0.9f ,0.7f, 1.0f), //dxf color code 41 |
117 | | aiColor4D (0.7f, 0.6f ,0.0f, 1.0f), //dxf color code 42 |
118 | | aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 43 |
119 | | aiColor4D (0.5f, 0.4f ,0.0f, 1.0f), //dxf color code 44 |
120 | | aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 45 |
121 | | aiColor4D (0.4f, 0.3f ,0.0f, 1.0f), //dxf color code 46 |
122 | | aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 47 |
123 | | aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 48 |
124 | | aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 49 |
125 | | aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 50 |
126 | | aiColor4D (1.0f, 1.0f ,0.7f, 1.0f), //dxf color code 51 |
127 | | aiColor4D (0.7f, 0.7f ,0.0f, 1.0f), //dxf color code 52 |
128 | | aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 53 |
129 | | aiColor4D (0.5f, 0.5f ,0.0f, 1.0f), //dxf color code 54 |
130 | | aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 55 |
131 | | aiColor4D (0.4f, 0.4f ,0.0f, 1.0f), //dxf color code 56 |
132 | | aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 57 |
133 | | aiColor4D (0.3f, 0.3f ,0.0f, 1.0f), //dxf color code 58 |
134 | | aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 59 |
135 | | aiColor4D (0.7f, 1.0f ,0.0f, 1.0f), //dxf color code 60 |
136 | | aiColor4D (0.9f, 1.0f ,0.7f, 1.0f), //dxf color code 61 |
137 | | aiColor4D (0.6f, 0.7f ,0.0f, 1.0f), //dxf color code 62 |
138 | | aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 63 |
139 | | aiColor4D (0.4f, 0.5f ,0.0f, 1.0f), //dxf color code 64 |
140 | | aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 65 |
141 | | aiColor4D (0.3f, 0.4f ,0.0f, 1.0f), //dxf color code 66 |
142 | | aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 67 |
143 | | aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 68 |
144 | | aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 69 |
145 | | aiColor4D (0.5f, 1.0f ,0.0f, 1.0f), //dxf color code 70 |
146 | | aiColor4D (0.8f, 1.0f ,0.7f, 1.0f), //dxf color code 71 |
147 | | aiColor4D (0.4f, 0.7f ,0.0f, 1.0f), //dxf color code 72 |
148 | | aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 73 |
149 | | aiColor4D (0.3f, 0.5f ,0.0f, 1.0f), //dxf color code 74 |
150 | | aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 75 |
151 | | aiColor4D (0.2f, 0.4f ,0.0f, 1.0f), //dxf color code 76 |
152 | | aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 77 |
153 | | aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 78 |
154 | | aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 79 |
155 | | aiColor4D (0.2f, 1.0f ,0.0f, 1.0f), //dxf color code 80 |
156 | | aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 81 |
157 | | aiColor4D (0.2f, 0.7f ,0.0f, 1.0f), //dxf color code 82 |
158 | | aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 83 |
159 | | aiColor4D (0.1f, 0.5f ,0.0f, 1.0f), //dxf color code 84 |
160 | | aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 85 |
161 | | aiColor4D (0.1f, 0.4f ,0.0f, 1.0f), //dxf color code 86 |
162 | | aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 87 |
163 | | aiColor4D (0.1f, 0.3f ,0.0f, 1.0f), //dxf color code 88 |
164 | | aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 89 |
165 | | aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 90 |
166 | | aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 91 |
167 | | aiColor4D (0.0f, 0.7f ,0.0f, 1.0f), //dxf color code 92 |
168 | | aiColor4D (0.5f, 0.7f ,0.5f, 1.0f), //dxf color code 93 |
169 | | aiColor4D (0.0f, 0.5f ,0.0f, 1.0f), //dxf color code 94 |
170 | | aiColor4D (0.3f, 0.5f ,0.3f, 1.0f), //dxf color code 95 |
171 | | aiColor4D (0.0f, 0.4f ,0.0f, 1.0f), //dxf color code 96 |
172 | | aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 97 |
173 | | aiColor4D (0.0f, 0.3f ,0.0f, 1.0f), //dxf color code 98 |
174 | | aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 99 |
175 | | aiColor4D (0.0f, 1.0f ,0.2f, 1.0f), //dxf color code 100 |
176 | | aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 101 |
177 | | aiColor4D (0.0f, 0.7f ,0.2f, 1.0f), //dxf color code 102 |
178 | | aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 103 |
179 | | aiColor4D (0.0f, 0.5f ,0.1f, 1.0f), //dxf color code 104 |
180 | | aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 105 |
181 | | aiColor4D (0.0f, 0.4f ,0.1f, 1.0f), //dxf color code 106 |
182 | | aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 107 |
183 | | aiColor4D (0.0f, 0.3f ,0.1f, 1.0f), //dxf color code 108 |
184 | | aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 109 |
185 | | aiColor4D (0.0f, 1.0f ,0.5f, 1.0f), //dxf color code 110 |
186 | | aiColor4D (0.7f, 1.0f ,0.8f, 1.0f), //dxf color code 111 |
187 | | aiColor4D (0.0f, 0.7f ,0.4f, 1.0f), //dxf color code 112 |
188 | | aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 113 |
189 | | aiColor4D (0.0f, 0.5f ,0.3f, 1.0f), //dxf color code 114 |
190 | | aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 115 |
191 | | aiColor4D (0.0f, 0.4f ,0.2f, 1.0f), //dxf color code 116 |
192 | | aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 117 |
193 | | aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 118 |
194 | | aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 119 |
195 | | aiColor4D (0.0f, 1.0f ,0.7f, 1.0f), //dxf color code 120 |
196 | | aiColor4D (0.7f, 1.0f ,0.9f, 1.0f), //dxf color code 121 |
197 | | aiColor4D (0.0f, 0.7f ,0.6f, 1.0f), //dxf color code 122 |
198 | | aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 123 |
199 | | aiColor4D (0.0f, 0.5f ,0.4f, 1.0f), //dxf color code 124 |
200 | | aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 125 |
201 | | aiColor4D (0.0f, 0.4f ,0.3f, 1.0f), //dxf color code 126 |
202 | | aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 127 |
203 | | aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 128 |
204 | | aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 129 |
205 | | aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 130 |
206 | | aiColor4D (0.7f, 1.0f ,1.0f, 1.0f), //dxf color code 131 |
207 | | aiColor4D (0.0f, 0.7f ,0.7f, 1.0f), //dxf color code 132 |
208 | | aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 133 |
209 | | aiColor4D (0.0f, 0.5f ,0.5f, 1.0f), //dxf color code 134 |
210 | | aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 135 |
211 | | aiColor4D (0.0f, 0.4f ,0.4f, 1.0f), //dxf color code 136 |
212 | | aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 137 |
213 | | aiColor4D (0.0f, 0.3f ,0.3f, 1.0f), //dxf color code 138 |
214 | | aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 139 |
215 | | aiColor4D (0.0f, 0.7f ,1.0f, 1.0f), //dxf color code 140 |
216 | | aiColor4D (0.7f, 0.9f ,1.0f, 1.0f), //dxf color code 141 |
217 | | aiColor4D (0.0f, 0.6f ,0.7f, 1.0f), //dxf color code 142 |
218 | | aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 143 |
219 | | aiColor4D (0.0f, 0.4f ,0.5f, 1.0f), //dxf color code 144 |
220 | | aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 145 |
221 | | aiColor4D (0.0f, 0.3f ,0.4f, 1.0f), //dxf color code 146 |
222 | | aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 147 |
223 | | aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 148 |
224 | | aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 149 |
225 | | aiColor4D (0.0f, 0.5f ,1.0f, 1.0f), //dxf color code 150 |
226 | | aiColor4D (0.7f, 0.8f ,1.0f, 1.0f), //dxf color code 151 |
227 | | aiColor4D (0.0f, 0.4f ,0.7f, 1.0f), //dxf color code 152 |
228 | | aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 153 |
229 | | aiColor4D (0.0f, 0.3f ,0.5f, 1.0f), //dxf color code 154 |
230 | | aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 155 |
231 | | aiColor4D (0.0f, 0.2f ,0.4f, 1.0f), //dxf color code 156 |
232 | | aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 157 |
233 | | aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 158 |
234 | | aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 159 |
235 | | aiColor4D (0.0f, 0.2f ,1.0f, 1.0f), //dxf color code 160 |
236 | | aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 161 |
237 | | aiColor4D (0.0f, 0.2f ,0.7f, 1.0f), //dxf color code 162 |
238 | | aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 163 |
239 | | aiColor4D (0.0f, 0.1f ,0.5f, 1.0f), //dxf color code 164 |
240 | | aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 165 |
241 | | aiColor4D (0.0f, 0.1f ,0.4f, 1.0f), //dxf color code 166 |
242 | | aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 167 |
243 | | aiColor4D (0.0f, 0.1f ,0.3f, 1.0f), //dxf color code 168 |
244 | | aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 169 |
245 | | aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 170 |
246 | | aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 171 |
247 | | aiColor4D (0.0f, 0.0f ,0.7f, 1.0f), //dxf color code 172 |
248 | | aiColor4D (0.5f, 0.5f ,0.7f, 1.0f), //dxf color code 173 |
249 | | aiColor4D (0.0f, 0.0f ,0.5f, 1.0f), //dxf color code 174 |
250 | | aiColor4D (0.3f, 0.3f ,0.5f, 1.0f), //dxf color code 175 |
251 | | aiColor4D (0.0f, 0.0f ,0.4f, 1.0f), //dxf color code 176 |
252 | | aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 177 |
253 | | aiColor4D (0.0f, 0.0f ,0.3f, 1.0f), //dxf color code 178 |
254 | | aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 179 |
255 | | aiColor4D (0.2f, 0.0f ,1.0f, 1.0f), //dxf color code 180 |
256 | | aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 181 |
257 | | aiColor4D (0.2f, 0.0f ,0.7f, 1.0f), //dxf color code 182 |
258 | | aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 183 |
259 | | aiColor4D (0.1f, 0.0f ,0.5f, 1.0f), //dxf color code 184 |
260 | | aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 185 |
261 | | aiColor4D (0.1f, 0.0f ,0.4f, 1.0f), //dxf color code 186 |
262 | | aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 187 |
263 | | aiColor4D (0.1f, 0.0f ,0.3f, 1.0f), //dxf color code 188 |
264 | | aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 189 |
265 | | aiColor4D (0.5f, 0.0f ,1.0f, 1.0f), //dxf color code 190 |
266 | | aiColor4D (0.8f, 0.7f ,1.0f, 1.0f), //dxf color code 191 |
267 | | aiColor4D (0.4f, 0.0f ,0.7f, 1.0f), //dxf color code 192 |
268 | | aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 193 |
269 | | aiColor4D (0.3f, 0.0f ,0.5f, 1.0f), //dxf color code 194 |
270 | | aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 195 |
271 | | aiColor4D (0.2f, 0.0f ,0.4f, 1.0f), //dxf color code 196 |
272 | | aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 197 |
273 | | aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 198 |
274 | | aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 199 |
275 | | aiColor4D (0.7f, 0.0f ,1.0f, 1.0f), //dxf color code 200 |
276 | | aiColor4D (0.9f, 0.7f ,1.0f, 1.0f), //dxf color code 201 |
277 | | aiColor4D (0.6f, 0.0f ,0.7f, 1.0f), //dxf color code 202 |
278 | | aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 203 |
279 | | aiColor4D (0.4f, 0.0f ,0.5f, 1.0f), //dxf color code 204 |
280 | | aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 205 |
281 | | aiColor4D (0.3f, 0.0f ,0.4f, 1.0f), //dxf color code 206 |
282 | | aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 207 |
283 | | aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 208 |
284 | | aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 209 |
285 | | aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 210 |
286 | | aiColor4D (1.0f, 0.7f ,1.0f, 1.0f), //dxf color code 211 |
287 | | aiColor4D (0.7f, 0.0f ,0.7f, 1.0f), //dxf color code 212 |
288 | | aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 213 |
289 | | aiColor4D (0.5f, 0.0f ,0.5f, 1.0f), //dxf color code 214 |
290 | | aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 215 |
291 | | aiColor4D (0.4f, 0.0f ,0.4f, 1.0f), //dxf color code 216 |
292 | | aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 217 |
293 | | aiColor4D (0.3f, 0.0f ,0.3f, 1.0f), //dxf color code 218 |
294 | | aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 219 |
295 | | aiColor4D (1.0f, 0.0f ,0.7f, 1.0f), //dxf color code 220 |
296 | | aiColor4D (1.0f, 0.7f ,0.9f, 1.0f), //dxf color code 221 |
297 | | aiColor4D (0.7f, 0.0f ,0.6f, 1.0f), //dxf color code 222 |
298 | | aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 223 |
299 | | aiColor4D (0.5f, 0.0f ,0.4f, 1.0f), //dxf color code 224 |
300 | | aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 225 |
301 | | aiColor4D (0.4f, 0.0f ,0.3f, 1.0f), //dxf color code 226 |
302 | | aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 227 |
303 | | aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 228 |
304 | | aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 229 |
305 | | aiColor4D (1.0f, 0.0f ,0.5f, 1.0f), //dxf color code 230 |
306 | | aiColor4D (1.0f, 0.7f ,0.8f, 1.0f), //dxf color code 231 |
307 | | aiColor4D (0.7f, 0.0f ,0.4f, 1.0f), //dxf color code 232 |
308 | | aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 233 |
309 | | aiColor4D (0.5f, 0.0f ,0.3f, 1.0f), //dxf color code 234 |
310 | | aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 235 |
311 | | aiColor4D (0.4f, 0.0f ,0.2f, 1.0f), //dxf color code 236 |
312 | | aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 237 |
313 | | aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 238 |
314 | | aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 239 |
315 | | aiColor4D (1.0f, 0.0f ,0.2f, 1.0f), //dxf color code 240 |
316 | | aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 241 |
317 | | aiColor4D (0.7f, 0.0f ,0.2f, 1.0f), //dxf color code 242 |
318 | | aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 243 |
319 | | aiColor4D (0.5f, 0.0f ,0.1f, 1.0f), //dxf color code 244 |
320 | | aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 245 |
321 | | aiColor4D (0.4f, 0.0f ,0.1f, 1.0f), //dxf color code 246 |
322 | | aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 247 |
323 | | aiColor4D (0.3f, 0.0f ,0.1f, 1.0f), //dxf color code 248 |
324 | | aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 249 |
325 | | aiColor4D (0.2f, 0.2f ,0.2f, 1.0f), //dxf color code 250 |
326 | | aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 251 |
327 | | aiColor4D (0.4f, 0.4f ,0.4f, 1.0f), //dxf color code 252 |
328 | | aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 253 |
329 | | aiColor4D (0.7f, 0.7f ,0.7f, 1.0f), //dxf color code 254 |
330 | | aiColor4D (1.0f, 1.0f ,1.0f, 1.0f) //dxf color code 255 |
331 | | }; |
332 | | |
333 | 313 | #define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0])) |
334 | 358 | #define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC" |
335 | | |
336 | | static const int GroupCode_Name = 2; |
337 | | static const int GroupCode_XComp = 10; |
338 | | static const int GroupCode_YComp = 20; |
339 | | static const int GroupCode_ZComp = 30; |
340 | | |
341 | | static constexpr aiImporterDesc desc = { |
342 | | "Drawing Interchange Format (DXF) Importer", |
343 | | "", |
344 | | "", |
345 | | "", |
346 | | aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport, |
347 | | 0, |
348 | | 0, |
349 | | 0, |
350 | | 0, |
351 | | "dxf" |
352 | | }; |
353 | | |
354 | | // ------------------------------------------------------------------------------------------------ |
355 | | // Returns whether the class can handle the format of the given file. |
356 | 671 | bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool /*checkSig*/ ) const { |
357 | 671 | static const char *tokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" }; |
358 | 671 | return SearchFileHeaderForToken(pIOHandler, filename, tokens, AI_COUNT_OF(tokens), 32); |
359 | 671 | } |
360 | | |
361 | | // ------------------------------------------------------------------------------------------------ |
362 | | // Get a list of all supported file extensions |
363 | 1.37k | const aiImporterDesc* DXFImporter::GetInfo () const { |
364 | 1.37k | return &desc; |
365 | 1.37k | } |
366 | | |
367 | | // ------------------------------------------------------------------------------------------------ |
368 | | // Imports the given file into the given scene structure. |
369 | 174 | void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene, IOSystem* pIOHandler) { |
370 | 174 | std::shared_ptr<IOStream> file = std::shared_ptr<IOStream>( pIOHandler->Open( filename) ); |
371 | | |
372 | | // Check whether we can read the file |
373 | 174 | if (file == nullptr) { |
374 | 0 | throw DeadlyImportError( "Failed to open DXF file ", filename, ""); |
375 | 0 | } |
376 | | |
377 | | // Check whether this is a binary DXF file - we can't read binary DXF files :-( |
378 | 174 | char buff[AI_DXF_BINARY_IDENT_LEN] = {0}; |
379 | 174 | file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1); |
380 | | |
381 | 174 | if (0 == memcmp(AI_DXF_BINARY_IDENT,buff,AI_DXF_BINARY_IDENT_LEN)) { |
382 | 0 | throw DeadlyImportError("DXF: Binary files are not supported at the moment"); |
383 | 0 | } |
384 | | |
385 | | // DXF files can grow very large, so read them via the StreamReader, |
386 | | // which will choose a suitable strategy. |
387 | 174 | file->Seek(0,aiOrigin_SET); |
388 | 174 | StreamReaderLE stream( std::move(file) ); |
389 | | |
390 | 174 | DXF::LineReader reader (stream); |
391 | 174 | DXF::FileData output; |
392 | | |
393 | | // now get all lines of the file and process top-level sections |
394 | 174 | bool eof = false; |
395 | 3.84k | while(!reader.End()) { |
396 | | |
397 | | // blocks table - these 'build blocks' are later (in ENTITIES) |
398 | | // referenced an included via INSERT statements. |
399 | 3.67k | if (reader.Is(2,"BLOCKS")) { |
400 | 151 | ParseBlocks(reader,output); |
401 | 151 | continue; |
402 | 151 | } |
403 | | |
404 | | // primary entity table |
405 | 3.52k | if (reader.Is(2,"ENTITIES")) { |
406 | 196 | ParseEntities(reader,output); |
407 | 196 | continue; |
408 | 196 | } |
409 | | |
410 | | // skip unneeded sections entirely to avoid any problems with them |
411 | | // altogether. |
412 | 3.32k | else if (reader.Is(2,"CLASSES") || reader.Is(2,"TABLES")) { |
413 | 0 | SkipSection(reader); |
414 | 0 | continue; |
415 | 0 | } |
416 | | |
417 | 3.32k | else if (reader.Is(2,"HEADER")) { |
418 | 0 | ParseHeader(reader,output); |
419 | 0 | continue; |
420 | 0 | } |
421 | | |
422 | | // comments |
423 | 3.32k | else if (reader.Is(999)) { |
424 | 0 | ASSIMP_LOG_INFO("DXF Comment: ", reader.Value()); |
425 | 0 | } |
426 | | |
427 | | // don't read past the official EOF sign |
428 | 3.32k | else if (reader.Is(0,"EOF")) { |
429 | 0 | eof = true; |
430 | 0 | break; |
431 | 0 | } |
432 | | |
433 | 3.32k | ++reader; |
434 | 3.32k | } |
435 | 174 | if (!eof) { |
436 | 164 | ASSIMP_LOG_WARN("DXF: EOF reached, but did not encounter DXF EOF marker"); |
437 | 164 | } |
438 | | |
439 | 174 | ConvertMeshes(pScene,output); |
440 | | |
441 | | // Now rotate the whole scene by 90 degrees around the x axis to convert from AutoCAD's to Assimp's coordinate system |
442 | 174 | pScene->mRootNode->mTransformation = aiMatrix4x4( |
443 | 174 | 1.f,0.f,0.f,0.f, |
444 | 174 | 0.f,0.f,1.f,0.f, |
445 | 174 | 0.f,-1.f,0.f,0.f, |
446 | 174 | 0.f,0.f,0.f,1.f) * pScene->mRootNode->mTransformation; |
447 | 174 | } |
448 | | |
449 | | // ------------------------------------------------------------------------------------------------ |
450 | 164 | void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) { |
451 | | // the process of resolving all the INSERT statements can grow the |
452 | | // poly-count excessively, so log the original number. |
453 | | // XXX Option to import blocks as separate nodes? |
454 | 164 | if (!DefaultLogger::isNullLogger()) { |
455 | 0 | unsigned int vcount = 0, icount = 0; |
456 | 0 | for (const DXF::Block& bl : output.blocks) { |
457 | 0 | for (std::shared_ptr<const DXF::PolyLine> pl : bl.lines) { |
458 | 0 | vcount += static_cast<unsigned int>(pl->positions.size()); |
459 | 0 | icount += static_cast<unsigned int>(pl->counts.size()); |
460 | 0 | } |
461 | 0 | } |
462 | |
|
463 | 0 | ASSIMP_LOG_VERBOSE_DEBUG("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount); |
464 | 0 | } |
465 | | |
466 | 164 | if (output.blocks.empty()) { |
467 | 2 | throw DeadlyImportError("DXF: no data blocks loaded"); |
468 | 2 | } |
469 | | |
470 | 162 | DXF::Block* entities( nullptr ); |
471 | | |
472 | | // index blocks by name |
473 | 162 | DXF::BlockMap blocks_by_name; |
474 | 1.43k | for (DXF::Block& bl : output.blocks) { |
475 | 1.43k | blocks_by_name[bl.name] = &bl; |
476 | 1.43k | if ( !entities && bl.name == AI_DXF_ENTITIES_MAGIC_BLOCK ) { |
477 | 162 | entities = &bl; |
478 | 162 | } |
479 | 1.43k | } |
480 | | |
481 | 162 | if (!entities) { |
482 | 0 | throw DeadlyImportError("DXF: no ENTITIES data block loaded"); |
483 | 0 | } |
484 | | |
485 | 162 | typedef std::map<std::string, unsigned int> LayerMap; |
486 | | |
487 | 162 | LayerMap layers; |
488 | 162 | std::vector< std::vector< const DXF::PolyLine*> > corr; |
489 | | |
490 | | // now expand all block references in the primary ENTITIES block |
491 | | // XXX this involves heavy memory copying, consider a faster solution for future versions. |
492 | 162 | ExpandBlockReferences(*entities,blocks_by_name); |
493 | | |
494 | 162 | unsigned int cur = 0; |
495 | 106k | for (std::shared_ptr<const DXF::PolyLine> pl : entities->lines) { |
496 | 106k | if (pl->positions.size()) { |
497 | | |
498 | 106k | std::map<std::string, unsigned int>::iterator it = layers.find(pl->layer); |
499 | 106k | if (it == layers.end()) { |
500 | 232 | ++pScene->mNumMeshes; |
501 | | |
502 | 232 | layers[pl->layer] = cur++; |
503 | | |
504 | 232 | std::vector< const DXF::PolyLine* > pv; |
505 | 232 | pv.push_back(&*pl); |
506 | | |
507 | 232 | corr.push_back(pv); |
508 | 232 | } |
509 | 106k | else { |
510 | 106k | corr[(*it).second].push_back(&*pl); |
511 | 106k | } |
512 | 106k | } |
513 | 106k | } |
514 | | |
515 | 162 | if ( 0 == pScene->mNumMeshes) { |
516 | 36 | throw DeadlyImportError("DXF: this file contains no 3d data"); |
517 | 36 | } |
518 | | |
519 | 126 | pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ] (); |
520 | | |
521 | 187 | for(const LayerMap::value_type& elem : layers){ |
522 | 187 | aiMesh* const mesh = pScene->mMeshes[elem.second] = new aiMesh(); |
523 | 187 | mesh->mName.Set(elem.first); |
524 | | |
525 | 187 | unsigned int cvert = 0,cface = 0; |
526 | 106k | for(const DXF::PolyLine* pl : corr[elem.second]){ |
527 | | // sum over all faces since we need to 'verbosify' them. |
528 | 106k | cvert += std::accumulate(pl->counts.begin(),pl->counts.end(),0); |
529 | 106k | cface += static_cast<unsigned int>(pl->counts.size()); |
530 | 106k | } |
531 | | |
532 | 187 | aiVector3D* verts = mesh->mVertices = new aiVector3D[cvert]; |
533 | 187 | aiColor4D* colors = mesh->mColors[0] = new aiColor4D[cvert]; |
534 | 187 | aiFace* faces = mesh->mFaces = new aiFace[cface]; |
535 | | |
536 | 187 | mesh->mNumVertices = cvert; |
537 | 187 | mesh->mNumFaces = cface; |
538 | | |
539 | 187 | unsigned int prims = 0; |
540 | 187 | unsigned int overall_indices = 0; |
541 | 105k | for(const DXF::PolyLine* pl : corr[elem.second]){ |
542 | | |
543 | 105k | std::vector<unsigned int>::const_iterator it = pl->indices.begin(); |
544 | 106k | for(unsigned int facenumv : pl->counts) { |
545 | 106k | aiFace& face = *faces++; |
546 | 106k | face.mIndices = new unsigned int[face.mNumIndices = facenumv]; |
547 | | |
548 | 469k | for (unsigned int i = 0; i < facenumv; ++i) { |
549 | 363k | face.mIndices[i] = overall_indices++; |
550 | | |
551 | 363k | ai_assert(pl->positions.size() == pl->colors.size()); |
552 | 363k | if (*it >= pl->positions.size()) { |
553 | 32 | throw DeadlyImportError("DXF: vertex index out of bounds"); |
554 | 32 | } |
555 | | |
556 | 363k | *verts++ = pl->positions[*it]; |
557 | 363k | *colors++ = pl->colors[*it++]; |
558 | 363k | } |
559 | | |
560 | | // set primitive flags now, this saves the extra pass in ScenePreprocessor. |
561 | 106k | switch(face.mNumIndices) { |
562 | 37 | case 1: |
563 | 37 | prims |= aiPrimitiveType_POINT; |
564 | 37 | break; |
565 | 7.77k | case 2: |
566 | 7.77k | prims |= aiPrimitiveType_LINE; |
567 | 7.77k | break; |
568 | 46.0k | case 3: |
569 | 46.0k | prims |= aiPrimitiveType_TRIANGLE; |
570 | 46.0k | break; |
571 | 52.4k | default: |
572 | 52.4k | prims |= aiPrimitiveType_POLYGON; |
573 | 52.4k | break; |
574 | 106k | } |
575 | 106k | } |
576 | 105k | } |
577 | | |
578 | 155 | mesh->mPrimitiveTypes = prims; |
579 | 155 | mesh->mMaterialIndex = 0; |
580 | 155 | } |
581 | | |
582 | 94 | GenerateHierarchy(pScene,output); |
583 | 94 | GenerateMaterials(pScene,output); |
584 | 94 | } |
585 | | |
586 | | |
587 | | // ------------------------------------------------------------------------------------------------ |
588 | 162 | void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& blocks_by_name) { |
589 | 4.76k | for (const DXF::InsertBlock& insert : bl.insertions) { |
590 | | |
591 | | // first check if the referenced blocks exists ... |
592 | 4.76k | const DXF::BlockMap::const_iterator it = blocks_by_name.find(insert.name); |
593 | 4.76k | if (it == blocks_by_name.end()) { |
594 | 1.77k | ASSIMP_LOG_ERROR("DXF: Failed to resolve block reference: ", insert.name,"; skipping" ); |
595 | 1.77k | continue; |
596 | 1.77k | } |
597 | | |
598 | | // XXX this would be the place to implement recursive expansion if needed. |
599 | 2.98k | const DXF::Block& bl_src = *(*it).second; |
600 | | |
601 | 2.98k | const size_t size = bl_src.lines.size(); // the size may increase in the loop |
602 | 103k | for (size_t i = 0; i < size; ++i) { |
603 | 100k | std::shared_ptr<const DXF::PolyLine> pl_in = bl_src.lines[i]; |
604 | 100k | if (!pl_in) { |
605 | 0 | ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping."); |
606 | 0 | continue; |
607 | 0 | } |
608 | | |
609 | 100k | std::shared_ptr<DXF::PolyLine> pl_out = std::shared_ptr<DXF::PolyLine>(new DXF::PolyLine(*pl_in)); |
610 | | |
611 | 100k | if (bl_src.base.Length() || insert.scale.x!=1.f || insert.scale.y!=1.f || insert.scale.z!=1.f || insert.angle || insert.pos.Length()) { |
612 | | // manual coordinate system transformation |
613 | | // XXX order |
614 | 100k | aiMatrix4x4 trafo, tmp; |
615 | 100k | aiMatrix4x4::Translation(-bl_src.base,trafo); |
616 | | //Need to translate position before scaling the insert |
617 | | //otherwise the position ends up being the position*scaling |
618 | | //STH 2024.01.17 |
619 | 100k | trafo *= aiMatrix4x4::Translation(insert.pos,tmp); |
620 | 100k | trafo *= aiMatrix4x4::Scaling(insert.scale,tmp); |
621 | | //trafo *= aiMatrix4x4::Translation(insert.pos,tmp); |
622 | | |
623 | | // XXX rotation currently ignored - I didn't find an appropriate sample model. |
624 | 100k | if (insert.angle != 0.f) { |
625 | 0 | ASSIMP_LOG_WARN("DXF: BLOCK rotation not currently implemented"); |
626 | 0 | } |
627 | | |
628 | 344k | for (aiVector3D& v : pl_out->positions) { |
629 | 344k | v *= trafo; |
630 | 344k | } |
631 | 100k | } |
632 | | |
633 | 100k | bl.lines.push_back(pl_out); |
634 | 100k | } |
635 | 2.98k | } |
636 | 162 | } |
637 | | |
638 | | // ------------------------------------------------------------------------------------------------ |
639 | 94 | void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/) { |
640 | | // generate an almost-white default material. Reason: |
641 | | // the default vertex color is GREY, so we are |
642 | | // already at Assimp's usual default color. |
643 | | // generate a default material |
644 | 94 | aiMaterial* pcMat = new aiMaterial(); |
645 | 94 | aiString s; |
646 | 94 | s.Set(AI_DEFAULT_MATERIAL_NAME); |
647 | 94 | pcMat->AddProperty(&s, AI_MATKEY_NAME); |
648 | | |
649 | 94 | aiColor4D clrDiffuse(0.9f,0.9f,0.9f,1.0f); |
650 | 94 | pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE); |
651 | | |
652 | 94 | clrDiffuse = aiColor4D(1.0f,1.0f,1.0f,1.0f); |
653 | 94 | pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR); |
654 | | |
655 | 94 | clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f); |
656 | 94 | pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT); |
657 | | |
658 | 94 | pScene->mNumMaterials = 1; |
659 | 94 | pScene->mMaterials = new aiMaterial*[1]; |
660 | 94 | pScene->mMaterials[0] = pcMat; |
661 | 94 | } |
662 | | |
663 | | // ------------------------------------------------------------------------------------------------ |
664 | 94 | void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/) { |
665 | | // generate the output scene graph, which is just the root node with a single child for each layer. |
666 | 94 | pScene->mRootNode = new aiNode(); |
667 | 94 | pScene->mRootNode->mName.Set("<DXF_ROOT>"); |
668 | | |
669 | 94 | if (1 == pScene->mNumMeshes) { |
670 | 66 | pScene->mRootNode->mMeshes = new unsigned int[ pScene->mRootNode->mNumMeshes = 1 ]; |
671 | 66 | pScene->mRootNode->mMeshes[0] = 0; |
672 | 66 | } else { |
673 | 28 | pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren = pScene->mNumMeshes ]; |
674 | 117 | for (unsigned int m = 0; m < pScene->mRootNode->mNumChildren;++m) { |
675 | 89 | aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode(); |
676 | 89 | p->mName = pScene->mMeshes[m]->mName; |
677 | | |
678 | 89 | p->mMeshes = new unsigned int[p->mNumMeshes = 1]; |
679 | 89 | p->mMeshes[0] = m; |
680 | 89 | p->mParent = pScene->mRootNode; |
681 | 89 | } |
682 | 28 | } |
683 | 94 | } |
684 | | |
685 | | |
686 | | // ------------------------------------------------------------------------------------------------ |
687 | 0 | void DXFImporter::SkipSection(DXF::LineReader& reader) { |
688 | 0 | for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++); |
689 | 0 | } |
690 | | |
691 | | // ------------------------------------------------------------------------------------------------ |
692 | 0 | void DXFImporter::ParseHeader(DXF::LineReader& reader, DXF::FileData& ) { |
693 | 0 | for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++); |
694 | 0 | } |
695 | | |
696 | | // ------------------------------------------------------------------------------------------------ |
697 | 151 | void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) { |
698 | 11.7k | while( !reader.End() && !reader.Is(0,"ENDSEC")) { |
699 | 11.5k | if (reader.Is(0,"BLOCK")) { |
700 | 1.24k | ParseBlock(++reader,output); |
701 | 1.24k | continue; |
702 | 1.24k | } |
703 | 10.3k | ++reader; |
704 | 10.3k | } |
705 | | |
706 | 151 | ASSIMP_LOG_VERBOSE_DEBUG("DXF: got ", output.blocks.size()," entries in BLOCKS" ); |
707 | 151 | } |
708 | | |
709 | | // ------------------------------------------------------------------------------------------------ |
710 | 1.24k | void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output) { |
711 | | // push a new block onto the stack. |
712 | 1.24k | output.blocks.emplace_back(); |
713 | 1.24k | DXF::Block& block = output.blocks.back(); |
714 | | |
715 | 19.1k | while( !reader.End() && !reader.Is(0,"ENDBLK")) { |
716 | | |
717 | 18.6k | switch(reader.GroupCode()) { |
718 | 1.11k | case GroupCode_Name: |
719 | 1.11k | block.name = reader.Value(); |
720 | 1.11k | break; |
721 | | |
722 | 3 | case GroupCode_XComp: |
723 | 3 | block.base.x = reader.ValueAsFloat(); |
724 | 3 | break; |
725 | 0 | case GroupCode_YComp: |
726 | 0 | block.base.y = reader.ValueAsFloat(); |
727 | 0 | break; |
728 | 468 | case GroupCode_ZComp: |
729 | 468 | block.base.z = reader.ValueAsFloat(); |
730 | 468 | break; |
731 | 18.6k | } |
732 | | |
733 | 18.6k | if (reader.Is(0,"POLYLINE")) { |
734 | 43 | ParsePolyLine(++reader,output); |
735 | 43 | continue; |
736 | 43 | } |
737 | | |
738 | | // XXX is this a valid case? |
739 | 18.6k | if (reader.Is(0,"INSERT")) { |
740 | 806 | ASSIMP_LOG_WARN("DXF: INSERT within a BLOCK not currently supported; skipping"); |
741 | 13.5k | for( ;!reader.End() && !reader.Is(0,"ENDBLK"); ++reader); |
742 | 806 | break; |
743 | 806 | } |
744 | | |
745 | 17.8k | else if (reader.Is(0,"3DFACE") || reader.Is(0,"LINE") || reader.Is(0,"3DLINE")) { |
746 | | //http://sourceforge.net/tracker/index.php?func=detail&aid=2970566&group_id=226462&atid=1067632 |
747 | 1.54k | Parse3DFace(++reader, output); |
748 | 1.54k | continue; |
749 | 1.54k | } |
750 | 16.2k | ++reader; |
751 | 16.2k | } |
752 | 1.24k | } |
753 | | |
754 | | // ------------------------------------------------------------------------------------------------ |
755 | 196 | void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) { |
756 | | // Push a new block onto the stack. |
757 | 196 | output.blocks.emplace_back(); |
758 | 196 | DXF::Block& block = output.blocks.back(); |
759 | | |
760 | 196 | block.name = AI_DXF_ENTITIES_MAGIC_BLOCK; |
761 | | |
762 | 93.3k | while( !reader.End() && !reader.Is(0,"ENDSEC")) { |
763 | 93.1k | if (reader.Is(0,"POLYLINE")) { |
764 | 1.42k | ParsePolyLine(++reader,output); |
765 | 1.42k | continue; |
766 | 1.42k | } |
767 | | |
768 | 91.7k | else if (reader.Is(0,"INSERT")) { |
769 | 5.53k | ParseInsertion(++reader,output); |
770 | 5.53k | continue; |
771 | 5.53k | } |
772 | | |
773 | 86.1k | else if (reader.Is(0,"3DFACE") || reader.Is(0,"LINE") || reader.Is(0,"3DLINE")) { |
774 | | //http://sourceforge.net/tracker/index.php?func=detail&aid=2970566&group_id=226462&atid=1067632 |
775 | 8.74k | Parse3DFace(++reader, output); |
776 | 8.74k | continue; |
777 | 8.74k | } |
778 | | |
779 | 77.4k | ++reader; |
780 | 77.4k | } |
781 | | |
782 | 196 | ASSIMP_LOG_VERBOSE_DEBUG( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(), |
783 | 196 | " inserted blocks in ENTITIES" ); |
784 | 196 | } |
785 | | |
786 | 5.53k | void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output) { |
787 | 5.53k | output.blocks.back().insertions.emplace_back(); |
788 | 5.53k | DXF::InsertBlock& bl = output.blocks.back().insertions.back(); |
789 | | |
790 | 8.47k | while( !reader.End() && !reader.Is(0)) { |
791 | 2.93k | switch(reader.GroupCode()) { |
792 | | // name of referenced block |
793 | 1.77k | case GroupCode_Name: |
794 | 1.77k | bl.name = reader.Value(); |
795 | 1.77k | break; |
796 | | |
797 | | // translation |
798 | 0 | case GroupCode_XComp: |
799 | 0 | bl.pos.x = reader.ValueAsFloat(); |
800 | 0 | break; |
801 | 0 | case GroupCode_YComp: |
802 | 0 | bl.pos.y = reader.ValueAsFloat(); |
803 | 0 | break; |
804 | 42 | case GroupCode_ZComp: |
805 | 42 | bl.pos.z = reader.ValueAsFloat(); |
806 | 42 | break; |
807 | | |
808 | | // scaling |
809 | 2 | case 41: |
810 | 2 | bl.scale.x = reader.ValueAsFloat(); |
811 | 2 | break; |
812 | 1 | case 42: |
813 | 1 | bl.scale.y = reader.ValueAsFloat(); |
814 | 1 | break; |
815 | 0 | case 43: |
816 | 0 | bl.scale.z = reader.ValueAsFloat(); |
817 | 0 | break; |
818 | | |
819 | | // rotation angle |
820 | 191 | case 50: |
821 | 191 | bl.angle = reader.ValueAsFloat(); |
822 | 191 | break; |
823 | 2.93k | } |
824 | 2.93k | reader++; |
825 | 2.93k | } |
826 | 5.53k | } |
827 | | |
828 | | static constexpr unsigned int DXF_POLYLINE_FLAG_CLOSED = 0x1; |
829 | | // Currently unused |
830 | | //static constexpr unsigned int DXF_POLYLINE_FLAG_3D_POLYLINE = 0x8; |
831 | | //static constexpr unsigned int DXF_POLYLINE_FLAG_3D_POLYMESH = 0x10; |
832 | | static constexpr unsigned int DXF_POLYLINE_FLAG_POLYFACEMESH = 0x40; |
833 | | |
834 | | // ------------------------------------------------------------------------------------------------ |
835 | 1.46k | void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) { |
836 | 1.46k | output.blocks.back().lines.push_back( std::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() ) ); |
837 | 1.46k | DXF::PolyLine& line = *output.blocks.back().lines.back(); |
838 | | |
839 | 1.46k | unsigned int iguess = 0, vguess = 0; |
840 | 106k | while( !reader.End() && !reader.Is(0,"ENDSEC")) { |
841 | | |
842 | 106k | if (reader.Is(0,"VERTEX")) { |
843 | 5.26k | ParsePolyLineVertex(++reader,line); |
844 | 5.26k | if (reader.Is(0,"SEQEND")) { |
845 | 1.39k | break; |
846 | 1.39k | } |
847 | 3.86k | continue; |
848 | 5.26k | } |
849 | | |
850 | 101k | switch(reader.GroupCode()) |
851 | 101k | { |
852 | | // flags --- important that we know whether it is a |
853 | | // polyface mesh or 'just' a line. |
854 | 3.38k | case 70: |
855 | 3.38k | if (!line.flags) { |
856 | 1.78k | line.flags = reader.ValueAsSignedInt(); |
857 | 1.78k | } |
858 | 3.38k | break; |
859 | | |
860 | | // optional number of vertices |
861 | 1.02k | case 71: |
862 | 1.02k | vguess = reader.ValueAsSignedInt(); |
863 | 1.02k | line.positions.reserve(vguess); |
864 | 1.02k | break; |
865 | | |
866 | | // optional number of faces |
867 | 1.36k | case 72: |
868 | 1.36k | iguess = reader.ValueAsSignedInt(); |
869 | 1.36k | line.indices.reserve(iguess); |
870 | 1.36k | break; |
871 | | |
872 | | // 8 specifies the layer on which this line is placed on |
873 | 252 | case 8: |
874 | 252 | line.layer = reader.Value(); |
875 | 252 | break; |
876 | 101k | } |
877 | | |
878 | 101k | reader++; |
879 | 101k | } |
880 | | |
881 | 1.46k | if (vguess && line.positions.size() != vguess) { |
882 | 553 | ASSIMP_LOG_WARN("DXF: unexpected vertex count in polymesh: ", |
883 | 553 | line.positions.size(),", expected ", vguess ); |
884 | 553 | } |
885 | | |
886 | 1.46k | if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH ) { |
887 | 192 | if (line.positions.size() < 3 || line.indices.size() < 3) { |
888 | 187 | ASSIMP_LOG_WARN("DXF: not enough vertices for polymesh; ignoring"); |
889 | 187 | output.blocks.back().lines.pop_back(); |
890 | 187 | return; |
891 | 187 | } |
892 | | |
893 | | // if these numbers are wrong, parsing might have gone wild. |
894 | | // however, the docs state that applications are not required |
895 | | // to set the 71 and 72 fields, respectively, to valid values. |
896 | | // So just fire a warning. |
897 | 5 | if (iguess && line.counts.size() != iguess) { |
898 | 0 | ASSIMP_LOG_WARN( "DXF: unexpected face count in polymesh: ", line.counts.size(),", expected ", iguess ); |
899 | 0 | } |
900 | 5 | } |
901 | 1.27k | else if (!line.indices.size() && !line.counts.size()) { |
902 | | // a poly-line - so there are no indices yet. |
903 | 742 | size_t guess = line.positions.size() + (line.flags & DXF_POLYLINE_FLAG_CLOSED ? 1 : 0); |
904 | 742 | line.indices.reserve(guess); |
905 | | |
906 | 742 | line.counts.reserve(guess/2); |
907 | 1.20k | for (unsigned int i = 0; i < line.positions.size()/2; ++i) { |
908 | 462 | line.indices.push_back(i*2); |
909 | 462 | line.indices.push_back(i*2+1); |
910 | 462 | line.counts.push_back(2); |
911 | 462 | } |
912 | | |
913 | | // closed polyline? |
914 | 742 | if (line.flags & DXF_POLYLINE_FLAG_CLOSED) { |
915 | 386 | line.indices.push_back(static_cast<unsigned int>(line.positions.size()-1)); |
916 | 386 | line.indices.push_back(0); |
917 | 386 | line.counts.push_back(2); |
918 | 386 | } |
919 | 742 | } |
920 | 1.46k | } |
921 | | |
922 | 714 | #define DXF_VERTEX_FLAG_PART_OF_POLYFACE 0x80 |
923 | | #define DXF_VERTEX_FLAG_HAS_POSITIONS 0x40 |
924 | | |
925 | | // ------------------------------------------------------------------------------------------------ |
926 | 5.26k | void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& line) { |
927 | 5.26k | unsigned int cnti = 0, flags = 0; |
928 | 5.26k | unsigned int indices[4]; |
929 | | |
930 | 5.26k | aiVector3D out; |
931 | 5.26k | aiColor4D clr = AI_DXF_DEFAULT_COLOR; |
932 | | |
933 | 13.3k | while( !reader.End() ) { |
934 | | |
935 | 13.3k | if (reader.Is(0)) { // SEQEND or another VERTEX |
936 | 5.26k | break; |
937 | 5.26k | } |
938 | | |
939 | 8.12k | switch (reader.GroupCode()) { |
940 | 157 | case 8: |
941 | | // layer to which the vertex belongs to - assume that |
942 | | // this is always the layer the top-level poly-line |
943 | | // entity resides on as well. |
944 | 157 | if(reader.Value() != line.layer) { |
945 | 157 | ASSIMP_LOG_WARN("DXF: expected vertex to be part of a poly-face but the 0x128 flag isn't set"); |
946 | 157 | } |
947 | 157 | break; |
948 | | |
949 | 3.95k | case 70: |
950 | 3.95k | flags = reader.ValueAsUnsignedInt(); |
951 | 3.95k | break; |
952 | | |
953 | | // VERTEX COORDINATES |
954 | 7 | case GroupCode_XComp: |
955 | 7 | out.x = reader.ValueAsFloat(); |
956 | 7 | break; |
957 | | |
958 | 0 | case GroupCode_YComp: |
959 | 0 | out.y = reader.ValueAsFloat(); |
960 | 0 | break; |
961 | | |
962 | 0 | case GroupCode_ZComp: |
963 | 0 | out.z = reader.ValueAsFloat(); |
964 | 0 | break; |
965 | | |
966 | | // POLYFACE vertex indices |
967 | 444 | case 71: |
968 | 902 | case 72: |
969 | 1.45k | case 73: |
970 | 2.21k | case 74: { |
971 | 2.21k | if (cnti == 4) { |
972 | 97 | ASSIMP_LOG_WARN("DXF: more than 4 indices per face not supported; ignoring"); |
973 | 97 | break; |
974 | 97 | } |
975 | 2.11k | const int index = reader.ValueAsSignedInt(); |
976 | 2.11k | if (index >= 0) { |
977 | 2.11k | indices[cnti++] = static_cast<unsigned int>(index); |
978 | 2.11k | } else { |
979 | 0 | indices[cnti++] = static_cast<unsigned int>(-index); |
980 | 0 | } |
981 | 2.11k | } |
982 | 0 | break; |
983 | | |
984 | | // color |
985 | 0 | case 62: |
986 | 0 | clr = g_aclrDxfIndexColors[reader.ValueAsUnsignedInt() % AI_DXF_NUM_INDEX_COLORS]; |
987 | 0 | break; |
988 | 8.12k | }; |
989 | | |
990 | 8.12k | reader++; |
991 | 8.12k | } |
992 | | |
993 | 5.26k | if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH && !(flags & DXF_VERTEX_FLAG_PART_OF_POLYFACE)) { |
994 | 530 | ASSIMP_LOG_WARN("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set"); |
995 | 530 | } |
996 | | |
997 | 5.26k | if (cnti) { |
998 | 1.59k | line.counts.push_back(cnti); |
999 | 3.71k | for (unsigned int i = 0; i < cnti; ++i) { |
1000 | | // IMPORTANT NOTE: POLYMESH indices are ONE-BASED |
1001 | 2.11k | if (indices[i] == 0) { |
1002 | 1.16k | ASSIMP_LOG_WARN("DXF: invalid vertex index, indices are one-based."); |
1003 | 1.16k | --line.counts.back(); |
1004 | | // Workaround to fix issue 2229 |
1005 | 1.16k | if (line.counts.back() == 0) { |
1006 | 692 | line.counts.pop_back(); |
1007 | 692 | } |
1008 | 1.16k | continue; |
1009 | 1.16k | } |
1010 | 954 | line.indices.push_back(indices[i]-1); |
1011 | 954 | } |
1012 | 3.66k | } else { |
1013 | 3.66k | line.positions.push_back(out); |
1014 | 3.66k | line.colors.push_back(clr); |
1015 | 3.66k | } |
1016 | 5.26k | } |
1017 | | |
1018 | | // ------------------------------------------------------------------------------------------------ |
1019 | 10.2k | void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output) { |
1020 | | // (note) this is also used for for parsing line entities, so we |
1021 | | // must handle the vertex_count == 2 case as well. |
1022 | | |
1023 | 10.2k | output.blocks.back().lines.push_back( std::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() ) ); |
1024 | 10.2k | DXF::PolyLine& line = *output.blocks.back().lines.back(); |
1025 | | |
1026 | 10.2k | aiVector3D vip[4]; |
1027 | 10.2k | aiColor4D clr = AI_DXF_DEFAULT_COLOR; |
1028 | | |
1029 | 10.2k | bool b[4] = {false,false,false,false}; |
1030 | 51.0k | while( !reader.End() ) { |
1031 | | |
1032 | | // next entity with a groupcode == 0 is probably already the next vertex or polymesh entity |
1033 | 51.0k | if (reader.GroupCode() == 0) { |
1034 | 10.2k | break; |
1035 | 10.2k | } |
1036 | 40.8k | switch (reader.GroupCode()) { |
1037 | | |
1038 | | // 8 specifies the layer |
1039 | 162 | case 8: |
1040 | 162 | line.layer = reader.Value(); |
1041 | 162 | break; |
1042 | | |
1043 | | // x position of the first corner |
1044 | 773 | case 10: |
1045 | 773 | vip[0].x = reader.ValueAsFloat(); |
1046 | 773 | b[2] = true; |
1047 | 773 | break; |
1048 | | |
1049 | | // y position of the first corner |
1050 | 0 | case 20: |
1051 | 0 | vip[0].y = reader.ValueAsFloat(); |
1052 | 0 | b[2] = true; |
1053 | 0 | break; |
1054 | | |
1055 | | // z position of the first corner |
1056 | 9.07k | case 30: |
1057 | 9.07k | vip[0].z = reader.ValueAsFloat(); |
1058 | 9.07k | b[2] = true; |
1059 | 9.07k | break; |
1060 | | |
1061 | | // x position of the second corner |
1062 | 1.06k | case 11: |
1063 | 1.06k | vip[1].x = reader.ValueAsFloat(); |
1064 | 1.06k | b[3] = true; |
1065 | 1.06k | break; |
1066 | | |
1067 | | // y position of the second corner |
1068 | 0 | case 21: |
1069 | 0 | vip[1].y = reader.ValueAsFloat(); |
1070 | 0 | b[3] = true; |
1071 | 0 | break; |
1072 | | |
1073 | | // z position of the second corner |
1074 | 9.50k | case 31: |
1075 | 9.50k | vip[1].z = reader.ValueAsFloat(); |
1076 | 9.50k | b[3] = true; |
1077 | 9.50k | break; |
1078 | | |
1079 | | // x position of the third corner |
1080 | 14 | case 12: |
1081 | 14 | vip[2].x = reader.ValueAsFloat(); |
1082 | 14 | b[0] = true; |
1083 | 14 | break; |
1084 | | |
1085 | | // y position of the third corner |
1086 | 11 | case 22: |
1087 | 11 | vip[2].y = reader.ValueAsFloat(); |
1088 | 11 | b[0] = true; |
1089 | 11 | break; |
1090 | | |
1091 | | // z position of the third corner |
1092 | 8.73k | case 32: |
1093 | 8.73k | vip[2].z = reader.ValueAsFloat(); |
1094 | 8.73k | b[0] = true; |
1095 | 8.73k | break; |
1096 | | |
1097 | | // x position of the fourth corner |
1098 | 4.15k | case 13: |
1099 | 4.15k | vip[3].x = reader.ValueAsFloat(); |
1100 | 4.15k | b[1] = true; |
1101 | 4.15k | break; |
1102 | | |
1103 | | // y position of the fourth corner |
1104 | 527 | case 23: |
1105 | 527 | vip[3].y = reader.ValueAsFloat(); |
1106 | 527 | b[1] = true; |
1107 | 527 | break; |
1108 | | |
1109 | | // z position of the fourth corner |
1110 | 350 | case 33: |
1111 | 350 | vip[3].z = reader.ValueAsFloat(); |
1112 | 350 | b[1] = true; |
1113 | 350 | break; |
1114 | | |
1115 | | // color |
1116 | 313 | case 62: |
1117 | 313 | clr = g_aclrDxfIndexColors[reader.ValueAsUnsignedInt() % AI_DXF_NUM_INDEX_COLORS]; |
1118 | 313 | break; |
1119 | 40.8k | }; |
1120 | | |
1121 | 40.8k | ++reader; |
1122 | 40.8k | } |
1123 | | |
1124 | | // the fourth corner may even be identical to the third, |
1125 | | // in this case we treat it as if it didn't exist. |
1126 | 10.2k | if (vip[3] == vip[2]) { |
1127 | 1.91k | b[1] = false; |
1128 | 1.91k | } |
1129 | | |
1130 | | // sanity checks to see if we got something meaningful |
1131 | 10.2k | if ((b[1] && !b[0]) || !b[2] || !b[3]) { |
1132 | 2.86k | ASSIMP_LOG_WARN("DXF: unexpected vertex setup in 3DFACE/LINE/FACE entity; ignoring"); |
1133 | 2.86k | output.blocks.back().lines.pop_back(); |
1134 | 2.86k | return; |
1135 | 2.86k | } |
1136 | | |
1137 | 7.42k | const unsigned int cnt = (2+(b[0]?1:0)+(b[1]?1:0)); |
1138 | 7.42k | line.counts.push_back(cnt); |
1139 | | |
1140 | 32.3k | for (unsigned int i = 0; i < cnt; ++i) { |
1141 | 24.9k | line.indices.push_back(static_cast<unsigned int>(line.positions.size())); |
1142 | 24.9k | line.positions.push_back(vip[i]); |
1143 | 24.9k | line.colors.push_back(clr); |
1144 | 24.9k | } |
1145 | 7.42k | } |
1146 | | |
1147 | | #endif // !! ASSIMP_BUILD_NO_DXF_IMPORTER |