Subversion Repositories Kolibri OS

Rev

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