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

Last change on this file since 732 was 732, checked in by Maciej Komosinski, 6 years ago

Added support for "checkpoints" (intermediate phases of development of the Model when converting between genetic encodings). See Model.checkpoint() and conv_f1.cpp for an example.

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