aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ldraw/imp_ldraw_mpd.c
blob: a699f2a8ca22a0503225f3ebec235b482cffedac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* $Id$ */

/*
    libg3d - 3D object loading library

    Copyright (C) 2005-2009  Markus Dahms <mad@automagically.de>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#include <string.h>
#include <stdio.h>

#include <g3d/types.h>
#include <g3d/matrix.h>
#include <g3d/object.h>

#include "imp_ldraw_types.h"
#include "imp_ldraw_part.h"
#include "imp_ldraw_library.h"

static inline void ldraw_create_subpart(LDrawLibrary *lib, gchar *name,
	gchar *buffer, GSList **partsp)
{
	G3DStream *substream;
	LDrawPart *part;

#if DEBUG > 2
	g_debug("LDraw: adding sub-file %s to library", name);
#endif

	substream = g3d_stream_from_buffer((guint8 *)buffer, strlen(buffer),
		name, TRUE);
	if(substream == NULL) {
		g_warning("LDraw: failed to create stream for %s", name);
		return;
	}
	part = g_new0(LDrawPart, 1);
	part->name = g_ascii_strup(name, -1);
	part->stream = substream;

	ldraw_library_insert(lib, part->name, part);
	*partsp = g_slist_append(*partsp, part);
}

gboolean ldraw_mpd_load(G3DStream *stream, G3DModel *model,
	LDrawLibrary *lib)
{
	G3DObject *object = NULL;
	GSList *parts = NULL, *item;
	LDrawPart *part;
	gchar buffer[1024], name[256], *streambuf = NULL;
	gsize size;
	goffset off;
	G3DFloat m[16];

	while(!g3d_stream_eof(stream)) {
		memset(buffer, 0, 1024);
		g3d_stream_read_line(stream, buffer, 1023);
		if(strncmp(buffer, "0 FILE ", 7) == 0) {
			if(streambuf) {
				ldraw_create_subpart(lib, name, streambuf, &parts);
				streambuf = NULL;
			}
			memset(name, 0, 256);
			if(sscanf(buffer + 7, "%255s", name) == 1)
				streambuf = g_strdup("");
		} else if(strncmp(buffer, "0 NOFILE", 8) == 0) {
			if(streambuf) {
				ldraw_create_subpart(lib, name, streambuf, &parts);
				streambuf = NULL;
			}
			break;
		} else if(streambuf) {
			/* append line to buffer */
			size = strlen(buffer) + strlen(streambuf) + 1;
			off = strlen(streambuf);
			streambuf = g_realloc(streambuf, size * sizeof(gchar));
			strcpy(streambuf + off, buffer);
		}
	} /* !eof */

	if(streambuf)
		ldraw_create_subpart(lib, name, streambuf, &parts);

	if(parts) {
		part = parts->data;
		part->master = TRUE;
		object = ldraw_part_get_object(part, lib);
		if(object != NULL) {
			g3d_matrix_identity(m);
			g3d_matrix_rotate_xyz(0.0, 0.0, G_PI, m);
			g3d_object_transform(object, m);
			model->objects = g_slist_append(model->objects, object);
		}
	}

#if 1
	/* close open streams */
	for(item = parts; item != NULL; item = item->next) {
		part = item->data;
		if(part->stream) {
			g3d_stream_close(part->stream);
			part->stream = NULL;
		}
	}
#endif
	return (object != NULL);
}