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

Last change on this file since 370 was 348, checked in by Maciej Komosinski, 10 years ago
  • explicit c_str() in SString instead of (const char*) cast
  • genetic converters and GenMan? are now thread-local which enables multi-threaded simulator separation
  • 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                        genotype->name.c_str());
28        }
29       
30        if (loader.getStatus() == MiniGenotypeLoader::OnError)
31        {
32                fprintf(stderr, "Error: %s\n", loader.getError().c_str());
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(genotype->name.c_str(), 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", loader.getError().c_str());
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        return 0;
104}
105
106class ModelBasedTestInvoker: public TestInvoker
107{
108        private:
109                void (*test)(Model &);
110        public:
111                ModelBasedTestInvoker(void (*_test)(Model &)):
112                        test(_test)
113                {}
114                void operator()(Model &model)
115                {
116                        test(model);
117                }
118};
119
120int GeometryTestUtils::execute(const SString header, int argc, char *argv[], void (*test)(Model &))
121{
122        srand(time(NULL));
123        StdioFileSystem_autoselect stdiofilesys;
124       
125        if ((argc == 3) && (strcmp("-l", argv[1]) == 0))
126        {
127                return printGenotypesList(argv[2]);
128        }
129       
130        if ((argc == 4) && (strcmp("-l", argv[1]) == 0))
131        {
132                ModelBasedTestInvoker invoker(test);
133                return executeTestUsingLoadedModel(argv[2], argv[3], invoker);
134        }
135       
136        if ((argc == 2) && (strcmp("-c", argv[1]) == 0))
137        {
138                ModelBasedTestInvoker invoker(test);
139                return executeTestUsingRandomModel(-1, invoker);
140        }
141       
142        if ((argc == 3) && (strcmp("-c", argv[1]) == 0) && isdigit(argv[2][0]))
143        {
144                int shape = atol(argv[2]);
145                ModelBasedTestInvoker invoker(test);
146                return executeTestUsingRandomModel(shape, invoker);
147        }
148       
149        fprintf(stderr,
150                "%s\n\n"
151                "argument lists:\n"
152                "-l FILENAME            - to print list of models in file\n"
153                "-l FILENAME GENO_ID    - to load model from file and run test\n"
154                "-c [SHAPE]             - to create simple random model and run test\n\n"
155                "FILENAME - name of file containing named f0 genotypes\n"
156                "GENO_ID - either genotype name or index (1-based)\n"
157                "SHAPE - 1=ellipsoid, 2=cuboid, 3=cylinder, others or none=random\n",
158                header.c_str());
159        return 1;
160}
161
162class ModelAndDensityBasedTestInvoker: public TestInvoker
163{
164        private:
165                void (*test)(Model &, const double);
166                double density;
167        public:
168                ModelAndDensityBasedTestInvoker(void (*_test)(Model &, const double), double _density):
169                        test(_test),
170                        density(_density)
171                {}
172               
173                void operator()(Model &model)
174                {
175                        test(model, density);
176                }
177};
178
179int GeometryTestUtils::execute(const SString header, int argc, char *argv[],
180        void (*test)(Model &, const double))
181{
182        srand(time(NULL));
183        StdioFileSystem_autoselect stdiofilesys;
184       
185        if ((argc == 3) && (strcmp("-l", argv[1]) == 0))
186        {
187                return printGenotypesList(argv[2]);
188        }
189
190        if ((argc == 5) && (strcmp("-l", argv[1]) == 0) && isdigit(argv[4][0]))
191        {
192                double density = atol(argv[4]);
193                ModelAndDensityBasedTestInvoker invoker(test, density);
194                return executeTestUsingLoadedModel(argv[2], argv[3], invoker);
195        }
196       
197        if ((argc == 3) && (strcmp("-c", argv[1]) == 0) && isdigit(argv[2][0]))
198        {
199                double density = atol(argv[2]);
200                ModelAndDensityBasedTestInvoker invoker(test, density);
201                return executeTestUsingRandomModel(-1, invoker);
202        }
203       
204        if ((argc == 4) && (strcmp("-c", argv[1]) == 0) && isdigit(argv[2][0]) && isdigit(argv[3][0]))
205        {
206                double density = atol(argv[2]);
207                int shape = atol(argv[3]);
208                ModelAndDensityBasedTestInvoker invoker(test, density);
209                return executeTestUsingRandomModel(shape, invoker);
210        }
211       
212        fprintf(stderr,
213                "%s\n\n"
214                "argument lists:\n"
215                "-l FILENAME                    - to print list of models in file\n"
216                "-l FILENAME GENO_ID DENSITY    - to load model from file and run test\n"
217                "-c DENSITY [SHAPE]             - to create simple random model and run test\n\n"
218                "FILENAME - name of file containing named f0 genotypes\n"
219                "GENO_ID - either genotype name or index (1-based)\n"
220                "DENSITY - minimal number of samples per unit\n"
221                "SHAPE - 1=ellipsoid, 2=cuboid, 3=cylinder, others or none=random\n",
222                header.c_str());
223        return 1;
224}
225
226void GeometryTestUtils::addAnchorToModel(Model &model)
227{
228        Part *part = model.addNewPart(Part::SHAPE_ELLIPSOID);
229       
230        part->p = Pt3D(0);
231        part->scale = Pt3D(0.1);
232        part->vcolor = Pt3D(1.0, 0.0, 1.0);
233       
234        addAxesToModel(Pt3D(0.5), Orient(Orient_1), Pt3D(0.0), model);
235}
236
237void GeometryTestUtils::addPointToModel(const Pt3D &markerLocation, Model &model)
238{
239        Part *anchor = model.getPart(0);
240        Part *part = model.addNewPart(Part::SHAPE_ELLIPSOID);
241       
242        part->p = Pt3D(markerLocation);
243        part->scale = Pt3D(0.05);
244        part->vcolor = Pt3D(1.0, 1.0, 0.0);
245       
246        model.addNewJoint(anchor, part, Joint::SHAPE_SOLID);
247}
248
249void GeometryTestUtils::addAxesToModel(const Pt3D &sizes, const Orient &axes, const Pt3D &center,
250        Model &model)
251{
252        Part *anchor = model.getPart(0);
253        Part *part;
254       
255        part = model.addNewPart(Part::SHAPE_CUBOID);
256        part->scale = Pt3D(sizes.x, 0.05, 0.05);
257        part->setOrient(axes);
258        part->p = center;
259        part->vcolor = Pt3D(1.0, 0.0, 0.0);
260        model.addNewJoint(anchor, part, Joint::SHAPE_SOLID);
261       
262        part = model.addNewPart(Part::SHAPE_CUBOID);
263        part->scale = Pt3D(0.05, sizes.y, 0.05);
264        part->setOrient(axes);
265        part->p = center;
266        part->vcolor = Pt3D(0.0, 1.0, 0.0);
267        model.addNewJoint(anchor, part, Joint::SHAPE_SOLID);
268       
269        part = model.addNewPart(Part::SHAPE_CUBOID);
270        part->scale = Pt3D(0.05, 0.05, sizes.z);
271        part->setOrient(axes);
272        part->p = center;
273        part->vcolor = Pt3D(0.0, 0.0, 1.0);
274        model.addNewJoint(anchor, part, Joint::SHAPE_SOLID);
275}
276
277void GeometryTestUtils::mergeModels(Model &target, Model &source)
278{
279        Part *targetAnchor = target.getPart(0);
280        Part *sourceAnchor = source.getPart(0);
281       
282        target.moveElementsFrom(source);
283       
284        target.addNewJoint(targetAnchor, sourceAnchor, Joint::SHAPE_SOLID);
285}
286
287double frand(double from, double width)
288{
289        return from + width * ((rand()%10000) / 10000.0);
290}
291
292void GeometryTestUtils::randomizePositionScaleAndOrient(Part *part)
293{
294        part->p = Pt3D(frand(1.5, 1.0), frand(1.5, 1.0), frand(1.5, 1.0));
295        part->scale = Pt3D(frand(0.1, 0.9), frand(0.1, 0.9), frand(0.1, 0.9));
296        part->setRot(Pt3D(frand(0.0, M_PI), frand(0.0, M_PI), frand(0.0, M_PI)));
297}
298
299void GeometryTestUtils::describePart(const Part *part, FILE *output)
300{
301        fprintf(output, "# shape=%d\n", part->shape);
302        fprintf(output, "# x=%f\n", part->p.x);
303        fprintf(output, "# y=%f\n", part->p.y);
304        fprintf(output, "# z=%f\n", part->p.z);
305        fprintf(output, "# sx=%f\n", part->scale.x);
306        fprintf(output, "# sy=%f\n", part->scale.y);
307        fprintf(output, "# sz=%f\n", part->scale.z);
308        fprintf(output, "# rx=%f\n", part->rot.x);
309        fprintf(output, "# ry=%f\n", part->rot.y);
310        fprintf(output, "# rz=%f\n", part->rot.z);
311}
Note: See TracBrowser for help on using the repository browser.