1 //-----------------------------------------------------------------------------
2 // Product:     OpenCTM tools
3 // File:        ctmbench.cpp
4 // Description: Load/save benchmark tool. This tools is actually just a quick
5 //              hack used for development and testing. To change the compression
6 //              parameters for the save benchmarks, a recompile is required.
7 //-----------------------------------------------------------------------------
8 // Copyright (c) 2009-2010 Marcus Geelnard
9 //
10 // This software is provided 'as-is', without any express or implied
11 // warranty. In no event will the authors be held liable for any damages
12 // arising from the use of this software.
13 //
14 // Permission is granted to anyone to use this software for any purpose,
15 // including commercial applications, and to alter it and redistribute it
16 // freely, subject to the following restrictions:
17 //
18 //     1. The origin of this software must not be misrepresented; you must not
19 //     claim that you wrote the original software. If you use this software
20 //     in a product, an acknowledgment in the product documentation would be
21 //     appreciated but is not required.
22 //
23 //     2. Altered source versions must be plainly marked as such, and must not
24 //     be misrepresented as being the original software.
25 //
26 //     3. This notice may not be removed or altered from any source
27 //     distribution.
28 //-----------------------------------------------------------------------------
29 
30 #include <stdexcept>
31 #include <iostream>
32 #include <cstdlib>
33 #include <openctm.h>
34 #include "systimer.h"
35 
36 using namespace std;
37 
38 
39 //-----------------------------------------------------------------------------
40 // BenchmarkLoads() - Benchmark function for loading OpenCTM files.
41 //-----------------------------------------------------------------------------
42 
BenchmarkLoads(int aIterations,const char * aFileName,double & tMin,double & tMax,double & tTotal)43 void BenchmarkLoads(int aIterations, const char * aFileName, double &tMin,
44   double &tMax, double &tTotal)
45 {
46   SysTimer timer;
47 
48   // Iterate...
49   cout << "Doing " << aIterations << " load iterations..." << endl << flush;
50   for(int i = 0; i < aIterations; ++ i)
51   {
52     CTMimporter ctm;
53 
54     // Start the timer
55     timer.Push();
56 
57     // Load the file
58     ctm.Load(aFileName);
59 
60     // Stop the timer
61     double t = timer.PopDelta();
62     if(i == 0)
63     {
64       tMin = t;
65       tMax = t;
66     }
67     else
68     {
69       if(t < tMin) tMin = t;
70       if(t > tMax) tMax = t;
71     }
72     tTotal += t;
73   }
74 }
75 
76 
77 //-----------------------------------------------------------------------------
78 // BenchmarkSaves() - Benchmark function for saving OpenCTM files.
79 //-----------------------------------------------------------------------------
80 
BenchmarkSaves(int aIterations,const char * aInFile,const char * aOutFile,double & tMin,double & tMax,double & tTotal)81 void BenchmarkSaves(int aIterations, const char * aInFile, const char * aOutFile,
82   double &tMin, double &tMax, double &tTotal)
83 {
84   SysTimer timer;
85 
86   // Load the file
87   CTMimporter in;
88   in.Load(aInFile);
89 
90   // Extract mesh definition
91   CTMint triCount = in.GetInteger(CTM_TRIANGLE_COUNT);
92   CTMint vertCount = in.GetInteger(CTM_VERTEX_COUNT);
93   const CTMuint * indx = in.GetIntegerArray(CTM_INDICES);
94   const CTMfloat * vert = in.GetFloatArray(CTM_VERTICES);
95   const CTMfloat * norm = 0;
96   if(in.GetInteger(CTM_HAS_NORMALS))
97     norm = in.GetFloatArray(CTM_NORMALS);
98 
99   // Iterate...
100   cout << "Doing " << aIterations << " save iterations..." << endl << flush;
101   for(int i = 0; i < aIterations; ++ i)
102   {
103     // Define the mesh
104     CTMexporter out;
105     out.DefineMesh(vert, vertCount, indx, triCount, norm);
106 
107     int uvCount = in.GetInteger(CTM_UV_MAP_COUNT);
108     for(int k = 0; k < uvCount; ++ k)
109     {
110       const CTMfloat * uvMap = in.GetFloatArray(CTMenum(CTM_UV_MAP_1 + k));
111       const char * name = in.GetUVMapString(CTMenum(CTM_UV_MAP_1 + k), CTM_NAME);
112       const char * fileName = in.GetUVMapString(CTMenum(CTM_UV_MAP_1 + k), CTM_FILE_NAME);
113       out.AddUVMap(uvMap, name, fileName);
114     }
115 
116     int attrCount = in.GetInteger(CTM_ATTRIB_MAP_COUNT);
117     for(int k = 0; k < attrCount; ++ k)
118     {
119       const CTMfloat * attrMap = in.GetFloatArray(CTMenum(CTM_ATTRIB_MAP_1 + k));
120       const char * name = in.GetAttribMapString(CTMenum(CTM_ATTRIB_MAP_1 + k), CTM_NAME);
121       out.AddAttribMap(attrMap, name);
122     }
123 
124     // Select compression parameters
125     out.CompressionMethod(CTM_METHOD_MG1);
126 
127     // Start the timer
128     timer.Push();
129 
130     // Save the file
131     out.Save(aOutFile);
132 
133     // Stop the timer
134     double t = timer.PopDelta();
135     if(i == 0)
136     {
137       tMin = t;
138       tMax = t;
139     }
140     else
141     {
142       if(t < tMin) tMin = t;
143       if(t > tMax) tMax = t;
144     }
145     tTotal += t;
146   }
147 }
148 
149 
150 //-----------------------------------------------------------------------------
151 // main() - Program entry.
152 //-----------------------------------------------------------------------------
153 
main(int argc,char ** argv)154 int main(int argc, char **argv)
155 {
156   // Usage?
157   if((argc < 3) || (argc > 4))
158   {
159     cout << "Usage: ctmbench iterations infile [outfile]" << endl;
160     return 0;
161   }
162 
163   // Get the number of iterations
164   int iterations;
165   iterations = atoi(argv[1]);
166   if(iterations < 1)
167     iterations = 1;
168 
169   // Should we do load benchmarking or save benchmarking?
170   bool benchSave = (argc == 4);
171 
172   try
173   {
174     double tMin = 0.0, tMax = 0.0, tTotal = 0.0;
175     if(benchSave)
176       BenchmarkSaves(iterations, argv[2], argv[3], tMin, tMax, tTotal);
177     else
178       BenchmarkLoads(iterations, argv[2], tMin, tMax, tTotal);
179 
180     // Print report
181     cout << " Min: " << tMin * 1000.0 << " ms" << endl;
182     cout << " Max: " << tMax * 1000.0 << " ms" << endl;
183     cout << "Avg.: " << (tTotal / iterations) * 1000.0 << " ms" << endl;
184   }
185   catch(exception &e)
186   {
187     cout << "Error: " << e.what() << endl;
188   }
189 }
190