Changeset 522 for cpp/frams/model/model.cpp
- Timestamp:
- 06/23/16 00:15:59 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified cpp/frams/model/model.cpp ¶
r519 r522 11 11 Model::Model() 12 12 { 13 autobuildmaps=false;14 init();13 autobuildmaps = false; 14 init(); 15 15 } 16 16 17 17 void Model::init() 18 18 { 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; 24 24 #ifdef MODEL_V1_COMPATIBLE 25 oldneurocount=-1; // == unknown26 oldconnections=0;25 oldneurocount=-1; // == unknown 26 oldconnections=0; 27 27 #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; 32 32 } 33 33 34 34 void Model::moveElementsFrom(Model &source) 35 35 { 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(); 46 46 } 47 47 48 48 void Model::internalCopy(const Model &mod) 49 49 { 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); 62 62 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); 69 69 addNeuro(n); 70 if (oldn->part_refno >=0) n->attachToPart(oldn->part_refno);70 if (oldn->part_refno >= 0) n->attachToPart(oldn->part_refno); 71 71 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++) 78 78 { 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); 83 83 } 84 84 } … … 87 87 88 88 89 Model::Model(const Geno &src, bool buildmaps)89 Model::Model(const Geno &src, bool buildmaps) 90 90 :autobuildmaps(buildmaps) 91 {init(src);} 91 { 92 init(src); 93 } 92 94 93 95 void Model::operator=(const Model &mod) 94 96 { 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 103 Model::Model(const Model &mod, bool buildmaps) 102 104 :autobuildmaps(buildmaps) 103 105 { 104 init();105 open();106 internalCopy(mod);107 buildstatus=mod.buildstatus;106 init(); 107 open(); 108 internalCopy(mod); 109 buildstatus = mod.buildstatus; 108 110 } 109 111 110 112 void Model::init(const Geno &src) 111 113 { 112 init();113 modelfromgenotype=1;114 geno=src;115 build();114 init(); 115 modelfromgenotype = 1; 116 geno = src; 117 build(); 116 118 } 117 119 118 120 void Model::resetAllDelta() 119 121 { 120 for (int i=0;i<getJointCount();i++)121 getJoint(i)->resetDelta();122 for (int i = 0; i < getJointCount(); i++) 123 getJoint(i)->resetDelta(); 122 124 } 123 125 124 126 void Model::useAllDelta(bool yesno) 125 127 { 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); 128 130 } 129 131 130 132 Model::~Model() 131 133 { 132 delmodel_list.action((intptr_t)this);133 clear();134 delmodel_list.action((intptr_t)this); 135 clear(); 134 136 } 135 137 136 138 void Model::clear() 137 139 { 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 154 Part *Model::addPart(Part *p) 155 { 156 p->owner = this; 157 p->refno = parts.size(); 158 parts += p; 159 return p; 160 } 161 162 Joint *Model::addJoint(Joint *j) 163 { 164 j->owner = this; 165 j->refno = joints.size(); 166 joints += j; 167 return j; 168 } 169 170 Neuro *Model::addNeuro(Neuro *n) 171 { 172 n->owner = this; 173 n->refno = neurons.size(); 174 neurons += n; 175 return n; 176 } 177 178 void 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 187 void 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; 139 207 delete p; 140 FOREACH(Joint*,j,joints) 208 } 209 210 void 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; 141 220 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 223 void 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) 234 236 { 235 237 n->removeInput(j); … … 239 241 } 240 242 241 neurons-=neuroindex;242 delete thisN;243 neurons -= neuroindex; 244 delete thisN; 243 245 } 244 246 245 247 MultiMap& Model::getMap() 246 248 { 247 if (!map) map=new MultiMap();248 return *map;249 if (!map) map = new MultiMap(); 250 return *map; 249 251 } 250 252 251 253 void Model::delMap() 252 254 { 253 if (map) {delete map; map=0;}255 if (map) { delete map; map = 0; } 254 256 } 255 257 void Model::delF0Map() 256 258 { 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 262 void 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); 266 268 } 267 269 268 270 void Model::getCurrentToF0Map(MultiMap& result) 269 271 { 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); 274 276 } 275 277 276 278 void Model::rebuild(bool buildm) 277 279 { 278 autobuildmaps=buildm;279 clear();280 build();280 autobuildmaps = buildm; 281 clear(); 282 build(); 281 283 } 282 284 283 285 void Model::initMap() 284 286 { 285 if (!map) map=new MultiMap();286 else map->clear();287 if (!map) map = new MultiMap(); 288 else map->clear(); 287 289 } 288 290 289 291 void Model::initF0Map() 290 292 { 291 if (!f0map) f0map=new MultiMap();292 else f0map->clear();293 if (!f0map) f0map = new MultiMap(); 294 else f0map->clear(); 293 295 } 294 296 295 297 void Model::build() 296 298 { 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; 332 307 if (convmap) delete convmap; 333 308 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; 351 355 } 352 356 } … … 354 358 const MultiMap& Model::getF0Map() 355 359 { 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; 363 367 } 364 368 365 369 Geno Model::rawGeno() 366 370 { 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 376 void 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++) 441 445 { // inputs 442 n=(Neuro*)neurons(a);443 // if ((n->getInputCount()==1)&&(n->getInput(0).refno <= n->refno))444 // continue; // already done with Neuro::conn_refno445 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_refno458 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'); 473 477 } 474 478 … … 477 481 void Model::open() 478 482 { 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(); 485 489 } 486 490 … … 490 494 void Model::setGeno(const Geno& newgeno) 491 495 { 492 geno=newgeno;496 geno = newgeno; 493 497 } 494 498 495 499 void Model::clearMap() 496 500 { 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(); 507 511 } 508 512 509 513 int Model::close() 510 514 { 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); 537 541 } 538 542 539 543 int Model::validate() 540 544 { 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 available568 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 548 Pt3D 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 560 int Model::singleStepBuild(const SString &singleline, const MultiRange* srcrange) 561 { 562 return singleStepBuild(singleline, 0, srcrange); 563 } 564 565 int 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 581 int 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)) 620 624 { 621 j->useDelta(1);622 j->resetDeltaMarkers();625 j->useDelta(1); 626 j->resetDeltaMarkers(); 623 627 } 624 j->attachToParts(j->p1_refno,j->p2_refno);625 if (srcrange) j->setMapping(*srcrange);626 return j->refno;627 } 628 else629 { 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; } 642 646 #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 646 669 { 647 670 delete nu; 648 671 return -1; 649 672 } 650 Neuro *parentNU=getNeuro(nu->neuro_refno);651 parentNU->addInput(nu,nu->weight);652 // default class for parented units: n-n link653 //if (nu->moredata.len()==0) nu->moredata="-";654 } 655 else673 Neuro *inputNU=getNeuro(nu->conn_refno); 674 nu->addInput(inputNU,nu->weight); 675 } 676 */ 677 #ifdef MODEL_V1_COMPATIBLE 678 nu->weight=1.0; 656 679 #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 { 666 736 delete nu; 667 737 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 } 675 783 #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; 781 785 } 782 786 … … 784 788 int Model::addOldConnectionsInputs() 785 789 { 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()) 794 798 { // good reference 795 796 797 798 799 800 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--; 801 805 } 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) */ 823 void 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; 802 836 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(); 837 841 #endif 838 842 } … … 840 844 #ifdef MODEL_V1_COMPATIBLE 841 845 /** move all old neurons (class "N") to the front of the neurons list. 842 843 846 @return number of old neurons 847 */ 844 848 int Model::reorderToOldLayout() 845 849 { 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; 859 863 } 860 864 #endif … … 863 867 void Model::updateNeuroRefno() 864 868 { 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; 869 873 } 870 874 } … … 882 886 void Model::updateRefno() 883 887 { 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; 888 892 } 889 893 890 894 SString Model::nameForErrors() const 891 895 { 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(); 895 899 } 896 900 897 901 int Model::internalcheck(int final) 898 902 { 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) 939 921 { 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; 942 924 } 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) 959 941 { 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)) 968 943 { 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()); 1009 946 } 1010 947 } 1011 948 } 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)) 1020 959 { 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) 1069 963 { 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) 1071 972 { 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); 1074 1002 } 1075 1003 } 1076 else 1077 if (j->part2->flags&LINKFLAG) 1004 if (final) 1078 1005 { 1079 if (!(j->part1->flags&LINKFLAG))1006 if (j->shape != Joint::SHAPE_SOLID) 1080 1007 { 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 } 1083 1013 } 1084 1014 } 1085 1015 } 1086 } 1087 for (i=0;i<parts.size();i++) 1088 { 1089 p=(Part*)parts(i); 1090 if (!(p->flags&LINKFLAG)) 1016 else 1091 1017 { 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; 1094 1110 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; 1095 1121 } 1096 1122 } 1097 1123 } 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; 1123 1127 } 1124 1128 … … 1127 1131 int Model::getErrorPosition(bool includingwarnings) 1128 1132 { 1129 return includingwarnings?1130 ((f0errorposition>=0) ? f0errorposition : f0warnposition)1131 :1132 f0errorposition;1133 return includingwarnings ? 1134 ((f0errorposition >= 0) ? f0errorposition : f0warnposition) 1135 : 1136 f0errorposition; 1133 1137 } 1134 1138 1135 1139 const Geno& Model::getGeno() const 1136 1140 { 1137 return geno;1141 return geno; 1138 1142 } 1139 1143 1140 1144 const Geno Model::getF0Geno() 1141 1145 { 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 else1154 { 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; 1161 1165 } 1162 1166 1163 1167 int Model::getPartCount() const 1164 1168 { 1165 return parts.size();1169 return parts.size(); 1166 1170 } 1167 1171 1168 1172 Part* Model::getPart(int i) const 1169 1173 { 1170 return ((Part*)parts(i));1174 return ((Part*)parts(i)); 1171 1175 } 1172 1176 1173 1177 int Model::getJointCount() const 1174 1178 { 1175 return joints.size();1179 return joints.size(); 1176 1180 } 1177 1181 1178 1182 Joint* Model::getJoint(int i) const 1179 1183 { 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 1187 int 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; 1191 1195 } 1192 1196 1193 1197 int Model::findNeuro(Neuro* n) 1194 {return neurons.find(n);} 1198 { 1199 return neurons.find(n); 1200 } 1195 1201 1196 1202 int Model::findPart(Part* p) 1197 {return parts.find(p);} 1203 { 1204 return parts.find(p); 1205 } 1198 1206 1199 1207 int Model::findJoint(Joint* j) 1200 {return joints.find(j);} 1208 { 1209 return joints.find(j); 1210 } 1201 1211 1202 1212 int Model::findJoint(Part *p1, Part *p2) 1203 1213 { 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; 1208 1218 } 1209 1219 … … 1214 1224 void Model::calcOldNeuroCount() 1215 1225 { 1216 if (oldneurocount>=0) return;1217 oldneurocount=reorderToOldLayout();1226 if (oldneurocount>=0) return; 1227 oldneurocount=reorderToOldLayout(); 1218 1228 } 1219 1229 1220 1230 int Model::old_getNeuroCount() 1221 1231 { calcOldNeuroCount(); 1222 1232 return oldneurocount;} 1223 1233 1224 1234 Neuro* Model::old_getNeuro(int i) … … 1233 1243 Neuro *Model::old_addNewNeuro() 1234 1244 { 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; 1241 1251 } 1242 1252 #endif … … 1245 1255 1246 1256 int Model::getNeuroCount() const 1247 {return neurons.size();} 1257 { 1258 return neurons.size(); 1259 } 1248 1260 1249 1261 Neuro* Model::getNeuro(int i) const 1250 {return (Neuro*)neurons(i);} 1262 { 1263 return (Neuro*)neurons(i); 1264 } 1251 1265 1252 1266 int Model::getConnectionCount() const 1253 1267 { 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; 1258 1272 } 1259 1273 1260 1274 int 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; 1277 1291 } 1278 1292 … … 1281 1295 void Model::disturb(double amount) 1282 1296 { 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); 1298 1312 } 1299 1313 } … … 1301 1315 void Model::move(const Pt3D& shift) 1302 1316 { 1303 FOREACH(Part*,p,parts)1304 p->p+=shift;1317 FOREACH(Part*, p, parts) 1318 p->p += shift; 1305 1319 } 1306 1320 1307 1321 void Model::rotate(const Orient& rotation) 1308 1322 { 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)); 1313 1327 } 1314 1328 } … … 1316 1330 void Model::buildUsingNewShapes(const Model& old, Part::Shape default_shape, float thickness) 1317 1331 { 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)) 1337 1351 { 1338 for(int j2=j+1;j2<old.getJointCount();j2++)1352 for (int j2 = j + 1; j2 < old.getJointCount(); j2++) 1339 1353 { 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)) 1342 1356 { 1343 addNewJoint(getPart(j),getPart(j2),Joint::SHAPE_SOLID);1357 addNewJoint(getPart(j), getPart(j2), Joint::SHAPE_SOLID); 1344 1358 } 1345 1359 } 1346 break;1360 break; 1347 1361 } 1348 1362 } … … 1352 1366 ////////////////////// 1353 1367 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;}1368 class MinPart : public Part { public: MinPart() { Param par(f0_part_paramtab, this); par.setMin(); } }; 1369 class MaxPart : public Part { public: MaxPart() { Param par(f0_part_paramtab, this); par.setMax(); } }; 1370 class MinJoint : public Joint { public: MinJoint() { Param par(f0_joint_paramtab, this); par.setMin(); } }; 1371 class MaxJoint : public Joint { public: MaxJoint() { Param par(f0_joint_paramtab, this); par.setMax(); } }; 1372 class MinNeuro : public Neuro { public: MinNeuro() { Param par(f0_neuro_paramtab, this); par.setMin(); } }; 1373 class MaxNeuro : public Neuro { public: MaxNeuro() { Param par(f0_neuro_paramtab, this); par.setMax(); } }; 1374 1375 Part& Model::getMinPart() { static MinPart part; return part; } 1376 Part& Model::getMaxPart() { static MaxPart part; return part; } 1377 Part& Model::getDefPart() { static Part part; return part; } 1378 Joint& Model::getMinJoint() { static MinJoint joint; return joint; } 1379 Joint& Model::getMaxJoint() { static MaxJoint joint; return joint; } 1380 Joint& Model::getDefJoint() { static Joint joint; return joint; } 1381 Neuro& Model::getMinNeuro() { static MinNeuro neuro; return neuro; } 1382 Neuro& Model::getMaxNeuro() { static MaxNeuro neuro; return neuro; } 1383 Neuro& Model::getDefNeuro() { static Neuro neuro; return neuro; }
Note: See TracChangeset
for help on using the changeset viewer.