Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7610 | IgorA | 1 | ; |
2 | ; Функции для преобразования файла *.stl в *.3ds |
||
3 | ; |
||
4 | ; Структура создаваемого файла *.3ds: |
||
5 | ; CHUNK_MAIN (40+n+v+f) |
||
6 | ; + CHUNK_OBJMESH (34+n+v+f) |
||
7 | ; + CHUNK_OBJBLOCK (28+n+v+f) |
||
8 | ; + CHUNK_TRIMESH (22+v+f) |
||
9 | ; + CHUNK_VERTLIST (8+v) |
||
10 | ; + CHUNK_FACELIST (8+f) |
||
11 | ; |
||
12 | ; в скобках указаны размеры блоков: |
||
13 | ; n - память для имени объекта |
||
14 | ; v - память для вершин |
||
15 | ; f - память для граней |
||
16 | |||
17 | ; Формат бинарного *.stl: |
||
18 | ; char[80] - заголовок |
||
19 | ; uint32 - число граней |
||
20 | ; для каждой грани: |
||
21 | ; float[3] - вектор нормали |
||
22 | ; float[9] - вершины 1,2,3 |
||
23 | ; uint16 - атрибуты |
||
24 | |||
25 | |||
26 | if lang eq ru |
||
27 | txt_err_stl_open: |
||
28 | db '"STL',13,10 |
||
29 | db 'Файл *.stl очень большой." -tW',0 |
||
30 | txt_err_stl_null_v: |
||
31 | db '"STL',13,10 |
||
32 | db 'Вершины не найдены." -tE',0 |
||
33 | else |
||
34 | txt_err_stl_open: |
||
35 | db '"STL',13,10 |
||
36 | db 'File *.stl is very large." -tW',0 |
||
37 | txt_err_stl_null_v: |
||
38 | db '"STL',13,10 |
||
39 | db 'Vertexes not found." -tE',0 |
||
40 | end if |
||
41 | |||
42 | ;output: |
||
43 | ; eax - указатель на сформированый файл 3ds (в случае неудачи 0) |
||
44 | ; ecx - размер сформированого файла 3ds |
||
45 | align 4 |
||
46 | proc convert_stl_3ds uses ebx edx edi esi, f_data:dword, f_size:dword |
||
47 | locals |
||
48 | c_mem dd ? ;память для преобразования (convert memory) |
||
49 | c_size dd ? ;размер памяти для преобразований (convert memory size) |
||
50 | vert_c dd ? ;число вершин (vertex count) |
||
51 | face_c dd ? ;число граней (faces count) |
||
52 | endl |
||
53 | xor eax,eax |
||
54 | mov esi,[f_data] |
||
55 | cmp dword[esi],'soli' |
||
56 | jne .bin_stl |
||
57 | cmp word[esi+4],'d ' |
||
58 | jne .bin_stl |
||
59 | |||
60 | jmp @f |
||
61 | .bin_stl: |
||
62 | ;проверяем файл на бинарный формат |
||
63 | mov ecx,[esi+80] |
||
64 | imul ecx,50 |
||
65 | add ecx,84 ;заголовок |
||
66 | cmp ecx,[f_size] |
||
67 | jne .no_stl |
||
68 | call convert_binary_stl |
||
69 | jmp .no_stl |
||
70 | @@: |
||
71 | |||
72 | ;в начале найдено 'solid ' |
||
73 | stdcall txt_next_line, 80 |
||
74 | |||
75 | mov eax,[f_data] |
||
76 | sub eax,esi |
||
77 | add eax,[f_size] |
||
78 | stdcall get_stl_vertex_count, esi,eax |
||
79 | or eax,eax |
||
80 | jnz @f |
||
81 | notify_window_run txt_err_stl_null_v |
||
82 | jmp .no_stl |
||
83 | @@: |
||
84 | cmp eax,0xffff |
||
85 | jle @f |
||
86 | notify_window_run txt_err_stl_open |
||
87 | mov eax,0xffff |
||
88 | @@: |
||
89 | |||
90 | mov [vert_c],eax |
||
91 | mov ecx,3 |
||
92 | xor edx,edx |
||
93 | div ecx |
||
94 | mov [face_c],eax |
||
95 | shl eax,3 |
||
96 | mov ecx,[vert_c] |
||
97 | imul ecx,12 |
||
98 | lea ecx,[ecx+eax+40] |
||
99 | lea edx,[esi-6] |
||
100 | sub edx,[f_data] |
||
101 | cmp edx,2 |
||
102 | jge @f |
||
103 | mov edx,2 ;минимальный размер для имени объекта |
||
104 | @@: |
||
105 | add ecx,edx ;for object name |
||
106 | mov [c_size],ecx |
||
107 | stdcall mem.Alloc,ecx |
||
108 | mov [c_mem],eax |
||
109 | mov ebx,eax |
||
110 | |||
111 | mov word[ebx],CHUNK_MAIN |
||
112 | mov dword[ebx+2],ecx |
||
113 | add ebx,6 |
||
114 | |||
115 | ;3d3d |
||
116 | mov word[ebx],CHUNK_OBJMESH |
||
117 | sub ecx,6 |
||
118 | mov dword[ebx+2],ecx |
||
119 | add ebx,6 |
||
120 | |||
121 | ;4000 |
||
122 | mov word[ebx],CHUNK_OBJBLOCK |
||
123 | sub ecx,6 |
||
124 | mov dword[ebx+2],ecx |
||
125 | add ebx,6 |
||
126 | |||
127 | push ecx esi |
||
128 | mov ecx,edx |
||
129 | mov edi,ebx |
||
130 | mov esi,[f_data] |
||
131 | add esi,6 ;пропускаем 'solid ' |
||
132 | rep movsb ;копируем имя объекта |
||
133 | mov byte[edi-1],0 |
||
134 | add ebx,edx |
||
135 | pop esi ecx |
||
136 | |||
137 | ;4100 |
||
138 | mov word[ebx],CHUNK_TRIMESH |
||
139 | sub ecx,6 |
||
140 | mov dword[ebx+2],ecx |
||
141 | add ebx,6 |
||
142 | |||
143 | ;4110 |
||
144 | mov word[ebx],CHUNK_VERTLIST |
||
145 | mov dword[ebx+2],8 ;+ число вершин * 12 |
||
146 | add ebx,6 |
||
147 | |||
148 | mov edx,ebx |
||
149 | mov word[edx],0 ;кол. вершин |
||
150 | add ebx,2 |
||
151 | finit |
||
152 | .cycle0: |
||
153 | call txt_ignore_space |
||
154 | cmp dword[esi],'face' |
||
155 | jne .end_v |
||
156 | stdcall txt_next_line, 80 |
||
157 | |||
158 | call txt_ignore_space |
||
159 | cmp dword[esi],'oute' |
||
160 | jne .end_v |
||
161 | stdcall txt_next_line, 80 |
||
162 | |||
163 | mov ecx,3 ;3 точки на 1 грань |
||
164 | @@: |
||
165 | stdcall stl_vertex_init, ebx |
||
166 | or eax,eax |
||
167 | jz .end_v |
||
168 | add ebx,12 |
||
169 | inc word[edx] |
||
170 | loop @b |
||
171 | |||
172 | mov eax,[vert_c] |
||
173 | cmp word[edx],ax |
||
174 | jge .end_v |
||
175 | call txt_ignore_space |
||
176 | cmp dword[esi],'endl' |
||
177 | jne .end_v |
||
178 | stdcall txt_next_line, 80 |
||
179 | |||
180 | call txt_ignore_space |
||
181 | cmp dword[esi],'endf' |
||
182 | jne .end_v |
||
183 | stdcall txt_next_line, 80 |
||
184 | jmp .cycle0 |
||
185 | .end_v: |
||
186 | |||
187 | movzx eax,word[edx] |
||
188 | imul eax,12 |
||
189 | add [edx-4],eax ;исправляем размер блока 4110 |
||
190 | |||
191 | ;4120 |
||
192 | mov word[ebx],CHUNK_FACELIST |
||
193 | mov ecx,[face_c] |
||
194 | mov edx,ecx |
||
195 | shl edx,3 ;кол. граней * 8 |
||
196 | add edx,8 |
||
197 | mov [ebx+2],edx |
||
198 | add ebx,6 |
||
199 | mov [ebx],cx ;кол. граней |
||
200 | add ebx,2 |
||
201 | xor eax,eax |
||
202 | @@: |
||
203 | mov [ebx],ax |
||
204 | inc eax |
||
205 | mov [ebx+2],ax |
||
206 | inc eax |
||
207 | mov [ebx+4],ax |
||
208 | inc eax |
||
209 | mov word[ebx+6],0 ;атрибуты |
||
210 | add ebx,8 |
||
211 | loop @b |
||
212 | |||
213 | mov eax,[c_mem] |
||
214 | mov ecx,[c_size] |
||
215 | .no_stl: |
||
216 | ret |
||
217 | endp |
||
218 | |||
219 | ;input: |
||
220 | ; esi - указатель на начало файла |
||
221 | ; ecx - размер файла |
||
222 | align 4 |
||
223 | proc convert_binary_stl |
||
224 | locals |
||
225 | c_mem dd ? ;память для преобразования (convert memory) |
||
226 | c_size dd ? ;размер памяти для преобразований (convert memory size) |
||
227 | vert_c dd ? ;число вершин (vertex count) |
||
228 | face_c dd ? ;число граней (faces count) |
||
229 | endl |
||
230 | mov eax,[esi+80] |
||
231 | or eax,eax |
||
232 | jnz @f |
||
233 | notify_window_run txt_err_stl_null_v |
||
234 | jmp .no_stl |
||
235 | @@: |
||
236 | cmp eax,0xffff/3 |
||
237 | jle @f |
||
238 | notify_window_run txt_err_stl_open |
||
239 | mov eax,0xffff/3 |
||
240 | @@: |
||
241 | |||
242 | mov [face_c],eax |
||
243 | mov ecx,eax |
||
244 | imul eax,3 |
||
245 | mov [vert_c],eax |
||
246 | shl ecx,3 |
||
247 | imul eax,12 |
||
248 | lea ecx,[ecx+eax+40+4] ;+4 размер для имени объекта |
||
249 | mov [c_size],ecx |
||
250 | stdcall mem.Alloc,ecx |
||
251 | mov [c_mem],eax |
||
252 | mov ebx,eax |
||
253 | |||
254 | mov word[ebx],CHUNK_MAIN |
||
255 | mov dword[ebx+2],ecx |
||
256 | add ebx,6 |
||
257 | |||
258 | ;3d3d |
||
259 | mov word[ebx],CHUNK_OBJMESH |
||
260 | sub ecx,6 |
||
261 | mov dword[ebx+2],ecx |
||
262 | add ebx,6 |
||
263 | |||
264 | ;4000 |
||
265 | mov word[ebx],CHUNK_OBJBLOCK |
||
266 | sub ecx,6 |
||
267 | mov dword[ebx+2],ecx |
||
268 | add ebx,6 |
||
269 | mov dword[ebx],'Stl' ;имя объекта |
||
270 | add ebx,4 |
||
271 | |||
272 | ;4100 |
||
273 | mov word[ebx],CHUNK_TRIMESH |
||
274 | sub ecx,6 |
||
275 | mov dword[ebx+2],ecx |
||
276 | add ebx,6 |
||
277 | |||
278 | ;4110 |
||
279 | mov word[ebx],CHUNK_VERTLIST |
||
280 | mov dword[ebx+2],8 ;+ число вершин * 12 |
||
281 | add ebx,6 |
||
282 | |||
283 | mov edx,ebx |
||
284 | mov ecx,[vert_c] |
||
285 | mov word[edx],cx ;кол. вершин |
||
286 | add ebx,2 |
||
287 | |||
288 | add esi,80+4+12 ;пропуск заголовка, числа граней, 1-го вектора нормалей |
||
289 | mov edi,ebx |
||
290 | mov eax,[face_c] |
||
291 | @@: ;цикл по граням |
||
292 | mov ecx,9 |
||
293 | rep movsd ;копируем координаты 3-х вершин |
||
294 | add esi,14 ;пропуск вектора нормалей и атрибутов |
||
295 | dec eax |
||
296 | jnz @b |
||
297 | mov ebx,edi |
||
298 | |||
299 | movzx eax,word[edx] |
||
300 | imul eax,12 |
||
301 | add [edx-4],eax ;исправляем размер блока 4110 |
||
302 | |||
303 | ;4120 |
||
304 | mov word[ebx],CHUNK_FACELIST |
||
305 | mov ecx,[face_c] |
||
306 | mov edx,ecx |
||
307 | shl edx,3 ;кол. граней * 8 |
||
308 | add edx,8 |
||
309 | mov [ebx+2],edx |
||
310 | add ebx,6 |
||
311 | mov [ebx],cx ;кол. граней |
||
312 | add ebx,2 |
||
313 | xor eax,eax |
||
314 | @@: |
||
315 | mov [ebx],ax |
||
316 | inc eax |
||
317 | mov [ebx+2],ax |
||
318 | inc eax |
||
319 | mov [ebx+4],ax |
||
320 | inc eax |
||
321 | mov word[ebx+6],0 ;атрибуты |
||
322 | add ebx,8 |
||
323 | loop @b |
||
324 | |||
325 | mov eax,[c_mem] |
||
326 | mov ecx,[c_size] |
||
327 | .no_stl: |
||
328 | ret |
||
329 | endp |
||
330 | |||
331 | ;output: |
||
332 | ; eax - vertex count |
||
333 | align 4 |
||
334 | proc get_stl_vertex_count uses ebx ecx edi, f_data:dword, f_size:dword |
||
335 | mov al,'v' |
||
336 | xor ebx,ebx |
||
337 | mov ecx,[f_size] |
||
338 | mov edi,[f_data] |
||
339 | .cycle0: |
||
340 | repne scasb |
||
341 | cmp dword[edi],'erte' |
||
342 | jne @f |
||
343 | inc ebx |
||
344 | add edi,4 |
||
345 | sub ecx,4 |
||
346 | cmp ecx,4 |
||
347 | jg .cycle0 |
||
348 | @@: |
||
349 | mov eax,ebx |
||
350 | ret |
||
351 | endp |
||
352 | |||
353 | ;input: |
||
354 | ; esi - input description text |
||
355 | ; ppoi - pointer to vertex struct |
||
356 | ;output: |
||
357 | ; eax - 0 (if error init) or 1 |
||
358 | ; esi - output description text |
||
359 | align 4 |
||
360 | proc stl_vertex_init uses ebx ecx edi, ppoi:dword |
||
361 | call txt_ignore_space |
||
362 | cmp dword[esi],'vert' |
||
363 | jne .err_init |
||
364 | cmp word[esi+4],'ex' |
||
365 | jne .err_init |
||
366 | add esi,6 |
||
367 | mov ebx,[ppoi] |
||
368 | |||
369 | call txt_copy_data |
||
370 | call String_to_DoubleFloat |
||
371 | fld qword[Data_Double] |
||
372 | fstp dword[ebx] ;coord X |
||
373 | |||
374 | call txt_copy_data |
||
375 | call String_to_DoubleFloat |
||
376 | fld qword[Data_Double] |
||
377 | fstp dword[ebx+4] ;coord X |
||
378 | |||
379 | call txt_copy_data |
||
380 | call String_to_DoubleFloat |
||
381 | fld qword[Data_Double] |
||
382 | fstp dword[ebx+8] ;coord Z |
||
383 | |||
384 | stdcall txt_next_line, 80 |
||
385 | jmp @f |
||
386 | .err_init: |
||
387 | xor eax,eax |
||
388 | jmp .end_f |
||
389 | @@: |
||
390 | xor eax,eax |
||
391 | inc eax |
||
392 | .end_f: |
||
393 | ret |
||
394 | endp |
||
395 | |||
396 | ;input: |
||
397 | ; esi - указатель на начало строки с пробелами |
||
398 | ;output: |
||
399 | ; al - destroy |
||
400 | ; ecx - destroy |
||
401 | ; esi - указатель на первый непробельный символ |
||
402 | align 4 |
||
403 | txt_ignore_space: |
||
404 | mov ecx,64 ;защита от зацикливания |
||
405 | @@: |
||
406 | lodsb |
||
407 | cmp al,' ' |
||
408 | jne @f |
||
409 | loop @b |
||
410 | @@: |
||
411 | dec esi |
||
412 | ret |
||
413 | |||
414 | ;input: |
||
415 | ; esi - указатель на строку с числом (пробелы в начале строки игнорируються) |
||
416 | ;output: |
||
417 | ; al - destroy |
||
418 | ; ecx - destroy |
||
419 | ; edi - destroy |
||
420 | ; esi - указатель на конец копированного числа |
||
421 | ; Data_String - строка с числом из esi |
||
422 | align 4 |
||
423 | txt_copy_data: |
||
424 | call txt_ignore_space |
||
425 | mov ecx,32 |
||
426 | mov edi,esi |
||
427 | @@: |
||
428 | lodsb |
||
429 | or al,al |
||
430 | jz @f |
||
431 | cmp al,' ' |
||
432 | je @f |
||
433 | cmp al,13 |
||
434 | je @f |
||
435 | loop @b |
||
436 | @@: |
||
437 | mov esi,edi |
||
438 | sub ecx,32 |
||
439 | neg ecx |
||
440 | mov edi,Data_String |
||
441 | rep movsb |
||
442 | mov byte[edi],0 |
||
443 | ret |
||
444 | |||
445 | ;input: |
||
446 | ; esi - text pointer |
||
447 | align 4 |
||
448 | proc txt_next_line uses eax ecx edi, mlen:dword |
||
449 | mov al,13 |
||
450 | mov ecx,[mlen] |
||
451 | mov edi,esi |
||
452 | repne scasb |
||
453 | cmp byte[edi],10 |
||
454 | jne @f |
||
455 | inc edi |
||
456 | @@: |
||
457 | mov esi,edi |
||
458 | ret |
||
459 | endp |