aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_kmz/imp_kmz.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_kmz/imp_kmz.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_kmz/imp_kmz.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_kmz/imp_kmz.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_kmz/imp_kmz.c
new file mode 100644
index 0000000..9f44f87
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_kmz/imp_kmz.c
@@ -0,0 +1,168 @@
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 <g3d/config.h>
24
25#include <locale.h>
26#include <string.h>
27
28#include <libxml/parser.h>
29#include <libxml/tree.h>
30
31#include <g3d/types.h>
32#include <g3d/stream.h>
33#include <g3d/plugins.h>
34
35static gchar * kmz_find_model(xmlDocPtr xmldoc);
36
37static int kml_stream_read_cb(gpointer ctx, gchar *buffer, gint len)
38{
39 return g3d_stream_read((G3DStream *)ctx, buffer, len);
40}
41
42EAPI
43gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream,
44 G3DModel *model)
45{
46 G3DStream *stream_dockml, *stream_model;
47 gchar *daename;
48 xmlDocPtr xmldoc;
49 gboolean retval = FALSE, from_zip = TRUE;
50
51 setlocale(LC_NUMERIC, "C");
52
53 xmlInitParser();
54
55 stream_dockml = g3d_stream_open_zip_from_stream(stream, "doc.kml");
56 if(stream_dockml == NULL) {
57 g_debug("KMZ: failed to read 'doc.kml' from '%s', trying to "
58 "use input stream as 'doc.kml'", stream->uri);
59 stream_dockml = stream;
60 from_zip = FALSE;
61 }
62
63 xmldoc = xmlReadIO(kml_stream_read_cb, NULL,
64 stream_dockml, "file:///tmp/doc.kml", NULL, 0);
65 if(xmldoc) {
66 g_debug("KMZ: parsed doc.kml");
67
68 daename = kmz_find_model(xmldoc);
69 if(daename != NULL) {
70/*#if DEBUG > 1*/
71 g_debug("KMZ: loading '%s' from '%s'", daename, stream->uri);
72/*#endif*/
73 if(from_zip)
74 stream_model = g3d_stream_open_zip_from_stream(stream,
75 daename);
76 else
77 stream_model = g3d_stream_open_file(daename, "r");
78
79 if(stream_model != NULL) {
80 retval = g3d_plugins_load_model_from_stream(context,
81 stream_model, model);
82 g3d_stream_close(stream_model);
83 } else {
84 g_warning("KMZ: failed to find '%s'%s%s%s", daename,
85 from_zip ? " in '" : "",
86 from_zip ? stream->uri : "",
87 from_zip ? "'" : "");
88 }
89 }
90
91 xmlFreeDoc(xmldoc);
92 }
93
94 if(from_zip)
95 g3d_stream_close(stream_dockml);
96 xmlCleanupParser();
97
98 return retval;
99}
100
101EAPI
102gchar *plugin_description(void)
103{
104 return g_strdup("Keyhole Markup Language model containers.");
105}
106
107EAPI
108gchar **plugin_extensions(void)
109{
110 return g_strsplit("kmz:kml:zip", ":", 0);
111}
112
113/*****************************************************************************/
114
115static xmlNodePtr kmz_find_node(xmlNodePtr parentnode, const gchar *path)
116{
117 gchar *slash, *elem;
118 xmlNodePtr node, pathnode;
119 gboolean last = FALSE;
120
121 slash = strchr(path, '/');
122 if(slash)
123 elem = g_strndup(path, slash - path);
124 else {
125 elem = g_strdup(path);
126 last = TRUE;
127 }
128
129 if(strlen(elem) == 0)
130 return NULL;
131
132 for(node = parentnode->children; node != NULL; node = node->next) {
133 if(node->type != XML_ELEMENT_NODE)
134 continue;
135 if(xmlStrcmp(node->name, (xmlChar *)elem) == 0) {
136 if(last) {
137 g_free(elem);
138 return node;
139 } else {
140 pathnode = kmz_find_node(node, slash + 1);
141 if(pathnode != NULL) {
142 g_free(elem);
143 return pathnode;
144 }
145 }
146 }
147 }
148 g_free(elem);
149 return NULL;
150}
151
152static gchar * kmz_find_model(xmlDocPtr xmldoc)
153{
154 xmlNodePtr rootnode, hrefnode;
155
156 rootnode = xmlDocGetRootElement(xmldoc);
157 if(rootnode == NULL)
158 return NULL;
159
160 hrefnode = kmz_find_node(rootnode, "Folder/Placemark/Model/Link/href");
161 if(hrefnode)
162 return (gchar *)hrefnode->children->content;
163 hrefnode = kmz_find_node(rootnode, "Placemark/Model/Link/href");
164 if(hrefnode)
165 return (gchar *)hrefnode->children->content;
166 return NULL;
167}
168