~vibhavp/ubuntu/raring/libg3d/add-autopkgtest

« back to all changes in this revision

Viewing changes to .pc/fix-memory-leaks-2.patch/plugins/import/imp_obj/imp_obj.c

  • Committer: Bazaar Package Importer
  • Author(s): Sven Eckelmann
  • Date: 2010-06-28 23:51:12 UTC
  • Revision ID: james.westby@ubuntu.com-20100628235112-lykpvnz82k8kh7ms
Tags: 0.0.8-10
* debian/patches:
  - Add fix-memory-leaks-2.patch, Fix memory leaks (Closes: #570084)
    Thanks Picca Frederic-Emmanuel <picca@synchrotron-soleil.fr>
  - Add pc-glib2-private.patch, Only require glib2.0 for header files when
    using pkg-config
* Remove outdated README.source
* debian/rules:
  - Enable parallel builds using dh's --parallel
  - Inform about missing installed files using dh's --list-missing
* Upgraded to policy 3.9.0, no changes required

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id$ */
 
2
 
 
3
/*
 
4
    libg3d - 3D object loading library
 
5
 
 
6
    Copyright (C) 2005-2009  Markus Dahms <mad@automagically.de>
 
7
 
 
8
    This library is free software; you can redistribute it and/or
 
9
    modify it under the terms of the GNU Lesser General Public
 
10
    License as published by the Free Software Foundation; either
 
11
    version 2.1 of the License, or (at your option) any later version.
 
12
 
 
13
    This library is distributed in the hope that it will be useful,
 
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
    Lesser General Public License for more details.
 
17
 
 
18
    You should have received a copy of the GNU Lesser General Public
 
19
    License along with this library; if not, write to the Free Software
 
20
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
21
*/
 
22
 
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <errno.h>
 
27
#include <locale.h>
 
28
 
 
29
#include <g3d/context.h>
 
30
#include <g3d/types.h>
 
31
#include <g3d/material.h>
 
32
#include <g3d/face.h>
 
33
#include <g3d/stream.h>
 
34
 
 
35
#define OBJ_USE_GROUPING 0
 
36
 
 
37
typedef struct {
 
38
        goffset goff;
 
39
        goffset ooff;
 
40
        G3DObject *object;
 
41
} ObjGroupOffset;
 
42
 
 
43
static gboolean obj_tryloadmat(G3DModel *model, const gchar *filename);
 
44
static G3DMaterial *obj_usemat(G3DModel *model, const gchar *matname);
 
45
 
 
46
static G3DObject *obj_object_by_name(G3DModel *model, const gchar *name);
 
47
#if OBJ_USE_GROUPING
 
48
static G3DObject *obj_get_offset(GSList *group_list, guint32 *voffp,
 
49
        guint32 index, G3DObject *defobj);
 
50
#endif
 
51
 
 
52
gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream,
 
53
        G3DModel *model, gpointer user_data)
 
54
{
 
55
        gchar line[2048], matname[128], matfile[1024];
 
56
        gchar *filename;
 
57
        G3DObject *object = NULL;
 
58
        G3DMaterial *material = NULL;
 
59
        gfloat pcnt, prev_pcnt = 0.0;
 
60
        gdouble x,y,z;
 
61
        guint32 num_v, v_off = 1, v_cnt = 0;
 
62
#if OBJ_USE_GROUPING
 
63
        gchar oname[128];
 
64
        ObjGroupOffset *grpoff;
 
65
        GSList *group_list = NULL;
 
66
#endif
 
67
        goffset global_vertex_count = 0;
 
68
 
 
69
        setlocale(LC_NUMERIC, "C");
 
70
        filename = g3d_stream_get_uri(stream);
 
71
 
 
72
        strncpy(matfile, filename, strlen(filename) - 3);
 
73
        matfile[strlen(filename)-3] = '\0';
 
74
        strcat(matfile, "mtl");
 
75
        obj_tryloadmat(model, matfile);
 
76
 
 
77
        object = obj_object_by_name(model, "(default)");
 
78
 
 
79
        while(!g3d_stream_eof(stream))
 
80
        {
 
81
                memset(line, 0, 2048);
 
82
                g3d_stream_read_line(stream, line, 2048);
 
83
                /* remove leading and trailing whitespace characters */
 
84
                g_strstrip(line);
 
85
                if(strlen(line) > 0) {
 
86
                        switch(line[0]) {
 
87
                                case '#':
 
88
                                        continue;
 
89
                                        break;
 
90
 
 
91
                                case 'g': /* group */
 
92
#if OBJ_USE_GROUPING
 
93
                                        if(strlen(line) == 1)
 
94
                                                strcpy(oname, "(default)");
 
95
                                        else
 
96
                                                sscanf(line, "g %s", oname);
 
97
 
 
98
                                        material = obj_usemat(model, oname);
 
99
 
 
100
                                        grpoff = g_new0(ObjGroupOffset, 1);
 
101
                                        grpoff->object = obj_object_by_name(model, oname);
 
102
                                        grpoff->goff = global_vertex_count;
 
103
                                        grpoff->ooff = grpoff->object->vertex_count;
 
104
                                        group_list = g_slist_append(group_list, grpoff);
 
105
#if DEBUG > 0
 
106
                                        g_debug("[g] 0x%08x / 0x%08x: \"%s\"",
 
107
                                                (guint32)grpoff->goff,
 
108
                                                (guint32)grpoff->ooff, grpoff->object->name);
 
109
#endif
 
110
                                        object = grpoff->object;
 
111
                                        v_cnt = grpoff->ooff;
 
112
#endif
 
113
                                        break;
 
114
 
 
115
                                case 'l': /* line */
 
116
                                        break;
 
117
 
 
118
                                case 'o': /* object */
 
119
                                        break;
 
120
 
 
121
                                case 'v': /* vertex */
 
122
                                        if(strncmp(line, "vn ", 3) == 0)
 
123
                                        {
 
124
                                                /* normal ? */
 
125
                                        }
 
126
                                        else if(strncmp(line, "vt ", 3) == 0)
 
127
                                        {
 
128
                                                /* ?? */
 
129
                                        }
 
130
                                        else if(sscanf(line, "v %lf %lf %lf", &x, &y, &z) == 3)
 
131
                                        {
 
132
                                                object->vertex_count ++;
 
133
                                                object->vertex_data = g_realloc(object->vertex_data,
 
134
                                                        object->vertex_count * 3 * sizeof(gfloat));
 
135
                                                object->vertex_data[v_cnt * 3 + 0] = x;
 
136
                                                object->vertex_data[v_cnt * 3 + 1] = y;
 
137
                                                object->vertex_data[v_cnt * 3 + 2] = z;
 
138
 
 
139
                                                v_cnt ++;
 
140
                                                global_vertex_count ++;
 
141
                                        }
 
142
                                        else g_warning("parse error in line: %s", line);
 
143
                                        break;
 
144
 
 
145
                                case 'f': /* face */
 
146
                                        if(strncmp("f ", line, 2) == 0)
 
147
                                        {
 
148
                                                G3DFace *face;
 
149
                                                gchar **vertex, **vstrs = g_strsplit(line, " ", 0);
 
150
                                                int i;
 
151
 
 
152
                                                num_v = 0;
 
153
                                                face = g_new0(G3DFace, 1);
 
154
                                                if(material != NULL)
 
155
                                                        face->material = material;
 
156
                                                else face->material =
 
157
                                                        g_slist_nth_data(object->materials, 0);
 
158
 
 
159
                                                /* find number of vertices in line */
 
160
                                                vertex = vstrs;
 
161
                                                while(*vertex != NULL) { num_v++; vertex++; }
 
162
                                                face->vertex_count = num_v - 1;
 
163
 
 
164
                                                /* next one if # of vertices < 3 */
 
165
                                                if(face->vertex_count < 3) {
 
166
                                                        g3d_face_free(face);
 
167
                                                        continue;
 
168
                                                }
 
169
 
 
170
                                                /* calculate object-local vertex offset, indices
 
171
                                                 * in .obj files are absolute */
 
172
                                                i = strtol(vstrs[1], NULL, 10);
 
173
#if OBJ_USE_GROUPING
 
174
                                                object = obj_get_offset(group_list, &v_off,
 
175
                                                        (i < 0) ? global_vertex_count - i - 1 : i,
 
176
                                                        object);
 
177
#else
 
178
                                                v_off = 0;
 
179
#endif
 
180
                                                if(object == NULL) {
 
181
                                                        g_warning("error: face before object");
 
182
                                                        g3d_face_free(face);
 
183
                                                        return FALSE;
 
184
                                                }
 
185
 
 
186
                                                /* read vertices */
 
187
                                                face->vertex_indices = g_new0(guint32, num_v - 1);
 
188
                                                for(i = 1; i < num_v; i ++) {
 
189
                                                        gint32 index = strtol(vstrs[i], NULL, 10);
 
190
 
 
191
                                                        if(index < 0)
 
192
                                                                face->vertex_indices[i - 1] =
 
193
                                                                        global_vertex_count + index + v_off - 1;
 
194
                                                        else
 
195
                                                                face->vertex_indices[i - 1] = MIN(
 
196
                                                                        (index - 1) + v_off,
 
197
                                                                        object->vertex_count - 1);
 
198
                                                }
 
199
                                                g_strfreev(vstrs);
 
200
                                                object->faces = g_slist_prepend(object->faces, face);
 
201
                                        }
 
202
                                        else
 
203
                                                g_warning("parse error in line: %s", line);
 
204
                                        break;
 
205
 
 
206
                                case 'u': /* usemat? */
 
207
                                case 'm':
 
208
                                case 's':
 
209
                                        if(sscanf(line, "usemtl %s", matname) == 1) {
 
210
                                                material = obj_usemat(model, matname);
 
211
                                        } else if(sscanf(line, "mtllib %s", matfile) == 1) {
 
212
                                                /* loads external material library */
 
213
                                                if(obj_tryloadmat(model, matfile) != TRUE)
 
214
                                                        g_warning("error loading material library '%s'",
 
215
                                                                matfile);
 
216
                                        }
 
217
                                        break;
 
218
                                default:
 
219
#if DEBUG > 0
 
220
                                        g_debug("unknown type of line: %s", line);
 
221
#endif
 
222
                                        break;
 
223
                        }
 
224
                }
 
225
 
 
226
#if 1
 
227
                pcnt = (gfloat)g3d_stream_tell(stream) /
 
228
                        (gfloat)g3d_stream_size(stream);
 
229
                if((pcnt - prev_pcnt) > 0.01) {
 
230
                        prev_pcnt = pcnt;
 
231
                        g3d_context_update_progress_bar(context, pcnt, TRUE);
 
232
                }
 
233
#endif
 
234
                g3d_context_update_interface(context);
 
235
        } /* !eof(stream) */
 
236
        return TRUE;
 
237
}
 
238
 
 
239
gchar *plugin_description(void)
 
240
{
 
241
        return g_strdup(
 
242
                "Import plugin for Maya .obj files\n");
 
243
}
 
244
 
 
245
gchar **plugin_extensions(void)
 
246
{
 
247
        return g_strsplit("obj", ":", 0);
 
248
}
 
249
 
 
250
/*****************************************************************************/
 
251
 
 
252
/*****************************************************************************/
 
253
/* material file ops                                                         */
 
254
/*****************************************************************************/
 
255
 
 
256
int obj_tryloadmat(G3DModel *model, const char *filename)
 
257
{
 
258
        FILE *f;
 
259
        G3DMaterial *material = NULL;
 
260
 
 
261
        f = fopen(filename, "r");
 
262
        if(f == NULL) {
 
263
#if DEBUG > 1
 
264
                g_warning("obj_tryloadmat: loading '%s' failed: %s", filename,
 
265
                        strerror(errno));
 
266
#endif
 
267
                return FALSE;
 
268
        }
 
269
#if DEBUG > 0
 
270
        g_debug("loading material library %s", filename);
 
271
#endif
 
272
        while(!feof(f)) {
 
273
                char line[2048];
 
274
                float r,g,b, t1,t2, ni;
 
275
                int tf, ns, il;
 
276
 
 
277
                fgets(line, 2048, f);
 
278
                g_strstrip(line);
 
279
                if(strlen(line))
 
280
                {
 
281
                        char mname[128];
 
282
 
 
283
                        if(line[0] == '#') continue;   /* comments */
 
284
                        if(line[0] == '\n') continue;  /* empty lines */
 
285
 
 
286
                        if(sscanf(line, "newmtl %s", mname) == 1)
 
287
                        {
 
288
                                /* new material */
 
289
                                material = g3d_material_new();
 
290
                                material->name = g_strdup(mname);
 
291
                                model->materials = g_slist_append(model->materials, material);
 
292
                        }
 
293
                        else if(sscanf(line, " Kd %f %f %f", &r, &g, &b) == 3)
 
294
                        {
 
295
                                /* material color? */
 
296
                                if(material != NULL)
 
297
                                {
 
298
                                        material->r = r;
 
299
                                        material->g = g;
 
300
                                        material->b = b;
 
301
                                }
 
302
                        }
 
303
                        else if(sscanf(line, " Ks %f %f %f", &r, &g, &b) == 3)
 
304
                        {
 
305
                                /* ?? */
 
306
                        }
 
307
                        else if(sscanf(line, " Tf %f %f %d", &t1, &t2, &tf) == 3)
 
308
                        {
 
309
                                /* transparency ?? */
 
310
                                if(material != NULL)
 
311
                                {
 
312
                                        if(tf == 1) material->a = 1.0 - t1;
 
313
                                }
 
314
                        }
 
315
                        else if(sscanf(line, " Ns %d Ni %f", &ns, &ni) == 2)
 
316
                        {
 
317
                                /* ?? */
 
318
                        }
 
319
                        else if(sscanf(line, " illum %d", &il) == 1)
 
320
                        {
 
321
                                /* ?? */
 
322
                        }
 
323
                        else {
 
324
#if DEBUG > 0
 
325
                                g_warning("unknown type of line: %s", line);
 
326
#endif
 
327
                        }
 
328
                }
 
329
        } /* !feof */
 
330
        return TRUE;
 
331
}
 
332
 
 
333
G3DMaterial *obj_usemat(G3DModel *model, const gchar *matname)
 
334
{
 
335
        /* sets new active material from named list */
 
336
        GSList *mlist = model->materials;
 
337
        while(mlist != NULL)
 
338
        {
 
339
                G3DMaterial *mat = (G3DMaterial*)mlist->data;
 
340
                if(strcmp(matname, mat->name) == 0)
 
341
                {
 
342
                        return mat;
 
343
                }
 
344
                mlist = mlist->next;
 
345
        }
 
346
 
 
347
        return NULL;
 
348
}
 
349
 
 
350
static G3DObject *obj_object_by_name(G3DModel *model, const gchar *name)
 
351
{
 
352
        G3DObject *object;
 
353
        G3DMaterial *material;
 
354
        GSList *oitem;
 
355
 
 
356
#if DEBUG > 4
 
357
        g_debug("looking for object '%s'", name);
 
358
#endif
 
359
 
 
360
        for(oitem = model->objects; oitem != NULL; oitem = oitem->next) {
 
361
                object = oitem->data;
 
362
                if(strcmp(object->name, name) == 0)
 
363
                        return object;
 
364
        }
 
365
 
 
366
        material = g3d_material_new();
 
367
        material->name = g_strdup("(default material)");
 
368
 
 
369
        object = g_new0(G3DObject, 1);
 
370
        object->name = g_strdup(name);
 
371
        object->materials = g_slist_append(object->materials, material);
 
372
        model->objects = g_slist_append(model->objects, object);
 
373
 
 
374
        return object;
 
375
}
 
376
 
 
377
#if OBJ_USE_GROUPING
 
378
static G3DObject *obj_get_offset(GSList *group_list, guint32 *voffp,
 
379
        guint32 index, G3DObject *defobj)
 
380
{
 
381
        GSList *leitem, *gitem;
 
382
        ObjGroupOffset *grpoff;
 
383
 
 
384
        for(leitem = gitem = group_list; gitem != NULL; gitem = gitem->next) {
 
385
                grpoff = gitem->data;
 
386
 
 
387
                /* this one is too big */
 
388
                if(grpoff->goff > index) {
 
389
                        grpoff = leitem->data;
 
390
                        *voffp = grpoff->ooff - grpoff->goff;
 
391
#if DEBUG > 0
 
392
                        g_debug("[o]: i=%-6d, go=%-6d, oo=%-6d, vo=%-6d (%s, %d vtxs)",
 
393
                                index, (guint32)grpoff->goff, (guint32)grpoff->ooff, *voffp,
 
394
                                grpoff->object->name, grpoff->object->vertex_count);
 
395
#endif
 
396
                        return grpoff->object;
 
397
                }
 
398
                leitem = gitem;
 
399
        }
 
400
 
 
401
        *voffp = 0;
 
402
        return defobj;
 
403
}
 
404
#endif
 
405