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

Last change on this file since 547 was 547, checked in by oriona, 8 years ago

PreconfiguredGenetics? added in geometrytestutils

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