2 * Copyright (C) 2012 by Jan Boon (Kaetemi)
4 * This file is part of RYZOM CORE PIPELINE.
5 * RYZOM CORE PIPELINE is free software: you can redistribute it
6 * and/or modify it under the terms of the GNU Affero General Public
7 * License as published by the Free Software Foundation, either
8 * version 3 of the License, or (at your option) any later version.
10 * RYZOM CORE PIPELINE is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
15 * You should have received a copy of the GNU Affero General Public
16 * License along with RYZOM CORE PIPELINE. If not, see
17 * <http://www.gnu.org/licenses/>.
20 #include <nel/misc/types_nl.h>
21 #include <nel/misc/common.h>
23 #include <gsf/gsf-infile-msole.h>
24 #include <gsf/gsf-infile.h>
25 #include <gsf/gsf-input-stdio.h>
26 #include <gsf/gsf-utils.h>
27 #include <gsf/gsf-doc-meta-data.h>
28 #include <gsf/gsf-msole-utils.h>
29 #include <glib/gi18n.h>
38 #include <nel/misc/file.h>
39 #include <nel/misc/vector.h>
41 #include "../pipeline_max/storage_stream.h"
42 #include "../pipeline_max/storage_object.h"
43 #include "../pipeline_max/dll_directory.h"
44 #include "../pipeline_max/class_directory_3.h"
45 #include "../pipeline_max/class_data.h"
46 #include "../pipeline_max/config.h"
47 #include "../pipeline_max/scene.h"
48 #include "../pipeline_max/scene_class_registry.h"
51 #include "../pipeline_max/builtin/builtin.h"
52 #include "../pipeline_max/update1/update1.h"
53 #include "../pipeline_max/epoly/epoly.h"
55 #include "../pipeline_max/builtin/storage/app_data.h"
56 #include "../pipeline_max/builtin/storage/geom_buffers.h"
57 #include "../pipeline_max/builtin/scene_impl.h"
58 #include "../pipeline_max/builtin/i_node.h"
59 #include "../pipeline_max/update1/editable_mesh.h"
60 #include "../pipeline_max/epoly/editable_poly.h"
62 using namespace PIPELINE::MAX
;
63 using namespace PIPELINE::MAX::BUILTIN
;
64 using namespace PIPELINE::MAX::BUILTIN::STORAGE
;
65 using namespace PIPELINE::MAX::UPDATE1
;
66 using namespace PIPELINE::MAX::EPOLY
;
68 //static const char *filename = "/srv/work/database/interfaces/anims_max/cp_fy_hof_species.max";
69 //static const char *filename = "/home/kaetemi/source/minimax/GE_Acc_MikotoBaniere.max";
70 //static const char *filename = "/home/kaetemi/3dsMax/scenes/test2008.max";
71 //static const char *filename = "/home/kaetemi/3dsMax/scenes/teapot_test_scene.max";
72 //static const char *filename = "/home/kaetemi/3dsMax/scenes/testplane.max";
73 //static const char *filename = "/home/kaetemi/3dsMax/scenes/geomobjects.max";
74 static const char *filename
= "/mnt/tsurugi/ryzom-assets/database/landscape/ligo/desert/pipeline_max/zonematerial-converted-165_eg.max";
75 static const char *streamname
= "Scene";
77 #define PBMS_GEOM_BUFFERS_POLY_A_VERTEX_CHUNK_ID 0x0100
78 #define PBMS_GEOM_BUFFERS_POLY_A_EDGE_CHUNK_ID 0x010a
79 #define PBMS_GEOM_BUFFERS_POLY_A_FACE_CHUNK_ID 0x011a
80 // CStorageArraySizePre<CGeomPolyVertexInfo>
81 // CStorageArraySizePre<CGeomPolyEdgeInfo>
82 // CStorageArrayDynSize<CGeomPolyFaceInfo>
84 void exportObj(const std::string
&fileName
, const CReferenceMaker
*geomObject
)
86 nlassert(dynamic_cast<const CGeomObject
*>(geomObject
));
87 const CEditableMesh
*mesh
= dynamic_cast<const CEditableMesh
*>(geomObject
);
90 nlerror("Not implemented!");
92 IStorageObject *bufferBlock = triObject->findStorageObject(0x08fe);
93 nlassert(bufferBlock->isContainer());
94 CStorageContainer *buffers = static_cast<CStorageContainer *>(bufferBlock);
95 CStorageArraySizePre<NLMISC::CVector> *vertexBuffer = static_cast<CStorageArraySizePre<NLMISC::CVector> *>(buffers->findStorageObject(0x0914));
96 CStorageArraySizePre<CGeomTriIndexInfo> *indexBuffer = static_cast<CStorageArraySizePre<CGeomTriIndexInfo> *>(buffers->findStorageObject(0x0912));
98 std::ofstream ofs(fileName.c_str());
99 for (uint i = 0; i < vertexBuffer->Value.size(); ++i)
100 ofs << "v " << vertexBuffer->Value[i].x << " " << vertexBuffer->Value[i].y << " " << vertexBuffer->Value[i].z << "\n";
101 for (uint i = 0; i < indexBuffer->Value.size(); ++i)
102 ofs << "f " << (indexBuffer->Value[i].a + 1) << " " << (indexBuffer->Value[i].b + 1) << " " << (indexBuffer->Value[i].c + 1) << "\n"; // + 1 as .obj indexes at 1...
106 const CEditablePoly
*poly
= dynamic_cast<const CEditablePoly
*>(geomObject
);
109 CGeomBuffers
*geomBuffers
= poly
->geomBuffers();
110 CStorageArraySizePre
<CGeomPolyVertexInfo
> *vertexBuffer
= static_cast<CStorageArraySizePre
<CGeomPolyVertexInfo
> *>(geomBuffers
->findStorageObject(PBMS_GEOM_BUFFERS_POLY_A_VERTEX_CHUNK_ID
));
111 CStorageArraySizePre
<CGeomPolyEdgeInfo
> *edgeBuffer
= static_cast<CStorageArraySizePre
<CGeomPolyEdgeInfo
> *>(geomBuffers
->findStorageObject(PBMS_GEOM_BUFFERS_POLY_A_EDGE_CHUNK_ID
));
112 CStorageArrayDynSize
<CGeomPolyFaceInfo
> *faceBuffer
= static_cast<CStorageArrayDynSize
<CGeomPolyFaceInfo
> *>(geomBuffers
->findStorageObject(PBMS_GEOM_BUFFERS_POLY_A_FACE_CHUNK_ID
));
113 nlassert(vertexBuffer
);
114 nlassert(edgeBuffer
);
115 nlassert(faceBuffer
);
116 std::ofstream
ofs(fileName
.c_str());
117 for (uint i
= 0; i
< vertexBuffer
->Value
.size(); ++i
)
118 ofs
<< "v " << vertexBuffer
->Value
[i
].v
.x
<< " " << vertexBuffer
->Value
[i
].v
.y
<< " " << vertexBuffer
->Value
[i
].v
.z
<< "\n";
119 std::vector
<CGeomTriIndex
> triangles
;
120 for (uint i
= 0; i
< faceBuffer
->Value
.size(); ++i
)
122 CGeomObject::triangulatePolyFace(triangles
, faceBuffer
->Value
[i
]);
123 for (uint j
= 0; j
< triangles
.size(); ++j
)
125 ofs
<< "f " << (triangles
[j
].a
+ 1) << " " << (triangles
[j
].b
+ 1) << " " << (triangles
[j
].c
+ 1) << "\n"; // + 1 as .obj indexes at 1...
131 nlerror("Not handled!");
134 // int __stdcall WinMain(void *, void *, void *, int)
135 int main(int argc
, char **argv
)
137 //printf("Pipeline Max Dump (Temporary Tool)\n");
139 char const *me
= (argv
[0] ? argv
[0] : "pipeline_max_dump");
143 // Register all plugin classes
144 CSceneClassRegistry sceneClassRegistry
;
145 CBuiltin::registerClasses(&sceneClassRegistry
);
146 CUpdate1::registerClasses(&sceneClassRegistry
);
147 CEPoly::registerClasses(&sceneClassRegistry
);
150 GError
*error
= NULL
;
154 src
= gsf_input_stdio_new(filename
, &error
);
158 display_name
= g_filename_display_name(filename
);
159 g_printerr (_("%s: Failed to open %s: %s\n"),
163 g_free(display_name
);
167 infile
= gsf_infile_msole_new(src
, NULL
);
171 display_name
= g_filename_display_name(filename
);
172 g_printerr (_("%s: Failed to recognize %s as an archive\n"),
175 g_free (display_name
);
179 display_name
= g_filename_display_name(filename
);
180 //g_print("%s\n", display_name);
181 g_free(display_name
);
182 // g_print("%s\n", streamname);
185 GsfInput
*input
= NULL
;
188 PIPELINE::MAX::CDllDirectory dllDirectory
;
189 input
= gsf_infile_child_by_name(infile
, "DllDirectory");
191 PIPELINE::MAX::CStorageStream
instream(input
);
192 PIPELINE::MAX::CStorageContainer ctr
;
193 ctr
.serial(instream
);
195 NLMISC::COFile
of("temp.bin");
196 ctr
.serial(of
); // out
197 // nldebug("Written %i bytes", of.getPos());
200 NLMISC::CIFile
inf("temp.bin");
201 dllDirectory
.serial(inf
); // in
203 //dllDirectory.serial(instream);
205 g_object_unref(input
);
206 //dllDirectory.toString(std::cout);
208 dllDirectory
.parse(PIPELINE::MAX::VersionUnknown
); // parse the structure to readable data
209 dllDirectory
.clean(); // cleanup unused file structure
210 dllDirectory
.toString(std::cout
);
212 //dllDirectory.build(PIPELINE::MAX::VersionUnknown);
213 //dllDirectory.disown();
214 //dllDirectory.toString(std::cout);
221 PIPELINE::MAX::CClassDirectory3
classDirectory3(&dllDirectory
);
222 input
= gsf_infile_child_by_name(infile
, "ClassDirectory3");
224 PIPELINE::MAX::CStorageStream
instream(input
);
225 classDirectory3
.serial(instream
);
227 g_object_unref(input
);
228 //classDirectory3.toString(std::cout);
230 classDirectory3
.parse(PIPELINE::MAX::VersionUnknown
); // parse the structure to readable data
231 classDirectory3
.clean(); // cleanup unused file structure
232 classDirectory3
.toString(std::cout
);
234 //classDirectory3.build(PIPELINE::MAX::VersionUnknown);
235 //classDirectory3.disown();
236 //classDirectory3.toString(std::cout);
243 PIPELINE::MAX::CScene
scene(&sceneClassRegistry
, &dllDirectory
, &classDirectory3
);
244 //PIPELINE::MAX::CStorageContainer scene;
245 input
= gsf_infile_child_by_name(infile
, "Scene");
247 PIPELINE::MAX::CStorageStream
instream(input
);
248 scene
.serial(instream
);
250 g_object_unref(input
);
251 //classDirectory3.toString(std::cout);
253 scene
.parse(PIPELINE::MAX::VersionUnknown
); // parse the structure to readable data
254 scene
.clean(); // cleanup unused file structure
257 scene
.build(PIPELINE::MAX::VersionUnknown
);
261 scene
.parse(PIPELINE::MAX::VersionUnknown
); // parse the structure to readable data
263 //scene.clean(); // cleanup unused file structure, don't clean up if we want direct access to chunks as well
265 scene
.toString(std::cout
);//##
267 //classDirectory3.build(PIPELINE::MAX::VersionUnknown);
268 //classDirectory3.disown();
269 //classDirectory3.toString(std::cout);
273 scene
.container()->scene()->rootNode()->dumpNodes(std::cout
);
276 //PIPELINE::MAX::BUILTIN::INode *node = scene.container()->scene()->rootNode()->find(ucstring("TR_HOF_civil01_gilet")); nlassert(node);
277 //node->toString(std::cout);
278 //exportObj("tr_hof_civil01_gilet.obj", node->getReference(1)->getReference(1)); // => CDerivedObject::getBase(node->object())
280 /*INode *node = scene.container()->scene()->rootNode()->find(ucstring("GE_Acc_MikotoBaniere")); nlassert(node);
281 //INode *node = scene.container()->scene()->rootNode()->find(ucstring("testplane")); nlassert(node);
282 CReferenceMaker *object = node->getReference(1);
283 object->toString(std::cout);
284 exportObj("ge_acc_mikotobaniere.obj", object);*/
287 //GE_Acc_MikotoBaniere
291 #define MAXSCRIPT_UTILITY_CLASS_ID (NLMISC::CClassId(0x04d64858, 0x16d1751d))
292 #define UTILITY_CLASS_ID (4128)
293 #define NEL3D_APPDATA_ENV_FX (84682543)
295 PIPELINE::MAX::CSceneClassContainer *ssc = scene.container();
296 for (PIPELINE::MAX::CStorageContainer::TStorageObjectConstIt it = ssc->chunks().begin(), end = ssc->chunks().end(); it != end; ++it)
298 PIPELINE::MAX::CStorageContainer *subc = static_cast<PIPELINE::MAX::CStorageContainer *>(it->second);
299 for (PIPELINE::MAX::CStorageContainer::TStorageObjectConstIt subit = subc->chunks().begin(), subend = subc->chunks().end(); subit != subend; ++subit)
301 PIPELINE::MAX::IStorageObject *storageChunk = subit->second;
302 PIPELINE::MAX::BUILTIN::STORAGE::CAppData *appData = dynamic_cast<PIPELINE::MAX::BUILTIN::STORAGE::CAppData *>(storageChunk);
306 nlinfo("Found AppData");
307 CStorageRaw *raw = appData->get<CStorageRaw>(MAXSCRIPT_UTILITY_CLASS_ID, UTILITY_CLASS_ID, NEL3D_APPDATA_ENV_FX);
310 nlinfo("Found NEL3D_APPDATA_ENV_FX, size %i", raw->Value.size());
311 //raw->Value.resize(200);
322 scene.build(PIPELINE::MAX::VersionUnknown);
324 scene.parse(PIPELINE::MAX::VersionUnknown);
326 ssc = scene.container();
327 for (PIPELINE::MAX::CStorageContainer::TStorageObjectConstIt it = ssc->chunks().begin(), end = ssc->chunks().end(); it != end; ++it)
329 PIPELINE::MAX::CStorageContainer *subc = static_cast<PIPELINE::MAX::CStorageContainer *>(it->second);
330 for (PIPELINE::MAX::CStorageContainer::TStorageObjectConstIt subit = subc->chunks().begin(), subend = subc->chunks().end(); subit != subend; ++subit)
332 PIPELINE::MAX::IStorageObject *storageChunk = subit->second;
333 PIPELINE::MAX::BUILTIN::STORAGE::CAppData *appData = dynamic_cast<PIPELINE::MAX::BUILTIN::STORAGE::CAppData *>(storageChunk);
337 nlinfo("Found AppData");
338 const CStorageRaw *raw = appData->get<CStorageRaw>(MAXSCRIPT_UTILITY_CLASS_ID, UTILITY_CLASS_ID, NEL3D_APPDATA_ENV_FX);
341 nlinfo("Found NEL3D_APPDATA_ENV_FX, size %i", raw->Value.size());
350 GsfInput *input = gsf_infile_child_by_name(infile, streamname);
353 //gsf_input_dump(input, 1); // just a regular hex dump of this input stream
354 PIPELINE::MAX::CStorageStream instream(input);
355 //dumpContainer(instream, "");
356 PIPELINE::MAX::CScene ctr;
357 ctr.serial(instream);
358 ctr.toString(std::cout);
363 g_object_unref(input);
367 g_object_unref(infile
);