Changeset 732


Ignore:
Timestamp:
02/15/18 00:42:07 (6 years ago)
Author:
Maciej Komosinski
Message:

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.

Location:
cpp/frams
Files:
2 added
30 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/Makefile-SDK-files

    r729 r732  
    2525STDOUT_LOGGER_OBJS=common/virtfile/virtfile.o common/loggers/loggertostdout.o common/console.o
    2626
    27 GENOTYPE_LOADER_OBJS=frams/_demos/genotypeloader.o frams/param/multiparamload.o
     27GENOTYPE_LOADER_OBJS=frams/_demos/genotypeloader.o frams/_demos/genotypemini.o frams/param/multiparamload.o
    2828SDK_LIB_OBJS= $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GENMAN_SDK_OBJS) $(GEOMETRY_OBJS) $(GENOTYPE_LOADER_OBJS) common/virtfile/stdiofile.o
    2929
     
    3636F0_VARIANTS_OBJS=frams/_demos/f0_variants_test.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS)
    3737
    38 LOADER_TEST_OBJS=frams/_demos/genotypeloader.o frams/_demos/loader_test_geno.o common/virtfile/virtfile.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS)
     38LOADER_TEST_OBJS=frams/_demos/genotypeloader.o frams/_demos/genotypemini.o frams/_demos/loader_test_geno.o common/virtfile/virtfile.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS)
    3939
    4040LOADER_TEST_PARAM_OBJS=frams/_demos/loader_test_param.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS)
    4141
    42 SAVER_TEST_OBJS=frams/_demos/genotypeloader.o frams/_demos/saver_test_geno.o common/virtfile/virtfile.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS)
     42SAVER_TEST_OBJS=frams/_demos/genotypeloader.o frams/_demos/genotypemini.o frams/_demos/saver_test_geno.o common/virtfile/virtfile.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS)
    4343
    4444GENOCONV_TEST_OBJS= frams/_demos/genoconv_test.o frams/_demos/printconvmap.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS)
     
    6464NEURO_LAYOUT_TEST_OBJS= frams/_demos/neuro_layout_test.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GENMAN_SDK_OBJS) frams/canvas/nn_layout_model.o frams/canvas/nn_simple_layout.o frams/canvas/nn_smart_layout.o
    6565
    66 GEOMETRY_INFO_TEST_OBJS=frams/_demos/geometry/info_test.o frams/_demos/geometry/geometrytestutils.o frams/_demos/genotypeloader.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GEOMETRY_OBJS) $(GENMAN_SDK_OBJS) $(STDOUT_LOGGER_OBJS)
     66GEOMETRY_INFO_TEST_OBJS=frams/_demos/geometry/info_test.o frams/_demos/geometry/geometrytestutils.o frams/_demos/genotypeloader.o frams/_demos/genotypemini.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GEOMETRY_OBJS) $(GENMAN_SDK_OBJS) $(STDOUT_LOGGER_OBJS)
    6767
    68 GEOMETRY_SURFACE_TEST_OBJS=frams/_demos/geometry/surface_test.o frams/_demos/geometry/geometrytestutils.o frams/_demos/genotypeloader.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GEOMETRY_OBJS) $(GENMAN_SDK_OBJS) $(STDOUT_LOGGER_OBJS)
     68GEOMETRY_SURFACE_TEST_OBJS=frams/_demos/geometry/surface_test.o frams/_demos/geometry/geometrytestutils.o frams/_demos/genotypeloader.o frams/_demos/genotypemini.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GEOMETRY_OBJS) $(GENMAN_SDK_OBJS) $(STDOUT_LOGGER_OBJS)
    6969
    70 GEOMETRY_VOLUME_TEST_OBJS=frams/_demos/geometry/volume_test.o frams/_demos/geometry/geometrytestutils.o frams/_demos/genotypeloader.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GEOMETRY_OBJS) $(GENMAN_SDK_OBJS) $(STDOUT_LOGGER_OBJS)
     70GEOMETRY_VOLUME_TEST_OBJS=frams/_demos/geometry/volume_test.o frams/_demos/geometry/geometrytestutils.o frams/_demos/genotypeloader.o frams/_demos/genotypemini.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GEOMETRY_OBJS) $(GENMAN_SDK_OBJS) $(STDOUT_LOGGER_OBJS)
    7171
    72 GEOMETRY_APICES_TEST_OBJS=frams/_demos/geometry/apices_test.o frams/_demos/geometry/geometrytestutils.o frams/_demos/genotypeloader.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GEOMETRY_OBJS) $(GENMAN_SDK_OBJS) $(STDOUT_LOGGER_OBJS)
     72GEOMETRY_APICES_TEST_OBJS=frams/_demos/geometry/apices_test.o frams/_demos/geometry/geometrytestutils.o frams/_demos/genotypeloader.o frams/_demos/genotypemini.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GEOMETRY_OBJS) $(GENMAN_SDK_OBJS) $(STDOUT_LOGGER_OBJS)
    7373
    7474SIMIL_TEST_OBJS=frams/_demos/simil_test.o frams/model/similarity/SVD/lapack.o frams/model/similarity/SVD/matrix_tools.o frams/model/similarity/simil_match.o frams/model/similarity/simil_model.o  \
    75      frams/_demos/genotypeloader.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GENMAN_SDK_OBJS)
     75     frams/_demos/genotypeloader.o frams/_demos/genotypemini.o frams/param/multiparamload.o common/virtfile/stdiofile.o $(STDOUT_LOGGER_OBJS) $(SDK_OBJS) $(GENOCONV_SDK_OBJS) $(GENMAN_SDK_OBJS)
    7676
    7777SIMIL_UNITTESTS_OBJS=frams/_demos/simil_unittests.o frams/model/similarity/simil_match.o
  • cpp/frams/_demos/genoconv_test.cpp

    r727 r732  
    2727                in_format = 'x';
    2828        }
    29         SString convert(SString &i, MultiMap *map) { return SString("after conversion..."); }
     29        SString convert(SString &i, MultiMap *map, bool using_checkpoints) { return SString("after conversion..."); }
    3030        ~GenoConv_Test() {}
    3131};
     
    4242        }
    4343
    44         SString convert(SString &i, MultiMap *map)
     44        SString convert(SString &i, MultiMap *map, bool using_checkpoints)
    4545        {
    4646                Model mod;
     
    5353                return mod.getF0Geno().getGenes();
    5454        }
    55        
     55
    5656        ~GenoConv_Test2() {}
    5757};
     
    7070                mapsupport = 1;
    7171        }
    72         SString convert(SString &in, MultiMap *map);
     72        SString convert(SString &in, MultiMap *map, bool using_checkpoints);
    7373        ~GenoConv_Test3() {}
    7474};
    7575
    7676/** main converting routine - most important: direct conversion map example */
    77 SString GenoConv_Test3::convert(SString &in, MultiMap *map)
     77SString GenoConv_Test3::convert(SString &in, MultiMap *map, bool using_checkpoints)
    7878{
    7979        SString dst;
     
    116116}
    117117
     118// arguments:
     119//     genotype (or - meaning "read from stdin") [default: X]
     120//     target format [default: 0]
     121//     "checkpoints" (just write this exact word) [default: not using checkpoints]
    118122int main(int argc, char *argv[])
    119123{
     
    146150                src = "X";
    147151        char dst = (argc > 2) ? *argv[2] : '0';
     152        bool using_checkpoints = (argc > 3) ? (strcmp(argv[3], "checkpoints") == 0) : false;
    148153
    149154        printf("*** Source genotype:\n");
     
    151156        printGen(g1);
    152157        MultiMap m;
    153         Geno g2 = g1.getConverted(dst, &m);
     158        Geno g2 = g1.getConverted(dst, &m, using_checkpoints);
    154159        printf("*** Converted to f%c:\n", dst);
    155160        printGen(g2);
    156         if (m.isEmpty())
    157                 printf("(conversion map not available)\n");
     161
     162        if (using_checkpoints)
     163        { // using Model with checkpoints
     164                Model m1(g2, false, true);//true=using_checkpoints
     165                printf("\nModel built from the converted f%c genotype has %d checkpoints\n", g2.getFormat(), m1.getCheckpointCount());
     166                Model m2(g1, false, true);//true=using_checkpoints
     167                printf("Model built from the source f%c genotype has %d checkpoints\n", g1.getFormat(), m2.getCheckpointCount());
     168                // accessing individual checkpoint models (if available)
     169                if (m1.getCheckpointCount() > 0)
     170                {
     171                        int c = m1.getCheckpointCount() / 2;
     172                        Model *cm = m1.getCheckpoint(c);
     173                        printf("Checkpoint #%d (%d parts, %d joint, %d neurons)\n%s", c, cm->getPartCount(), cm->getJointCount(), cm->getNeuroCount(), cm->getF0Geno().getGenesAndFormat().c_str());
     174                }
     175        }
    158176        else
    159         {
    160                 printf("Conversion map:\n");
    161                 m.print();
    162                 printConvMap(g1.getGenes(), g2.getGenes(), m);
    163                 printf("Reverse conversion map:\n");
    164                 MultiMap rm;
    165                 rm.addReversed(m);
    166                 rm.print();
    167                 printConvMap(g2.getGenes(), g1.getGenes(), rm);
    168         }
    169 
    170         Model mod1(g1, 1);
    171         printf("\nModel map for f%c genotype:\n", g1.getFormat());
    172         printModelMap(g1.getGenes(), mod1.getMap());
    173         mod1.getMap().print();
    174         Model mod2(g2, 1);
    175         printf("\nModel map for f%c genotype:\n", g2.getFormat());
    176         printModelMap(g2.getGenes(), mod2.getMap());
    177         mod2.getMap().print();
     177        { // there is no mapping for checkpoints so it's nothing interesting to see here in the checkpoints mode
     178                if (m.isEmpty())
     179                        printf("(conversion map not available)\n");
     180                else
     181                {
     182                        printf("Conversion map:\n");
     183                        m.print();
     184                        printConvMap(g1.getGenes(), g2.getGenes(), m);
     185                        printf("Reverse conversion map:\n");
     186                        MultiMap rm;
     187                        rm.addReversed(m);
     188                        rm.print();
     189                        printConvMap(g2.getGenes(), g1.getGenes(), rm);
     190                }
     191
     192                Model mod1(g1, 1);
     193                printf("\nModel map for f%c genotype:\n", g1.getFormat());
     194                printModelMap(g1.getGenes(), mod1.getMap());
     195                MultiMap mod1combined;
     196                mod1combined.addCombined(mod1.getMap(), getModelDisplayMap());
     197                mod1combined.print();
     198                Model mod2(g2, 1);
     199                printf("\nModel map for f%c genotype:\n", g2.getFormat());
     200                printModelMap(g2.getGenes(), mod2.getMap());
     201                MultiMap mod2combined;
     202                mod2combined.addCombined(mod2.getMap(), getModelDisplayMap());
     203                mod2combined.print();
     204        }
    178205        return 0;
    179206}
  • cpp/frams/_demos/genotypeloader.cpp

    r639 r732  
    55#include "genotypeloader.h"
    66
    7 #define FIELDSTRUCT MiniGenotype
    8 ParamEntry minigenotype_paramtab[] =
    9 {
    10         { "Genotype", 1, 29, "org", },
    117
    12         { "name", 0, 0, "Name", "s 0 40", FIELD(name), },
    13         { "genotype", 0, 0, "Genotype", "s 1", FIELD(genotype), "Genes as a string of characters.", },
     8GenotypeMiniLoader::GenotypeMiniLoader() :genotype_param(genotypemini_paramtab, &genotype_object) { init(); }
     9GenotypeMiniLoader::GenotypeMiniLoader(VirtFILE *f) : MultiParamLoader(f), genotype_param(genotypemini_paramtab, &genotype_object) { init(); }
     10GenotypeMiniLoader::GenotypeMiniLoader(const char* filename) : MultiParamLoader(filename), genotype_param(genotypemini_paramtab, &genotype_object) { init(); }
    1411
    15         { "info_timestamp", 1, 0, "Last modified", "ft 0 -1 0", FIELD(info_timestamp), },
    16         { "info_author", 1, 0, "Author name", "s 0 100", FIELD(info_author), },
    17         { "info_author_ispublic", 1, 0, "Author name is public", "d 0 1 1", FIELD(info_author_ispublic), },
    18         { "info_email", 1, 0, "Author email", "s 0 100", FIELD(info_email), },
    19         { "info_email_ispublic", 1, 0, "Author email is public", "d 0 1 0", FIELD(info_email_ispublic), },
    20         { "info", 1, 0, "Description", "s 1 1000", FIELD(info), "Short description of key features of this creature.", },
    21         { "info_origin", 1, 0, "Origin", "d 0 4 0 ~Unspecified~Designed~Designed and evolved~Evolved under various conditions~Evolved using single, constant setup", FIELD(info_origin), "Declaration of how this genotype originated." },
    22         { "info_how_created", 1, 0, "How created", "s 1 1000", FIELD(info_how_created), "Description of the process of designing and/or evolving this genotype." },
    23         { "info_performance", 1, 0, "Performance notes", "s 1 1000", FIELD(info_performance), "Description of why this genotype is special/interesting and how it performs." },
    24 
    25         { "energy0", 0, 0, "Starting energy", "f 0 -1 0", FIELD(energy0), },
    26         { "numparts", 0, 0, "Body parts", "d", FIELD(numparts), },
    27         { "numjoints", 0, 0, "Body joints", "d", FIELD(numjoints), },
    28         { "numneurons", 0, 0, "Brain size", "d", FIELD(numneurons), },
    29         { "numconnections", 0, 0, "Brain connections", "d", FIELD(numconnections), },
    30 
    31         { "num", 0, 0, "Ordinal number", "d", FIELD(ordnumber), },
    32         { "gnum", 0, 0, "Generation", "d", FIELD(generation), },
    33 
    34         { "instances", 0, 0, "Instances", "d", FIELD(instances), "Copies of this genotype", },
    35 
    36         { "lifespan", 0, 0, "Life span", "f", FIELD(lifespan), "Average life span", },
    37         { "velocity", 0, 0, "Velocity", "f", FIELD(velocity), "Average velocity", },
    38         { "distance", 0, 0, "Distance", "f", FIELD(distance), },
    39         { "vertvel", 0, 0, "Vertical velocity", "f", FIELD(vertvel), },
    40         { "vertpos", 0, 0, "Vertical position", "f", FIELD(vertpos), },
    41 
    42         { "user1", 0, 0, "User field 1", "x", FIELD(user1), },
    43         { "user2", 0, 0, "User field 2", "x", FIELD(user2), },
    44         { "user3", 0, 0, "User field 3", "x", FIELD(user3), },
    45 
    46         { "is_valid", 0, 0, "Validity", "d -1 1 -1", FIELD(is_valid),
    47         "0 = invalid genotype\n"
    48         "1 = valid genotype\n"
    49         "-1 = validity is not known." },
    50 
    51         { "uid", 0, 0, "#", "s", FIELD(uid), "Unique identifier" },
    52 
    53         { 0, 0, 0, },
    54 };
    55 #undef FIELDSTRUCT
    56 
    57 MiniGenotypeLoader::MiniGenotypeLoader() :genotype_param(minigenotype_paramtab, &genotype_object) { init(); }
    58 MiniGenotypeLoader::MiniGenotypeLoader(VirtFILE *f) : MultiParamLoader(f), genotype_param(minigenotype_paramtab, &genotype_object) { init(); }
    59 MiniGenotypeLoader::MiniGenotypeLoader(const char* filename) : MultiParamLoader(filename), genotype_param(minigenotype_paramtab, &genotype_object) { init(); }
    60 
    61 void MiniGenotypeLoader::init()
     12void GenotypeMiniLoader::init()
    6213{
    6314        addObject(&genotype_param);
     
    6516}
    6617
    67 MiniGenotype* MiniGenotypeLoader::loadNextGenotype()
     18GenotypeMini* GenotypeMiniLoader::loadNextGenotype()
    6819{
    6920        genotype_object.clear();
  • cpp/frams/_demos/genotypeloader.h

    r635 r732  
    88#include <frams/util/sstring.h>
    99#include <frams/param/multiparamload.h>
    10 
    11 /** Defines the association between "org:" object (found in genotype files)
    12         and the MiniGenotype fields. MiniGenotypeLoader uses this definition
    13         but you can also use it to make MultiParamLoader load genotype
    14         */
    15 extern ParamEntry minigenotype_paramtab[];
    16 
    17 /** Helper class, mostly useful with MultiParamLoader
    18         or its specialized version: MiniGenotypeLoader.
    19         MiniGenotype stores the subset of Genotype fields (the ones normally saved in .gen files)
    20         */
    21 class MiniGenotype
    22 {
    23 public:
    24         SString name, genotype, info, uid;
    25         double info_timestamp;
    26         SString info_author, info_email;
    27         paInt info_author_ispublic, info_email_ispublic, info_origin;
    28         SString info_how_created, info_performance;
    29         double energy0, lifespan, velocity, distance, vertvel, vertpos;
    30         paInt numparts, numjoints, numneurons, numconnections, ordnumber, generation, instances, is_valid;
    31         ExtValue user1, user2, user3;
    32         void clear() { Param p(minigenotype_paramtab, this); p.setDefault(); }
    33 };
     10#include "genotypemini.h"
    3411
    3512/** In most simple cases this is the class you would use to load a series of genotypes from
     
    4825        methods, or you can use it as a guide for creating your own specialized class.
    4926        */
    50 class MiniGenotypeLoader : public MultiParamLoader
     27class GenotypeMiniLoader : public MultiParamLoader
    5128{
    52         MiniGenotype genotype_object;
     29        GenotypeMini genotype_object;
    5330        Param genotype_param;
    5431        bool initialized;
    5532        void init();
    5633public:
    57         MiniGenotypeLoader();
    58         MiniGenotypeLoader(VirtFILE *f);
    59         MiniGenotypeLoader(const char* filename);
     34        GenotypeMiniLoader();
     35        GenotypeMiniLoader(VirtFILE *f);
     36        GenotypeMiniLoader(const char* filename);
    6037
    6138        /** @returns genotype object if one was loaded or NULL otherwise.
    6239
    63                 Returned MiniGenotype pointer always references the the same object (MiniGenotypeLoader::genotype_object)
     40                Returned GenotypeMini pointer always references the the same object (GenotypeMiniLoader::genotype_object)
    6441                which means you may need to copy the data from it before calling loadNextGenotype() again.
    65                 In the default configuration (simple MiniGenotypeLoader) NULL is always final and should be used
     42                In the default configuration (simple GenotypeMiniLoader) NULL is always final and should be used
    6643                to finish processing.
    6744
     
    7047                MultiParamLoader::finished() and other methods to determine the real cause of NULL.
    7148                */
    72         MiniGenotype* loadNextGenotype();
     49        GenotypeMini* loadNextGenotype();
    7350};
    7451
  • cpp/frams/_demos/geometry/geometrytestutils.cpp

    r662 r732  
    1818        long count = 0;
    1919        long totalSize = 0;
    20         MiniGenotypeLoader loader(file);
    21         MiniGenotype *genotype;
    22        
     20        GenotypeMiniLoader loader(file);
     21        GenotypeMini *genotype;
     22
    2323        while (genotype = loader.loadNextGenotype())
    2424        {
    2525                count++;
    2626                totalSize += genotype->genotype.len();
    27                
     27
    2828                fprintf(stderr, "%d. (%6d chars) %s\n", count, genotype->genotype.len(),
    2929                        genotype->name.c_str());
    3030        }
    31        
    32         if (loader.getStatus() == MiniGenotypeLoader::OnError)
     31
     32        if (loader.getStatus() == GenotypeMiniLoader::OnError)
    3333        {
    3434                fprintf(stderr, "Error: %s\n", loader.getError().c_str());
     
    4444class TestInvoker
    4545{
    46         public:
    47                 virtual void operator()(Model &model) = 0;
     46public:
     47        virtual void operator()(Model &model) = 0;
    4848};
    4949
     
    5353        const int genoIndex = isdigit(genoId[0]) ? atol(genoId) : 0;
    5454        long count = 0;
    55         MiniGenotypeLoader loader(file);
    56         MiniGenotype *genotype;
    57        
     55        GenotypeMiniLoader loader(file);
     56        GenotypeMini *genotype;
     57
    5858        while (genotype = loader.loadNextGenotype())
    5959        {
    6060                count++;
    61                
     61
    6262                if ((genoIndex == count) || (strcmp(genotype->name.c_str(), genoName) == 0))
    6363                {
    6464                        Model model(genotype->genotype);
    65                        
     65
    6666                        if (!model.isValid())
    6767                        {
     
    7474                }
    7575        }
    76        
    77         if (loader.getStatus() == MiniGenotypeLoader::OnError)
     76
     77        if (loader.getStatus() == GenotypeMiniLoader::OnError)
    7878        {
    7979                fprintf(stderr, "Error: %s\n", loader.getError().c_str());
     
    9494        if ((shape < 1) || (shape > 3))
    9595        {
    96                 shape = (rand()%3) + 1;
     96                shape = (rand() % 3) + 1;
    9797        }
    9898
     
    106106}
    107107
    108 class 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                 }
     108class ModelBasedTestInvoker : public TestInvoker
     109{
     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        }
    120120};
    121121
    122 int GeometryTestUtils::execute(const SString header, int argc, char *argv[], void (*test)(Model &))
     122int GeometryTestUtils::execute(const SString header, int argc, char *argv[], void(*test)(Model &))
    123123{
    124124        LoggerToStdout messages_to_stdout(LoggerBase::Enable); //comment this object out to mute error/warning messages
    125125        StdioFileSystem_autoselect stdiofilesys;
    126126        PreconfiguredGenetics genetics;
    127        
     127
    128128        srand(time(NULL));
    129129
     
    132132                return printGenotypesList(argv[2]);
    133133        }
    134        
     134
    135135        if ((argc == 4) && (strcmp("-l", argv[1]) == 0))
    136136        {
     
    138138                return executeTestUsingLoadedModel(argv[2], argv[3], invoker);
    139139        }
    140        
     140
    141141        if ((argc == 2) && (strcmp("-c", argv[1]) == 0))
    142142        {
     
    144144                return executeTestUsingRandomModel(-1, invoker);
    145145        }
    146        
     146
    147147        if ((argc == 3) && (strcmp("-c", argv[1]) == 0) && isdigit(argv[2][0]))
    148148        {
     
    151151                return executeTestUsingRandomModel(shape, invoker);
    152152        }
    153        
     153
    154154        fprintf(stderr,
    155155                "%s\n\n"
     
    165165}
    166166
    167 class ModelAndDensityBasedTestInvoker: public TestInvoker
    168 {
    169         private:
    170                 void (*test)(Model &, const double);
    171                 double density;
    172         public:
    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                 }
     167class ModelAndDensityBasedTestInvoker : public TestInvoker
     168{
     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        }
    182182};
    183183
    184184int GeometryTestUtils::execute(const SString header, int argc, char *argv[],
    185         void (*test)(Model &, const double))
     185        void(*test)(Model &, const double))
    186186{
    187187        LoggerToStdout messages_to_stdout(LoggerBase::Enable); //comment this object out to mute error/warning messages
    188188        StdioFileSystem_autoselect stdiofilesys;
    189189        PreconfiguredGenetics genetics;
    190        
     190
    191191        srand(time(NULL));
    192192
     
    202202                return executeTestUsingLoadedModel(argv[2], argv[3], invoker);
    203203        }
    204        
     204
    205205        if ((argc == 3) && (strcmp("-c", argv[1]) == 0) && isdigit(argv[2][0]))
    206206        {
     
    209209                return executeTestUsingRandomModel(-1, invoker);
    210210        }
    211        
     211
    212212        if ((argc == 4) && (strcmp("-c", argv[1]) == 0) && isdigit(argv[2][0]) && isdigit(argv[3][0]))
    213213        {
     
    217217                return executeTestUsingRandomModel(shape, invoker);
    218218        }
    219        
     219
    220220        fprintf(stderr,
    221221                "%s\n\n"
     
    235235{
    236236        Part *part = model.addNewPart(Part::SHAPE_ELLIPSOID);
    237        
     237
    238238        part->p = Pt3D(0);
    239239        part->scale = Pt3D(0.1);
    240240        part->vcolor = Pt3D(1.0, 0.0, 1.0);
    241        
     241
    242242        addAxesToModel(Pt3D(0.5), Orient(Orient_1), Pt3D(0.0), model);
    243243}
     
    247247        Part *anchor = model.getPart(0);
    248248        Part *part = model.addNewPart(Part::SHAPE_ELLIPSOID);
    249        
     249
    250250        part->p = Pt3D(markerLocation);
    251251        part->scale = Pt3D(0.05);
    252252        part->vcolor = Pt3D(1.0, 1.0, 0.0);
    253        
     253
    254254        model.addNewJoint(anchor, part, Joint::SHAPE_FIXED);
    255255}
     
    260260        Part *anchor = model.getPart(0);
    261261        Part *part;
    262        
     262
    263263        part = model.addNewPart(Part::SHAPE_CUBOID);
    264264        part->scale = Pt3D(sizes.x, 0.05, 0.05);
     
    267267        part->vcolor = Pt3D(1.0, 0.0, 0.0);
    268268        model.addNewJoint(anchor, part, Joint::SHAPE_FIXED);
    269        
     269
    270270        part = model.addNewPart(Part::SHAPE_CUBOID);
    271271        part->scale = Pt3D(0.05, sizes.y, 0.05);
     
    274274        part->vcolor = Pt3D(0.0, 1.0, 0.0);
    275275        model.addNewJoint(anchor, part, Joint::SHAPE_FIXED);
    276        
     276
    277277        part = model.addNewPart(Part::SHAPE_CUBOID);
    278278        part->scale = Pt3D(0.05, 0.05, sizes.z);
     
    287287        Part *targetAnchor = target.getPart(0);
    288288        Part *sourceAnchor = source.getPart(0);
    289        
     289
    290290        target.moveElementsFrom(source);
    291        
     291
    292292        target.addNewJoint(targetAnchor, sourceAnchor, Joint::SHAPE_FIXED);
    293293}
     
    295295double frand(double from, double width)
    296296{
    297         return from + width * ((rand()%10000) / 10000.0);
     297        return from + width * ((rand() % 10000) / 10000.0);
    298298}
    299299
  • cpp/frams/_demos/loader_test_geno.cpp

    r520 r732  
    2626        long count = 0, totalsize = 0;
    2727        StdioFileSystem_autoselect stdiofilesys;
    28         MiniGenotypeLoader loader(argv[1]);
     28        GenotypeMiniLoader loader(argv[1]);
    2929        const char* selected = (argc < 3) ? NULL : argv[2];
    3030        const char* field_name = (argc < 4) ? NULL : argv[3];
    3131        int selected_index = (selected&&isdigit(selected[0])) ? atol(selected) : 0;
    3232        // using char* constructor (passing the file name to open)
    33         MiniGenotype *loaded;
     33        GenotypeMini *loaded;
    3434        while (loaded = loader.loadNextGenotype())
    3535        { // if loaded != NULL then the "org:" object data was
     
    5151                        if (field_name)
    5252                        {
    53                                 Param p(minigenotype_paramtab, loaded);
     53                                Param p(genotypemini_paramtab, loaded);
    5454                                int field_index = p.findId(field_name);
    5555                                if (field_index < 0)
     
    6868        }
    6969        // the loop repeats until loaded==NULL, which could be beacause of error
    70         if (loader.getStatus() == MiniGenotypeLoader::OnError)
     70        if (loader.getStatus() == GenotypeMiniLoader::OnError)
    7171                fprintf(stderr, "Error: %s", loader.getError().c_str());
    7272        // (otherwise it was the end of the file)
  • cpp/frams/_demos/paramtree_paramlist_test.cpp

    r730 r732  
    2222        PreconfiguredGenetics genetics;
    2323
    24         Param minigenotype_param(minigenotype_paramtab);
     24        Param genotypemini_param(genotypemini_paramtab);
    2525        NeuroFactory neurofac;
    2626        neurofac.setStandardImplementation();
     
    3636        combined += &Pt3D_Ext::getStaticParam();
    3737        combined += &Orient_Ext::getStaticParam();
    38         combined += &minigenotype_param;
     38        combined += &genotypemini_param;
    3939        combined += &nn_config.par;
    4040        combined += &modelgeo.par;
  • cpp/frams/_demos/printconvmap.cpp

    r348 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    66#include <stdio.h>
    77#include <frams/util/multimap.h>
     8#include <frams/model/model.h>
    89
    910#define GEN1MAX 15
    1011
    11 void printN(const char* t,int maxlen)
     12void printN(const char* t, int maxlen)
    1213{
    13 while(maxlen-- > 0)
    14         if (*t) putchar(*(t++));
    15         else putchar(' ');
     14        while (maxlen-- > 0)
     15                if (*t) putchar(*(t++));
     16                else putchar(' ');
    1617}
    1718
    18 void printN(char t,int maxlen)
     19void printN(char t, int maxlen)
    1920{
    20 while(maxlen-- > 0) putchar(t);
     21        while (maxlen-- > 0) putchar(t);
    2122}
    2223
    23 void printmapping(const char* gen1, int len1,const MultiRange &mr,const char* gen2,int len2)
     24void printmapping(const char* gen1, int len1, const MultiRange &mr, const char* gen2, int len2)
    2425{
    25 printN(' ',GEN1MAX-len1);
    26 printN(gen1,len1);
    27 printf(" : ");
    28 int i;
    29 for(i=0;i<len2;i++)
    30         if (mr.contains(i))
    31                 putchar(gen2[i]);
    32         else
    33                 putchar('.');
    34 putchar('\n');
     26        printN(' ', GEN1MAX - len1);
     27        printN(gen1, len1);
     28        printf(" : ");
     29        int i;
     30        for (i = 0; i < len2; i++)
     31                if (mr.contains(i))
     32                        putchar(gen2[i]);
     33                else
     34                        putchar('.');
     35        putchar('\n');
    3536}
    3637
    3738void stripstring(SString &str)
    3839{
    39 char *t=str.directWrite();
    40 for(;*t;t++)
    41         if (strchr("\n\r\t",*t)) *t=' ';
     40        char *t = str.directWrite();
     41        for (; *t; t++)
     42                if (strchr("\n\r\t", *t)) *t = ' ';
    4243}
    4344
    44 void printConvMap(const SString& gen1,const SString& gen2,const MultiMap& map)
     45void printConvMap(const SString& gen1, const SString& gen2, const MultiMap& map)
    4546{
    46 int y,y2,len1;
    47 int id=0;
    48 if (map.isEmpty())
     47        int y, y2, len1;
     48        int id = 0;
     49        if (map.isEmpty())
    4950        {
    50         printf("{ empty }\n");
    51         return;
     51                printf("{ empty }\n");
     52                return;
    5253        }
    53 len1=gen1.len();
    54 SString g1=gen1;
    55 stripstring(g1);
    56 SString g2=gen2;
    57 stripstring(g2);
    58 const char* g=g1.c_str();
    59 y=0;
    60 MultiRange *mr;
    61 MultiRange emptyrange;
    62 printN(' ',GEN1MAX);
    63 printf("   %s\n",g2.c_str());
    64 int begin=map.getBegin();
    65 int end=map.getEnd();
    66 while(y<len1)
     54        len1 = gen1.len();
     55        SString g1 = gen1;
     56        stripstring(g1);
     57        SString g2 = gen2;
     58        stripstring(g2);
     59        const char* g = g1.c_str();
     60        y = 0;
     61        MultiRange *mr;
     62        MultiRange emptyrange;
     63        printN(' ', GEN1MAX);
     64        printf("   %s\n", g2.c_str());
     65        int begin = map.getBegin();
     66        int end = map.getEnd();
     67        while (y < len1)
    6768        {
    68         if (y<begin)
     69                if (y < begin)
    6970                {
    70                 mr=&emptyrange;
    71                 y2=begin;
     71                        mr = &emptyrange;
     72                        y2 = begin;
    7273                }
    73         else if (y>end)
     74                else if (y > end)
    7475                {
    75                 mr=&emptyrange;
    76                 y2=len1;
     76                        mr = &emptyrange;
     77                        y2 = len1;
    7778                }
    78         else    {
    79                 id=map.findMappingId(y);
    80                 mr=&map.getMapping(id)->to;
    81                 y2=map.getMapping(id+1)->begin;
     79                else    {
     80                        id = map.findMappingId(y);
     81                        mr = &map.getMapping(id)->to;
     82                        y2 = map.getMapping(id + 1)->begin;
    8283                }
    83         if ((y2-y) > GEN1MAX) y2=y+GEN1MAX;
    84         if (y2>(y+len1)) y2=y+len1;
    85         printmapping(g+y,y2-y,*mr,g2.c_str(),g2.len());
    86         y=y2;
     84                if ((y2 - y) > GEN1MAX) y2 = y + GEN1MAX;
     85                if (y2 > (y + len1)) y2 = y + len1;
     86                printmapping(g + y, y2 - y, *mr, g2.c_str(), g2.len());
     87                y = y2;
    8788        }
    8889}
    8990
    90 void printModelMap(const SString& gen1,const MultiMap& map)
     91const MultiMap & getModelDisplayMap()
    9192{
    92 SString g2("012345678901234567890123456789");
    93 printN(' ',GEN1MAX);
    94 printf("   Parts     Joints    Neurons\n");
    95 printConvMap(gen1,g2,map);
     93        static MultiMap display_map;
     94        if (display_map.isEmpty())
     95        {
     96                for (int i = 0; i < 10; i++)
     97                {
     98                        display_map.add(Model::partToMap(i), Model::partToMap(i), i, i);
     99                        display_map.add(Model::jointToMap(i), Model::jointToMap(i), 10 + i, 10 + i);
     100                        display_map.add(Model::neuroToMap(i), Model::neuroToMap(i), 20 + i, 20 + i);
     101                }
     102        }
     103        return display_map;
    96104}
     105
     106void printModelMap(const SString& gen1, const MultiMap& map)
     107{
     108        MultiMap combined_map;
     109        combined_map.addCombined(map, getModelDisplayMap());
     110        SString g2("012345678901234567890123456789");
     111        printN(' ', GEN1MAX);
     112        printf("   Parts     Joints    Neurons\n");
     113        printConvMap(gen1, g2, combined_map);
     114}
  • cpp/frams/_demos/printconvmap.h

    r286 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1010class MultiMap;
    1111
    12 void printConvMap(const SString& gen1,const SString& gen2,const MultiMap& map);
    13 void printModelMap(const SString& gen1,const MultiMap& map);
     12void printConvMap(const SString& gen1, const SString& gen2, const MultiMap& map);
     13void printModelMap(const SString& gen1, const MultiMap& map); //automaticaly combines the map with the ModelDisplayMap
     14const MultiMap & getModelDisplayMap(); // mapping: true model -> display (so the regular map printing/debugging tools can be used for model maps, avoiding invonveniently huge numbers)
    1415
    1516#endif
  • cpp/frams/_demos/saver_test_geno.cpp

    r520 r732  
    2828        {
    2929                int N = atoi(argv[2]);
    30                 MiniGenotype g;
    31                 Param p(minigenotype_paramtab, &g);
     30                GenotypeMini g;
     31                Param p(genotypemini_paramtab, &g);
    3232                g.clear();
    3333                printf("Saving %d genotypes to %s\n", N, argv[1]);
  • cpp/frams/_demos/simil_test.cpp

    r612 r732  
    125125
    126126        long count = 0, totalsize = 0;
    127         MiniGenotypeLoader loader(szFileName);
    128         MiniGenotype *loaded;
     127        GenotypeMiniLoader loader(szFileName);
     128        GenotypeMini *loaded;
    129129        while (loaded = loader.loadNextGenotype())
    130130        {
     
    147147                }
    148148        }
    149         if (loader.getStatus() == MiniGenotypeLoader::OnError)
     149        if (loader.getStatus() == GenotypeMiniLoader::OnError)
    150150        {
    151151                printf("Error: %s", loader.getError().c_str());
  • cpp/frams/config/f0-SDK.def

    r528 r732  
    8989PROP(getInputNeuroIndex,0,1+2,`get input neuron index',p d(d),,,,p_getInputNeuroIndex,PROCEDURE)
    9090PROP(getInputWeight,0,1+2,`get input weight',p f(d),,,,p_getInputWeight,PROCEDURE)
    91 PROP(classObject,0,1+2,`neuron class',o NeuroClass,,,,classObject,GETONLY)
     91PROP(classObject,0,1+2,`neuron class',oNeuroClass,,,,classObject,GETONLY)
    9292ENDCLASS
    9393
  • cpp/frams/config/f0.def

    r656 r732  
    8989PROP(getInputNeuroIndex,0,0,`get input neuron index',p d(d),,,,p_getInputNeuroIndex,PROCEDURE)
    9090PROP(getInputWeight,0,0,`get input weight',p f(d),,,,p_getInputWeight,PROCEDURE)
    91 PROP(classObject,0,1+2,`neuron class',o NeuroClass,,,,classObject,GETONLY)
     91PROP(classObject,0,1+2,`neuron class',oNeuroClass,,,,classObject,GETONLY)
    9292ENDCLASS
    9393
  • cpp/frams/config/sdk_build_config.h

    r318 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1515
    1616#define NOCREATUREOBJECT
    17 #define EASYMAPDEBUG
    1817#define SDK_WITHOUT_FRAMS
    1918#define NO_BARRIER
  • cpp/frams/genetics/f1/conv_f1.cpp

    r726 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1414
    1515F1Props stdprops = { 1, 0, 1, 0.4, 0.25, 0.25, 0.25, 0.25, 0.0, 1.0, 1.0, 1,
    16         0.2, 0.5, 0.5, 0.5 };
     160.2, 0.5, 0.5, 0.5 };
    1717
    1818class Builder
     
    106106
    107107/** main conversion function - with conversion map support */
    108 SString GenoConv_f1::convert(SString &i, MultiMap *map)
     108SString GenoConv_f1::convert(SString &i, MultiMap *map, bool using_checkpoints)
    109109{
    110110        const char* g = i.c_str();
    111111        Builder builder(g, map ? 1 : 0);
    112         builder.model.open();
     112        builder.model.open(using_checkpoints);
    113113        builder.grow(-1, g, Pt3D_0, stdprops, -1); // uses Model::addFromString() to create model elements
    114114        if (builder.invalid) return SString();
     
    242242
    243243                        if (c.muscle_reset_range) c.muscle_bend_range = 1.0; else c.muscle_reset_range = true;
     244                        model.checkpoint();
    244245                        grow(part2, g + 1, Pt3D_0, c, branching_part);
    245246                        return;
  • cpp/frams/genetics/f1/conv_f1.h

    r671 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    6969                mapsupport = 1;
    7070        }
    71         SString convert(SString &i, MultiMap *map);
     71        SString convert(SString &i, MultiMap *map, bool using_checkpoints);
    7272        ~GenoConv_f1() {}
    7373};
  • cpp/frams/genetics/geno.cpp

    r534 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    3232        name = genname;
    3333        txt = comment;
    34         setGenesAndFormat(genstring,genformat);
     34        setGenesAndFormat(genstring, genformat);
    3535}
    3636
     
    5454                                        mapinshift = end + 1;
    5555                                        gencopy = genstring.substr(end + 1);
    56                                         if ((end>0) && (genstring[end-1]=='\r')) end--;
     56                                        if ((end > 0) && (genstring[end - 1] == '\r')) end--;
    5757                                        error_end = end;
    5858                                        if (end != 3) genformat = INVALID_FORMAT;
     
    8282                                break;
    8383                        }
    84                         if (!isalnum(genformat)) genformat=INVALID_FORMAT;
     84                        if (!isalnum(genformat)) genformat = INVALID_FORMAT;
    8585                        if (genformat == INVALID_FORMAT)
    8686                        {
     
    9393                                        cut = genstring.substr(0, error_end);
    9494                                int lf = cut.indexOf('\n');
    95                                 if (lf >= 0) { if ((lf>0)&&(cut[lf-1]=='\r')) lf--; cut = cut.substr(0, lf); }
     95                                if (lf >= 0) { if ((lf > 0) && (cut[lf - 1] == '\r')) lf--; cut = cut.substr(0, lf); }
    9696                                sstringQuote(cut);
    9797                                logPrintf("Geno", "init", LOG_ERROR, "Invalid genotype format declaration: '%s'%s", cut.c_str(), name.len() ? SString::sprintf(" in '%s'", name.c_str()).c_str() : "");
     
    226226        {
    227227                bool converter_missing;
    228                 Geno f0geno = g.getConverted('0', NULL, &converter_missing);
     228                Geno f0geno = g.getConverted('0', NULL, false, &converter_missing);
    229229                if (converter_missing)
    230230                        return -1;//no result
     
    295295}
    296296
    297 Geno Geno::getConverted(char otherformat, MultiMap *m, bool *converter_missing)
     297Geno Geno::getConverted(char otherformat, MultiMap *m, bool using_checkpoints, bool *converter_missing)
    298298{
    299299        if (otherformat == getFormat()) { if (converter_missing) *converter_missing = false; return *this; }
     
    302302        if (converters)
    303303        {
    304                 if ((otherformat == '0') && (!m))
     304                if ((otherformat == '0') && (!m) && (!using_checkpoints))
    305305                {
    306306                        if (!f0gen)
    307                                 f0gen = new Geno(converters->convert(*this, otherformat, NULL, converter_missing));
     307                                f0gen = new Geno(converters->convert(*this, otherformat, NULL, using_checkpoints, converter_missing));
    308308                        else
    309309                        {
     
    313313                }
    314314                else
    315                         return converters->convert(*this, otherformat, m, converter_missing);
     315                        return converters->convert(*this, otherformat, m, using_checkpoints, converter_missing);
    316316        }
    317317#endif
  • cpp/frams/genetics/geno.h

    r534 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2016  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    9090
    9191        /** @param genformat=-1 -> detect genotype format from genstring comment (like the constructor does), else specify the valid format in genformat and pure genes in genstring. */
    92         void setGenesAndFormat(const SString& genstring, char genformat=-1);
     92        void setGenesAndFormat(const SString& genstring, char genformat = -1);
    9393        /** g must be pure genes, without format. For the standard behavior use setGenesAndFormat() */
    9494        void setGenesAssumingSameFormat(const SString& g);
     
    107107        /// make converted version of the genotype.
    108108        /// @param converter_missing optional output parameter (ignored when NULL). Receives true if the conversion fails because of the lack of appropriate converter(s) (the returned Geno is always invalid in this case). Receives false if the genotype was converted by a converter or a converter chain (the returned Geno can be valid or invalid, depending on the converter's decision).
    109         Geno getConverted(char otherformat, MultiMap *m = 0, bool *converter_missing = NULL);
     109        Geno getConverted(char otherformat, MultiMap *m = 0, bool using_checkpoints = false, bool *converter_missing = NULL);
    110110
    111111        /// @return -1 = before first char in the string
  • cpp/frams/genetics/genoconv.cpp

    r534 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    8181
    8282GenoConvManager::GenoConvManager()
    83 :param(this)
     83        :param(this)
    8484{
    8585}
     
    166166}
    167167
    168 Geno GenoConvManager::convert(Geno &in, char format, MultiMap *map, bool *converter_missing)
     168Geno GenoConvManager::convert(Geno &in, char format, MultiMap *map, bool using_checkpoints, bool *converter_missing)
    169169{
    170170        if (in.getFormat() == format) { if (converter_missing) *converter_missing = false; return in; }
     
    187187        {
    188188                GenoConverter *gk = (GenoConverter*)converters(*t);
    189                 tmp = gk->convert(tmp, mapavail ? &tmpmap : 0);
     189                tmp = gk->convert(tmp, mapavail ? &tmpmap : 0, using_checkpoints);
    190190                if (!tmp.len())
    191191                {
    192                         string t=ssprintf("f%c->f%c conversion failed (%s)", gk->in_format, gk->out_format, gk->name);
     192                        string t = ssprintf("f%c->f%c conversion failed (%s)", gk->in_format, gk->out_format, gk->name);
    193193                        return Geno(0, 0, 0, t.c_str());
    194194                }
  • cpp/frams/genetics/genoconv.h

    r513 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    5353        /// Any other return value is assumed to be output genotype.
    5454        /// @param map if not null, mapping informaton is requested, converter should add conversion map to this object
    55         virtual SString convert(SString &i, MultiMap *map) { return SString(); }
     55        virtual SString convert(SString &i, MultiMap *map, bool using_checkpoints) { return SString(); }
    5656
    5757        virtual ~GenoConverter() {}
     
    7878        /// make a genotype in other format. genotype will be invalid
    7979        /// if GenoConvManager cannot convert it.
    80         Geno convert(Geno &in, char format, MultiMap *map = 0, bool *converter_missing = NULL);
     80        Geno convert(Geno &in, char format, MultiMap *map = 0, bool using_checkpoints = false, bool *converter_missing = NULL);
    8181        /// register GenoConverter, the added object will be automatically deleted when GenoConvManager is destructed (call removeConverter() if this is not desirable)
    8282        void addConverter(GenoConverter *conv);
  • cpp/frams/model/defassign-f0-SDK.h

    r528 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2016  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
  • cpp/frams/model/f0-SDK-classes.h

    r528 r732  
    155155 {"getInputNeuroIndex",0,1+2,"get input neuron index","p d(d)",PROCEDURE(p_getInputNeuroIndex),},
    156156 {"getInputWeight",0,1+2,"get input weight","p f(d)",PROCEDURE(p_getInputWeight),},
    157  {"classObject",0,1+2,"neuron class","o NeuroClass",GETONLY(classObject),},
     157 {"classObject",0,1+2,"neuron class","oNeuroClass",GETONLY(classObject),},
    158158 {0,0,0,}
    159159};
  • cpp/frams/model/model.cpp

    r726 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    99#include <common/loggers/loggers.h>
    1010
     11#define F0_CHECKPOINT_LINE "checkpoint:"
     12
    1113Model::Model()
    1214{
     
    1820{
    1921        partmappingchanged = 0;
     22        using_checkpoints = false;
     23        is_checkpoint = false;
    2024        buildstatus = empty;
    2125        modelfromgenotype = 0;
     
    4751        f0genoknown = 0;
    4852        startenergy = mod.startenergy;
    49         if (mod.getStatus() == valid)
    50         {
    51                 modelfromgenotype = mod.modelfromgenotype;
    52                 {for (int i = 0; i < mod.getPartCount(); i++)
    53                         addPart(new Part(*mod.getPart(i))); }
    54         {for (int i = 0; i < mod.getJointCount(); i++)
     53        modelfromgenotype = mod.modelfromgenotype;
     54        for (int i = 0; i < mod.getPartCount(); i++)
     55                addPart(new Part(*mod.getPart(i)));
     56        for (int i = 0; i < mod.getJointCount(); i++)
    5557        {
    5658                Joint *oldj = mod.getJoint(i);
     
    5860                addJoint(j);
    5961                j->attachToParts(oldj->part1->refno, oldj->part2->refno);
    60         }}
    61         {for (int i = 0; i < mod.getNeuroCount(); i++)
     62        }
     63        for (int i = 0; i < mod.getNeuroCount(); i++)
    6264        {
    6365                Neuro *oldn = mod.getNeuro(i);
     
    6668                if (oldn->part_refno >= 0) n->attachToPart(oldn->part_refno);
    6769                else n->attachToJoint(oldn->joint_refno);
    68         }}
    69                 for (int i = 0; i < mod.getNeuroCount(); i++)
    70                 {
    71                         Neuro *oldn = mod.getNeuro(i);
    72                         Neuro *n = getNeuro(i);
    73                         for (int ni = 0; ni < oldn->getInputCount(); ni++)
    74                         {
    75                                 double w;
    76                                 Neuro *oldinput = oldn->getInput(ni, w);
    77                                 SString info = n->getInputInfo(ni);
    78                                 n->addInput(getNeuro(oldinput->refno), w, &info);
    79                         }
    80                 }
    81         }
    82 }
    83 
    84 
    85 Model::Model(const Geno &src, bool buildmaps)
     70        }
     71        for (int i = 0; i < mod.getNeuroCount(); i++)
     72        {
     73                Neuro *oldn = mod.getNeuro(i);
     74                Neuro *n = getNeuro(i);
     75                for (int ni = 0; ni < oldn->getInputCount(); ni++)
     76                {
     77                        double w;
     78                        Neuro *oldinput = oldn->getInput(ni, w);
     79                        SString info = n->getInputInfo(ni);
     80                        n->addInput(getNeuro(oldinput->refno), w, &info);
     81                }
     82        }
     83        updateRefno();
     84        if (using_checkpoints)
     85                for (vector<Model*>::const_iterator it = mod.checkpoints.begin(); it != mod.checkpoints.end(); it++)
     86                {
     87                Model *m = *it;
     88                Model *n = new Model(*m, m->autobuildmaps, false, true);
     89                checkpoints.push_back(n);
     90                }
     91}
     92
     93
     94Model::Model(const Geno &src, bool buildmaps, bool _using_checkpoints, bool _is_checkpoint)
    8695        :autobuildmaps(buildmaps)
    8796{
    88         init(src);
     97        init(src, _using_checkpoints, _is_checkpoint);
    8998}
    9099
     
    92101{
    93102        clear();
    94         open();
     103        open(mod.isUsingCheckpoints(), mod.isCheckpoint());
    95104        internalCopy(mod);
    96105        buildstatus = mod.buildstatus;
    97106}
    98107
    99 Model::Model(const Model &mod, bool buildmaps)
     108Model::Model(const Model &mod, bool buildmaps, bool _using_checkpoints, bool _is_checkpoint)
    100109        :autobuildmaps(buildmaps)
    101110{
    102111        init();
    103         open();
     112        open(_using_checkpoints, _is_checkpoint);
    104113        internalCopy(mod);
    105         buildstatus = mod.buildstatus;
    106 }
    107 
    108 void Model::init(const Geno &src)
     114        if (is_checkpoint)
     115                close();
     116        else
     117                buildstatus = mod.buildstatus;
     118        if (mod.map)
     119                map = new MultiMap(*mod.map);
     120        if (mod.f0map)
     121                f0map = new MultiMap(*mod.f0map);
     122}
     123
     124void Model::init(const Geno &src, bool _using_checkpoints, bool _is_checkpoint)
    109125{
    110126        init();
     127        using_checkpoints = _using_checkpoints;
     128        is_checkpoint = _is_checkpoint;
    111129        modelfromgenotype = 1;
    112130        geno = src;
     
    146164        geno = Geno();
    147165        f0geno = Geno();
     166        for (vector<Model*>::iterator it = checkpoints.begin(); it != checkpoints.end(); it++)
     167                delete *it;
     168        checkpoints.clear();
    148169}
    149170
     
    293314Model::ItemType Model::itemTypeFromLinePrefix(const char* line)
    294315{
    295 struct PrefixAndItem { const char* prefix; ItemType type; };
    296 static const PrefixAndItem types[]={ {"m:",ModelType},{"p:",PartType},{"j:",JointType},{"n:",NeuronType},{"c:",NeuronConnectionType},{NULL} };
    297 for(const PrefixAndItem *t=types;t->prefix!=NULL;t++)
    298         {
    299         const char* in=line;
    300         const char* pattern=t->prefix;
    301         for(;*in==*pattern;in++,pattern++)
    302                 if (*pattern==':')
    303                         return t->type;
    304         }
    305 return UnknownType;
     316        struct PrefixAndItem { const char* prefix; ItemType type; };
     317        static const PrefixAndItem types[] = { { "m:", ModelType }, { "p:", PartType }, { "j:", JointType }, { "n:", NeuronType }, { "c:", NeuronConnectionType }, { F0_CHECKPOINT_LINE, CheckpointType }, { NULL } };
     318        for (const PrefixAndItem *t = types; t->prefix != NULL; t++)
     319        {
     320                const char* in = line;
     321                const char* pattern = t->prefix;
     322                for (; *in == *pattern; in++, pattern++)
     323                        if (*pattern == ':')
     324                                return t->type;
     325        }
     326        return UnknownType;
    306327}
    307328
     
    311332        f0warnposition = -1;
    312333        MultiMap *convmap = autobuildmaps ? new MultiMap() : NULL;
    313         f0geno = (geno.getFormat() == '0') ? geno : geno.getConverted('0', convmap);
     334        f0geno = (geno.getFormat() == '0') ? geno : geno.getConverted('0', convmap, using_checkpoints);
    314335        f0genoknown = 1;
    315336        if (f0geno.isInvalid())
     
    331352        MultiRange frommap;
    332353        LoggerToMemory mh(LoggerBase::Enable | LoggerBase::DontBlock);
     354        Model *current_model = this;
    333355        for (; f0txt.getNextToken(pos, line, '\n'); lnum++)
    334356        {
    335                 const char* line_ptr=line.c_str();
     357                const char* line_ptr = line.c_str();
    336358                for (; *line_ptr; line_ptr++)
    337359                        if (!strchr(" \r\t", *line_ptr)) break;
     
    339361                if (!*line_ptr) continue;
    340362
    341                 const char* colon=strchr(line_ptr,':');
    342                 ItemType type=UnknownType;
     363                const char* colon = strchr(line_ptr, ':');
     364                ItemType type = UnknownType;
    343365                SString excluding_prefix;
    344                 if (colon!=NULL)
    345                         {
     366                if (colon != NULL)
     367                {
    346368                        colon++;
    347                         type=itemTypeFromLinePrefix(line_ptr);
     369                        type = itemTypeFromLinePrefix(line_ptr);
    348370                        for (; *colon; colon++)
    349371                                if (!strchr(" \r\t", *colon)) break;
    350                         excluding_prefix=colon;
    351                         }
    352                
     372                        excluding_prefix = colon;
     373                }
     374
    353375                if (autobuildmaps)
    354376                {
     
    357379                }
    358380                mh.reset();
    359                 if (addFromString(type, excluding_prefix, lnum, autobuildmaps ? (&frommap) : 0) == -1)
     381                if (type == CheckpointType)
     382                {
     383                        current_model->close();
     384                        current_model = new Model;
     385                        current_model->open(false, true);
     386                        checkpoints.push_back(current_model);
     387                }
     388                else if (current_model->addFromString(type, excluding_prefix, lnum, autobuildmaps ? (&frommap) : 0) == -1)
    360389                {
    361390                        buildstatus = invalid;
     
    371400        }
    372401        mh.disable();
    373         close();
     402        current_model->close();
    374403        if (convmap)
    375404        {
     
    503532                }
    504533        }
     534
     535        for (vector<Model*>::const_iterator it = checkpoints.begin(); it != checkpoints.end(); it++)
     536        {
     537                Geno g = (*it)->getF0Geno();
     538                gen += F0_CHECKPOINT_LINE "\n";
     539                gen += g.getGenes();
     540        }
     541
    505542        g = Geno(gen.c_str(), '0');
    506543}
     
    508545//////////////
    509546
    510 void Model::open()
     547void Model::open(bool _using_checkpoints, bool _is_checkpoint)
    511548{
    512549        if (buildstatus == building) return;
     550        using_checkpoints = _using_checkpoints;
     551        is_checkpoint = _is_checkpoint;
    513552        buildstatus = building;
    514553        modelfromgenotype = 0;
     
    518557}
    519558
     559int Model::getCheckpointCount()
     560{
     561        return checkpoints.size();
     562}
     563
     564Model* Model::getCheckpoint(int i)
     565{
     566        return checkpoints[i];
     567}
     568
    520569void Model::checkpoint()
    521 {}
     570{
     571        if (!using_checkpoints) return;
     572        updateRefno();
     573        Model *m = new Model(*this, false, false, true);
     574        checkpoints.push_back(m);
     575}
    522576
    523577void Model::setGeno(const Geno& newgeno)
     
    544598        if (buildstatus != building)
    545599                logPrintf("Model", "close", LOG_WARN, "Unexpected close() - no open()");
    546         if (internalcheck(building_live_model ? LIVE_CHECK : FINAL_CHECK) > 0)
     600        if (internalcheck(is_checkpoint ? CHECKPOINT_CHECK : (building_live_model ? LIVE_CHECK : FINAL_CHECK)) > 0)
    547601        {
    548602                buildstatus = valid;
     
    589643int Model::addFromString(ItemType item_type, const SString &singleline, const MultiRange* srcrange)
    590644{
    591         return addFromString(item_type,singleline, 0, srcrange);
     645        return addFromString(item_type, singleline, 0, srcrange);
    592646}
    593647
     
    612666        error_message = SString::empty();
    613667        ParamInterface::LoadOptions opts;
    614         switch(item_type)
    615                 {
    616                 case PartType:
    617                 {
     668        switch (item_type)
     669        {
     670        case PartType:
     671        {
    618672                Param partparam(f0_part_paramtab);
    619673                Part *p = new Part();
     
    626680                if (srcrange) p->setMapping(*srcrange);
    627681                return getPartCount() - 1;
    628                 }
    629 
    630                 case ModelType:
    631                 {
     682        }
     683
     684        case ModelType:
     685        {
    632686                Param modelparam(f0_model_paramtab);
    633687                modelparam.select(this);
     
    635689                if (opts.parse_failed) { error_message = "Invalid 'm:'"; return -1; }
    636690                return 0;
    637                 }
    638 
    639                 case JointType:
    640                 {
     691        }
     692
     693        case JointType:
     694        {
    641695                Param jointparam(f0_joint_paramtab);
    642696                Joint *j = new Joint();
     
    665719                        return -1;
    666720                }
    667                 }
    668 
    669                 case NeuronType:
    670                 {
     721        }
     722
     723        case NeuronType:
     724        {
    671725                Param neuroparam(f0_neuro_paramtab);
    672726                Neuro *nu = new Neuro();
     
    714768                        return neurons.size() - 1;
    715769                }
    716                 }
    717 
    718                 case NeuronConnectionType:                     
    719                 {
     770        }
     771
     772        case NeuronConnectionType:
     773        {
    720774                Param ncparam(f0_neuroconn_paramtab);
    721775                NeuroConn c;
     
    736790                error_message = SString::sprintf("Invalid reference to Neuro #%d", n1_ok ? c.n2_refno : c.n1_refno);
    737791                return -1;
    738                 }
    739 
    740                 case UnknownType: //handled by addFromString for uniform error handling
    741                         return -1;
    742                 }
     792        }
     793
     794        case CheckpointType: case UnknownType: //handled by addFromString for uniform error handling
     795                return -1;
     796        }
    743797        return -1;
    744798}
     
    747801/////////////
    748802
    749 /** change the sequence of neuro units
    750         and fix references in "-" objects (n-n connections)  */
    751 void Model::moveNeuro(int oldpos, int newpos)
    752 {
    753         if (oldpos == newpos) return; // nop!
    754         Neuro *n = getNeuro(oldpos);
    755         neurons -= oldpos;
    756         neurons.insert(newpos, n);
    757         // conn_refno could be broken -> fix it
    758 }
    759 
    760 ////////////
    761 
    762 void Model::updateNeuroRefno()
    763 {
     803void Model::updateRefno()
     804{
     805        for (int i = 0; i < parts.size(); i++)
     806                getPart(i)->refno = i;
     807        for (int i = 0; i < joints.size(); i++)
     808        {
     809                Joint *j = getJoint(i);
     810                j->refno = i;
     811                if (j->part1 && j->part2 && (j->part1 != j->part2))
     812                {
     813                        j->p1_refno = j->part1->refno;
     814                        j->p2_refno = j->part2->refno;
     815                }
     816        }
    764817        for (int i = 0; i < neurons.size(); i++)
    765         {
    766                 Neuro* n = (Neuro*)neurons(i);
    767                 n->refno = i;
    768         }
     818                getNeuro(i)->refno = i;
    769819}
    770820
     
    779829#define LINKFLAG 0x8000000
    780830
    781 void Model::updateRefno()
    782 {
    783         int i;
    784         for (i = 0; i < getPartCount(); i++) getPart(i)->refno = i;
    785         for (i = 0; i < getJointCount(); i++) getJoint(i)->refno = i;
    786         for (i = 0; i < getNeuroCount(); i++) getNeuro(i)->refno = i;
    787 }
    788 
    789831SString Model::nameForErrors() const
    790832{
     
    802844        int ret = 1;
    803845        shape = SHAPE_UNKNOWN;
     846        updateRefno();
    804847        if ((parts.size() == 0) && (neurons.size() == 0)) return 0;
    805848        if (parts.size() == 0)
     
    812855                        p = (Part*)parts(i);
    813856                        p->owner = this;
    814                         p->refno = i;
    815857                        if (checklevel > 0)
    816858                                p->mass = 0.0;
     
    907949                                        }
    908950                                }
    909                                 if (check != LIVE_CHECK)
     951                                if ((check != LIVE_CHECK) && (check != CHECKPOINT_CHECK))
    910952                                {
    911953                                        if (j->shape != Joint::SHAPE_FIXED)
     
    935977        }
    936978
    937         updateNeuroRefno(); // valid refno is important for n-n connections check (later)
    938 
    939979        for (i = 0; i < neurons.size(); i++)
    940980        {
     
    944984        }
    945985
    946         if (parts.size() && (checklevel > 0))
    947         {
    948                 for (i = 0; i < parts.size(); i++)
    949                 {
    950                         p = (Part*)parts(i);
    951                         if (p->mass <= 0.001)
    952                                 p->mass = 1.0;
    953                         p->flags &= ~LINKFLAG;
    954                 }
    955                 getPart(0)->flags |= LINKFLAG;
    956                 int change = 1;
    957                 while (change)
    958                 {
    959                         change = 0;
    960                         for (i = 0; i < joints.size(); i++)
    961                         {
    962                                 j = (Joint*)joints(i);
    963                                 if (j->part1->flags&LINKFLAG)
     986        if (check != CHECKPOINT_CHECK)
     987        {
     988
     989                if (parts.size() && (checklevel > 0))
     990                {
     991                        for (i = 0; i < parts.size(); i++)
     992                        {
     993                                p = (Part*)parts(i);
     994                                if (p->mass <= 0.001)
     995                                        p->mass = 1.0;
     996                                p->flags &= ~LINKFLAG;
     997                        }
     998                        getPart(0)->flags |= LINKFLAG;
     999                        int change = 1;
     1000                        while (change)
     1001                        {
     1002                                change = 0;
     1003                                for (i = 0; i < joints.size(); i++)
    9641004                                {
    965                                         if (!(j->part2->flags&LINKFLAG))
     1005                                        j = (Joint*)joints(i);
     1006                                        if (j->part1->flags&LINKFLAG)
    9661007                                        {
    967                                                 change = 1;
    968                                                 j->part2->flags |= LINKFLAG;
     1008                                                if (!(j->part2->flags&LINKFLAG))
     1009                                                {
     1010                                                        change = 1;
     1011                                                        j->part2->flags |= LINKFLAG;
     1012                                                }
    9691013                                        }
     1014                                        else
     1015                                                if (j->part2->flags&LINKFLAG)
     1016                                                {
     1017                                                if (!(j->part1->flags&LINKFLAG))
     1018                                                {
     1019                                                        change = 1;
     1020                                                        j->part1->flags |= LINKFLAG;
     1021                                                }
     1022                                                }
    9701023                                }
    971                                 else
    972                                         if (j->part2->flags&LINKFLAG)
    973                                         {
    974                                         if (!(j->part1->flags&LINKFLAG))
    975                                         {
    976                                                 change = 1;
    977                                                 j->part1->flags |= LINKFLAG;
    978                                         }
    979                                         }
    980                         }
    981                 }
    982                 for (i = 0; i < parts.size(); i++)
    983                 {
    984                         p = (Part*)parts(i);
    985                         if (!(p->flags&LINKFLAG))
    986                         {
    987                                 logPrintf("Model", "internalCheck", LOG_ERROR, "Not all parts connected (eg. Part #0 and Part #%d)%s", i, nameForErrors().c_str());
     1024                        }
     1025                        for (i = 0; i < parts.size(); i++)
     1026                        {
     1027                                p = (Part*)parts(i);
     1028                                if (!(p->flags&LINKFLAG))
     1029                                {
     1030                                        logPrintf("Model", "internalCheck", LOG_ERROR, "Not all parts connected (eg. Part #0 and Part #%d)%s", i, nameForErrors().c_str());
     1031                                        ret = 0;
     1032                                        break;
     1033                                }
     1034                        }
     1035                }
     1036
     1037                for (i = 0; i < joints.size(); i++)
     1038                {
     1039                        j = (Joint*)joints(i);
     1040                        if (j->p1_refno == j->p2_refno)
     1041                        {
     1042                                logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal self connection, Joint #%d%s", i, nameForErrors().c_str());
    9881043                                ret = 0;
    9891044                                break;
    9901045                        }
    991                 }
    992         }
    993 
    994         for (i = 0; i < joints.size(); i++)
    995         {
    996                 j = (Joint*)joints(i);
    997                 if (j->p1_refno == j->p2_refno)
    998                 {
    999                         logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal self connection, Joint #%d%s", i, nameForErrors().c_str());
    1000                         ret = 0;
    1001                         break;
    1002                 }
    1003                 for (k = i + 1; k < joints.size(); k++)
    1004                 {
    1005                         Joint* j2 = (Joint*)joints(k);
    1006                         if (((j->p1_refno == j2->p1_refno) && (j->p2_refno == j2->p2_refno))
    1007                                 || ((j->p1_refno == j2->p2_refno) && (j->p2_refno == j2->p1_refno)))
    1008                         {
    1009                                 logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal duplicate Joint #%d and Joint #%d%s", i, k, nameForErrors().c_str());
    1010                                 ret = 0;
    1011                                 break;
    1012                         }
    1013                 }
    1014         }
     1046                        for (k = i + 1; k < joints.size(); k++)
     1047                        {
     1048                                Joint* j2 = (Joint*)joints(k);
     1049                                if (((j->p1_refno == j2->p1_refno) && (j->p2_refno == j2->p2_refno))
     1050                                        || ((j->p1_refno == j2->p2_refno) && (j->p2_refno == j2->p1_refno)))
     1051                                {
     1052                                        logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal duplicate Joint #%d and Joint #%d%s", i, k, nameForErrors().c_str());
     1053                                        ret = 0;
     1054                                        break;
     1055                                }
     1056                        }
     1057                }
     1058        }
     1059
    10151060        if (shape == SHAPE_ILLEGAL)
    10161061                ret = 0;
     
    12501295//////////////////////
    12511296
     1297int Model::elementToMap(ItemType type, int index)
     1298{
     1299        switch (type)
     1300        {
     1301        case PartType: return partToMap(index);
     1302        case JointType: return jointToMap(index);
     1303        case NeuronType: return neuroToMap(index);
     1304        default: return -1;
     1305        }
     1306}
     1307
     1308Model::TypeAndIndex Model::mapToElement(int map_index)
     1309{
     1310        if ((map_index >= 0) && (map_index < MODEL_MAPPING_OFFSET))
     1311                return TypeAndIndex(PartType, mapToPart(map_index));
     1312        if ((map_index >= MODEL_MAPPING_OFFSET) && (map_index < 2 * MODEL_MAPPING_OFFSET))
     1313                return TypeAndIndex(JointType, mapToJoint(map_index));
     1314        if ((map_index >= 2 * MODEL_MAPPING_OFFSET) && (map_index < 3 * MODEL_MAPPING_OFFSET))
     1315                return TypeAndIndex(NeuronType, mapToNeuro(map_index));
     1316        return TypeAndIndex();
     1317}
     1318
     1319int Model::partToMap(int i) { return MODEL_MAPPING_OFFSET + i; }
     1320int Model::jointToMap(int i) { return 2 * MODEL_MAPPING_OFFSET + i; }
     1321int Model::neuroToMap(int i) { return 3 * MODEL_MAPPING_OFFSET + i; }
     1322int Model::mapToPart(int i) { return i - MODEL_MAPPING_OFFSET; }
     1323int Model::mapToJoint(int i) { return i - 2 * MODEL_MAPPING_OFFSET; }
     1324int Model::mapToNeuro(int i) { return i - 3 * MODEL_MAPPING_OFFSET; }
     1325
     1326
     1327//////////////////////
     1328
    12521329class MinPart : public Part { public: MinPart() { Param par(f0_part_paramtab, this); par.setMin(); } };
    12531330class MaxPart : public Part { public: MaxPart() { Param par(f0_part_paramtab, this); par.setMax(); } };
  • cpp/frams/model/model.h

    r726 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1515
    1616extern ParamEntry f0_model_paramtab[];
    17 
    18 //#define EASYMAPDEBUG
    1917
    2018enum ModelBuildStatus { empty, building, invalid, valid };
     
    6462        /// make model map in build()
    6563        bool autobuildmaps;
     64        /// supports adding checkpoints
     65        bool using_checkpoints;
     66        /// means less strict validation
     67        bool is_checkpoint;
    6668        /// valid if build from f0 genotype
    6769        int f0errorposition;
     
    7577        SList parts, joints, neurons;
    7678        char partmappingchanged;
     79        vector<Model*> checkpoints;
    7780
    7881        void internalCopy(const Model &mod);
     
    9598                EDITING_CHECK, ///< Used in Model::validate(). Default validation - does not modify elements of the Model.
    9699                FINAL_CHECK,   ///< Used in Model::close() when a Model is built from a genotype. Like EDITING_CHECK, but also calculates Joint::d and Joint::rot.
    97                 LIVE_CHECK     ///< used in Model::close() when a Model is built from a Creature. Like FINAL_CHECK but does not limit joint length which could make some liveModels invalid.
     100                LIVE_CHECK,     ///< used in Model::close() when a Model is built from a Creature. Like FINAL_CHECK but does not limit joint length which could make some liveModels invalid.
     101                CHECKPOINT_CHECK     ///< used when storing checkpoint models. Like LIVE_CHECK, excluding consistency check (disjoint parts are acceptable)
    98102        };
    99103protected:
    100104        ShapeType shape;
    101105
    102         void updateNeuroRefno(); // set Neuro::refno for all neurons
    103106        SString nameForErrors() const;
    104107        int internalcheck(CheckType check);
    105108
    106         void moveNeuro(int oldpos, int newpos);
    107 
    108         void init(const Geno &srcgen);
     109        void init(const Geno &srcgen, bool _using_checkpoints, bool _is_checkpoint);
    109110        void init();
    110111
     
    134135        int getErrorPosition(bool includingwarnings = false);
    135136        ShapeType getShapeType() const { return shape; }
     137        bool isUsingCheckpoints() const { return using_checkpoints; }
     138        bool isCheckpoint() const { return is_checkpoint; }
    136139
    137140        void updateRefno(); // set ::refno for all elements
     141
     142        int getCheckpointCount();
     143        Model* getCheckpoint(int i);
    138144
    139145        /// The bounding box size. Valid if the model is valid. Read only.
     
    153159           @see getMap()
    154160           */
    155         Model(const Geno &src, bool buildmaps = false);
    156         Model(const Model &mod, bool buildmaps = false);
     161        Model(const Geno &src, bool buildmaps = false, bool _using_checkpoints = false, bool _is_checkpoint = false);
     162        Model(const Model &mod, bool buildmaps = false, bool _using_checkpoints = false, bool _is_checkpoint = false);
    157163        /** duplicate the model.
    158164                the resulting object's status is 'building' (opened).
     
    255261        void clear();
    256262
    257         enum ItemType { UnknownType,ModelType,PartType,JointType,NeuronType,NeuronConnectionType };
     263        enum ItemType { UnknownType, ModelType, PartType, JointType, NeuronType, NeuronConnectionType, CheckpointType };
    258264        static ItemType itemTypeFromLinePrefix(const char* line);
    259265        /** Execute single line of <B>f0</B> genotype.
     
    264270                @param srcrange source genotype range which will be mapped to this element
    265271                */
    266         int addFromString(ItemType item_type,const SString &singleline, int line_num, const MultiRange* srcrange = NULL);
     272        int addFromString(ItemType item_type, const SString &singleline, int line_num, const MultiRange* srcrange = NULL);
    267273        /** Execute single line of <B>f0</B> genotype - compatiblity variant */
    268         int addFromString(ItemType item_type,const SString &singleline, const MultiRange* srcrange = NULL);
     274        int addFromString(ItemType item_type, const SString &singleline, const MultiRange* srcrange = NULL);
    269275        /** Execute single line of <B>f0</B> genotype - low level variant, used by Model::build(), error messages returned as string instead of calling logger */
    270         int addFromStringNoLog(ItemType item_type,const SString &singleline, SString& error_message, const MultiRange* srcrange = 0);
     276        int addFromStringNoLog(ItemType item_type, const SString &singleline, SString& error_message, const MultiRange* srcrange = 0);
    271277
    272278        /// separate build stages (for future use)
     
    289295        /// or modify the model created from the genotype.
    290296        /// Between open() and close() the model is not fully usable.
    291         void open();
     297        void open(bool _using_checkpoints = false, bool _is_checkpoint = false);
    292298
    293299        /// Current model written as f0 genotype while building
     
    379385        void buildUsingSolidShapeTypes(const Model& src_ballandstick_shapes, Part::Shape use_shape = Part::SHAPE_CYLINDER, float thickness = 0.2);
    380386
    381 #ifdef EASYMAPDEBUG
    382         static int partToMap(int i) {return 0+i;}
    383         static int jointToMap(int i) {return 10+i;}
    384         static int neuroToMap(int i) {return 20+i;}
    385         static int mapToPart(int i) {return i-0;}
    386         static int mapToJoint(int i) {return i-10;}
    387         static int mapToNeuro(int i) {return i-20;}
    388 #else
    389         static int partToMap(int i) { return 0x10000000 + i; }
    390         static int jointToMap(int i) { return 0x20000000 + i; }
    391         static int neuroToMap(int i) { return 0x30000000 + i; }
    392         static int mapToPart(int i) { return i - 0x10000000; }
    393         static int mapToJoint(int i) { return i - 0x20000000; }
    394         static int mapToNeuro(int i) { return i - 0x30000000; }
    395 #endif
     387protected:
     388        static const int MODEL_MAPPING_OFFSET = 0x10000000;
     389public:
     390        static int elementToMap(ItemType t, int i);
     391        struct TypeAndIndex
     392        {
     393                ItemType type; int index;
     394                TypeAndIndex() :type(UnknownType), index(0) {}
     395                TypeAndIndex(ItemType _type, int _index) :type(_type), index(_index) {}
     396        };
     397        static TypeAndIndex mapToElement(int i);
     398        static int partToMap(int i);
     399        static int jointToMap(int i);
     400        static int neuroToMap(int i);
     401        static int mapToPart(int i);
     402        static int mapToJoint(int i);
     403        static int mapToNeuro(int i);
    396404
    397405        static void makeGenToGenMap(MultiMap& result, const MultiMap& gen1tomodel, const MultiMap& gen2tomodel);
  • cpp/frams/model/modelobj.cpp

    r722 r732  
    77ParamEntry modelobj_paramtab[] =
    88{
    9         { "Model", 1, 16, "Model", },
     9        { "Model", 1, 21, "Model", },
    1010        { "se", 0, PARAM_NOSTATIC, "startenergy", "f", FIELD(startenergy), },
    1111        { "Vstyle", 0, PARAM_NOSTATIC, "vis_style", "s", FIELD(vis_style), },
    1212
    13         { "geno", 0, PARAM_NOSTATIC | PARAM_READONLY, "geno", "o Geno", GETONLY(geno), },
    14         { "newFromString", 0, 0, "create new object", "p oModel(s genotype)", PROCEDURE(p_newfromstring), },
    15         { "newFromGeno", 0, 0, "create new object", "p oModel(oGeno)", PROCEDURE(p_newfromgeno), },
     13        { "geno", 0, PARAM_NOSTATIC | PARAM_READONLY, "Geno", "oGeno", GETONLY(geno), },
     14        { "newFromString", 0, 0, "Create a new object", "p oModel(s genotype)", PROCEDURE(p_newfromstring), },
     15        { "newFromGeno", 0, 0, "Create a new object", "p oModel(oGeno)", PROCEDURE(p_newfromgeno), },
     16        { "newWithCheckpoints", 0, 0, "Create a new object", "p oModel(x Geno object or string genotype)", PROCEDURE(p_newwithcheckpoints), "Creates a Model with the \"Checkpoints\" option enabled. Genotype converters supporting Checkpoints provide a sequence of Models that reflects development stages of the creature (this sequence is used purely for debugging and visualization of phenotype growth/development). Checkpoint Models can be accessed using getCheckpoint(i) for i ranging from 0 to numcheckpoints-1. Models created without the Checkpoint option and Models coming from unsupported converters have numcheckpoints=0." },
    1617
    17         { "numparts", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "number of parts", "d", GETONLY(numparts), },
    18         { "numjoints", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "number of joints", "d", GETONLY(numjoints), },
    19         { "numneurons", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "number of neurons", "d", GETONLY(numneurons), },
    20         { "numconnections", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "number of neuron connections", "d", GETONLY(numconnections), },
     18        { "numparts", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "Number of parts", "d", GETONLY(numparts), },
     19        { "numjoints", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "Number of joints", "d", GETONLY(numjoints), },
     20        { "numneurons", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "Number of neurons", "d", GETONLY(numneurons), },
     21        { "numconnections", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "Number of neuron connections", "d", GETONLY(numconnections), },
    2122
    2223        { "getPart", 0, PARAM_USERHIDDEN | PARAM_NOSTATIC, "getPart (static model information)", "p oPart(d index)", PROCEDURE(p_getpart), },
     
    2425        { "getNeuroDef", 0, PARAM_USERHIDDEN | PARAM_NOSTATIC, "getNeuroDef", "p oNeuroDef(d index)", PROCEDURE(p_getneuro), },
    2526
    26         { "size_x", 0, PARAM_READONLY | PARAM_NOSTATIC | PARAM_DEPRECATED, "bounding box x size", "f", FIELD(size.x), "(size_x,size_y,size_z) are dimensions of the axis-aligned bounding box of the creature, including imaginary Part sizes (Part.s, usually 1.0). A creature consisting of a single default part has the size of (2.0,2.0,2.0) - twice the Part.s value (like a sphere diameter is twice its radius).\nSee also: Creature.moveAbs" },
    27         { "size_y", 0, PARAM_READONLY | PARAM_NOSTATIC | PARAM_DEPRECATED, "bounding box y size", "f", FIELD(size.y), "See Model.size_x" },
    28         { "size_z", 0, PARAM_READONLY | PARAM_NOSTATIC | PARAM_DEPRECATED, "bounding box z size", "f", FIELD(size.z), "See Model.size_x" },
     27        { "size_x", 0, PARAM_READONLY | PARAM_NOSTATIC | PARAM_DEPRECATED, "Bounding box x size", "f", FIELD(size.x), "(size_x,size_y,size_z) are dimensions of the axis-aligned bounding box of the creature, including imaginary Part sizes (Part.s, usually 1.0). A creature consisting of a single default part has the size of (2.0,2.0,2.0) - twice the Part.s value (like a sphere diameter is twice its radius).\nSee also: Creature.moveAbs" },
     28        { "size_y", 0, PARAM_READONLY | PARAM_NOSTATIC | PARAM_DEPRECATED, "Bounding box y size", "f", FIELD(size.y), "See Model.size_x" },
     29        { "size_z", 0, PARAM_READONLY | PARAM_NOSTATIC | PARAM_DEPRECATED, "Bounding box z size", "f", FIELD(size.z), "See Model.size_x" },
    2930        { "bboxSize", 0, PARAM_READONLY | PARAM_NOSTATIC, "Bounding box size", "oXYZ", GETONLY(bboxsize) },
     31        { "numcheckpoints", 0, PARAM_DONTSAVE | PARAM_READONLY | PARAM_NOSTATIC, "Number of checkpoints", "d", GETONLY(numcheckpoints) },
     32        { "getCheckpoint", 0, PARAM_USERHIDDEN | PARAM_NOSTATIC, "getCheckpoint", "p oModel(d index)", PROCEDURE(p_getcheckpoint),
     33        "Checkpoint Model objects are only valid as long as the parent Model object exists.\n"
     34        "See also: Model.newWithCheckpoints()\n\n"
     35        "// incorrect usage - calling getCheckpoint() on a temporary object:\n"
     36        "var c=Model.newWithCheckpoints(\"XXX\").getCheckpoint(1).genotype.geno;\n\n"
     37        "// correct usage - keeping the parent Model reference in 'm':\n"
     38        "var m=Model.newWithCheckpoints(\"XXX\");\n"
     39        "var c=m.getCheckpoint(1).genotype.geno;\n"
     40        },
     41        { "shape_type", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "Shape type", "d 0 3 ~Unknown~Illegal~Ball-and-stick~Solids", GETONLY(shape_type) },
     42        { "solid_model", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "Solid shapes model", "oModel", GETONLY(solid_model), "Conversion of this Model to solid shapes. Note! Only available when this Model has shape_type==2 (Ball-and-stick)." },
    3043
    3144        { 0, 0, 0, },
     
    5770}
    5871
     72void ModelObj::p_newwithcheckpoints(ExtValue *args, ExtValue *ret)
     73{
     74        Model *m = NULL;
     75        if (args[0].getType() == TString)
     76                m = new Model(Geno(args[0].getString()), false, true);
     77        else
     78        {
     79                Geno *g = GenoObj::fromObject(args[0].getObject(), false);
     80                if (g)
     81                        m = new Model(*g, false, true);
     82                else
     83                        logPrintf("Model", "newWithCheckpoints", LOG_ERROR, "Geno or string expected, %s found", args[0].typeDescription().c_str());
     84        }
     85
     86        if (m != NULL)
     87                *ret = makeDynamicObject(m);
     88        else
     89                ret->setEmpty();
     90}
     91
    5992Param& ModelObj::getStaticParam()
    6093{
    6194#ifdef __CODEGUARD__
    6295        static ModelObj static_modelobj;
    63         static Param static_modelparam(modelobj_paramtab,&static_modelobj);
     96        static Param static_modelparam(modelobj_paramtab, &static_modelobj);
    6497#else
    6598        static Param static_modelparam(modelobj_paramtab);
     
    131164        *ret = Pt3D_Ext::makeDynamicObject(new Pt3D_Ext(size));
    132165}
     166
     167void ModelObj::p_getcheckpoint(PARAMPROCARGS)
     168{
     169        int i = args->getInt();
     170        if ((i < 0) || (i >= getCheckpointCount()))
     171        {
     172                ret->setEmpty();
     173                return;
     174        }
     175        ret->setObject(makeStaticObject(getCheckpoint(i)));
     176}
     177
     178void ModelObj::get_solid_model(ExtValue *ret)
     179{
     180        if (getShapeType() != Model::SHAPE_BALL_AND_STICK)
     181                ret->setEmpty();
     182        Model *m = new Model;
     183        m->open();
     184        m->buildUsingSolidShapeTypes(*this);
     185        m->close();
     186        *ret = makeDynamicObject(m);
     187}
     188
     189void ModelObj::get_shape_type(ExtValue *ret)
     190{
     191        ret->setInt(getShapeType());
     192}
  • cpp/frams/model/modelobj.h

    r722 r732  
    1414        PARAMPROCDEF(p_newfromstring);
    1515        PARAMPROCDEF(p_newfromgeno);
     16        PARAMPROCDEF(p_newwithcheckpoints);
    1617
    1718#define GETDELEGATE(name,type,value) PARAMGETDEF(name) {arg1->set ## type (value);}
     
    2021        GETDELEGATE(numneurons, Int, getNeuroCount())
    2122        GETDELEGATE(numconnections, Int, getConnectionCount())
     23        GETDELEGATE(numcheckpoints, Int, getCheckpointCount())
    2224#undef GETDELEGATE
    2325
     
    2628        PARAMPROCDEF(p_getneuro);
    2729        PARAMGETDEF(bboxsize);
     30        PARAMPROCDEF(p_getcheckpoint);
     31        PARAMGETDEF(shape_type);
     32        PARAMGETDEF(solid_model);
    2833
    2934#undef STATRICKCLASS
  • cpp/frams/neuro/neuroimpl.cpp

    r720 r732  
    324324        { "position_y", 0, PARAM_READONLY, "Position y", "f", GETONLY(position_y), },
    325325        { "position_z", 0, PARAM_READONLY, "Position z", "f", GETONLY(position_z), },
    326         { "creature", 0, PARAM_READONLY, "Gets owner creature", "o Creature", GETONLY(creature), },
    327         { "part", 0, PARAM_READONLY, "The Part object where this neuron is located", "o MechPart", GETONLY(part), },
    328         { "joint", 0, PARAM_READONLY, "The Joint object where this neuron is located", "o MechJoint", GETONLY(joint), },
    329         { "neuroproperties", 0, PARAM_READONLY, "Custom neuron fields", "o NeuroProperties", GETONLY(fields),
     326        { "creature", 0, PARAM_READONLY, "Gets owner creature", "oCreature", GETONLY(creature), },
     327        { "part", 0, PARAM_READONLY, "The Part object where this neuron is located", "oMechPart", GETONLY(part), },
     328        { "joint", 0, PARAM_READONLY, "The Joint object where this neuron is located", "oMechJoint", GETONLY(joint), },
     329        { "neuroproperties", 0, PARAM_READONLY, "Custom neuron fields", "oNeuroProperties", GETONLY(fields),
    330330        "Neurons can have different fields depending on their class. Script neurons have their fields defined using the \"property:\" syntax. If you develop a custom neuron script you should use the NeuroProperties object for accessing your own neuron fields. The Neuro.neuroproperties property is meant for accessing the neuron fields from the outside script.\n"
    331331        "Examples:\n"
     
    341341        "for(i=0;i<iobj.size;i++)\n"
    342342        " Simulator.print(iobj.getId(i)+\" (\"+iobj.getName(i)+\")\");", },
    343         { "def", 0, PARAM_READONLY, "Neuron definition from which this live neuron was built", "o NeuroDef", GETONLY(neurodef), },
    344         { "classObject", 0, PARAM_READONLY, "Neuron class for this neuron", "o NeuroClass", GETONLY(classObject), },
     343        { "def", 0, PARAM_READONLY, "Neuron definition from which this live neuron was built", "oNeuroDef", GETONLY(neurodef), },
     344        { "classObject", 0, PARAM_READONLY, "Neuron class for this neuron", "oNeuroClass", GETONLY(classObject), },
    345345#ifdef NEURO_SIGNALS
    346         { "signals", 0, PARAM_READONLY, "Signals", "o NeuroSignals", FIELD(sigs_obj), },
     346        { "signals", 0, PARAM_READONLY, "Signals", "oNeuroSignals", FIELD(sigs_obj), },
    347347#endif
    348348
  • cpp/frams/param/param.cpp

    r720 r732  
    853853        else
    854854        {
     855                if ((t[0] == 'o') && (t[1] == ' '))
     856                {
     857                        err = "space after 'o'";
     858                }
    855859                if (!(pe->flags & (PARAM_READONLY | PARAM_DONTSAVE | PARAM_USERREADONLY | PARAM_CONST | PARAM_DONTLOAD | PARAM_LINECOMMENT | PARAM_OBJECTSET)))
    856860                { //write access
     
    12871291                if (i >= 0) i++;
    12881292#ifdef __CODEGUARD__
    1289                 if (next_field<end-1) t=next_field+1; else return fields_loaded;
     1293                if (next_field < end - 1) t = next_field + 1; else return fields_loaded;
    12901294#else
    12911295                t = next_field + 1;
  • cpp/frams/vm/classes/genoobj.cpp

    r534 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1111ParamEntry geno_paramtab[] =
    1212{
    13         { "Geno", 1, 15, "Geno", "All information about a single genotype.\nThis is a genetics-only object which does not contain any performance data. See also: Genotype class" },
     13        { "Geno", 1, 16, "Geno", "All information about a single genotype.\nThis is a genetics-only object which does not contain any performance data. See also: Genotype class" },
    1414        { "name", 0, PARAM_NOSTATIC, "Name", "s 0 40", GETSET(name), },
    1515        { "rawgenotype", 0, PARAM_NOSTATIC | PARAM_READONLY, "Raw genotype", "s 1", GETONLY(genotype), "Genotype, excluding the format specifier" },
     
    2323        "-1 = validity is not known. This is a transient state. The value of \"is_valid\" will never be -1 when read. It is safe to treat is_valid as boolean in statements like \"if (g.is_valid) ...\". Setting \"is_valid=-1\" will make it 0 or 1 again. This third state (-1) is only needed for loading Genotype objects from files where the \"is_valid\" field might not be present."
    2424        },
    25         { "getConverted", 0, PARAM_NOSTATIC, "get converted genotype", "p oGeno(s format)", PROCEDURE(p_getconvert), },
     25        { "getConverted", 0, PARAM_NOSTATIC, "Get converted genotype", "p oGeno(s format)", PROCEDURE(p_getconvert), },
     26        { "getConvertedWithCheckpoints", 0, PARAM_NOSTATIC, "Get converted genotype", "p oGeno(s format)", PROCEDURE(p_getconvert_ch), "See also Model.newWithCheckpoints()" },
    2627        { "f0genotype", 0, PARAM_NOSTATIC | PARAM_READONLY, "f0 genotype", "s 1", GETONLY(f0genotype), "converted to f0 genotype", },
    2728        { "new", 0, 0, "create new empty object", "p oGeno()", PROCEDURE(p_new), },
     
    8586void GenoObj::get_format(ExtValue *ret)
    8687{
    87         char format_as_string[2]={getFormat(),0};
     88        char format_as_string[2] = { getFormat(), 0 };
    8889        ret->setString(format_as_string);
    8990}
     
    102103char GenoObj::formatFromExtValue(ExtValue& v)
    103104{
    104 if (v.getType()==TInt)
    105         return v.getInt();
    106 if (v.getType()==TString)
     105        if (v.getType() == TInt)
     106                return v.getInt();
     107        if (v.getType() == TString)
    107108        {
    108         SString s=v.getString();
    109         if (s.len()==1)
    110                 return s.charAt(0);
     109                SString s = v.getString();
     110                if (s.len() == 1)
     111                        return s.charAt(0);
    111112        }
    112 return Geno::INVALID_FORMAT;
     113        return Geno::INVALID_FORMAT;
    113114}
    114115
     
    116117{
    117118        *ret = makeDynamicObjectAndDecRef(new Geno(getConverted(formatFromExtValue(args[0]))));
     119}
     120
     121void GenoObj::p_getconvert_ch(ExtValue *args, ExtValue *ret)
     122{
     123        *ret = makeDynamicObjectAndDecRef(new Geno(getConverted(formatFromExtValue(args[0]), NULL, true)));
    118124}
    119125
  • cpp/frams/vm/classes/genoobj.h

    r516 r732  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    2525        PARAMGETDEF(string);
    2626        PARAMPROCDEF(p_getconvert);
     27        PARAMPROCDEF(p_getconvert_ch);
    2728        PARAMGETDEF(f0genotype);
    2829        PARAMPROCDEF(p_new);
Note: See TracChangeset for help on using the changeset viewer.