source: cpp/frams/_demos/geometry/geometrytestutils.cpp @ 299

Last change on this file since 299 was 299, checked in by Maciej Komosinski, 9 years ago

Instead of linking with stdiofile-autoinit.cpp, create an object StdioFileSystem_autoselect stdiofilesys;

  • Property svn:eol-style set to native
File size: 8.0 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "geometrytestutils.h"
6
7#include "../genotypeloader.h"
8#include <frams/virtfile/stdiofile.h>
9#include <math.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <time.h>
13
14int printGenotypesList(const char *file)
15{
16        long count = 0;
17        long totalSize = 0;
18        MiniGenotypeLoader loader(file);
19        MiniGenotype *genotype;
20       
21        while (genotype = loader.loadNextGenotype())
22        {
23                count++;
24                totalSize += genotype->genotype.len();
25               
26                fprintf(stderr, "%d. (%6d chars) %s\n", count, genotype->genotype.len(),
27                        (const char*)genotype->name);
28        }
29       
30        if (loader.getStatus() == MiniGenotypeLoader::OnError)
31        {
32                fprintf(stderr, "Error: %s\n", (const char*)loader.getError());
33                return 2;
34        }
35        else
36        {
37                fprintf(stderr, "\ntotal: %d items, %d chars\n", count, totalSize);
38                return 0;
39        }
40}
41
42class TestInvoker
43{
44        public:
45                virtual void operator()(Model &model) = 0;
46};
47
48int executeTestUsingLoadedModel(const char *file, const char *genoId, TestInvoker &test)
49{
50        const char* genoName = genoId;
51        const int genoIndex = isdigit(genoId[0]) ? atol(genoId) : 0;
52        long count = 0;
53        MiniGenotypeLoader loader(file);
54        MiniGenotype *genotype;
55       
56        while (genotype = loader.loadNextGenotype())
57        {
58                count++;
59               
60                if ((genoIndex == count) || (strcmp((const char*)genotype->name, genoName) == 0))
61                {
62                        Model model(genotype->genotype);
63                       
64                        if (!model.isValid())
65                        {
66                                fprintf(stderr, "Cannot build Model from this genotype!\n");
67                                return 4;
68                        }
69                       
70                        test(model);
71                        return 0;
72                }
73        }
74       
75        if (loader.getStatus() == MiniGenotypeLoader::OnError)
76        {
77                fprintf(stderr, "Error: %s\n", (const char*)loader.getError());
78                return 2;
79        }
80        else
81        {
82                fprintf(stderr, "Genotype %s not found in %s\n", genoId, file);
83                return 3;
84        }
85}
86
87int executeTestUsingRandomModel(int shape, TestInvoker &test)
88{
89        Model model;
90        model.open();
91
92        if ((shape < 1) || (shape > 3))
93        {
94                shape = (rand()%3) + 1;
95        }
96
97        Part *part = model.addNewPart(Part::Shape(shape));
98        GeometryTestUtils::randomizePositionScaleAndOrient(part);
99
100        model.close();
101        test(model);
102        GeometryTestUtils::describePart(part, stdout);
103}
104
105class ModelBasedTestInvoker: public TestInvoker
106{
107        private:
108                void (*test)(Model &);
109        public:
110                ModelBasedTestInvoker(void (*_test)(Model &)):
111                        test(_test)
112                {}
113                void operator()(Model &model)
114                {
115                        test(model);
116                }
117};
118
119int GeometryTestUtils::execute(const SString header, int argc, char *argv[], void (*test)(Model &))
120{
121        srand(time(NULL));
122        StdioFileSystem_autoselect stdiofilesys;
123       
124        if ((argc == 3) && (strcmp("-l", argv[1]) == 0))
125        {
126                return printGenotypesList(argv[2]);
127        }
128       
129        if ((argc == 4) && (strcmp("-l", argv[1]) == 0))
130        {
131                ModelBasedTestInvoker invoker(test);
132                return executeTestUsingLoadedModel(argv[2], argv[3], invoker);
133        }
134       
135        if ((argc == 2) && (strcmp("-c", argv[1]) == 0))
136        {
137                ModelBasedTestInvoker invoker(test);
138                return executeTestUsingRandomModel(-1, invoker);
139        }
140       
141        if ((argc == 3) && (strcmp("-c", argv[1]) == 0) && isdigit(argv[2][0]))
142        {
143                int shape = atol(argv[2]);
144                ModelBasedTestInvoker invoker(test);
145                return executeTestUsingRandomModel(shape, invoker);
146        }
147       
148        fprintf(stderr,
149                "%s\n\n"
150                "argument lists:\n"
151                "-l FILENAME            - to print list of models in file\n"
152                "-l FILENAME GENO_ID    - to load model from file and run test\n"
153                "-c [SHAPE]             - to create simple random model and run test\n\n"
154                "FILENAME - name of file containing named f0 genotypes\n"
155                "GENO_ID - either genotype name or index (1-based)\n"
156                "SHAPE - 1=ellipsoid, 2=cuboid, 3=cylinder, others or none=random\n",
157                (const char*)header);
158        return 1;
159}
160
161class ModelAndDensityBasedTestInvoker: public TestInvoker
162{
163        private:
164                void (*test)(Model &, const double);
165                double density;
166        public:
167                ModelAndDensityBasedTestInvoker(void (*_test)(Model &, const double), double _density):
168                        test(_test),
169                        density(_density)
170                {}
171               
172                void operator()(Model &model)
173                {
174                        test(model, density);
175                }
176};
177
178int GeometryTestUtils::execute(const SString header, int argc, char *argv[],
179        void (*test)(Model &, const double))
180{
181        srand(time(NULL));
182        StdioFileSystem_autoselect stdiofilesys;
183       
184        if ((argc == 3) && (strcmp("-l", argv[1]) == 0))
185        {
186                return printGenotypesList(argv[2]);
187        }
188
189        if ((argc == 5) && (strcmp("-l", argv[1]) == 0) && isdigit(argv[4][0]))
190        {
191                double density = atol(argv[4]);
192                ModelAndDensityBasedTestInvoker invoker(test, density);
193                return executeTestUsingLoadedModel(argv[2], argv[3], invoker);
194        }
195       
196        if ((argc == 3) && (strcmp("-c", argv[1]) == 0) && isdigit(argv[2][0]))
197        {
198                double density = atol(argv[2]);
199                ModelAndDensityBasedTestInvoker invoker(test, density);
200                return executeTestUsingRandomModel(-1, invoker);
201        }
202       
203        if ((argc == 4) && (strcmp("-c", argv[1]) == 0) && isdigit(argv[2][0]) && isdigit(argv[3][0]))
204        {
205                double density = atol(argv[2]);
206                int shape = atol(argv[3]);
207                ModelAndDensityBasedTestInvoker invoker(test, density);
208                return executeTestUsingRandomModel(shape, invoker);
209        }
210       
211        fprintf(stderr,
212                "%s\n\n"
213                "argument lists:\n"
214                "-l FILENAME                    - to print list of models in file\n"
215                "-l FILENAME GENO_ID DENSITY    - to load model from file and run test\n"
216                "-c DENSITY [SHAPE]             - to create simple random model and run test\n\n"
217                "FILENAME - name of file containing named f0 genotypes\n"
218                "GENO_ID - either genotype name or index (1-based)\n"
219                "DENSITY - minimal number of samples per unit\n"
220                "SHAPE - 1=ellipsoid, 2=cuboid, 3=cylinder, others or none=random\n",
221                (const char*)header);
222        return 1;
223}
224
225void GeometryTestUtils::addAnchorToModel(Model &model)
226{
227        Part *part = model.addNewPart(Part::SHAPE_ELLIPSOID);
228       
229        part->p = Pt3D(0);
230        part->scale = Pt3D(0.1);
231        part->vcolor = Pt3D(1.0, 0.0, 1.0);
232       
233        addAxesToModel(Pt3D(0.5), Orient(Orient_1), Pt3D(0.0), model);
234}
235
236void GeometryTestUtils::addPointToModel(const Pt3D &markerLocation, Model &model)
237{
238        Part *anchor = model.getPart(0);
239        Part *part = model.addNewPart(Part::SHAPE_ELLIPSOID);
240       
241        part->p = Pt3D(markerLocation);
242        part->scale = Pt3D(0.05);
243        part->vcolor = Pt3D(1.0, 1.0, 0.0);
244       
245        model.addNewJoint(anchor, part, Joint::SHAPE_SOLID);
246}
247
248void GeometryTestUtils::addAxesToModel(const Pt3D &sizes, const Orient &axes, const Pt3D &center,
249        Model &model)
250{
251        Part *anchor = model.getPart(0);
252        Part *part;
253       
254        part = model.addNewPart(Part::SHAPE_CUBOID);
255        part->scale = Pt3D(sizes.x, 0.05, 0.05);
256        part->setOrient(axes);
257        part->p = center;
258        part->vcolor = Pt3D(1.0, 0.0, 0.0);
259        model.addNewJoint(anchor, part, Joint::SHAPE_SOLID);
260       
261        part = model.addNewPart(Part::SHAPE_CUBOID);
262        part->scale = Pt3D(0.05, sizes.y, 0.05);
263        part->setOrient(axes);
264        part->p = center;
265        part->vcolor = Pt3D(0.0, 1.0, 0.0);
266        model.addNewJoint(anchor, part, Joint::SHAPE_SOLID);
267       
268        part = model.addNewPart(Part::SHAPE_CUBOID);
269        part->scale = Pt3D(0.05, 0.05, sizes.z);
270        part->setOrient(axes);
271        part->p = center;
272        part->vcolor = Pt3D(0.0, 0.0, 1.0);
273        model.addNewJoint(anchor, part, Joint::SHAPE_SOLID);
274}
275
276void GeometryTestUtils::mergeModels(Model &target, Model &source)
277{
278        Part *targetAnchor = target.getPart(0);
279        Part *sourceAnchor = source.getPart(0);
280       
281        target.moveElementsFrom(source);
282       
283        target.addNewJoint(targetAnchor, sourceAnchor, Joint::SHAPE_SOLID);
284}
285
286double frand(double from, double width)
287{
288        return from + width * ((rand()%10000) / 10000.0);
289}
290
291void GeometryTestUtils::randomizePositionScaleAndOrient(Part *part)
292{
293        part->p = Pt3D(frand(1.5, 1.0), frand(1.5, 1.0), frand(1.5, 1.0));
294        part->scale = Pt3D(frand(0.1, 0.9), frand(0.1, 0.9), frand(0.1, 0.9));
295        part->setRot(Pt3D(frand(0.0, M_PI), frand(0.0, M_PI), frand(0.0, M_PI)));
296}
297
298void GeometryTestUtils::describePart(const Part *part, FILE *output)
299{
300        fprintf(output, "# shape=%d\n", part->shape);
301        fprintf(output, "# x=%f\n", part->p.x);
302        fprintf(output, "# y=%f\n", part->p.y);
303        fprintf(output, "# z=%f\n", part->p.z);
304        fprintf(output, "# sx=%f\n", part->scale.x);
305        fprintf(output, "# sy=%f\n", part->scale.y);
306        fprintf(output, "# sz=%f\n", part->scale.z);
307        fprintf(output, "# rx=%f\n", part->rot.x);
308        fprintf(output, "# ry=%f\n", part->rot.y);
309        fprintf(output, "# rz=%f\n", part->rot.z);
310}
Note: See TracBrowser for help on using the repository browser.