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

Last change on this file since 277 was 271, checked in by Maciej Komosinski, 10 years ago

Refreshed header comments

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