Ignore:
Timestamp:
06/23/16 00:15:59 (8 years ago)
Author:
Maciej Komosinski
Message:

Code formatting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/model/model.cpp

    r519 r522  
    1111Model::Model()
    1212{
    13 autobuildmaps=false;
    14 init();
     13        autobuildmaps = false;
     14        init();
    1515}
    1616
    1717void Model::init()
    1818{
    19 partmappingchanged=0;
    20 buildstatus=empty;
    21 modelfromgenotype=0;
    22 startenergy=1.0;
    23 checklevel=1;
     19        partmappingchanged = 0;
     20        buildstatus = empty;
     21        modelfromgenotype = 0;
     22        startenergy = 1.0;
     23        checklevel = 1;
    2424#ifdef MODEL_V1_COMPATIBLE
    25 oldneurocount=-1; // == unknown
    26 oldconnections=0;
     25        oldneurocount=-1; // == unknown
     26        oldconnections=0;
    2727#endif
    28 map=0;
    29 f0map=0;
    30 f0genoknown=1;
    31 shape=SHAPE_UNKNOWN;
     28        map = 0;
     29        f0map = 0;
     30        f0genoknown = 1;
     31        shape = SHAPE_UNKNOWN;
    3232}
    3333
    3434void Model::moveElementsFrom(Model &source)
    3535{
    36 int i;
    37 open();
    38 for (i=0;i<source.getPartCount();i++)
    39         addPart(source.getPart(i));
    40 for (i=0;i<source.getJointCount();i++)
    41         addJoint(source.getJoint(i));
    42 for (i=0;i<source.getNeuroCount();i++)
    43         addNeuro(source.getNeuro(i));
    44 source.parts.clear(); source.joints.clear(); source.neurons.clear();
    45 source.clear();
     36        int i;
     37        open();
     38        for (i = 0; i < source.getPartCount(); i++)
     39                addPart(source.getPart(i));
     40        for (i = 0; i < source.getJointCount(); i++)
     41                addJoint(source.getJoint(i));
     42        for (i = 0; i < source.getNeuroCount(); i++)
     43                addNeuro(source.getNeuro(i));
     44        source.parts.clear(); source.joints.clear(); source.neurons.clear();
     45        source.clear();
    4646}
    4747
    4848void Model::internalCopy(const Model &mod)
    4949{
    50 geno=mod.geno;
    51 f0genoknown=0;
    52 startenergy=mod.startenergy;
    53 if (mod.getStatus()==valid)
    54         {
    55         modelfromgenotype=mod.modelfromgenotype;
    56         {for (int i=0;i<mod.getPartCount();i++)
    57                 addPart(new Part(*mod.getPart(i)));}
    58         {for (int i=0;i<mod.getJointCount();i++)
    59                 {
    60                 Joint *oldj=mod.getJoint(i);
    61                 Joint *j=new Joint(*oldj);
     50        geno = mod.geno;
     51        f0genoknown = 0;
     52        startenergy = mod.startenergy;
     53        if (mod.getStatus() == valid)
     54        {
     55                modelfromgenotype = mod.modelfromgenotype;
     56                {for (int i = 0; i < mod.getPartCount(); i++)
     57                        addPart(new Part(*mod.getPart(i))); }
     58        {for (int i = 0; i < mod.getJointCount(); i++)
     59        {
     60                Joint *oldj = mod.getJoint(i);
     61                Joint *j = new Joint(*oldj);
    6262                addJoint(j);
    63                 j->attachToParts(oldj->part1->refno,oldj->part2->refno);
    64                 }}
    65         {for (int i=0;i<mod.getNeuroCount();i++)
    66                 {
    67                 Neuro *oldn=mod.getNeuro(i);
    68                 Neuro *n=new Neuro(*oldn);
     63                j->attachToParts(oldj->part1->refno, oldj->part2->refno);
     64        }}
     65        {for (int i = 0; i < mod.getNeuroCount(); i++)
     66        {
     67                Neuro *oldn = mod.getNeuro(i);
     68                Neuro *n = new Neuro(*oldn);
    6969                addNeuro(n);
    70                 if (oldn->part_refno>=0) n->attachToPart(oldn->part_refno);
     70                if (oldn->part_refno >= 0) n->attachToPart(oldn->part_refno);
    7171                else n->attachToJoint(oldn->joint_refno);
    72                 }}
    73         for (int i=0;i<mod.getNeuroCount();i++)
    74                 {
    75                 Neuro *oldn=mod.getNeuro(i);
    76                 Neuro *n=getNeuro(i);
    77                 for (int ni=0;ni < oldn->getInputCount();ni++)
     72        }}
     73                for (int i = 0; i < mod.getNeuroCount(); i++)
     74                {
     75                        Neuro *oldn = mod.getNeuro(i);
     76                        Neuro *n = getNeuro(i);
     77                        for (int ni = 0; ni < oldn->getInputCount(); ni++)
    7878                        {
    79                         double w;
    80                         Neuro *oldinput=oldn->getInput(ni,w);
    81                         SString info=n->getInputInfo(ni);
    82                         n->addInput(getNeuro(oldinput->refno),w,&info);
     79                                double w;
     80                                Neuro *oldinput = oldn->getInput(ni, w);
     81                                SString info = n->getInputInfo(ni);
     82                                n->addInput(getNeuro(oldinput->refno), w, &info);
    8383                        }
    8484                }
     
    8787
    8888
    89 Model::Model(const Geno &src,bool buildmaps)
     89Model::Model(const Geno &src, bool buildmaps)
    9090        :autobuildmaps(buildmaps)
    91 {init(src);}
     91{
     92        init(src);
     93}
    9294
    9395void Model::operator=(const Model &mod)
    9496{
    95 clear();
    96 open();
    97 internalCopy(mod);
    98 buildstatus=mod.buildstatus;
    99 }
    100 
    101 Model::Model(const Model &mod,bool buildmaps)
     97        clear();
     98        open();
     99        internalCopy(mod);
     100        buildstatus = mod.buildstatus;
     101}
     102
     103Model::Model(const Model &mod, bool buildmaps)
    102104        :autobuildmaps(buildmaps)
    103105{
    104 init();
    105 open();
    106 internalCopy(mod);
    107 buildstatus=mod.buildstatus;
     106        init();
     107        open();
     108        internalCopy(mod);
     109        buildstatus = mod.buildstatus;
    108110}
    109111
    110112void Model::init(const Geno &src)
    111113{
    112 init();
    113 modelfromgenotype=1;
    114 geno=src;
    115 build();
     114        init();
     115        modelfromgenotype = 1;
     116        geno = src;
     117        build();
    116118}
    117119
    118120void Model::resetAllDelta()
    119121{
    120 for (int i=0;i<getJointCount();i++)
    121         getJoint(i)->resetDelta();
     122        for (int i = 0; i < getJointCount(); i++)
     123                getJoint(i)->resetDelta();
    122124}
    123125
    124126void Model::useAllDelta(bool yesno)
    125127{
    126 for (int i=0;i<getJointCount();i++)
    127         getJoint(i)->useDelta(yesno);
     128        for (int i = 0; i < getJointCount(); i++)
     129                getJoint(i)->useDelta(yesno);
    128130}
    129131
    130132Model::~Model()
    131133{
    132 delmodel_list.action((intptr_t)this);
    133 clear();
     134        delmodel_list.action((intptr_t)this);
     135        clear();
    134136}
    135137
    136138void Model::clear()
    137139{
    138 FOREACH(Part*,p,parts)
     140        FOREACH(Part*, p, parts)
     141                delete p;
     142        FOREACH(Joint*, j, joints)
     143                delete j;
     144        FOREACH(Neuro*, n, neurons)
     145                delete n;
     146        parts.clear(); joints.clear(); neurons.clear();
     147        delMap();
     148        delF0Map();
     149        init();
     150        geno = Geno();
     151        f0geno = Geno();
     152}
     153
     154Part *Model::addPart(Part *p)
     155{
     156        p->owner = this;
     157        p->refno = parts.size();
     158        parts += p;
     159        return p;
     160}
     161
     162Joint *Model::addJoint(Joint *j)
     163{
     164        j->owner = this;
     165        j->refno = joints.size();
     166        joints += j;
     167        return j;
     168}
     169
     170Neuro *Model::addNeuro(Neuro *n)
     171{
     172        n->owner = this;
     173        n->refno = neurons.size();
     174        neurons += n;
     175        return n;
     176}
     177
     178void Model::removeNeuros(SList &nlist)
     179{
     180        FOREACH(Neuro*, nu, nlist)
     181        {
     182                int i = findNeuro(nu);
     183                if (i >= 0) removeNeuro(i);
     184        }
     185}
     186
     187void Model::removePart(int partindex, int removeattachedjoints, int removeattachedneurons)
     188{
     189        Part *p = getPart(partindex);
     190        if (removeattachedjoints)
     191        {
     192                SList jlist;
     193                findJoints(jlist, p);
     194                FOREACH(Joint*, j, jlist)
     195                {
     196                        int i = findJoint(j);
     197                        if (i >= 0) removeJoint(i, removeattachedneurons);
     198                }
     199        }
     200        if (removeattachedneurons)
     201        {
     202                SList nlist;
     203                findNeuros(nlist, 0, p);
     204                removeNeuros(nlist);
     205        }
     206        parts -= partindex;
    139207        delete p;
    140 FOREACH(Joint*,j,joints)
     208}
     209
     210void Model::removeJoint(int jointindex, int removeattachedneurons)
     211{
     212        Joint *j = getJoint(jointindex);
     213        if (removeattachedneurons)
     214        {
     215                SList nlist;
     216                findNeuros(nlist, 0, 0, j);
     217                removeNeuros(nlist);
     218        }
     219        joints -= jointindex;
    141220        delete j;
    142 FOREACH(Neuro*,n,neurons)
    143         delete n;
    144 parts.clear(); joints.clear(); neurons.clear();
    145 delMap();
    146 delF0Map();
    147 init();
    148 geno=Geno();
    149 f0geno=Geno();
    150 }
    151 
    152 Part *Model::addPart(Part *p)
    153 {
    154 p->owner=this;
    155 p->refno=parts.size();
    156 parts+=p;
    157 return p;
    158 }
    159 
    160 Joint *Model::addJoint(Joint *j)
    161 {
    162 j->owner=this;
    163 j->refno=joints.size();
    164 joints+=j;
    165 return j;
    166 }
    167 
    168 Neuro *Model::addNeuro(Neuro *n)
    169 {
    170 n->owner=this;
    171 n->refno=neurons.size();
    172 neurons+=n;
    173 return n;
    174 }
    175 
    176 void Model::removeNeuros(SList &nlist)
    177 {
    178 FOREACH(Neuro*,nu,nlist)
    179         {
    180         int i=findNeuro(nu);
    181         if (i>=0) removeNeuro(i);
    182         }
    183 }
    184 
    185 void Model::removePart(int partindex,int removeattachedjoints,int removeattachedneurons)
    186 {
    187 Part *p=getPart(partindex);
    188 if (removeattachedjoints)
    189         {
    190         SList jlist;
    191         findJoints(jlist,p);
    192         FOREACH(Joint*,j,jlist)
    193                 {
    194                 int i=findJoint(j);
    195                 if (i>=0) removeJoint(i,removeattachedneurons);
    196                 }
    197         }
    198 if (removeattachedneurons)
    199         {
    200         SList nlist;
    201         findNeuros(nlist,0,p);
    202         removeNeuros(nlist);
    203         }
    204 parts-=partindex;
    205 delete p;
    206 }
    207 
    208 void Model::removeJoint(int jointindex,int removeattachedneurons)
    209 {
    210 Joint *j=getJoint(jointindex);
    211 if (removeattachedneurons)
    212         {
    213         SList nlist;
    214         findNeuros(nlist,0,0,j);
    215         removeNeuros(nlist);
    216         }
    217 joints-=jointindex;
    218 delete j;
    219 }
    220 
    221 void Model::removeNeuro(int neuroindex,bool removereferences)
    222 {
    223 Neuro* thisN=getNeuro(neuroindex);
    224 
    225 if (removereferences)
    226         {
    227         Neuro* n;
    228 // remove all references to thisN
    229         for (int i=0;n=(Neuro*)neurons(i);i++)
    230                 {
    231                 Neuro *inp;
    232                 for (int j=0;inp=n->getInput(j);j++)
    233                         if (inp==thisN)
     221}
     222
     223void Model::removeNeuro(int neuroindex, bool removereferences)
     224{
     225        Neuro* thisN = getNeuro(neuroindex);
     226
     227        if (removereferences)
     228        {
     229                Neuro* n;
     230                // remove all references to thisN
     231                for (int i = 0; n = (Neuro*)neurons(i); i++)
     232                {
     233                        Neuro *inp;
     234                        for (int j = 0; inp = n->getInput(j); j++)
     235                                if (inp == thisN)
    234236                                {
    235237                                n->removeInput(j);
     
    239241        }
    240242
    241 neurons-=neuroindex;
    242 delete thisN;
     243        neurons -= neuroindex;
     244        delete thisN;
    243245}
    244246
    245247MultiMap& Model::getMap()
    246248{
    247 if (!map) map=new MultiMap();
    248 return *map;
     249        if (!map) map = new MultiMap();
     250        return *map;
    249251}
    250252
    251253void Model::delMap()
    252254{
    253 if (map) {delete map; map=0;}
     255        if (map) { delete map; map = 0; }
    254256}
    255257void Model::delF0Map()
    256258{
    257 if (f0map) {delete f0map; f0map=0;}
    258 }
    259 
    260 void Model::makeGenToGenMap(MultiMap& result,const MultiMap& gen1tomodel,const MultiMap& gen2tomodel)
    261 {
    262 result.clear();
    263 MultiMap m;
    264 m.addReversed(gen2tomodel);
    265 result.addCombined(gen1tomodel,m);
     259        if (f0map) { delete f0map; f0map = 0; }
     260}
     261
     262void Model::makeGenToGenMap(MultiMap& result, const MultiMap& gen1tomodel, const MultiMap& gen2tomodel)
     263{
     264        result.clear();
     265        MultiMap m;
     266        m.addReversed(gen2tomodel);
     267        result.addCombined(gen1tomodel, m);
    266268}
    267269
    268270void Model::getCurrentToF0Map(MultiMap& result)
    269271{
    270 result.clear();
    271 if (!map) return;
    272 const MultiMap& f0m=getF0Map();
    273 makeGenToGenMap(result,*map,f0m);
     272        result.clear();
     273        if (!map) return;
     274        const MultiMap& f0m = getF0Map();
     275        makeGenToGenMap(result, *map, f0m);
    274276}
    275277
    276278void Model::rebuild(bool buildm)
    277279{
    278 autobuildmaps=buildm;
    279 clear();
    280 build();
     280        autobuildmaps = buildm;
     281        clear();
     282        build();
    281283}
    282284
    283285void Model::initMap()
    284286{
    285 if (!map) map=new MultiMap();
    286 else map->clear();
     287        if (!map) map = new MultiMap();
     288        else map->clear();
    287289}
    288290
    289291void Model::initF0Map()
    290292{
    291 if (!f0map) f0map=new MultiMap();
    292 else f0map->clear();
     293        if (!f0map) f0map = new MultiMap();
     294        else f0map->clear();
    293295}
    294296
    295297void Model::build()
    296298{
    297 f0errorposition=-1;
    298 f0warnposition=-1;
    299 MultiMap *convmap=autobuildmaps ? new MultiMap() : NULL;
    300 f0geno=(geno.getFormat()=='0')? geno : geno.getConverted('0',convmap);
    301 f0genoknown=1;
    302 if (f0geno.isInvalid())
    303         {
    304         buildstatus=invalid;
    305         if (convmap) delete convmap;
    306         return;
    307         }
    308 SString f0txt=f0geno.getGene();
    309 buildstatus=building; // was: open();
    310 if (autobuildmaps)
    311         {
    312         partmappingchanged=0;
    313         initMap();
    314         initF0Map();
    315         }
    316 int pos=0,lnum=1,lastpos=0;
    317 SString line;
    318 MultiRange frommap;
    319 LoggerToMemory mh(LoggerBase::Enable | LoggerBase::DontBlock);
    320 for (;f0txt.getNextToken(pos,line,'\n');lnum++)
    321         {
    322         if (autobuildmaps)
    323                 {
    324                 frommap.clear();
    325                 frommap.add(lastpos,pos-1);
    326                 }
    327         mh.reset();
    328         if (singleStepBuild(line,lnum,autobuildmaps ? (&frommap) : 0) == -1)
    329                 {
    330                 buildstatus=invalid;
    331                 f0errorposition=lastpos;
     299        f0errorposition = -1;
     300        f0warnposition = -1;
     301        MultiMap *convmap = autobuildmaps ? new MultiMap() : NULL;
     302        f0geno = (geno.getFormat() == '0') ? geno : geno.getConverted('0', convmap);
     303        f0genoknown = 1;
     304        if (f0geno.isInvalid())
     305        {
     306                buildstatus = invalid;
    332307                if (convmap) delete convmap;
    333308                return;
    334                 }
    335         if (mh.getWarningCount())
    336                 {if (f0warnposition<0) f0warnposition=lastpos;}
    337         lastpos=pos;
    338         }
    339 mh.disable();
    340 close();
    341 if (convmap)
    342         {
    343         *f0map=*map;
    344         if (geno.getFormat()!='0')
    345                 {
    346                 MultiMap tmp;
    347                 tmp.addCombined(*convmap,getMap());
    348                 *map=tmp;
    349                 }
    350         delete convmap;
     309        }
     310        SString f0txt = f0geno.getGene();
     311        buildstatus = building; // was: open();
     312        if (autobuildmaps)
     313        {
     314                partmappingchanged = 0;
     315                initMap();
     316                initF0Map();
     317        }
     318        int pos = 0, lnum = 1, lastpos = 0;
     319        SString line;
     320        MultiRange frommap;
     321        LoggerToMemory mh(LoggerBase::Enable | LoggerBase::DontBlock);
     322        for (; f0txt.getNextToken(pos, line, '\n'); lnum++)
     323        {
     324                if (autobuildmaps)
     325                {
     326                        frommap.clear();
     327                        frommap.add(lastpos, pos - 1);
     328                }
     329                mh.reset();
     330                if (singleStepBuild(line, lnum, autobuildmaps ? (&frommap) : 0) == -1)
     331                {
     332                        buildstatus = invalid;
     333                        f0errorposition = lastpos;
     334                        if (convmap) delete convmap;
     335                        return;
     336                }
     337                if (mh.getWarningCount())
     338                {
     339                        if (f0warnposition < 0) f0warnposition = lastpos;
     340                }
     341                lastpos = pos;
     342        }
     343        mh.disable();
     344        close();
     345        if (convmap)
     346        {
     347                *f0map = *map;
     348                if (geno.getFormat() != '0')
     349                {
     350                        MultiMap tmp;
     351                        tmp.addCombined(*convmap, getMap());
     352                        *map = tmp;
     353                }
     354                delete convmap;
    351355        }
    352356}
     
    354358const MultiMap& Model::getF0Map()
    355359{
    356 if (!f0map)
    357         {
    358         f0map=new MultiMap();
    359         makeGeno(f0geno,f0map);
    360         f0genoknown=1;
    361         }
    362 return *f0map;
     360        if (!f0map)
     361        {
     362                f0map = new MultiMap();
     363                makeGeno(f0geno, f0map);
     364                f0genoknown = 1;
     365        }
     366        return *f0map;
    363367}
    364368
    365369Geno Model::rawGeno()
    366370{
    367 Geno tmpgen;
    368 makeGeno(tmpgen);
    369 return tmpgen;
    370 }
    371 
    372 void Model::makeGeno(Geno &g,MultiMap *map,bool handle_defaults)
    373 {
    374 if ((buildstatus!=valid)&&(buildstatus!=building))
    375         {
    376         g=Geno(0,0,0,"invalid model");
    377         return;
    378         }
    379 
    380 SString gen;
    381 
    382 Param modelparam(f0_model_paramtab);
    383 Param partparam(f0_part_paramtab);
    384 Param jointparam(f0_joint_paramtab);
    385 Param neuroparam(f0_neuro_paramtab);
    386 Param connparam(f0_neuroconn_paramtab);
    387 
    388 static Part defaultpart;
    389 static Joint defaultjoint;
    390 static Neuro defaultneuro;
    391 static Model defaultmodel;
    392 static NeuroConn defaultconn;
    393 //static NeuroItem defaultneuroitem;
    394 
    395 Part *p;
    396 Joint *j;
    397 Neuro *n;
    398 int i;
    399 int len;
    400 int a,b;
    401 //NeuroItem *ni;
    402 
    403 SString mod_props;
    404 modelparam.select(this);
    405 modelparam.save2(mod_props,handle_defaults ? &defaultmodel : NULL,true,!handle_defaults);
    406 if (mod_props.len()>1) //are there any non-default values? ("\n" is empty)
    407         {
    408         gen+="m:";
    409         gen+=mod_props;
    410         }
    411 
    412 for (i=0;p=(Part*)parts(i);i++)
    413         {
    414         partparam.select(p);
    415         len=gen.len();
    416         gen+="p:";
    417         partparam.save2(gen,handle_defaults ? &defaultpart : NULL,true,!handle_defaults);
    418         if (map)
    419                 map->add(len,gen.len()-1,partToMap(i));
    420         }
    421 for (i=0;j=(Joint*)joints(i);i++)
    422         {
    423         jointparam.select(j);
    424         len=gen.len();
    425         jointparam.setParamTab(j->usedelta?f0_joint_paramtab:f0_nodeltajoint_paramtab);
    426         gen+="j:";
    427         jointparam.save2(gen,handle_defaults ? &defaultjoint : NULL,true,!handle_defaults);
    428         if (map)
    429                 map->add(len,gen.len()-1,jointToMap(i));
    430         }
    431 for (i=0;n=(Neuro*)neurons(i);i++)
    432         {
    433         neuroparam.select(n);
    434         len=gen.len();
    435         gen+="n:";
    436         neuroparam.save2(gen,handle_defaults ? &defaultneuro : NULL,true,!handle_defaults);
    437         if (map)
    438                 map->add(len,gen.len()-1,neuroToMap(i));
    439         }
    440 for (a=0;a<neurons.size();a++)
     371        Geno tmpgen;
     372        makeGeno(tmpgen);
     373        return tmpgen;
     374}
     375
     376void Model::makeGeno(Geno &g, MultiMap *map, bool handle_defaults)
     377{
     378        if ((buildstatus != valid) && (buildstatus != building))
     379        {
     380                g = Geno(0, 0, 0, "invalid model");
     381                return;
     382        }
     383
     384        SString gen;
     385
     386        Param modelparam(f0_model_paramtab);
     387        Param partparam(f0_part_paramtab);
     388        Param jointparam(f0_joint_paramtab);
     389        Param neuroparam(f0_neuro_paramtab);
     390        Param connparam(f0_neuroconn_paramtab);
     391
     392        static Part defaultpart;
     393        static Joint defaultjoint;
     394        static Neuro defaultneuro;
     395        static Model defaultmodel;
     396        static NeuroConn defaultconn;
     397        //static NeuroItem defaultneuroitem;
     398
     399        Part *p;
     400        Joint *j;
     401        Neuro *n;
     402        int i;
     403        int len;
     404        int a, b;
     405        //NeuroItem *ni;
     406
     407        SString mod_props;
     408        modelparam.select(this);
     409        modelparam.save2(mod_props, handle_defaults ? &defaultmodel : NULL, true, !handle_defaults);
     410        if (mod_props.len() > 1) //are there any non-default values? ("\n" is empty)
     411        {
     412                gen += "m:";
     413                gen += mod_props;
     414        }
     415
     416        for (i = 0; p = (Part*)parts(i); i++)
     417        {
     418                partparam.select(p);
     419                len = gen.len();
     420                gen += "p:";
     421                partparam.save2(gen, handle_defaults ? &defaultpart : NULL, true, !handle_defaults);
     422                if (map)
     423                        map->add(len, gen.len() - 1, partToMap(i));
     424        }
     425        for (i = 0; j = (Joint*)joints(i); i++)
     426        {
     427                jointparam.select(j);
     428                len = gen.len();
     429                jointparam.setParamTab(j->usedelta ? f0_joint_paramtab : f0_nodeltajoint_paramtab);
     430                gen += "j:";
     431                jointparam.save2(gen, handle_defaults ? &defaultjoint : NULL, true, !handle_defaults);
     432                if (map)
     433                        map->add(len, gen.len() - 1, jointToMap(i));
     434        }
     435        for (i = 0; n = (Neuro*)neurons(i); i++)
     436        {
     437                neuroparam.select(n);
     438                len = gen.len();
     439                gen += "n:";
     440                neuroparam.save2(gen, handle_defaults ? &defaultneuro : NULL, true, !handle_defaults);
     441                if (map)
     442                        map->add(len, gen.len() - 1, neuroToMap(i));
     443        }
     444        for (a = 0; a < neurons.size(); a++)
    441445        { // inputs
    442         n=(Neuro*)neurons(a);
    443 //      if ((n->getInputCount()==1)&&(n->getInput(0).refno <= n->refno))
    444 //              continue; // already done with Neuro::conn_refno
    445 
    446         for (b=0;b<n->getInputCount();b++)
    447                 {
    448                 double w;
    449                 NeuroConn nc;
    450                 Neuro* n2=n->getInput(b,w);
    451 //              if (((n2.parentcount==1)&&(n2.parent)&&(n2.parent->refno < n2.refno)) ^
    452 //                  (n2.neuro_refno>=0))
    453 //                      printf("!!!! bad Neuro::neuro_refno ?!\n");
    454 
    455 //              if ((n2.parentcount==1)&&(n2.parent)&&(n2.parent->refno < n2.refno))
    456 //              if (n2.neuro_refno>=0)
    457 //                      continue; // already done with Neuro::neuro_refno
    458 
    459                 nc.n1_refno=n->refno; nc.n2_refno=n2->refno;
    460                 nc.weight=w;
    461                 SString **s=n->inputInfo(b);
    462                 if ((s)&&(*s))
    463                 nc.info=**s;
    464                 connparam.select(&nc);
    465                 len=gen.len();
    466                 gen+="c:";
    467                 connparam.save2(gen,handle_defaults ? &defaultconn : NULL,true,!handle_defaults);
    468                 if (map)
    469                         map->add(len,gen.len()-1,neuroToMap(n->refno));
    470                 }
    471         }
    472 g=Geno(gen.c_str(),'0');
     446                n = (Neuro*)neurons(a);
     447                //      if ((n->getInputCount()==1)&&(n->getInput(0).refno <= n->refno))
     448                //              continue; // already done with Neuro::conn_refno
     449
     450                for (b = 0; b < n->getInputCount(); b++)
     451                {
     452                        double w;
     453                        NeuroConn nc;
     454                        Neuro* n2 = n->getInput(b, w);
     455                        //              if (((n2.parentcount==1)&&(n2.parent)&&(n2.parent->refno < n2.refno)) ^
     456                        //                  (n2.neuro_refno>=0))
     457                        //                      printf("!!!! bad Neuro::neuro_refno ?!\n");
     458
     459                        //              if ((n2.parentcount==1)&&(n2.parent)&&(n2.parent->refno < n2.refno))
     460                        //              if (n2.neuro_refno>=0)
     461                        //                      continue; // already done with Neuro::neuro_refno
     462
     463                        nc.n1_refno = n->refno; nc.n2_refno = n2->refno;
     464                        nc.weight = w;
     465                        SString **s = n->inputInfo(b);
     466                        if ((s) && (*s))
     467                                nc.info = **s;
     468                        connparam.select(&nc);
     469                        len = gen.len();
     470                        gen += "c:";
     471                        connparam.save2(gen, handle_defaults ? &defaultconn : NULL, true, !handle_defaults);
     472                        if (map)
     473                                map->add(len, gen.len() - 1, neuroToMap(n->refno));
     474                }
     475        }
     476        g = Geno(gen.c_str(), '0');
    473477}
    474478
     
    477481void Model::open()
    478482{
    479 if (buildstatus==building) return;
    480 buildstatus=building;
    481 modelfromgenotype=0;
    482 partmappingchanged=0;
    483 f0genoknown=0;
    484 delMap();
     483        if (buildstatus == building) return;
     484        buildstatus = building;
     485        modelfromgenotype = 0;
     486        partmappingchanged = 0;
     487        f0genoknown = 0;
     488        delMap();
    485489}
    486490
     
    490494void Model::setGeno(const Geno& newgeno)
    491495{
    492 geno=newgeno;
     496        geno = newgeno;
    493497}
    494498
    495499void Model::clearMap()
    496500{
    497 Part *p; Joint *j; Neuro *n;
    498 int i;
    499 delMap();
    500 delF0Map();
    501 for (i=0;p=(Part*)parts(i);i++)
    502         p->clearMapping();
    503 for (i=0;j=(Joint*)joints(i);i++)
    504         j->clearMapping();
    505 for (i=0;n=(Neuro*)neurons(i);i++)
    506         n->clearMapping();
     501        Part *p; Joint *j; Neuro *n;
     502        int i;
     503        delMap();
     504        delF0Map();
     505        for (i = 0; p = (Part*)parts(i); i++)
     506                p->clearMapping();
     507        for (i = 0; j = (Joint*)joints(i); i++)
     508                j->clearMapping();
     509        for (i = 0; n = (Neuro*)neurons(i); i++)
     510                n->clearMapping();
    507511}
    508512
    509513int Model::close()
    510514{
    511 if (buildstatus!=building)
    512         logPrintf("Model","close",LOG_WARN,"Unexpected close() - no open()");
    513 if (internalcheck(1)>0)
    514         {
    515         buildstatus=valid;
    516 
    517         if (partmappingchanged)
    518                 {
    519                 getMap();
    520                 Part *p; Joint *j; Neuro *n;
    521                 int i;
    522                 for (i=0;p=(Part*)parts(i);i++)
    523                         if (p->getMapping())
    524                                 map->add(*p->getMapping(),partToMap(i));
    525                 for (i=0;j=(Joint*)joints(i);i++)
    526                         if (j->getMapping())
    527                                 map->add(*j->getMapping(),jointToMap(i));
    528                 for (i=0;n=(Neuro*)neurons(i);i++)
    529                         if (n->getMapping())
    530                                 map->add(*n->getMapping(),neuroToMap(i));
    531                 }
    532         }
    533 else
    534         buildstatus=invalid;
    535 
    536 return (buildstatus==valid);
     515        if (buildstatus != building)
     516                logPrintf("Model", "close", LOG_WARN, "Unexpected close() - no open()");
     517        if (internalcheck(1) > 0)
     518        {
     519                buildstatus = valid;
     520
     521                if (partmappingchanged)
     522                {
     523                        getMap();
     524                        Part *p; Joint *j; Neuro *n;
     525                        int i;
     526                        for (i = 0; p = (Part*)parts(i); i++)
     527                                if (p->getMapping())
     528                                        map->add(*p->getMapping(), partToMap(i));
     529                        for (i = 0; j = (Joint*)joints(i); i++)
     530                                if (j->getMapping())
     531                                        map->add(*j->getMapping(), jointToMap(i));
     532                        for (i = 0; n = (Neuro*)neurons(i); i++)
     533                                if (n->getMapping())
     534                                        map->add(*n->getMapping(), neuroToMap(i));
     535                }
     536        }
     537        else
     538                buildstatus = invalid;
     539
     540        return (buildstatus == valid);
    537541}
    538542
    539543int Model::validate()
    540544{
    541 return internalcheck(0);
    542 }
    543 
    544 Pt3D Model::whereDelta(const Part& start,const Pt3D& rot, const Pt3D& delta)
    545 {
    546 Orient roto;
    547 roto=rot;
    548 Orient o;
    549 roto.transform(o,start.o);
    550 //o.x=start.o/roto.x;
    551 //o.y=start.o/roto.y;
    552 //o.z=start.o/roto.z;
    553 return o.transform(delta)+start.p;
    554 }
    555 
    556 int Model::singleStepBuild(const SString &singleline,const MultiRange* srcrange)
    557 {
    558 return singleStepBuild(singleline,0,srcrange);
    559 }
    560 
    561 int Model::singleStepBuild(const SString &singleline,int line_num,const MultiRange* srcrange)
    562 {
    563 SString error_message;
    564 int result=singleStepBuildNoLog(singleline,error_message,srcrange);
    565 if (result<0)
    566         {
    567         if (error_message.len()==0) // generic error when no detailed message is available
    568                 error_message="Invalid f0 code";
    569         if (line_num>0)
    570                 error_message+=SString::sprintf(", line #%d",line_num);
    571         error_message+=nameForErrors();
    572         logPrintf("Model","build",LOG_ERROR,"%s",error_message.c_str());
    573         }
    574 return result;
    575 }
    576 
    577 int Model::singleStepBuildNoLog(const SString &line,SString& error_message,const MultiRange* srcrange)
    578 {
    579 error_message=SString::empty();
    580 int pos=0; const char*t=line.c_str();
    581 for (;*t;t++,pos++)
    582         if (!strchr(" \r\t",*t)) break;
    583 if (*t=='#') return 0;
    584 if (!*t) return 0;
    585 if (!strncmp(t,"p:",2))
    586         {
    587         Param partparam(f0_part_paramtab);
    588         Part *p=new Part();
    589         partparam.select(p);
    590         pos+=2;
    591         if (partparam.load2(line,pos) & ParamInterface::LOAD2_PARSE_FAILED) {delete p; error_message="Invalid 'p:'"; return -1;}
    592         p->o.rotate(p->rot);
    593         parts+=p;
    594         p->owner=this;
    595         if (srcrange) p->setMapping(*srcrange);
    596         return getPartCount()-1;
    597         }
    598 if (!strncmp(t,"m:",2))
    599         {
    600         Param modelparam(f0_model_paramtab);
    601         modelparam.select(this);
    602         pos+=2;
    603         if (modelparam.load2(line,pos) & ParamInterface::LOAD2_PARSE_FAILED) { error_message="Invalid 'm:'"; return -1;}
    604         return 0;
    605         }
    606 else if (!strncmp(t,"j:",2))
    607         {
    608         Param jointparam(f0_joint_paramtab);
    609         Joint *j=new Joint();
    610         jointparam.select(j);
    611         pos+=2;
    612         j->owner=this;
    613         if (jointparam.load2(line,pos) & ParamInterface::LOAD2_PARSE_FAILED) {delete j; error_message="Invalid 'j:'"; return -1;}
    614         bool p1_ok=false, p2_ok=false;
    615         if ((p1_ok=((j->p1_refno>=0)&&(j->p1_refno<getPartCount())))&&
    616             (p2_ok=((j->p2_refno>=0)&&(j->p2_refno<getPartCount()))))
    617                 {
    618                 addJoint(j);
    619                 if ((j->d.x != JOINT_DELTA_MARKER) || (j->d.y != JOINT_DELTA_MARKER) || (j->d.z != JOINT_DELTA_MARKER))
     545        return internalcheck(0);
     546}
     547
     548Pt3D Model::whereDelta(const Part& start, const Pt3D& rot, const Pt3D& delta)
     549{
     550        Orient roto;
     551        roto = rot;
     552        Orient o;
     553        roto.transform(o, start.o);
     554        //o.x=start.o/roto.x;
     555        //o.y=start.o/roto.y;
     556        //o.z=start.o/roto.z;
     557        return o.transform(delta) + start.p;
     558}
     559
     560int Model::singleStepBuild(const SString &singleline, const MultiRange* srcrange)
     561{
     562        return singleStepBuild(singleline, 0, srcrange);
     563}
     564
     565int Model::singleStepBuild(const SString &singleline, int line_num, const MultiRange* srcrange)
     566{
     567        SString error_message;
     568        int result = singleStepBuildNoLog(singleline, error_message, srcrange);
     569        if (result < 0)
     570        {
     571                if (error_message.len() == 0) // generic error when no detailed message is available
     572                        error_message = "Invalid f0 code";
     573                if (line_num>0)
     574                        error_message += SString::sprintf(", line #%d", line_num);
     575                error_message += nameForErrors();
     576                logPrintf("Model", "build", LOG_ERROR, "%s", error_message.c_str());
     577        }
     578        return result;
     579}
     580
     581int Model::singleStepBuildNoLog(const SString &line, SString& error_message, const MultiRange* srcrange)
     582{
     583        error_message = SString::empty();
     584        int pos = 0; const char*t = line.c_str();
     585        for (; *t; t++, pos++)
     586                if (!strchr(" \r\t", *t)) break;
     587        if (*t == '#') return 0;
     588        if (!*t) return 0;
     589        if (!strncmp(t, "p:", 2))
     590        {
     591                Param partparam(f0_part_paramtab);
     592                Part *p = new Part();
     593                partparam.select(p);
     594                pos += 2;
     595                if (partparam.load2(line, pos) & ParamInterface::LOAD2_PARSE_FAILED) { delete p; error_message = "Invalid 'p:'"; return -1; }
     596                p->o.rotate(p->rot);
     597                parts += p;
     598                p->owner = this;
     599                if (srcrange) p->setMapping(*srcrange);
     600                return getPartCount() - 1;
     601        }
     602        if (!strncmp(t, "m:", 2))
     603        {
     604                Param modelparam(f0_model_paramtab);
     605                modelparam.select(this);
     606                pos += 2;
     607                if (modelparam.load2(line, pos) & ParamInterface::LOAD2_PARSE_FAILED) { error_message = "Invalid 'm:'"; return -1; }
     608                return 0;
     609        }
     610        else if (!strncmp(t, "j:", 2))
     611        {
     612                Param jointparam(f0_joint_paramtab);
     613                Joint *j = new Joint();
     614                jointparam.select(j);
     615                pos += 2;
     616                j->owner = this;
     617                if (jointparam.load2(line, pos) & ParamInterface::LOAD2_PARSE_FAILED) { delete j; error_message = "Invalid 'j:'"; return -1; }
     618                bool p1_ok = false, p2_ok = false;
     619                if ((p1_ok = ((j->p1_refno >= 0) && (j->p1_refno < getPartCount()))) &&
     620                        (p2_ok = ((j->p2_refno >= 0) && (j->p2_refno < getPartCount()))))
     621                {
     622                        addJoint(j);
     623                        if ((j->d.x != JOINT_DELTA_MARKER) || (j->d.y != JOINT_DELTA_MARKER) || (j->d.z != JOINT_DELTA_MARKER))
    620624                        {
    621                         j->useDelta(1);
    622                         j->resetDeltaMarkers();
     625                                j->useDelta(1);
     626                                j->resetDeltaMarkers();
    623627                        }
    624                 j->attachToParts(j->p1_refno,j->p2_refno);
    625                 if (srcrange) j->setMapping(*srcrange);
    626                 return j->refno;
    627                 }
    628         else
    629                 {
    630                 error_message=SString::sprintf("Invalid reference to Part #%d",p1_ok?j->p1_refno:j->p2_refno);
    631                 delete j;
    632                 return -1;
    633                 }
    634         }
    635 else if (!strncmp(t,"n:",2)) // neuro (or the old neuro object as the special case)
    636         {
    637         Param neuroparam(f0_neuro_paramtab);
    638         Neuro *nu=new Neuro();
    639         neuroparam.select(nu);
    640         pos+=2;
    641         if (neuroparam.load2(line,pos) & ParamInterface::LOAD2_PARSE_FAILED) {delete nu; error_message="Invalid 'n:'"; return -1;}
     628                        j->attachToParts(j->p1_refno, j->p2_refno);
     629                        if (srcrange) j->setMapping(*srcrange);
     630                        return j->refno;
     631                }
     632                else
     633                {
     634                        error_message = SString::sprintf("Invalid reference to Part #%d", p1_ok ? j->p1_refno : j->p2_refno);
     635                        delete j;
     636                        return -1;
     637                }
     638        }
     639        else if (!strncmp(t, "n:", 2)) // neuro (or the old neuro object as the special case)
     640        {
     641                Param neuroparam(f0_neuro_paramtab);
     642                Neuro *nu = new Neuro();
     643                neuroparam.select(nu);
     644                pos += 2;
     645                if (neuroparam.load2(line, pos) & ParamInterface::LOAD2_PARSE_FAILED) { delete nu; error_message = "Invalid 'n:'"; return -1; }
    642646#ifdef MODEL_V1_COMPATIBLE
    643         if (nu->neuro_refno>=0) // parent specified...
    644                 {
    645                 if (nu->neuro_refno >= getNeuroCount()) // and it's illegal
     647                if (nu->neuro_refno>=0) // parent specified...
     648                {
     649                        if (nu->neuro_refno >= getNeuroCount()) // and it's illegal
     650                        {
     651                                delete nu;
     652                                return -1;
     653                        }
     654                        Neuro *parentNU=getNeuro(nu->neuro_refno);
     655                        parentNU->addInput(nu,nu->weight);
     656                        // default class for parented units: n-n link
     657                        //if (nu->moredata.len()==0) nu->moredata="-";
     658                }
     659                else
     660#endif
     661                {
     662                        // default class for unparented units: standard neuron
     663                        if (nu->getClassName().len() == 0) nu->setClassName("N");
     664                }
     665                /*
     666                        if (nu->conn_refno>=0) // input specified...
     667                        {
     668                        if (nu->conn_refno >= getNeuroCount()) // and it's illegal
    646669                        {
    647670                        delete nu;
    648671                        return -1;
    649672                        }
    650                 Neuro *parentNU=getNeuro(nu->neuro_refno);
    651                 parentNU->addInput(nu,nu->weight);
    652                 // default class for parented units: n-n link
    653                 //if (nu->moredata.len()==0) nu->moredata="-";
    654                 }
    655         else
     673                        Neuro *inputNU=getNeuro(nu->conn_refno);
     674                        nu->addInput(inputNU,nu->weight);
     675                        }
     676                        */
     677#ifdef MODEL_V1_COMPATIBLE
     678                nu->weight=1.0;
    656679#endif
    657                 {
    658                 // default class for unparented units: standard neuron
    659                 if (nu->getClassName().len()==0) nu->setClassName("N");
    660                 }
    661 /*
    662         if (nu->conn_refno>=0) // input specified...
    663                 {
    664                 if (nu->conn_refno >= getNeuroCount()) // and it's illegal
    665                         {
     680                nu->owner = this;
     681                // attach to part/joint
     682                if (nu->part_refno >= 0)
     683                        nu->attachToPart(nu->part_refno);
     684                if (nu->joint_refno >= 0)
     685                        nu->attachToJoint(nu->joint_refno);
     686                if (srcrange) nu->setMapping(*srcrange);
     687                // todo: check part/joint ref#
     688#ifdef MODEL_V1_COMPATIBLE
     689                if (hasOldNeuroLayout())
     690                {
     691                        int count=old_getNeuroCount();
     692                        neurons.insert(count,nu);
     693                        oldneurocount=count+1;
     694                        return oldneurocount-1;
     695                }
     696                else
     697#endif
     698                {
     699                        neurons += nu;
     700                        return neurons.size() - 1;
     701                }
     702        }
     703        else if (!strncmp(t, "c:", 2)) // add input
     704        {
     705                Param ncparam(f0_neuroconn_paramtab);
     706                NeuroConn c;
     707                ncparam.select(&c);
     708                pos += 2;
     709                if (ncparam.load2(line, pos) & ParamInterface::LOAD2_PARSE_FAILED) { error_message = "Invalid 'c:'"; return -1; }
     710                bool n1_ok = false, n2_ok = false;
     711                if ((n1_ok = ((c.n1_refno >= 0) && (c.n1_refno < getNeuroCount())))
     712                        && (n2_ok = ((c.n2_refno >= 0) && (c.n2_refno < getNeuroCount()))))
     713                {
     714                        Neuro *na = getNeuro(c.n1_refno);
     715                        Neuro *nb = getNeuro(c.n2_refno);
     716                        na->addInput(nb, c.weight, &c.info);
     717                        if (srcrange)
     718                                na->addMapping(*srcrange);
     719                        return 0;
     720                }
     721                error_message = SString::sprintf("Invalid reference to Neuro #%d", n1_ok ? c.n2_refno : c.n1_refno);
     722                return -1;
     723        }
     724#ifdef MODEL_V1_COMPATIBLE
     725        else if (!strncmp(t,"ni:",3)) // old neuroitem
     726        {
     727                // we always use old layout for "ni:"
     728                Param neuroitemparam(f0_neuroitem_paramtab);
     729                Neuro *nu=new Neuro();
     730                neuroitemparam.select(nu);
     731                pos+=3;
     732                if (neuroitemparam.load2(line,pos) & ParamInterface::LOAD2_PARSE_FAILED) {delete nu; return -1;}
     733                // illegal parent?
     734                if ((nu->neuro_refno<0)||(nu->neuro_refno>=old_getNeuroCount()))
     735                {
    666736                        delete nu;
    667737                        return -1;
    668                         }
    669                 Neuro *inputNU=getNeuro(nu->conn_refno);
    670                 nu->addInput(inputNU,nu->weight);
    671                 }
    672 */
    673 #ifdef MODEL_V1_COMPATIBLE
    674         nu->weight=1.0;
     738                }
     739                Neuro *parentN=getNeuro(nu->neuro_refno);
     740                // copy part/joint refno from parent, if possible
     741                if ((nu->part_refno<0)&&(parentN->part_refno>=0))
     742                        nu->part_refno=parentN->part_refno;
     743                if ((nu->joint_refno<0)&&(parentN->joint_refno>=0))
     744                        nu->joint_refno=parentN->joint_refno;
     745                nu->owner=this;
     746                // attach to part/joint
     747                if (nu->part_refno>=0)
     748                        nu->attachToPart(nu->part_refno);
     749                if (nu->joint_refno>=0)
     750                        nu->attachToJoint(nu->joint_refno);
     751                if (srcrange)
     752                        nu->setMapping(*srcrange);
     753                // special case: old muscles
     754                // PARENT neuron will be set up to be the CHILD of the current one (!)
     755                if (nu->isOldEffector())
     756                {
     757                        nu->neuro_refno=parentN->refno;
     758                        neurons+=nu;
     759                        nu->owner=this;
     760                        nu->addInput(parentN,nu->weight); // (!)
     761                        nu->weight=1.0;
     762                        parentN->invalidateOldItems();
     763                        return 0; // !!! -> ...getItemCount()-1;
     764                }
     765                parentN->addInput(nu,nu->weight);
     766                neurons+=nu;
     767                parentN->invalidateOldItems();
     768                if (nu->getClassName().len()==0)
     769                {
     770                        nu->setClassName("-");
     771                        // for compatibility, "ni" can define a n-n connection
     772                        // referring to non-existent neuron (which will be hopefully defined later)
     773                        // internal check will add the proper input to this unit
     774                        // if conn_refno >=0 and input count==0
     775                        oldconnections=1;
     776                        if (srcrange)
     777                                parentN->addMapping(*srcrange);
     778                }
     779                else
     780                        nu->weight=1.0;
     781                return 0; // !!! -> ...getItemCount()-1;
     782        }
    675783#endif
    676         nu->owner=this;
    677         // attach to part/joint
    678         if (nu->part_refno>=0)
    679                 nu->attachToPart(nu->part_refno);
    680         if (nu->joint_refno>=0)
    681                 nu->attachToJoint(nu->joint_refno);
    682         if (srcrange) nu->setMapping(*srcrange);
    683         // todo: check part/joint ref#
    684 #ifdef MODEL_V1_COMPATIBLE
    685         if (hasOldNeuroLayout())
    686                 {
    687                 int count=old_getNeuroCount();
    688                 neurons.insert(count,nu);
    689                 oldneurocount=count+1;
    690                 return oldneurocount-1;
    691                 }
    692         else
    693 #endif
    694                 {
    695                 neurons+=nu;
    696                 return neurons.size()-1;
    697                 }
    698         }
    699 else if (!strncmp(t,"c:",2)) // add input
    700         {
    701         Param ncparam(f0_neuroconn_paramtab);
    702         NeuroConn c;
    703         ncparam.select(&c);
    704         pos+=2;
    705         if (ncparam.load2(line,pos) & ParamInterface::LOAD2_PARSE_FAILED) { error_message="Invalid 'c:'"; return -1; }
    706         bool n1_ok=false,n2_ok=false;
    707         if ((n1_ok=((c.n1_refno>=0)&&(c.n1_refno<getNeuroCount())))
    708             && (n2_ok=((c.n2_refno>=0)&&(c.n2_refno<getNeuroCount()))))
    709                 {
    710                 Neuro *na=getNeuro(c.n1_refno);
    711                 Neuro *nb=getNeuro(c.n2_refno);
    712                 na->addInput(nb,c.weight,&c.info);
    713                 if (srcrange)
    714                         na->addMapping(*srcrange);
    715                 return 0;
    716                 }
    717         error_message=SString::sprintf("Invalid reference to Neuro #%d",n1_ok ? c.n2_refno : c.n1_refno);
    718         return -1;
    719         }
    720 #ifdef MODEL_V1_COMPATIBLE
    721 else if (!strncmp(t,"ni:",3)) // old neuroitem
    722         {
    723         // we always use old layout for "ni:"
    724         Param neuroitemparam(f0_neuroitem_paramtab);
    725         Neuro *nu=new Neuro();
    726         neuroitemparam.select(nu);
    727         pos+=3;
    728         if (neuroitemparam.load2(line,pos) & ParamInterface::LOAD2_PARSE_FAILED) {delete nu; return -1;}
    729         // illegal parent?
    730         if ((nu->neuro_refno<0)||(nu->neuro_refno>=old_getNeuroCount()))
    731                 {
    732                 delete nu;
    733                 return -1;
    734                 }
    735         Neuro *parentN=getNeuro(nu->neuro_refno);
    736         // copy part/joint refno from parent, if possible
    737         if ((nu->part_refno<0)&&(parentN->part_refno>=0))
    738                 nu->part_refno=parentN->part_refno;
    739         if ((nu->joint_refno<0)&&(parentN->joint_refno>=0))
    740                 nu->joint_refno=parentN->joint_refno;
    741         nu->owner=this;
    742         // attach to part/joint
    743         if (nu->part_refno>=0)
    744                 nu->attachToPart(nu->part_refno);
    745         if (nu->joint_refno>=0)
    746                 nu->attachToJoint(nu->joint_refno);
    747         if (srcrange)
    748                 nu->setMapping(*srcrange);
    749         // special case: old muscles
    750         // PARENT neuron will be set up to be the CHILD of the current one (!)
    751         if (nu->isOldEffector())
    752                 {
    753                 nu->neuro_refno=parentN->refno;
    754                 neurons+=nu;
    755                 nu->owner=this;
    756                 nu->addInput(parentN,nu->weight); // (!)
    757                 nu->weight=1.0;
    758                 parentN->invalidateOldItems();
    759                 return 0; // !!! -> ...getItemCount()-1;
    760                 }
    761         parentN->addInput(nu,nu->weight);
    762         neurons+=nu;
    763         parentN->invalidateOldItems();
    764         if (nu->getClassName().len()==0)
    765                 {
    766                 nu->setClassName("-");
    767                 // for compatibility, "ni" can define a n-n connection
    768                 // referring to non-existent neuron (which will be hopefully defined later)
    769                 // internal check will add the proper input to this unit
    770                 // if conn_refno >=0 and input count==0
    771                 oldconnections=1;
    772                 if (srcrange)
    773                         parentN->addMapping(*srcrange);
    774                 }
    775         else
    776                 nu->weight=1.0;
    777         return 0; // !!! -> ...getItemCount()-1;
    778         }
    779 #endif
    780 else return -1;
     784        else return -1;
    781785}
    782786
     
    784788int Model::addOldConnectionsInputs()
    785789{
    786 if (!oldconnections) return 1;
    787 Neuro* n;
    788 for (int i=0;i<neurons.size();i++)
    789         {
    790         n=(Neuro*)neurons(i);
    791         if (n->conn_refno>=0)
    792                 if (n->isNNConnection())
    793                         if (n->conn_refno < old_getNeuroCount())
     790        if (!oldconnections) return 1;
     791        Neuro* n;
     792        for (int i=0;i<neurons.size();i++)
     793        {
     794                n=(Neuro*)neurons(i);
     795                if (n->conn_refno>=0)
     796                        if (n->isNNConnection())
     797                                if (n->conn_refno < old_getNeuroCount())
    794798                                { // good reference
    795                                 Neuro* parent=n->parent; // nn connection has exactly one parent
    796                                 int inp=parent->findInput(n);
    797                                 Neuro* target=getNeuro(n->conn_refno);
    798                                 parent->setInput(inp,target,n->weight);
    799                                 removeNeuro(i,0); // no need to remove references
    800                                 i--;
     799                        Neuro* parent=n->parent; // nn connection has exactly one parent
     800                        int inp=parent->findInput(n);
     801                        Neuro* target=getNeuro(n->conn_refno);
     802                        parent->setInput(inp,target,n->weight);
     803                        removeNeuro(i,0); // no need to remove references
     804                        i--;
    801805                                }
     806                                else
     807                                {
     808                                        logPrintf("Model","internalCheck",LOG_ERROR,
     809                                                "illegal N-N connection #%d (reference to #%d)%s",
     810                                                i,n->conn_refno,nameForErrors().c_str());
     811                                        return 0;
     812                                }
     813        }
     814        oldconnections=0;
     815        return 1;
     816}
     817#endif
     818
     819/////////////
     820
     821/** change the sequence of neuro units
     822        and fix references in "-" objects (n-n connections)  */
     823void Model::moveNeuro(int oldpos, int newpos)
     824{
     825        if (oldpos == newpos) return; // nop!
     826        Neuro *n = getNeuro(oldpos);
     827        neurons -= oldpos;
     828        neurons.insert(newpos, n);
     829        // conn_refno could be broken -> fix it
     830#ifdef MODEL_V1_COMPATIBLE
     831        for (int i=0;i<neurons.size();i++)
     832        {
     833                Neuro *n2=getNeuro(i);
     834                if (n2->isNNConnection())
     835                        if (n2->conn_refno == oldpos) n2->conn_refno=newpos;
    802836                        else
    803                                 {
    804                                 logPrintf("Model","internalCheck",LOG_ERROR,
    805                                          "illegal N-N connection #%d (reference to #%d)%s",
    806                                           i,n->conn_refno,nameForErrors().c_str());
    807                                 return 0;
    808                                 }
    809         }
    810 oldconnections=0;
    811 return 1;
    812 }
    813 #endif
    814 
    815 /////////////
    816 
    817 /** change the sequence of neuro units
    818     and fix references in "-" objects (n-n connections)  */
    819 void Model::moveNeuro(int oldpos,int newpos)
    820 {
    821 if (oldpos==newpos) return; // nop!
    822 Neuro *n=getNeuro(oldpos);
    823 neurons-=oldpos;
    824 neurons.insert(newpos,n);
    825  // conn_refno could be broken -> fix it
    826 #ifdef MODEL_V1_COMPATIBLE
    827 for (int i=0;i<neurons.size();i++)
    828         {
    829         Neuro *n2=getNeuro(i);
    830         if (n2->isNNConnection())
    831                 if (n2->conn_refno == oldpos) n2->conn_refno=newpos;
    832                 else
    833                 { if (n2->conn_refno > oldpos) n2->conn_refno--;
    834                   if (n2->conn_refno >= newpos) n2->conn_refno++; }
    835         }
    836 invalidateOldNeuroCount();
     837                        { if (n2->conn_refno > oldpos) n2->conn_refno--;
     838                if (n2->conn_refno >= newpos) n2->conn_refno++; }
     839        }
     840        invalidateOldNeuroCount();
    837841#endif
    838842}
     
    840844#ifdef MODEL_V1_COMPATIBLE
    841845/** move all old neurons (class "N") to the front of the neurons list.
    842     @return number of old neurons
    843   */
     846        @return number of old neurons
     847        */
    844848int Model::reorderToOldLayout()
    845849{
    846 Neuro *n;
    847 int neurocount=0;
    848 for (int i=0;i<neurons.size();i++)
    849         {
    850         n=(Neuro*)neurons(i);
    851         if (n->isOldNeuron())
    852                 {
    853                 moveNeuro(i,neurocount);
    854                 neurocount++;
    855                 i=neurocount-1;
    856                 }
    857         }
    858 return neurocount;
     850        Neuro *n;
     851        int neurocount=0;
     852        for (int i=0;i<neurons.size();i++)
     853        {
     854                n=(Neuro*)neurons(i);
     855                if (n->isOldNeuron())
     856                {
     857                        moveNeuro(i,neurocount);
     858                        neurocount++;
     859                        i=neurocount-1;
     860                }
     861        }
     862        return neurocount;
    859863}
    860864#endif
     
    863867void Model::updateNeuroRefno()
    864868{
    865 for (int i=0;i<neurons.size();i++)
    866         {
    867         Neuro* n=(Neuro*)neurons(i);
    868         n->refno=i;
     869        for (int i = 0; i < neurons.size(); i++)
     870        {
     871                Neuro* n = (Neuro*)neurons(i);
     872                n->refno = i;
    869873        }
    870874}
     
    882886void Model::updateRefno()
    883887{
    884 int i;
    885 for (i=0;i<getPartCount();i++) getPart(i)->refno=i;
    886 for (i=0;i<getJointCount();i++) getJoint(i)->refno=i;
    887 for (i=0;i<getNeuroCount();i++) getNeuro(i)->refno=i;
     888        int i;
     889        for (i = 0; i < getPartCount(); i++) getPart(i)->refno = i;
     890        for (i = 0; i < getJointCount(); i++) getJoint(i)->refno = i;
     891        for (i = 0; i < getNeuroCount(); i++) getNeuro(i)->refno = i;
    888892}
    889893
    890894SString Model::nameForErrors() const
    891895{
    892 if (geno.getName().len()>0)
    893         return SString::sprintf(" in '%s'",geno.getName().c_str());
    894 return SString::empty();
     896        if (geno.getName().len()>0)
     897                return SString::sprintf(" in '%s'", geno.getName().c_str());
     898        return SString::empty();
    895899}
    896900
    897901int Model::internalcheck(int final)
    898902{
    899 Part *p;
    900 Joint *j;
    901 Neuro *n;
    902 int i,k;
    903 int ret=1;
    904 shape=SHAPE_UNKNOWN;
    905 if ((parts.size()==0)&&(neurons.size()==0)) return 0;
    906 if (parts.size()==0)
    907         size=Pt3D_0;
    908 else
    909         {
    910 Pt3D bbmin=((Part*)parts(0))->p, bbmax=bbmin;
    911 for (i=0;i<parts.size();i++)
    912         {
    913         p=(Part*)parts(i);
    914         p->owner=this;
    915         p->refno=i;
    916         if (p->shape==0)
    917                 {
    918                 if (checklevel>0)
    919                         p->mass=0.0;
    920                 }
    921 //      VALIDMINMAX(p,part,mass);
    922         VALIDMINMAX(p,Part,size);
    923         VALIDMINMAX(p,Part,density);
    924         VALIDMINMAX(p,Part,friction);
    925         VALIDMINMAX(p,Part,ingest);
    926         VALIDMINMAX(p,Part,assim);
    927         p->flags&=~LINKFLAG; // for delta joint cycle detection
    928         if (p->p.x-p->size < bbmin.x) bbmin.x=p->p.x-p->size;
    929         if (p->p.y-p->size < bbmin.y) bbmin.y=p->p.y-p->size;
    930         if (p->p.z-p->size < bbmin.z) bbmin.z=p->p.z-p->size;
    931         if (p->p.x+p->size > bbmax.x) bbmax.x=p->p.x+p->size;
    932         if (p->p.y+p->size > bbmax.y) bbmax.y=p->p.y+p->size;
    933         if (p->p.z+p->size > bbmax.z) bbmax.z=p->p.z+p->size;
    934         if (shape==SHAPE_UNKNOWN)
    935                 shape=(p->shape==Part::SHAPE_DEFAULT)?SHAPE_OLD:SHAPE_NEW;
    936         else if (shape!=SHAPE_ILLEGAL)
    937                 {
    938                 if ((p->shape==Part::SHAPE_DEFAULT) ^ (shape==SHAPE_OLD))
     903        Part *p;
     904        Joint *j;
     905        Neuro *n;
     906        int i, k;
     907        int ret = 1;
     908        shape = SHAPE_UNKNOWN;
     909        if ((parts.size() == 0) && (neurons.size() == 0)) return 0;
     910        if (parts.size() == 0)
     911                size = Pt3D_0;
     912        else
     913        {
     914                Pt3D bbmin = ((Part*)parts(0))->p, bbmax = bbmin;
     915                for (i = 0; i < parts.size(); i++)
     916                {
     917                        p = (Part*)parts(i);
     918                        p->owner = this;
     919                        p->refno = i;
     920                        if (p->shape == 0)
    939921                        {
    940                         shape=SHAPE_ILLEGAL;
    941                         logPrintf("Model","internalCheck",LOG_WARN,"Inconsistent part shapes (mixed old and new shapes)%s",nameForErrors().c_str());
     922                                if (checklevel > 0)
     923                                        p->mass = 0.0;
    942924                        }
    943                 }
    944         }
    945 size=bbmax-bbmin;
    946 for (i=0;i<joints.size();i++)
    947         {
    948         j=(Joint*)joints(i);
    949         VALIDMINMAX(j,Joint,stamina);
    950         VALIDMINMAX(j,Joint,stif);
    951         VALIDMINMAX(j,Joint,rotstif);
    952         j->refno=i;
    953         j->owner=this;
    954         if (j->part1 && j->part2 && (j->part1 != j->part2))
    955                 {
    956                 j->p1_refno=j->part1->refno;
    957                 j->p2_refno=j->part2->refno;
    958                 if (checklevel>0)
     925                        //      VALIDMINMAX(p,part,mass);
     926                        VALIDMINMAX(p, Part, size);
     927                        VALIDMINMAX(p, Part, density);
     928                        VALIDMINMAX(p, Part, friction);
     929                        VALIDMINMAX(p, Part, ingest);
     930                        VALIDMINMAX(p, Part, assim);
     931                        p->flags &= ~LINKFLAG; // for delta joint cycle detection
     932                        if (p->p.x - p->size < bbmin.x) bbmin.x = p->p.x - p->size;
     933                        if (p->p.y - p->size < bbmin.y) bbmin.y = p->p.y - p->size;
     934                        if (p->p.z - p->size < bbmin.z) bbmin.z = p->p.z - p->size;
     935                        if (p->p.x + p->size > bbmax.x) bbmax.x = p->p.x + p->size;
     936                        if (p->p.y + p->size > bbmax.y) bbmax.y = p->p.y + p->size;
     937                        if (p->p.z + p->size > bbmax.z) bbmax.z = p->p.z + p->size;
     938                        if (shape == SHAPE_UNKNOWN)
     939                                shape = (p->shape == Part::SHAPE_DEFAULT) ? SHAPE_OLD : SHAPE_NEW;
     940                        else if (shape != SHAPE_ILLEGAL)
    959941                        {
    960                         if (j->part1->shape==0)
    961                                 j->part1->mass+=1.0;
    962                         if (j->part2->shape==0)
    963                                 j->part2->mass+=1.0;
    964                         }
    965                 if ((j->usedelta)&&((j->d.x!=JOINT_DELTA_MARKER)||(j->d.y!=JOINT_DELTA_MARKER)||(j->d.z!=JOINT_DELTA_MARKER)))
    966                         { // delta positioning -> calc. orient.
    967                         if (j->part2->flags & LINKFLAG)
     942                                if ((p->shape == Part::SHAPE_DEFAULT) ^ (shape == SHAPE_OLD))
    968943                                {
    969                                 ret=0;
    970                                 logPrintf("Model","internalCheck",LOG_ERROR,
    971                                          "Delta joint cycle detected at Joint #%d%s",
    972                                          i,nameForErrors().c_str());
    973                                 }
    974                         j->resetDeltaMarkers();
    975                         j->o=j->rot;
    976                         j->part1->o.transform(j->part2->o,j->o);
    977 //                      j->part2->o.x=j->part1->o/j->o.x;
    978 //                      j->part2->o.y=j->part1->o/j->o.y;
    979 //                      j->part2->o.z=j->part1->o/j->o.z;
    980                         j->part2->p=j->part2->o.transform(j->d)+j->part1->p;
    981                         j->part2->flags|=LINKFLAG; j->part1->flags|=LINKFLAG; // for delta joint cycle detection
    982                         }
    983                 else
    984                         { // abs.positioning -> calc. delta
    985                         if (final)
    986                         {
    987                         // calc orient delta
    988 //                      Orient tmpo(j->part2->o);
    989 //                      tmpo*=j->part1->o;
    990                         Orient tmpo;
    991                         j->part1->o.revTransform(tmpo,j->part2->o);
    992                         tmpo.getAngles(j->rot);
    993                         j->o=j->rot;
    994                         // calc position delta
    995                         Pt3D tmpp(j->part2->p);
    996                         tmpp-=j->part1->p;
    997                         j->d=j->part2->o.revTransform(tmpp);
    998                         }
    999                         }
    1000                 if (final)
    1001                         {
    1002                         if (j->shape!=Joint::SHAPE_SOLID)
    1003                                 {
    1004                         if (j->d()>getMaxJoint().d.x)
    1005                         {
    1006                         ret=0;
    1007                         logPrintf("Model","internalCheck",LOG_ERROR,"Joint #%d too long%s",i,nameForErrors().c_str());
    1008                         }
     944                                        shape = SHAPE_ILLEGAL;
     945                                        logPrintf("Model", "internalCheck", LOG_WARN, "Inconsistent part shapes (mixed old and new shapes)%s", nameForErrors().c_str());
    1009946                                }
    1010947                        }
    1011948                }
    1012         else
    1013                 {
    1014                 logPrintf("Model","internalCheck",LOG_ERROR,"Illegal part references in Joint #%d%s",i,nameForErrors().c_str());
    1015                 ret=0;
    1016                 }
    1017         if (shape!=SHAPE_ILLEGAL)
    1018                 {
    1019                 if ((j->shape==Joint::SHAPE_DEFAULT) ^ (shape==SHAPE_OLD))
     949                size = bbmax - bbmin;
     950                for (i = 0; i < joints.size(); i++)
     951                {
     952                        j = (Joint*)joints(i);
     953                        VALIDMINMAX(j, Joint, stamina);
     954                        VALIDMINMAX(j, Joint, stif);
     955                        VALIDMINMAX(j, Joint, rotstif);
     956                        j->refno = i;
     957                        j->owner = this;
     958                        if (j->part1 && j->part2 && (j->part1 != j->part2))
    1020959                        {
    1021                         shape=SHAPE_ILLEGAL;
    1022                         logPrintf("Model","internalCheck",LOG_WARN,"Inconsistent joint shapes (mixed old and new shapes)%s",nameForErrors().c_str());
    1023                         }
    1024                 }
    1025         }
    1026         }
    1027 #ifdef MODEL_V1_COMPATIBLE
    1028 if (!addOldConnectionsInputs())
    1029         return 0;
    1030 #endif
    1031 
    1032 updateNeuroRefno(); // valid refno is important for n-n connections check (later)
    1033 
    1034 for (i=0;i<neurons.size();i++)
    1035         {
    1036         n=(Neuro*)neurons(i);
    1037         VALIDMINMAX(n,Neuro,state);
    1038 #ifdef MODEL_V1_COMPATIBLE
    1039         VALIDMINMAX(n,Neuro,inertia);
    1040         VALIDMINMAX(n,Neuro,force);
    1041         VALIDMINMAX(n,Neuro,sigmo);
    1042         n->conn_refno=-1;
    1043         n->weight=1.0;
    1044         n->neuro_refno=-1;
    1045 #endif
    1046         n->part_refno=(n->part)?n->part->refno:-1;
    1047         n->joint_refno=(n->joint)?n->joint->refno:-1;
    1048         }
    1049 
    1050 if (parts.size()&&(checklevel>0))
    1051         {
    1052         for (i=0;i<parts.size();i++)
    1053                 {
    1054                 p=(Part*)parts(i);
    1055                 if (p->shape==0)
    1056                         if (p->mass<=0.001)
    1057                                 p->mass=1.0;
    1058                 p->flags&=~LINKFLAG;
    1059                 }
    1060         getPart(0)->flags|=LINKFLAG;
    1061         int change=1;
    1062         while(change)
    1063                 {
    1064                 change=0;
    1065                 for (i=0;i<joints.size();i++)
    1066                         {
    1067                         j=(Joint*)joints(i);
    1068                         if (j->part1->flags&LINKFLAG)
     960                                j->p1_refno = j->part1->refno;
     961                                j->p2_refno = j->part2->refno;
     962                                if (checklevel > 0)
    1069963                                {
    1070                                 if (!(j->part2->flags&LINKFLAG))
     964                                        if (j->part1->shape == 0)
     965                                                j->part1->mass += 1.0;
     966                                        if (j->part2->shape == 0)
     967                                                j->part2->mass += 1.0;
     968                                }
     969                                if ((j->usedelta) && ((j->d.x != JOINT_DELTA_MARKER) || (j->d.y != JOINT_DELTA_MARKER) || (j->d.z != JOINT_DELTA_MARKER)))
     970                                { // delta positioning -> calc. orient.
     971                                        if (j->part2->flags & LINKFLAG)
    1071972                                        {
    1072                                         change=1;
    1073                                         j->part2->flags|=LINKFLAG;
     973                                                ret = 0;
     974                                                logPrintf("Model", "internalCheck", LOG_ERROR,
     975                                                        "Delta joint cycle detected at Joint #%d%s",
     976                                                        i, nameForErrors().c_str());
     977                                        }
     978                                        j->resetDeltaMarkers();
     979                                        j->o = j->rot;
     980                                        j->part1->o.transform(j->part2->o, j->o);
     981                                        //                      j->part2->o.x=j->part1->o/j->o.x;
     982                                        //                      j->part2->o.y=j->part1->o/j->o.y;
     983                                        //                      j->part2->o.z=j->part1->o/j->o.z;
     984                                        j->part2->p = j->part2->o.transform(j->d) + j->part1->p;
     985                                        j->part2->flags |= LINKFLAG; j->part1->flags |= LINKFLAG; // for delta joint cycle detection
     986                                }
     987                                else
     988                                { // abs.positioning -> calc. delta
     989                                        if (final)
     990                                        {
     991                                                // calc orient delta
     992                                                //                      Orient tmpo(j->part2->o);
     993                                                //                      tmpo*=j->part1->o;
     994                                                Orient tmpo;
     995                                                j->part1->o.revTransform(tmpo, j->part2->o);
     996                                                tmpo.getAngles(j->rot);
     997                                                j->o = j->rot;
     998                                                // calc position delta
     999                                                Pt3D tmpp(j->part2->p);
     1000                                                tmpp -= j->part1->p;
     1001                                                j->d = j->part2->o.revTransform(tmpp);
    10741002                                        }
    10751003                                }
    1076                         else
    1077                         if (j->part2->flags&LINKFLAG)
     1004                                if (final)
    10781005                                {
    1079                                 if (!(j->part1->flags&LINKFLAG))
     1006                                        if (j->shape != Joint::SHAPE_SOLID)
    10801007                                        {
    1081                                         change=1;
    1082                                         j->part1->flags|=LINKFLAG;
     1008                                                if (j->d() > getMaxJoint().d.x)
     1009                                                {
     1010                                                        ret = 0;
     1011                                                        logPrintf("Model", "internalCheck", LOG_ERROR, "Joint #%d too long%s", i, nameForErrors().c_str());
     1012                                                }
    10831013                                        }
    10841014                                }
    10851015                        }
    1086                 }
    1087         for (i=0;i<parts.size();i++)
    1088                 {
    1089                 p=(Part*)parts(i);
    1090                 if (!(p->flags&LINKFLAG))
     1016                        else
    10911017                        {
    1092                         logPrintf("Model","internalCheck",LOG_ERROR,"Not all parts connected (eg. Part #0 and Part #%d)%s",i,nameForErrors().c_str());
    1093                         ret=0;
     1018                                logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal part references in Joint #%d%s", i, nameForErrors().c_str());
     1019                                ret = 0;
     1020                        }
     1021                        if (shape != SHAPE_ILLEGAL)
     1022                        {
     1023                                if ((j->shape == Joint::SHAPE_DEFAULT) ^ (shape == SHAPE_OLD))
     1024                                {
     1025                                        shape = SHAPE_ILLEGAL;
     1026                                        logPrintf("Model", "internalCheck", LOG_WARN, "Inconsistent joint shapes (mixed old and new shapes)%s", nameForErrors().c_str());
     1027                                }
     1028                        }
     1029                }
     1030        }
     1031#ifdef MODEL_V1_COMPATIBLE
     1032        if (!addOldConnectionsInputs())
     1033                return 0;
     1034#endif
     1035
     1036        updateNeuroRefno(); // valid refno is important for n-n connections check (later)
     1037
     1038        for (i = 0; i < neurons.size(); i++)
     1039        {
     1040                n = (Neuro*)neurons(i);
     1041                VALIDMINMAX(n, Neuro, state);
     1042#ifdef MODEL_V1_COMPATIBLE
     1043                VALIDMINMAX(n,Neuro,inertia);
     1044                VALIDMINMAX(n,Neuro,force);
     1045                VALIDMINMAX(n,Neuro,sigmo);
     1046                n->conn_refno=-1;
     1047                n->weight=1.0;
     1048                n->neuro_refno=-1;
     1049#endif
     1050                n->part_refno = (n->part) ? n->part->refno : -1;
     1051                n->joint_refno = (n->joint) ? n->joint->refno : -1;
     1052        }
     1053
     1054        if (parts.size() && (checklevel > 0))
     1055        {
     1056                for (i = 0; i < parts.size(); i++)
     1057                {
     1058                        p = (Part*)parts(i);
     1059                        if (p->shape == 0)
     1060                                if (p->mass <= 0.001)
     1061                                        p->mass = 1.0;
     1062                        p->flags &= ~LINKFLAG;
     1063                }
     1064                getPart(0)->flags |= LINKFLAG;
     1065                int change = 1;
     1066                while (change)
     1067                {
     1068                        change = 0;
     1069                        for (i = 0; i < joints.size(); i++)
     1070                        {
     1071                                j = (Joint*)joints(i);
     1072                                if (j->part1->flags&LINKFLAG)
     1073                                {
     1074                                        if (!(j->part2->flags&LINKFLAG))
     1075                                        {
     1076                                                change = 1;
     1077                                                j->part2->flags |= LINKFLAG;
     1078                                        }
     1079                                }
     1080                                else
     1081                                        if (j->part2->flags&LINKFLAG)
     1082                                        {
     1083                                        if (!(j->part1->flags&LINKFLAG))
     1084                                        {
     1085                                                change = 1;
     1086                                                j->part1->flags |= LINKFLAG;
     1087                                        }
     1088                                        }
     1089                        }
     1090                }
     1091                for (i = 0; i < parts.size(); i++)
     1092                {
     1093                        p = (Part*)parts(i);
     1094                        if (!(p->flags&LINKFLAG))
     1095                        {
     1096                                logPrintf("Model", "internalCheck", LOG_ERROR, "Not all parts connected (eg. Part #0 and Part #%d)%s", i, nameForErrors().c_str());
     1097                                ret = 0;
     1098                                break;
     1099                        }
     1100                }
     1101        }
     1102
     1103        for (i = 0; i < joints.size(); i++)
     1104        {
     1105                j = (Joint*)joints(i);
     1106                if (j->p1_refno == j->p2_refno)
     1107                {
     1108                        logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal self connection, Joint #%d%s", i, nameForErrors().c_str());
     1109                        ret = 0;
    10941110                        break;
     1111                }
     1112                for (k = i + 1; k < joints.size(); k++)
     1113                {
     1114                        Joint* j2 = (Joint*)joints(k);
     1115                        if (((j->p1_refno == j2->p1_refno) && (j->p2_refno == j2->p2_refno))
     1116                                || ((j->p1_refno == j2->p2_refno) && (j->p2_refno == j2->p1_refno)))
     1117                        {
     1118                                logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal duplicate Joint #%d and Joint #%d%s", i, k, nameForErrors().c_str());
     1119                                ret = 0;
     1120                                break;
    10951121                        }
    10961122                }
    10971123        }
    1098 
    1099 for (i=0;i<joints.size();i++)
    1100         {
    1101         j=(Joint*)joints(i);
    1102         if (j->p1_refno==j->p2_refno)
    1103                 {
    1104                 logPrintf("Model","internalCheck",LOG_ERROR,"Illegal self connection, Joint #%d%s",i,nameForErrors().c_str());
    1105                 ret=0;
    1106                 break;
    1107                 }
    1108         for (k=i+1;k<joints.size();k++)
    1109                 {
    1110                 Joint* j2=(Joint*)joints(k);
    1111                 if (((j->p1_refno==j2->p1_refno)&&(j->p2_refno==j2->p2_refno))
    1112                     || ((j->p1_refno==j2->p2_refno)&&(j->p2_refno==j2->p1_refno)))
    1113                         {
    1114                         logPrintf("Model","internalCheck",LOG_ERROR,"Illegal duplicate Joint #%d and Joint #%d%s",i,k,nameForErrors().c_str());
    1115                         ret=0;
    1116                         break;
    1117                         }
    1118                 }
    1119         }
    1120 if (shape==SHAPE_ILLEGAL)
    1121         ret=0;
    1122 return ret;
     1124        if (shape == SHAPE_ILLEGAL)
     1125                ret = 0;
     1126        return ret;
    11231127}
    11241128
     
    11271131int Model::getErrorPosition(bool includingwarnings)
    11281132{
    1129 return includingwarnings?
    1130         ((f0errorposition>=0) ? f0errorposition : f0warnposition)
    1131         :
    1132         f0errorposition;
     1133        return includingwarnings ?
     1134                ((f0errorposition >= 0) ? f0errorposition : f0warnposition)
     1135                :
     1136                f0errorposition;
    11331137}
    11341138
    11351139const Geno& Model::getGeno() const
    11361140{
    1137 return geno;
     1141        return geno;
    11381142}
    11391143
    11401144const Geno Model::getF0Geno()
    11411145{
    1142 if (buildstatus==building)
    1143         logPrintf("Model","getGeno",LOG_WARN,"Model was not completed - missing close()");
    1144 if (buildstatus!=valid)
    1145         return Geno("",'0',"","invalid");
    1146 if (!f0genoknown)
    1147         {
    1148         if (autobuildmaps)
    1149                 {
    1150                 initF0Map();
    1151                 makeGeno(f0geno,f0map);
    1152                 }
    1153         else
    1154                 {
    1155                 delF0Map();
    1156                 makeGeno(f0geno);
    1157                 }
    1158         f0genoknown=1;
    1159         }
    1160 return f0geno;
     1146        if (buildstatus == building)
     1147                logPrintf("Model", "getGeno", LOG_WARN, "Model was not completed - missing close()");
     1148        if (buildstatus != valid)
     1149                return Geno("", '0', "", "invalid");
     1150        if (!f0genoknown)
     1151        {
     1152                if (autobuildmaps)
     1153                {
     1154                        initF0Map();
     1155                        makeGeno(f0geno, f0map);
     1156                }
     1157                else
     1158                {
     1159                        delF0Map();
     1160                        makeGeno(f0geno);
     1161                }
     1162                f0genoknown = 1;
     1163        }
     1164        return f0geno;
    11611165}
    11621166
    11631167int Model::getPartCount() const
    11641168{
    1165 return parts.size();
     1169        return parts.size();
    11661170}
    11671171
    11681172Part* Model::getPart(int i) const
    11691173{
    1170 return ((Part*)parts(i));
     1174        return ((Part*)parts(i));
    11711175}
    11721176
    11731177int Model::getJointCount() const
    11741178{
    1175 return joints.size();
     1179        return joints.size();
    11761180}
    11771181
    11781182Joint* Model::getJoint(int i) const
    11791183{
    1180 return ((Joint*)joints(i));
    1181 }
    1182 
    1183 int Model::findJoints(SList& result,const Part* part)
    1184 {
    1185 Joint *j;
    1186 int n0=result.size();
    1187 if (part)
    1188    for(int i=0;j=(Joint*)joints(i);i++)
    1189      if ((j->part1 == part) || (j->part2 == part)) result+=(void*)j;
    1190 return result.size()-n0;
     1184        return ((Joint*)joints(i));
     1185}
     1186
     1187int Model::findJoints(SList& result, const Part* part)
     1188{
     1189        Joint *j;
     1190        int n0 = result.size();
     1191        if (part)
     1192                for (int i = 0; j = (Joint*)joints(i); i++)
     1193                        if ((j->part1 == part) || (j->part2 == part)) result += (void*)j;
     1194        return result.size() - n0;
    11911195}
    11921196
    11931197int Model::findNeuro(Neuro* n)
    1194 {return neurons.find(n);}
     1198{
     1199        return neurons.find(n);
     1200}
    11951201
    11961202int Model::findPart(Part* p)
    1197 {return parts.find(p);}
     1203{
     1204        return parts.find(p);
     1205}
    11981206
    11991207int Model::findJoint(Joint* j)
    1200 {return joints.find(j);}
     1208{
     1209        return joints.find(j);
     1210}
    12011211
    12021212int Model::findJoint(Part *p1, Part *p2)
    12031213{
    1204 Joint* j;
    1205 for(int i=0;j=getJoint(i);i++)
    1206         if ((j->part1==p1)&&(j->part2==p2)) return i;
    1207 return -1;
     1214        Joint* j;
     1215        for (int i = 0; j = getJoint(i); i++)
     1216                if ((j->part1 == p1) && (j->part2 == p2)) return i;
     1217        return -1;
    12081218}
    12091219
     
    12141224void Model::calcOldNeuroCount()
    12151225{
    1216 if (oldneurocount>=0) return;
    1217 oldneurocount=reorderToOldLayout();
     1226        if (oldneurocount>=0) return;
     1227        oldneurocount=reorderToOldLayout();
    12181228}
    12191229
    12201230int Model::old_getNeuroCount()
    12211231{ calcOldNeuroCount();
    1222  return oldneurocount;}
     1232return oldneurocount;}
    12231233
    12241234Neuro* Model::old_getNeuro(int i)
     
    12331243Neuro *Model::old_addNewNeuro()
    12341244{
    1235 int count=old_getNeuroCount();
    1236 Neuro *nu=addNewNeuro();
    1237 nu->setClassName("N");
    1238 moveNeuro(nu->refno,oldneurocount);
    1239 oldneurocount=count+1;
    1240 return (Neuro*)nu;
     1245        int count=old_getNeuroCount();
     1246        Neuro *nu=addNewNeuro();
     1247        nu->setClassName("N");
     1248        moveNeuro(nu->refno,oldneurocount);
     1249        oldneurocount=count+1;
     1250        return (Neuro*)nu;
    12411251}
    12421252#endif
     
    12451255
    12461256int Model::getNeuroCount() const
    1247 {return neurons.size();}
     1257{
     1258        return neurons.size();
     1259}
    12481260
    12491261Neuro* Model::getNeuro(int i) const
    1250 {return (Neuro*)neurons(i);}
     1262{
     1263        return (Neuro*)neurons(i);
     1264}
    12511265
    12521266int Model::getConnectionCount() const
    12531267{
    1254 int n=0;
    1255 for(int i=0;i<getNeuroCount();i++)
    1256         n+=getNeuro(i)->getInputCount();
    1257 return n;
     1268        int n = 0;
     1269        for (int i = 0; i < getNeuroCount(); i++)
     1270                n += getNeuro(i)->getInputCount();
     1271        return n;
    12581272}
    12591273
    12601274int Model::findNeuros(SList& result,
    1261                           const char* classname,const Part* part,const Joint* joint)
    1262 {
    1263 Neuro *nu;
    1264 SString cn(classname);
    1265 int n0=result.size();
    1266 for(int i=0;nu=(Neuro*)neurons(i);i++)
    1267         {
    1268         if (part)
    1269                 if (nu->part != part) continue;
    1270         if (joint)
    1271                 if (nu->joint != joint) continue;
    1272         if (classname)
    1273                 if (nu->getClassName() != cn) continue;
    1274         result+=(void*)nu;
    1275         }
    1276 return result.size()-n0;
     1275        const char* classname, const Part* part, const Joint* joint)
     1276{
     1277        Neuro *nu;
     1278        SString cn(classname);
     1279        int n0 = result.size();
     1280        for (int i = 0; nu = (Neuro*)neurons(i); i++)
     1281        {
     1282                if (part)
     1283                        if (nu->part != part) continue;
     1284                if (joint)
     1285                        if (nu->joint != joint) continue;
     1286                if (classname)
     1287                        if (nu->getClassName() != cn) continue;
     1288                result += (void*)nu;
     1289        }
     1290        return result.size() - n0;
    12771291}
    12781292
     
    12811295void Model::disturb(double amount)
    12821296{
    1283 int i;
    1284 if (amount<=0) return;
    1285 for(i=0;i<parts.size();i++)
    1286         {
    1287         Part *p=getPart(i);
    1288         p->p.x+=(rnd01-0.5)*amount;
    1289         p->p.y+=(rnd01-0.5)*amount;
    1290         p->p.z+=(rnd01-0.5)*amount;
    1291         }
    1292 for(i=0;i<joints.size();i++)
    1293         {
    1294         Joint *j=getJoint(i);
    1295         Pt3D tmpp(j->part2->p);
    1296         tmpp-=j->part1->p;
    1297         j->d=j->part2->o.revTransform(tmpp);
     1297        int i;
     1298        if (amount <= 0) return;
     1299        for (i = 0; i < parts.size(); i++)
     1300        {
     1301                Part *p = getPart(i);
     1302                p->p.x += (rnd01 - 0.5)*amount;
     1303                p->p.y += (rnd01 - 0.5)*amount;
     1304                p->p.z += (rnd01 - 0.5)*amount;
     1305        }
     1306        for (i = 0; i < joints.size(); i++)
     1307        {
     1308                Joint *j = getJoint(i);
     1309                Pt3D tmpp(j->part2->p);
     1310                tmpp -= j->part1->p;
     1311                j->d = j->part2->o.revTransform(tmpp);
    12981312        }
    12991313}
     
    13011315void Model::move(const Pt3D& shift)
    13021316{
    1303 FOREACH(Part*,p,parts)
    1304         p->p+=shift;
     1317        FOREACH(Part*, p, parts)
     1318                p->p += shift;
    13051319}
    13061320
    13071321void Model::rotate(const Orient& rotation)
    13081322{
    1309 FOREACH(Part*,p,parts)
    1310         {
    1311         p->p=rotation.transform(p->p);
    1312         p->setOrient(rotation.transform(p->o));
     1323        FOREACH(Part*, p, parts)
     1324        {
     1325                p->p = rotation.transform(p->p);
     1326                p->setOrient(rotation.transform(p->o));
    13131327        }
    13141328}
     
    13161330void Model::buildUsingNewShapes(const Model& old, Part::Shape default_shape, float thickness)
    13171331{
    1318 for(int i=0;i<old.getJointCount();i++)
    1319         {
    1320         Joint *oj=old.getJoint(i);
    1321         Part *p = addNewPart(default_shape);
    1322         p->p=(oj->part1->p+oj->part2->p)/2;
    1323         Orient o;
    1324         o.lookAt(oj->part1->p-oj->part2->p);
    1325         p->rot=o.getAngles();
    1326         p->scale.x=oj->part1->p.distanceTo(oj->part2->p)/2;
    1327         p->scale.y = thickness;
    1328         p->scale.z = thickness;
    1329         }
    1330 for(int i=0;i<old.getPartCount();i++)
    1331         {
    1332         Part *op=old.getPart(i);
    1333         for(int j=0;j<old.getJointCount();j++)
    1334                 {
    1335                 Joint *oj=old.getJoint(j);
    1336                 if ((oj->part1==op)||(oj->part2==op))
     1332        for (int i = 0; i < old.getJointCount(); i++)
     1333        {
     1334                Joint *oj = old.getJoint(i);
     1335                Part *p = addNewPart(default_shape);
     1336                p->p = (oj->part1->p + oj->part2->p) / 2;
     1337                Orient o;
     1338                o.lookAt(oj->part1->p - oj->part2->p);
     1339                p->rot = o.getAngles();
     1340                p->scale.x = oj->part1->p.distanceTo(oj->part2->p) / 2;
     1341                p->scale.y = thickness;
     1342                p->scale.z = thickness;
     1343        }
     1344        for (int i = 0; i < old.getPartCount(); i++)
     1345        {
     1346                Part *op = old.getPart(i);
     1347                for (int j = 0; j < old.getJointCount(); j++)
     1348                {
     1349                        Joint *oj = old.getJoint(j);
     1350                        if ((oj->part1 == op) || (oj->part2 == op))
    13371351                        {
    1338                         for(int j2=j+1;j2<old.getJointCount();j2++)
     1352                                for (int j2 = j + 1; j2 < old.getJointCount(); j2++)
    13391353                                {
    1340                                 Joint *oj2=old.getJoint(j2);
    1341                                 if ((oj2->part1==op)||(oj2->part2==op))
     1354                                        Joint *oj2 = old.getJoint(j2);
     1355                                        if ((oj2->part1 == op) || (oj2->part2 == op))
    13421356                                        {
    1343                                         addNewJoint(getPart(j),getPart(j2),Joint::SHAPE_SOLID);
     1357                                                addNewJoint(getPart(j), getPart(j2), Joint::SHAPE_SOLID);
    13441358                                        }
    13451359                                }
    1346                         break;
     1360                                break;
    13471361                        }
    13481362                }
     
    13521366//////////////////////
    13531367
    1354 class MinPart: public Part {public: MinPart() {Param par(f0_part_paramtab,this);par.setMin();}};
    1355 class MaxPart: public Part {public: MaxPart() {Param par(f0_part_paramtab,this);par.setMax();}};
    1356 class MinJoint: public Joint {public: MinJoint() {Param par(f0_joint_paramtab,this);par.setMin();}};
    1357 class MaxJoint: public Joint {public: MaxJoint() {Param par(f0_joint_paramtab,this);par.setMax();}};
    1358 class MinNeuro: public Neuro {public: MinNeuro() {Param par(f0_neuro_paramtab,this);par.setMin();}};
    1359 class MaxNeuro: public Neuro {public: MaxNeuro() {Param par(f0_neuro_paramtab,this);par.setMax();}};
    1360 
    1361 Part& Model::getMinPart() {static MinPart part; return part;}
    1362 Part& Model::getMaxPart() {static MaxPart part; return part;}
    1363 Part& Model::getDefPart() {static Part part; return part;}
    1364 Joint& Model::getMinJoint() {static MinJoint joint; return joint;}
    1365 Joint& Model::getMaxJoint() {static MaxJoint joint; return joint;}
    1366 Joint& Model::getDefJoint() {static Joint joint; return joint;}
    1367 Neuro& Model::getMinNeuro() {static MinNeuro neuro; return neuro;}
    1368 Neuro& Model::getMaxNeuro() {static MaxNeuro neuro; return neuro;}
    1369 Neuro& Model::getDefNeuro() {static Neuro neuro; return neuro;}
     1368class MinPart : public Part { public: MinPart() { Param par(f0_part_paramtab, this); par.setMin(); } };
     1369class MaxPart : public Part { public: MaxPart() { Param par(f0_part_paramtab, this); par.setMax(); } };
     1370class MinJoint : public Joint { public: MinJoint() { Param par(f0_joint_paramtab, this); par.setMin(); } };
     1371class MaxJoint : public Joint { public: MaxJoint() { Param par(f0_joint_paramtab, this); par.setMax(); } };
     1372class MinNeuro : public Neuro { public: MinNeuro() { Param par(f0_neuro_paramtab, this); par.setMin(); } };
     1373class MaxNeuro : public Neuro { public: MaxNeuro() { Param par(f0_neuro_paramtab, this); par.setMax(); } };
     1374
     1375Part& Model::getMinPart() { static MinPart part; return part; }
     1376Part& Model::getMaxPart() { static MaxPart part; return part; }
     1377Part& Model::getDefPart() { static Part part; return part; }
     1378Joint& Model::getMinJoint() { static MinJoint joint; return joint; }
     1379Joint& Model::getMaxJoint() { static MaxJoint joint; return joint; }
     1380Joint& Model::getDefJoint() { static Joint joint; return joint; }
     1381Neuro& Model::getMinNeuro() { static MinNeuro neuro; return neuro; }
     1382Neuro& Model::getMaxNeuro() { static MaxNeuro neuro; return neuro; }
     1383Neuro& Model::getDefNeuro() { static Neuro neuro; return neuro; }
Note: See TracChangeset for help on using the changeset viewer.