+++ /dev/null
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program 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 program 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 program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: file.c,v 1.23 2005/01/11 10:20:36 madmac Exp $
- */
-#define LIB3DS_EXPORT
-#include <lib3ds/file.h>
-#include <lib3ds/chunk.h>
-#include <lib3ds/io.h>
-#include <lib3ds/material.h>
-#include <lib3ds/mesh.h>
-#include <lib3ds/camera.h>
-#include <lib3ds/light.h>
-#include <lib3ds/node.h>
-#include <lib3ds/vector.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#ifdef WITH_DMALLOC
-#include <dmalloc.h>
-#endif
-
-
-
-/*!
- * \defgroup file Files
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-static Lib3dsBool
-fileio_error_func(void *self)
-{
- FILE *f = (FILE*)self;
- return(ferror(f)!=0);
-}
-
-
-static long
-fileio_seek_func(void *self, long offset, Lib3dsIoSeek origin)
-{
- FILE *f = (FILE*)self;
- int o;
- switch (origin) {
- case LIB3DS_SEEK_SET:
- o = SEEK_SET;
- break;
- case LIB3DS_SEEK_CUR:
- o = SEEK_CUR;
- break;
- case LIB3DS_SEEK_END:
- o = SEEK_END;
- break;
- default:
- ASSERT(0);
- return(0);
- }
- return (fseek(f, offset, o));
-}
-
-
-static long
-fileio_tell_func(void *self)
-{
- FILE *f = (FILE*)self;
- return(ftell(f));
-}
-
-
-static int
-fileio_read_func(void *self, Lib3dsByte *buffer, int size)
-{
- FILE *f = (FILE*)self;
- return(fread(buffer, 1, size, f));
-}
-
-
-static int
-fileio_write_func(void *self, const Lib3dsByte *buffer, int size)
-{
- FILE *f = (FILE*)self;
- return(fwrite(buffer, 1, size, f));
-}
-
-
-/*!
- * Loads a .3DS file from disk into memory.
- *
- * \param filename The filename of the .3DS file
- *
- * \return A pointer to the Lib3dsFile structure containing the
- * data of the .3DS file.
- * If the .3DS file can not be loaded NULL is returned.
- *
- * \note To free the returned structure use lib3ds_free.
- *
- * \see lib3ds_file_save
- * \see lib3ds_file_new
- * \see lib3ds_file_free
- *
- * \ingroup file
- */
-Lib3dsFile*
-lib3ds_file_load(const char *filename)
-{
- FILE *f;
- Lib3dsFile *file;
- Lib3dsIo *io;
-
-
- f = fopen(filename, "rb");
- if (!f) {
- return(0);
- }
- file = lib3ds_file_new();
- if (!file) {
- fclose(f);
- return(0);
- }
- io = lib3ds_io_new(
- f,
- fileio_error_func,
- fileio_seek_func,
- fileio_tell_func,
- fileio_read_func,
- fileio_write_func
- );
- if (!io) {
- lib3ds_file_free(file);
- fclose(f);
- return(0);
- }
-
- if (!lib3ds_file_read(file, io)) {
- free(file);
- fclose(f);
- return(0);
- }
-
- lib3ds_io_free(io);
- fclose(f);
- return(file);
-}
-
-
-/*!
- * Saves a .3DS file from memory to disk.
- *
- * \param file A pointer to a Lib3dsFile structure containing the
- * the data that should be stored.
- * \param filename The filename of the .3DS file to store the data in.
- *
- * \return TRUE on success, FALSE otherwise.
- *
- * \see lib3ds_file_load
- *
- * \ingroup file
- */
-Lib3dsBool
-lib3ds_file_save(Lib3dsFile *file, const char *filename)
-{
- FILE *f;
- Lib3dsIo *io;
- Lib3dsBool result;
-
- f = fopen(filename, "wb");
- if (!f) {
- return(LIB3DS_FALSE);
- }
- io = lib3ds_io_new(
- f,
- fileio_error_func,
- fileio_seek_func,
- fileio_tell_func,
- fileio_read_func,
- fileio_write_func
- );
- if (!io) {
- fclose(f);
- return LIB3DS_FALSE;
- }
-
- result = lib3ds_file_write(file, io);
-
- fclose(f);
-
- lib3ds_io_free(io);
- return(result);
-}
-
-
-/*!
- * Creates and returns a new, empty Lib3dsFile object.
- *
- * \return A pointer to the Lib3dsFile structure.
- * If the structure cannot be allocated, NULL is returned.
- *
- * \ingroup file
- */
-Lib3dsFile*
-lib3ds_file_new()
-{
- Lib3dsFile *file;
-
- file=(Lib3dsFile*)calloc(sizeof(Lib3dsFile),1);
- if (!file) {
- return(0);
- }
- file->mesh_version=3;
- file->master_scale=1.0f;
- file->keyf_revision=5;
- strcpy(file->name, "LIB3DS");
-
- file->frames=100;
- file->segment_from=0;
- file->segment_to=100;
- file->current_frame=0;
-
- return(file);
-}
-
-
-/*!
- * Free a Lib3dsFile object and all of its resources.
- *
- * \param file The Lib3dsFile object to be freed.
- *
- * \ingroup file
- */
-void
-lib3ds_file_free(Lib3dsFile* file)
-{
- ASSERT(file);
- lib3ds_viewport_set_views(&file->viewport,0);
- {
- Lib3dsMaterial *p,*q;
-
- for (p=file->materials; p; p=q) {
- q=p->next;
- lib3ds_material_free(p);
- }
- file->materials=0;
- }
- {
- Lib3dsCamera *p,*q;
-
- for (p=file->cameras; p; p=q) {
- q=p->next;
- lib3ds_camera_free(p);
- }
- file->cameras=0;
- }
- {
- Lib3dsLight *p,*q;
-
- for (p=file->lights; p; p=q) {
- q=p->next;
- lib3ds_light_free(p);
- }
- file->lights=0;
- }
- {
- Lib3dsMesh *p,*q;
-
- for (p=file->meshes; p; p=q) {
- q=p->next;
- lib3ds_mesh_free(p);
- }
- file->meshes=0;
- }
- {
- Lib3dsNode *p,*q;
-
- for (p=file->nodes; p; p=q) {
- q=p->next;
- lib3ds_node_free(p);
- }
- }
- free(file);
-}
-
-
-/*!
- * Evaluate all of the nodes in this Lib3dsFile object.
- *
- * \param file The Lib3dsFile object to be evaluated.
- * \param t time value, between 0. and file->frames
- *
- * \see lib3ds_node_eval
- *
- * \ingroup file
- */
-void
-lib3ds_file_eval(Lib3dsFile *file, Lib3dsFloat t)
-{
- Lib3dsNode *p;
-
- for (p=file->nodes; p!=0; p=p->next) {
- lib3ds_node_eval(p, t);
- }
-}
-
-
-static Lib3dsBool
-named_object_read(Lib3dsFile *file, Lib3dsIo *io)
-{
- Lib3dsChunk c;
- char name[64];
- Lib3dsWord chunk;
-
- if (!lib3ds_chunk_read_start(&c, LIB3DS_NAMED_OBJECT, io)) {
- return(LIB3DS_FALSE);
- }
- if (!lib3ds_io_read_string(io, name, 64)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_dump_info(" NAME=%s", name);
- lib3ds_chunk_read_tell(&c, io);
-
- while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
- switch (chunk) {
- case LIB3DS_N_TRI_OBJECT:
- {
- Lib3dsMesh *mesh;
-
- mesh=lib3ds_mesh_new(name);
- if (!mesh) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_mesh_read(mesh, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_mesh(file, mesh);
- }
- break;
- case LIB3DS_N_CAMERA:
- {
- Lib3dsCamera *camera;
-
- camera=lib3ds_camera_new(name);
- if (!camera) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_camera_read(camera, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_camera(file, camera);
- }
- break;
- case LIB3DS_N_DIRECT_LIGHT:
- {
- Lib3dsLight *light;
-
- light=lib3ds_light_new(name);
- if (!light) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_light_read(light, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_light(file, light);
- }
- break;
- default:
- lib3ds_chunk_unknown(chunk);
- }
- }
-
- lib3ds_chunk_read_end(&c, io);
- return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-ambient_read(Lib3dsFile *file, Lib3dsIo *io)
-{
- Lib3dsChunk c;
- Lib3dsWord chunk;
- Lib3dsBool have_lin=LIB3DS_FALSE;
-
- if (!lib3ds_chunk_read_start(&c, LIB3DS_AMBIENT_LIGHT, io)) {
- return(LIB3DS_FALSE);
- }
-
- while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
- switch (chunk) {
- case LIB3DS_LIN_COLOR_F:
- {
- int i;
- for (i=0; i<3; ++i) {
- file->ambient[i]=lib3ds_io_read_float(io);
- }
- }
- have_lin=LIB3DS_TRUE;
- break;
- case LIB3DS_COLOR_F:
- {
- /* gamma corrected color chunk
- replaced in 3ds R3 by LIN_COLOR_24 */
- if (!have_lin) {
- int i;
- for (i=0; i<3; ++i) {
- file->ambient[i]=lib3ds_io_read_float(io);
- }
- }
- }
- break;
- default:
- lib3ds_chunk_unknown(chunk);
- }
- }
-
- lib3ds_chunk_read_end(&c, io);
- return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-mdata_read(Lib3dsFile *file, Lib3dsIo *io)
-{
- Lib3dsChunk c;
- Lib3dsWord chunk;
-
- if (!lib3ds_chunk_read_start(&c, LIB3DS_MDATA, io)) {
- return(LIB3DS_FALSE);
- }
-
- while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
- switch (chunk) {
- case LIB3DS_MESH_VERSION:
- {
- file->mesh_version=lib3ds_io_read_intd(io);
- }
- break;
- case LIB3DS_MASTER_SCALE:
- {
- file->master_scale=lib3ds_io_read_float(io);
- }
- break;
- case LIB3DS_SHADOW_MAP_SIZE:
- case LIB3DS_LO_SHADOW_BIAS:
- case LIB3DS_HI_SHADOW_BIAS:
- case LIB3DS_SHADOW_SAMPLES:
- case LIB3DS_SHADOW_RANGE:
- case LIB3DS_SHADOW_FILTER:
- case LIB3DS_RAY_BIAS:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_shadow_read(&file->shadow, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- case LIB3DS_VIEWPORT_LAYOUT:
- case LIB3DS_DEFAULT_VIEW:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_viewport_read(&file->viewport, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- case LIB3DS_O_CONSTS:
- {
- int i;
- for (i=0; i<3; ++i) {
- file->construction_plane[i]=lib3ds_io_read_float(io);
- }
- }
- break;
- case LIB3DS_AMBIENT_LIGHT:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!ambient_read(file, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- case LIB3DS_BIT_MAP:
- case LIB3DS_SOLID_BGND:
- case LIB3DS_V_GRADIENT:
- case LIB3DS_USE_BIT_MAP:
- case LIB3DS_USE_SOLID_BGND:
- case LIB3DS_USE_V_GRADIENT:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_background_read(&file->background, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- case LIB3DS_FOG:
- case LIB3DS_LAYER_FOG:
- case LIB3DS_DISTANCE_CUE:
- case LIB3DS_USE_FOG:
- case LIB3DS_USE_LAYER_FOG:
- case LIB3DS_USE_DISTANCE_CUE:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_atmosphere_read(&file->atmosphere, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- case LIB3DS_MAT_ENTRY:
- {
- Lib3dsMaterial *material;
-
- material=lib3ds_material_new();
- if (!material) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_material_read(material, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_material(file, material);
- }
- break;
- case LIB3DS_NAMED_OBJECT:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!named_object_read(file, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- default:
- lib3ds_chunk_unknown(chunk);
- }
- }
-
- lib3ds_chunk_read_end(&c, io);
- return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-kfdata_read(Lib3dsFile *file, Lib3dsIo *io)
-{
- Lib3dsChunk c;
- Lib3dsWord chunk;
-
- if (!lib3ds_chunk_read_start(&c, LIB3DS_KFDATA, io)) {
- return(LIB3DS_FALSE);
- }
-
- while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
- switch (chunk) {
- case LIB3DS_KFHDR:
- {
- file->keyf_revision=lib3ds_io_read_word(io);
- if (!lib3ds_io_read_string(io, file->name, 12+1)) {
- return(LIB3DS_FALSE);
- }
- file->frames=lib3ds_io_read_intd(io);
- }
- break;
- case LIB3DS_KFSEG:
- {
- file->segment_from=lib3ds_io_read_intd(io);
- file->segment_to=lib3ds_io_read_intd(io);
- }
- break;
- case LIB3DS_KFCURTIME:
- {
- file->current_frame=lib3ds_io_read_intd(io);
- }
- break;
- case LIB3DS_VIEWPORT_LAYOUT:
- case LIB3DS_DEFAULT_VIEW:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_viewport_read(&file->viewport_keyf, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- case LIB3DS_AMBIENT_NODE_TAG:
- {
- Lib3dsNode *node;
-
- node=lib3ds_node_new_ambient();
- if (!node) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_node_read(node, file, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_node(file, node);
- }
- break;
- case LIB3DS_OBJECT_NODE_TAG:
- {
- Lib3dsNode *node;
-
- node=lib3ds_node_new_object();
- if (!node) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_node_read(node, file, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_node(file, node);
- }
- break;
- case LIB3DS_CAMERA_NODE_TAG:
- {
- Lib3dsNode *node;
-
- node=lib3ds_node_new_camera();
- if (!node) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_node_read(node, file, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_node(file, node);
- }
- break;
- case LIB3DS_TARGET_NODE_TAG:
- {
- Lib3dsNode *node;
-
- node=lib3ds_node_new_target();
- if (!node) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_node_read(node, file, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_node(file, node);
- }
- break;
- case LIB3DS_LIGHT_NODE_TAG:
- case LIB3DS_SPOTLIGHT_NODE_TAG:
- {
- Lib3dsNode *node;
-
- node=lib3ds_node_new_light();
- if (!node) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_node_read(node, file, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_node(file, node);
- }
- break;
- case LIB3DS_L_TARGET_NODE_TAG:
- {
- Lib3dsNode *node;
-
- node=lib3ds_node_new_spot();
- if (!node) {
- return(LIB3DS_FALSE);
- }
- lib3ds_chunk_read_reset(&c, io);
- if (!lib3ds_node_read(node, file, io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_file_insert_node(file, node);
- }
- break;
- default:
- lib3ds_chunk_unknown(chunk);
- }
- }
-
- lib3ds_chunk_read_end(&c, io);
- return(LIB3DS_TRUE);
-}
-
-
-/*!
- * Read 3ds file data into a Lib3dsFile object.
- *
- * \param file The Lib3dsFile object to be filled.
- * \param io A Lib3dsIo object previously set up by the caller.
- *
- * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure.
- *
- * \ingroup file
- */
-Lib3dsBool
-lib3ds_file_read(Lib3dsFile *file, Lib3dsIo *io)
-{
- Lib3dsChunk c;
- Lib3dsWord chunk;
-
- if (!lib3ds_chunk_read_start(&c, 0, io)) {
- return(LIB3DS_FALSE);
- }
- switch (c.chunk) {
- case LIB3DS_MDATA:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!mdata_read(file, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- case LIB3DS_M3DMAGIC:
- case LIB3DS_MLIBMAGIC:
- case LIB3DS_CMAGIC:
- {
- while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
- switch (chunk) {
- case LIB3DS_M3D_VERSION:
- {
- file->mesh_version=lib3ds_io_read_dword(io);
- }
- break;
- case LIB3DS_MDATA:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!mdata_read(file, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- case LIB3DS_KFDATA:
- {
- lib3ds_chunk_read_reset(&c, io);
- if (!kfdata_read(file, io)) {
- return(LIB3DS_FALSE);
- }
- }
- break;
- default:
- lib3ds_chunk_unknown(chunk);
- }
- }
- }
- break;
- default:
- lib3ds_chunk_unknown(c.chunk);
- return(LIB3DS_FALSE);
- }
-
- lib3ds_chunk_read_end(&c, io);
- return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-colorf_write(Lib3dsRgba rgb, Lib3dsIo *io)
-{
- Lib3dsChunk c;
-
- c.chunk=LIB3DS_COLOR_F;
- c.size=18;
- lib3ds_chunk_write(&c,io);
- lib3ds_io_write_rgb(io, rgb);
-
- c.chunk=LIB3DS_LIN_COLOR_F;
- c.size=18;
- lib3ds_chunk_write(&c,io);
- lib3ds_io_write_rgb(io, rgb);
- return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-mdata_write(Lib3dsFile *file, Lib3dsIo *io)
-{
- Lib3dsChunk c;
-
- c.chunk=LIB3DS_MDATA;
- if (!lib3ds_chunk_write_start(&c,io)) {
- return(LIB3DS_FALSE);
- }
-
- { /*---- LIB3DS_MESH_VERSION ----*/
- Lib3dsChunk c;
- c.chunk=LIB3DS_MESH_VERSION;
- c.size=10;
- lib3ds_chunk_write(&c,io);
- lib3ds_io_write_intd(io, file->mesh_version);
- }
- { /*---- LIB3DS_MASTER_SCALE ----*/
- Lib3dsChunk c;
- c.chunk=LIB3DS_MASTER_SCALE;
- c.size=10;
- lib3ds_chunk_write(&c,io);
- lib3ds_io_write_float(io, file->master_scale);
- }
- { /*---- LIB3DS_O_CONSTS ----*/
- int i;
- for (i=0; i<3; ++i) {
- if (fabs(file->construction_plane[i])>LIB3DS_EPSILON) {
- break;
- }
- }
- if (i<3) {
- Lib3dsChunk c;
- c.chunk=LIB3DS_O_CONSTS;
- c.size=18;
- lib3ds_chunk_write(&c,io);
- lib3ds_io_write_vector(io, file->construction_plane);
- }
- }
-
- { /*---- LIB3DS_AMBIENT_LIGHT ----*/
- int i;
- for (i=0; i<3; ++i) {
- if (fabs(file->ambient[i])>LIB3DS_EPSILON) {
- break;
- }
- }
- if (i<3) {
- Lib3dsChunk c;
- c.chunk=LIB3DS_AMBIENT_LIGHT;
- c.size=42;
- lib3ds_chunk_write(&c,io);
- colorf_write(file->ambient,io);
- }
- }
- lib3ds_background_write(&file->background, io);
- lib3ds_atmosphere_write(&file->atmosphere, io);
- lib3ds_shadow_write(&file->shadow, io);
- lib3ds_viewport_write(&file->viewport, io);
- {
- Lib3dsMaterial *p;
- for (p=file->materials; p!=0; p=p->next) {
- if (!lib3ds_material_write(p,io)) {
- return(LIB3DS_FALSE);
- }
- }
- }
- {
- Lib3dsCamera *p;
- Lib3dsChunk c;
-
- for (p=file->cameras; p!=0; p=p->next) {
- c.chunk=LIB3DS_NAMED_OBJECT;
- if (!lib3ds_chunk_write_start(&c,io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_io_write_string(io, p->name);
- lib3ds_camera_write(p,io);
- if (!lib3ds_chunk_write_end(&c,io)) {
- return(LIB3DS_FALSE);
- }
- }
- }
- {
- Lib3dsLight *p;
- Lib3dsChunk c;
-
- for (p=file->lights; p!=0; p=p->next) {
- c.chunk=LIB3DS_NAMED_OBJECT;
- if (!lib3ds_chunk_write_start(&c,io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_io_write_string(io,p->name);
- lib3ds_light_write(p,io);
- if (!lib3ds_chunk_write_end(&c,io)) {
- return(LIB3DS_FALSE);
- }
- }
- }
- {
- Lib3dsMesh *p;
- Lib3dsChunk c;
-
- for (p=file->meshes; p!=0; p=p->next) {
- c.chunk=LIB3DS_NAMED_OBJECT;
- if (!lib3ds_chunk_write_start(&c,io)) {
- return(LIB3DS_FALSE);
- }
- lib3ds_io_write_string(io, p->name);
- lib3ds_mesh_write(p,io);
- if (!lib3ds_chunk_write_end(&c,io)) {
- return(LIB3DS_FALSE);
- }
- }
- }
-
- if (!lib3ds_chunk_write_end(&c,io)) {
- return(LIB3DS_FALSE);
- }
- return(LIB3DS_TRUE);
-}
-
-
-
-static Lib3dsBool
-nodes_write(Lib3dsNode *node, Lib3dsFile *file, Lib3dsIo *io)
-{
- {
- Lib3dsNode *p;
- for (p=node->childs; p!=0; p=p->next) {
- if (!lib3ds_node_write(p, file, io)) {
- return(LIB3DS_FALSE);
- }
- nodes_write(p, file, io);
- }
- }
- return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-kfdata_write(Lib3dsFile *file, Lib3dsIo *io)
-{
- Lib3dsChunk c;
-
- if (!file->nodes) {
- return(LIB3DS_TRUE);
- }
-
- c.chunk=LIB3DS_KFDATA;
- if (!lib3ds_chunk_write_start(&c,io)) {
- return(LIB3DS_FALSE);
- }
-
- { /*---- LIB3DS_KFHDR ----*/
- Lib3dsChunk c;
- c.chunk=LIB3DS_KFHDR;
- c.size=6 + 2 + strlen(file->name)+1 +4;
- lib3ds_chunk_write(&c,io);
- lib3ds_io_write_intw(io, file->keyf_revision);
- lib3ds_io_write_string(io, file->name);
- lib3ds_io_write_intd(io, file->frames);
- }
- { /*---- LIB3DS_KFSEG ----*/
- Lib3dsChunk c;
- c.chunk=LIB3DS_KFSEG;
- c.size=14;
- lib3ds_chunk_write(&c,io);
- lib3ds_io_write_intd(io, file->segment_from);
- lib3ds_io_write_intd(io, file->segment_to);
- }
- { /*---- LIB3DS_KFCURTIME ----*/
- Lib3dsChunk c;
- c.chunk=LIB3DS_KFCURTIME;
- c.size=10;
- lib3ds_chunk_write(&c,io);
- lib3ds_io_write_intd(io, file->current_frame);
- }
- lib3ds_viewport_write(&file->viewport_keyf, io);
-
- {
- Lib3dsNode *p;
- for (p=file->nodes; p!=0; p=p->next) {
- if (!lib3ds_node_write(p, file, io)) {
- return(LIB3DS_FALSE);
- }
- if (!nodes_write(p, file, io)) {
- return(LIB3DS_FALSE);
- }
- }
- }
-
- if (!lib3ds_chunk_write_end(&c,io)) {
- return(LIB3DS_FALSE);
- }
- return(LIB3DS_TRUE);
-}
-
-
-/*!
- * Write 3ds file data from a Lib3dsFile object to a file.
- *
- * \param file The Lib3dsFile object to be written.
- * \param io A Lib3dsIo object previously set up by the caller.
- *
- * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure.
- *
- * \ingroup file
- */
-Lib3dsBool
-lib3ds_file_write(Lib3dsFile *file, Lib3dsIo *io)
-{
- Lib3dsChunk c;
-
- c.chunk=LIB3DS_M3DMAGIC;
- if (!lib3ds_chunk_write_start(&c,io)) {
- LIB3DS_ERROR_LOG;
- return(LIB3DS_FALSE);
- }
-
- { /*---- LIB3DS_M3D_VERSION ----*/
- Lib3dsChunk c;
-
- c.chunk=LIB3DS_M3D_VERSION;
- c.size=10;
- lib3ds_chunk_write(&c,io);
- lib3ds_io_write_dword(io, file->mesh_version);
- }
-
- if (!mdata_write(file, io)) {
- return(LIB3DS_FALSE);
- }
- if (!kfdata_write(file, io)) {
- return(LIB3DS_FALSE);
- }
-
- if (!lib3ds_chunk_write_end(&c,io)) {
- return(LIB3DS_FALSE);
- }
- return(LIB3DS_TRUE);
-}
-
-
-/*!
- * Insert a new Lib3dsMaterial object into the materials list of
- * a Lib3dsFile object.
- *
- * The new Lib3dsMaterial object is inserted into the materials list
- * in alphabetic order by name.
- *
- * \param file The Lib3dsFile object to be modified.
- * \param material The Lib3dsMaterial object to be inserted into file->materials
- *
- * \ingroup file
- */
-void
-lib3ds_file_insert_material(Lib3dsFile *file, Lib3dsMaterial *material)
-{
- Lib3dsMaterial *p,*q;
-
- ASSERT(file);
- ASSERT(material);
- ASSERT(!material->next);
-
- q=0;
- for (p=file->materials; p!=0; p=p->next) {
- if (strcmp(material->name, p->name)<0) {
- break;
- }
- q=p;
- }
- if (!q) {
- material->next=file->materials;
- file->materials=material;
- }
- else {
- material->next=q->next;
- q->next=material;
- }
-}
-
-
-/*!
- * Remove a Lib3dsMaterial object from the materials list of
- * a Lib3dsFile object.
- *
- * If the Lib3dsMaterial is not found in the materials list, nothing is
- * done (except that an error log message may be generated.)
- *
- * \param file The Lib3dsFile object to be modified.
- * \param material The Lib3dsMaterial object to be removed from file->materials
- *
- * \ingroup file
- */
-void
-lib3ds_file_remove_material(Lib3dsFile *file, Lib3dsMaterial *material)
-{
- Lib3dsMaterial *p,*q;
-
- ASSERT(file);
- ASSERT(material);
- ASSERT(file->materials);
- for (p=0,q=file->materials; q; p=q,q=q->next) {
- if (q==material) {
- break;
- }
- }
- if (!q) {
- ASSERT(LIB3DS_FALSE);
- return;
- }
- if (!p) {
- file->materials=material->next;
- }
- else {
- p->next=q->next;
- }
- material->next=0;
-}
-
-
-/*!
- * Return a Lib3dsMaterial object by name.
- *
- * \param file Lib3dsFile object to be searched.
- * \param name Name of the Lib3dsMaterial object to be searched for.
- *
- * \return A pointer to the named Lib3dsMaterial, or NULL if not found.
- *
- * \ingroup file
- */
-Lib3dsMaterial*
-lib3ds_file_material_by_name(Lib3dsFile *file, const char *name)
-{
- Lib3dsMaterial *p;
-
- ASSERT(file);
- for (p=file->materials; p!=0; p=p->next) {
- if (strcmp(p->name,name)==0) {
- return(p);
- }
- }
- return(0);
-}
-
-
-/*!
- * Dump all Lib3dsMaterial objects found in a Lib3dsFile object.
- *
- * \param file Lib3dsFile object to be dumped.
- *
- * \see lib3ds_material_dump
- *
- * \ingroup file
- */
-void
-lib3ds_file_dump_materials(Lib3dsFile *file)
-{
- Lib3dsMaterial *p;
-
- ASSERT(file);
- for (p=file->materials; p!=0; p=p->next) {
- lib3ds_material_dump(p);
- }
-}
-
-
-/*!
- * Insert a new Lib3dsMesh object into the meshes list of
- * a Lib3dsFile object.
- *
- * The new Lib3dsMesh object is inserted into the meshes list
- * in alphabetic order by name.
- *
- * \param file The Lib3dsFile object to be modified.
- * \param material The Lib3dsMesh object to be inserted into file->meshes
- *
- * \ingroup file
- */
-void
-lib3ds_file_insert_mesh(Lib3dsFile *file, Lib3dsMesh *mesh)
-{
- Lib3dsMesh *p,*q;
-
- ASSERT(file);
- ASSERT(mesh);
- ASSERT(!mesh->next);
-
- q=0;
- for (p=file->meshes; p!=0; p=p->next) {
- if (strcmp(mesh->name, p->name)<0) {
- break;
- }
- q=p;
- }
- if (!q) {
- mesh->next=file->meshes;
- file->meshes=mesh;
- }
- else {
- mesh->next=q->next;
- q->next=mesh;
- }
-}
-
-
-/*!
- * Remove a Lib3dsMesh object from the meshes list of
- * a Lib3dsFile object.
- *
- * If the Lib3dsMesh is not found in the meshes list, nothing is done
- * (except that an error log message may be generated.)
- *
- * \param file The Lib3dsFile object to be modified.
- * \param material The Lib3dsMesh object to be removed from file->meshes
- *
- * \ingroup file
- */
-void
-lib3ds_file_remove_mesh(Lib3dsFile *file, Lib3dsMesh *mesh)
-{
- Lib3dsMesh *p,*q;
-
- ASSERT(file);
- ASSERT(mesh);
- ASSERT(file->meshes);
- for (p=0,q=file->meshes; q; p=q,q=q->next) {
- if (q==mesh) {
- break;
- }
- }
- if (!q) {
- ASSERT(LIB3DS_FALSE);
- return;
- }
- if (!p) {
- file->meshes=mesh->next;
- }
- else {
- p->next=q->next;
- }
- mesh->next=0;
-}
-
-
-/*!
- * Return a Lib3dsMesh object from a Lib3dsFile by name.
- *
- * \param file Lib3dsFile object to be searched.
- * \param name Name of the Lib3dsMesh object to be searched for.
- *
- * \return A pointer to the named Lib3dsMesh, or NULL if not found.
- *
- * \ingroup file
- */
-Lib3dsMesh*
-lib3ds_file_mesh_by_name(Lib3dsFile *file, const char *name)
-{
- Lib3dsMesh *p;
-
- ASSERT(file);
- for (p=file->meshes; p!=0; p=p->next) {
- if (strcmp(p->name,name)==0) {
- return(p);
- }
- }
- return(0);
-}
-
-
-/*!
- * Dump all Lib3dsMesh objects found in a Lib3dsFile object.
- *
- * \param file Lib3dsFile object to be dumped.
- *
- * \see lib3ds_mesh_dump
- *
- * \ingroup file
- */
-void
-lib3ds_file_dump_meshes(Lib3dsFile *file)
-{
- Lib3dsMesh *p;
-
- ASSERT(file);
- for (p=file->meshes; p!=0; p=p->next) {
- lib3ds_mesh_dump(p);
- }
-}
-
-
-static void
-dump_instances(Lib3dsNode *node, const char* parent)
-{
- Lib3dsNode *p;
- char name[255];
-
- ASSERT(node);
- ASSERT(parent);
- strcpy(name, parent);
- strcat(name, ".");
- strcat(name, node->name);
- if (node->type==LIB3DS_OBJECT_NODE) {
- printf(" %s : %s\n", name, node->data.object.instance);
- }
- for (p=node->childs; p!=0; p=p->next) {
- dump_instances(p, parent);
- }
-}
-
-
-/*!
- * Dump all Lib3dsNode object names found in a Lib3dsFile object.
- *
- * For each node of type OBJECT_NODE, its name and data.object.instance
- * fields are printed to stdout. Consider using lib3ds_file_dump_nodes()
- * instead, as that function dumps more information.
- *
- * Nodes are dumped recursively.
- *
- * \param file Lib3dsFile object to be dumped.
- *
- * \see lib3ds_file_dump_nodes
- *
- * \ingroup file
- */
-void
-lib3ds_file_dump_instances(Lib3dsFile *file)
-{
- Lib3dsNode *p;
-
- ASSERT(file);
- for (p=file->nodes; p!=0; p=p->next) {
- dump_instances(p,"");
- }
-}
-
-
-/*!
- * Insert a new Lib3dsCamera object into the cameras list of
- * a Lib3dsFile object.
- *
- * The new Lib3dsCamera object is inserted into the cameras list
- * in alphabetic order by name.
- *
- * \param file The Lib3dsFile object to be modified.
- * \param material The Lib3dsCamera object to be inserted into file->cameras
- *
- * \ingroup file
- */
-void
-lib3ds_file_insert_camera(Lib3dsFile *file, Lib3dsCamera *camera)
-{
- Lib3dsCamera *p,*q;
-
- ASSERT(file);
- ASSERT(camera);
- ASSERT(!camera->next);
-
- q=0;
- for (p=file->cameras; p!=0; p=p->next) {
- if (strcmp(camera->name, p->name)<0) {
- break;
- }
- q=p;
- }
- if (!q) {
- camera->next=file->cameras;
- file->cameras=camera;
- }
- else {
- camera->next=q->next;
- q->next=camera;
- }
-}
-
-
-/*!
- * Remove a Lib3dsCamera object from the cameras list of
- * a Lib3dsFile object.
- *
- * If the Lib3dsCamera is not found in the cameras list, nothing is done
- * (except that an error log message may be generated.)
- *
- * \param file The Lib3dsFile object to be modified.
- * \param material The Lib3dsCamera object to be removed from file->cameras
- *
- * \ingroup file
- */
-void
-lib3ds_file_remove_camera(Lib3dsFile *file, Lib3dsCamera *camera)
-{
- Lib3dsCamera *p,*q;
-
- ASSERT(file);
- ASSERT(camera);
- ASSERT(file->cameras);
- for (p=0,q=file->cameras; q; p=q,q=q->next) {
- if (q==camera) {
- break;
- }
- }
- if (!q) {
- ASSERT(LIB3DS_FALSE);
- return;
- }
- if (!p) {
- file->cameras=camera->next;
- }
- else {
- p->next=q->next;
- }
- camera->next=0;
-}
-
-
-/*!
- * Return a Lib3dsCamera object from a Lib3dsFile by name.
- *
- * \param file Lib3dsFile object to be searched.
- * \param name Name of the Lib3dsCamera object to be searched for.
- *
- * \return A pointer to the named Lib3dsCamera, or NULL if not found.
- *
- * \ingroup file
- */
-Lib3dsCamera*
-lib3ds_file_camera_by_name(Lib3dsFile *file, const char *name)
-{
- Lib3dsCamera *p;
-
- ASSERT(file);
- for (p=file->cameras; p!=0; p=p->next) {
- if (strcmp(p->name,name)==0) {
- return(p);
- }
- }
- return(0);
-}
-
-
-/*!
- * Dump all Lib3dsCamera objects found in a Lib3dsFile object.
- *
- * \param file Lib3dsFile object to be dumped.
- *
- * \see lib3ds_camera_dump
- *
- * \ingroup file
- */
-void
-lib3ds_file_dump_cameras(Lib3dsFile *file)
-{
- Lib3dsCamera *p;
-
- ASSERT(file);
- for (p=file->cameras; p!=0; p=p->next) {
- lib3ds_camera_dump(p);
- }
-}
-
-
-/*!
- * Insert a new Lib3dsLight object into the lights list of
- * a Lib3dsFile object.
- *
- * The new Lib3dsLight object is inserted into the lights list
- * in alphabetic order by name.
- *
- * \param file The Lib3dsFile object to be modified.
- * \param material The Lib3dsLight object to be inserted into file->lights
- *
- * \ingroup file
- */
-void
-lib3ds_file_insert_light(Lib3dsFile *file, Lib3dsLight *light)
-{
- Lib3dsLight *p,*q;
-
- ASSERT(file);
- ASSERT(light);
- ASSERT(!light->next);
-
- q=0;
- for (p=file->lights; p!=0; p=p->next) {
- if (strcmp(light->name, p->name)<0) {
- break;
- }
- q=p;
- }
- if (!q) {
- light->next=file->lights;
- file->lights=light;
- }
- else {
- light->next=q->next;
- q->next=light;
- }
-}
-
-
-/*!
- * Remove a Lib3dsLight object from the lights list of
- * a Lib3dsFile object.
- *
- * If the Lib3dsLight is not found in the lights list, nothing is done
- * (except that an error log message may be generated.)
- *
- * \param file The Lib3dsFile object to be modified.
- * \param material The Lib3dsLight object to be removed from file->lights
- *
- * \ingroup file
- */
-void
-lib3ds_file_remove_light(Lib3dsFile *file, Lib3dsLight *light)
-{
- Lib3dsLight *p,*q;
-
- ASSERT(file);
- ASSERT(light);
- ASSERT(file->lights);
- for (p=0,q=file->lights; q; p=q,q=q->next) {
- if (q==light) {
- break;
- }
- }
- if (!q) {
- ASSERT(LIB3DS_FALSE);
- return;
- }
- if (!p) {
- file->lights=light->next;
- }
- else {
- p->next=q->next;
- }
- light->next=0;
-}
-
-
-/*!
- * Return a Lib3dsLight object from a Lib3dsFile by name.
- *
- * \param file Lib3dsFile object to be searched.
- * \param name Name of the Lib3dsLight object to be searched for.
- *
- * \return A pointer to the named Lib3dsLight, or NULL if not found.
- *
- * \ingroup file
- */
-Lib3dsLight*
-lib3ds_file_light_by_name(Lib3dsFile *file, const char *name)
-{
- Lib3dsLight *p;
-
- ASSERT(file);
- for (p=file->lights; p!=0; p=p->next) {
- if (strcmp(p->name,name)==0) {
- return(p);
- }
- }
- return(0);
-}
-
-
-/*!
- * Dump all Lib3dsLight objects found in a Lib3dsFile object.
- *
- * \param file Lib3dsFile object to be dumped.
- *
- * \see lib3ds_light_dump
- *
- * \ingroup file
- */
-void
-lib3ds_file_dump_lights(Lib3dsFile *file)
-{
- Lib3dsLight *p;
-
- ASSERT(file);
- for (p=file->lights; p!=0; p=p->next) {
- lib3ds_light_dump(p);
- }
-}
-
-
-/*!
- * Compute the bounding box for Lib3dsFile objects.
- *
- * This function computes the bounding box for all meshes
- * in the Lib3dsFile object. Cameras and lights are not included.
- *
- * \param file The Lib3dsFile object to be examined.
- * \param min Returned minimum x,y,z values.
- * \param max Returned maximum x,y,z values.
- *
- * \ingroup file
- */
-void
-lib3ds_object_bounding_box(Lib3dsFile *file, Lib3dsVector min, Lib3dsVector max)
-{
- {
- Lib3dsVector lmin, lmax;
- Lib3dsMesh *p=file->meshes;
-
- if (p) {
- lib3ds_mesh_bounding_box(p, min, max);
- p = p->next;
- }
- while (p) {
- lib3ds_mesh_bounding_box(p, lmin, lmax);
- lib3ds_vector_min(min, lmin);
- lib3ds_vector_max(max, lmax);
- p=p->next;
- }
- }
-}
-
-
-/*!
- * Compute the bounding box for a Lib3dsFile.
- *
- * This function computes the bounding box for all meshes, cameras,
- * and lights in the Lib3dsFile object.
- *
- * \param file The Lib3dsFile object to be examined.
- * \param min Returned minimum x,y,z values.
- * \param max Returned maximum x,y,z values.
- *
- * \ingroup file
- */
-void
-lib3ds_file_bounding_box(Lib3dsFile *file, Lib3dsVector min, Lib3dsVector max)
-{
- Lib3dsBool init=LIB3DS_FALSE;
-
- {
- Lib3dsVector lmin, lmax;
- Lib3dsMesh *p=file->meshes;
-
- if (!init && p) {
- init = LIB3DS_TRUE;
- lib3ds_mesh_bounding_box(p, min, max);
- p = p->next;
- }
- while (p) {
- lib3ds_mesh_bounding_box(p, lmin, lmax);
- lib3ds_vector_min(min, lmin);
- lib3ds_vector_max(max, lmax);
- p=p->next;
- }
- }
- {
- Lib3dsCamera *p=file->cameras;
- if (!init && p) {
- init = LIB3DS_TRUE;
- lib3ds_vector_copy(min, p->position);
- lib3ds_vector_copy(max, p->position);
- }
-
- while (p) {
- lib3ds_vector_min(min, p->position);
- lib3ds_vector_max(max, p->position);
- lib3ds_vector_min(min, p->target);
- lib3ds_vector_max(max, p->target);
- p=p->next;
- }
- }
- {
- Lib3dsLight *p=file->lights;
- if (!init && p) {
- init = LIB3DS_TRUE;
- lib3ds_vector_copy(min, p->position);
- lib3ds_vector_copy(max, p->position);
- }
-
- while (p) {
- lib3ds_vector_min(min, p->position);
- lib3ds_vector_max(max, p->position);
- if (p->spot_light) {
- lib3ds_vector_min(min, p->spot);
- lib3ds_vector_max(max, p->spot);
- }
- p=p->next;
- }
- }
-}
-
-
-/*!
- * Return a node object by name and type.
- *
- * This function performs a recursive search for the specified node.
- * Both name and type must match.
- *
- * \param file The Lib3dsFile to be searched.
- * \param name The target node name.
- * \param type The target node type
- *
- * \return A pointer to the first matching node, or NULL if not found.
- *
- * \see lib3ds_node_by_name
- *
- * \ingroup file
- */
-Lib3dsNode*
-lib3ds_file_node_by_name(Lib3dsFile *file, const char* name, Lib3dsNodeTypes type)
-{
- Lib3dsNode *p,*q;
-
- ASSERT(file);
- for (p=file->nodes; p!=0; p=p->next) {
- if ((p->type==type) && (strcmp(p->name, name)==0)) {
- return(p);
- }
- q=lib3ds_node_by_name(p, name, type);
- if (q) {
- return(q);
- }
- }
- return(0);
-}
-
-
-/*!
- * Return a node object by id.
- *
- * This function performs a recursive search for the specified node.
- *
- * \param file The Lib3dsFile to be searched.
- * \param node_id The target node id.
- *
- * \return A pointer to the first matching node, or NULL if not found.
- *
- * \see lib3ds_node_by_id
- *
- * \ingroup file
- */
-Lib3dsNode*
-lib3ds_file_node_by_id(Lib3dsFile *file, Lib3dsWord node_id)
-{
- Lib3dsNode *p,*q;
-
- ASSERT(file);
- for (p=file->nodes; p!=0; p=p->next) {
- if (p->node_id==node_id) {
- return(p);
- }
- q=lib3ds_node_by_id(p, node_id);
- if (q) {
- return(q);
- }
- }
- return(0);
-}
-
-
-/*!
- * Insert a new node into a Lib3dsFile object.
- *
- * If the node's parent_id structure is not LIB3DS_NO_PARENT and the
- * specified parent is found inside the Lib3dsFile object, then the
- * node is inserted as a child of that parent. If the parent_id
- * structure is LIB3DS_NO_PARENT or the specified parent is not found,
- * then the node is inserted at the top level.
- *
- * Node is inserted in alphabetic order by name.
- *
- * Finally, if any other top-level nodes in file specify this node as
- * their parent, they are relocated as a child of this node.
- *
- * \param file The Lib3dsFile object to be modified.
- * \param node The node to be inserted into file
- *
- * \ingroup file
- */
-void
-lib3ds_file_insert_node(Lib3dsFile *file, Lib3dsNode *node)
-{
- Lib3dsNode *parent,*p,*n;
-
- ASSERT(node);
- ASSERT(!node->next);
- ASSERT(!node->parent);
-
- parent=0;
- if (node->parent_id!=LIB3DS_NO_PARENT) {
- parent=lib3ds_file_node_by_id(file, node->parent_id);
- }
- node->parent=parent;
-
- if (!parent) {
- for (p=0,n=file->nodes; n!=0; p=n,n=n->next) {
- if (strcmp(n->name, node->name)>0) {
- break;
- }
- }
- if (!p) {
- node->next=file->nodes;
- file->nodes=node;
- }
- else {
- node->next=p->next;
- p->next=node;
- }
- }
- else {
- for (p=0,n=parent->childs; n!=0; p=n,n=n->next) {
- if (strcmp(n->name, node->name)>0) {
- break;
- }
- }
- if (!p) {
- node->next=parent->childs;
- parent->childs=node;
- }
- else {
- node->next=p->next;
- p->next=node;
- }
- }
-
- if (node->node_id!=LIB3DS_NO_PARENT) {
- for (n=file->nodes; n!=0; n=p) {
- p=n->next;
- if (n->parent_id==node->node_id) {
- lib3ds_file_remove_node(file, n);
- lib3ds_file_insert_node(file, n);
- }
- }
- }
-}
-
-
-/*!
- * Remove a node from the a Lib3dsFile object.
- *
- * \param file The Lib3dsFile object to be modified.
- * \param node The Lib3dsNode object to be removed from file
- *
- * \return LIB3DS_TRUE on success, LIB3DS_FALSE if node is not found in file
- *
- * \ingroup file
- */
-Lib3dsBool
-lib3ds_file_remove_node(Lib3dsFile *file, Lib3dsNode *node)
-{
- Lib3dsNode *p,*n;
-
- if (node->parent) {
- for (p=0,n=node->parent->childs; n; p=n,n=n->next) {
- if (n==node) {
- break;
- }
- }
- if (!n) {
- return(LIB3DS_FALSE);
- }
-
- if (!p) {
- node->parent->childs=n->next;
- }
- else {
- p->next=n->next;
- }
- }
- else {
- for (p=0,n=file->nodes; n; p=n,n=n->next) {
- if (n==node) {
- break;
- }
- }
- if (!n) {
- return(LIB3DS_FALSE);
- }
-
- if (!p) {
- file->nodes=n->next;
- }
- else {
- p->next=n->next;
- }
- }
- return(LIB3DS_TRUE);
-}
-
-
-/*!
- * Dump all node objects found in a Lib3dsFile object.
- *
- * Nodes are dumped recursively.
- *
- * \param file Lib3dsFile object to be dumped.
- *
- * \see lib3ds_node_dump
- *
- * \ingroup file
- */
-void
-lib3ds_file_dump_nodes(Lib3dsFile *file)
-{
- Lib3dsNode *p;
-
- ASSERT(file);
- for (p=file->nodes; p!=0; p=p->next) {
- lib3ds_node_dump(p,1);
- }
-}
-
-
-/*!
-
-\typedef Lib3dsFile
- \ingroup file
- \sa _Lib3dsFile
-
-*/
-
-
-
-/* Programming trick to force users to compile their source code against the
- * correct headers. The symbol lib3ds_version1_3 will be defined iff the users
- * compile with the current version of <lib3ds/types.h>
- */
-
-/*
-extern int lib3ds_version1_3;
-static const int *lib3ds_version = &lib3ds_version1_3;
-*/