source: cpp/frams/model/modelparts.cpp @ 947

Last change on this file since 947 was 932, checked in by Maciej Komosinski, 5 years ago

Neuron classes now have a property (a bit field) that says whether each neuron class supports model shape BALL_AND_STICK, SOLIDS, or both

  • Property svn:eol-style set to native
File size: 16.0 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[932]2// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[109]4
5#include <stdlib.h>
6#include <math.h>
7#include <stdio.h>
8#include <string.h>
9#include <ctype.h>
10#include <time.h>
11#include <errno.h>
12
13///////////////////////////////     MODELPARTS.CPP     ///////////////
14
15#include "modelparts.h"
16#include "model.h"
17
18#include <common/nonstd.h>
19#include <frams/param/param.h>
20#include <frams/neuro/neurolibrary.h>
21#include <frams/util/multirange.h>
22#include <frams/util/extvalue.h>
23#include <frams/param/paramobj.h>
24
25#include F0_DEFASSIGN_FILE
26
[288]27#ifndef SDK_WITHOUT_FRAMS
[109]28#include <frams/neuro/neuroclsobject.h>
29#endif
30
31/////////////////////////
32
33PartBase::~PartBase()
[714]34{
35        if (mapped) delete mapped;
36}
[109]37
38void PartBase::notifyMappingChange()
39{
[714]40        if (owner) owner->partmappingchanged = 1;
[109]41}
42
43void PartBase::setMapping(const IRange &r)
44{
[714]45        if (mapped) (*mapped) = r;
46        else mapped = new MultiRange(r);
47        notifyMappingChange();
[109]48}
49
50void PartBase::clearMapping()
51{
[714]52        if (mapped) { delete mapped; mapped = 0; }
[109]53}
54
55void PartBase::addMapping(const IRange &r)
56{
[714]57        if (mapped) mapped->add(r);
58        else mapped = new MultiRange(r);
59        notifyMappingChange();
[109]60}
61
62void PartBase::setMapping(const MultiRange &mr)
63{
[714]64        if (mapped) (*mapped) = mr;
65        else mapped = new MultiRange(mr);
66        notifyMappingChange();
[109]67}
68
69void PartBase::addMapping(const MultiRange &mr)
70{
[714]71        if (mapped) mapped->add(mr);
72        else mapped = new MultiRange(mr);
73        notifyMappingChange();
[109]74}
75
[899]76void PartBase::setInfo(const SString &name, const SString &value)
[109]77{
[714]78        strSetField(info, name, value);
[109]79}
80
[899]81void PartBase::setInfo(const SString &name, int value)
[109]82{
[714]83        setInfo(name, SString::valueOf(value));
[109]84}
85
[899]86void PartBase::setInfo(const SString &name, double value)
[109]87{
[714]88        setInfo(name, SString::valueOf(value));
[109]89}
90
[899]91SString PartBase::getInfo(const SString &name)
[109]92{
[714]93        return strGetField(info, name);
[109]94}
95
96/////////////////////////
97
[714]98NeuroClass::NeuroClass(ParamEntry *_props, SString _description,
99        int _prefinputs, int _prefoutput, int _preflocation,
[932]100        int *_vectordata, bool own_vd, int vhints, int sup_shapes)
[109]101        :ownedvectordata(own_vd),
[714]102        name(_props->name), longname(_props->id), description(_description),
103        props(_props), ownedprops(false),
104        prefinputs(_prefinputs),
105        prefoutput(_prefoutput),
106        preflocation(_preflocation),
[932]107        supported_shape_types(sup_shapes),
[714]108        vectordata(_vectordata),
109        visualhints(vhints), impl_count(0),/*impl(0),*/active(1), genactive(0)
[109]110{}
111
112NeuroClass::~NeuroClass()
113{
[714]114        setSymbolGlyph(0, 0);
115        if (props && ownedprops)
116                ParamObject::freeParamTab(props);
[109]117}
118
119NeuroClass::NeuroClass()
120        :ownedvectordata(0),
[714]121        name("Invalid"),
122        props(empty_paramtab), ownedprops(false),
123        prefinputs(0), prefoutput(0),
124        preflocation(0), vectordata(0),
125        visualhints(0), impl_count(0), /*impl(0),*/ active(1), genactive(0)
[109]126{}
127
[714]128void NeuroClass::resetActive()
129{
130        for (int i = 0; i < Neuro::getClassCount(); i++)
131        {
132                Neuro::getClass(i)->genactive = 0;
133                Neuro::getClass(i)->active = 1;
134        }
135}
136
[899]137void NeuroClass::setGenActive(const char *genactive_classes[])
[714]138{
[899]139        for (const char **n = genactive_classes; *n; n++)
[714]140        {
[899]141                NeuroClass *cls = Neuro::getClass(*n);
[714]142                if (cls) cls->genactive = 1;
143        }
144}
145
[109]146SString NeuroClass::getSummary()
147{
[714]148        SString t;
149        t = getDescription();
150        if (t.len()) t += "\n\n";
151        t += "Characteristics:\n";
152        if (getPreferredInputs())
[109]153        {
[714]154                if (getPreferredInputs() < 0) t += "   supports any number of inputs\n";
155                else if (getPreferredInputs() == 1) t += "   uses single input\n";
156                else t += SString::sprintf("   uses %d inputs\n", getPreferredInputs());
[109]157        }
[714]158        else t += "   does not use inputs\n";
159        if (getPreferredOutput())
160                t += "   provides output value\n";
161        else
162                t += "   does not provide output value\n";
163        switch (getPreferredLocation())
[109]164        {
[714]165        case 0: t += "   does not require location in body\n"; break;
166        case 1: t += "   should be located on a Part\n"; break;
167        case 2: t += "   should be located on a Joint\n"; break;
[109]168        }
[714]169        Param p = getProperties();
170        if (p.getPropCount())
[109]171        {
[714]172                if (t.len()) t += "\n\n";
173                t += "Properties:\n";
174                const char *h;
175                int i;
176                for (i = 0; i < p.getPropCount(); i++)
[109]177                {
[714]178                        if (i) t += "\n";
179                        t += "   "; t += p.name(i); t += " ("; t += p.id(i); t += ") ";
[743]180                        t += p.friendlyTypeDescr(i);
[714]181                        if (h = p.help(i)) if (*h) { t += " - "; t += h; }
[109]182                }
183        }
[714]184        return t;
[109]185}
186
187/////////////////////////
188
189/////////////////////////////////////
190
[714]191Neuro::Neuro(double _state, double _inertia, double _force, double _sigmo)
192        :PartBase(getDefaultStyle()), state(_state)
[109]193{
[714]194        flags = 0;
195        myclass = 0;
196        knownclass = 1;
197        part_refno = -1; joint_refno = -1;
[109]198}
199
[714]200Neuro::Neuro(void) :PartBase(getDefaultStyle())
[109]201{
[714]202        defassign();
203        state = 0.0;
204        myclass = NULL;
205        myclassname = "N";//default d="N" but f0.def is unable to set this (d is GETSET, not a regular FIELD)
206        knownclass = 0;
207        refno = 0;
208        pos = Pt3D_0; rot = Pt3D_0;
209        parent = 0; part = 0; joint = 0;
210        parentcount = 0;
211        flags = 0;
212        part_refno = -1; joint_refno = -1;
[109]213}
214
215
216Neuro::~Neuro()
217{
[714]218        int i;
219        for (i = 0; i < inputs.size(); i++)
[109]220        {
[714]221                NInput &ni = inputs(i);
222                if (ni.info) delete ni.info;
[109]223        }
224}
225
[899]226SString **Neuro::inputInfo(int i)
[109]227{
[714]228        if (i >= getInputCount()) return 0;
229        return &inputs(i).info;
[109]230}
231
[899]232void Neuro::setInputInfo(int i, const SString &name, const SString &value)
[109]233{
[714]234        SString **s = inputInfo(i);
235        if (!s) return;
236        if (!*s) *s = new SString();
237        strSetField(**s, name, value);
[109]238}
239
[899]240void Neuro::setInputInfo(int i, const SString &name, int value)
[109]241{
[714]242        setInputInfo(i, name, SString::valueOf(value));
[109]243}
244
[899]245void Neuro::setInputInfo(int i, const SString &name, double value)
[109]246{
[714]247        setInputInfo(i, name, SString::valueOf(value));
[109]248}
249
250SString Neuro::getInputInfo(int i)
251{
[714]252        SString **s = inputInfo(i);
253        if (!s) return SString();
254        if (!*s) return SString();
255        return **s;
[109]256}
257
[899]258SString Neuro::getInputInfo(int i, const SString &name)
[109]259{
[714]260        SString **s = inputInfo(i);
261        if (!s) return SString();
262        if (!*s) return SString();
263        return strGetField(**s, name);
[109]264}
265
[899]266void Neuro::operator=(const Neuro &src)
[109]267{
[714]268        refno = src.refno;
269        state = src.state;
270        part_refno = -1;
271        joint_refno = -1;
272        pos = src.pos; rot = src.rot;
273        parent = 0; part = 0; joint = 0;
274        parentcount = 0;
275        flags = 0;
276        myclass = src.myclass;
277        knownclass = src.knownclass;
278        myclassname = src.myclassname;
279        myclassparams = src.myclassparams;
[109]280}
281
282void Neuro::attachToPart(int i)
[714]283{
284        attachToPart((i >= 0) ? owner->getPart(i) : 0);
285}
[109]286
287void Neuro::attachToJoint(int i)
[714]288{
289        attachToJoint((i >= 0) ? owner->getJoint(i) : 0);
290}
[109]291
292int Neuro::getClassCount()
[714]293{
294        return NeuroLibrary::staticlibrary.getClassCount();
295}
[109]296
[899]297NeuroClass *Neuro::getClass(int classindex)
[714]298{
299        return NeuroLibrary::staticlibrary.getClass(classindex);
300}
[109]301
[899]302NeuroClass *Neuro::getClass(const SString &classname)
[714]303{
304        return NeuroLibrary::staticlibrary.findClass(classname);
305}
[109]306
[899]307int Neuro::getClassIndex(const NeuroClass *nc)
[714]308{
[899]309        return NeuroLibrary::staticlibrary.classes.find((void *)nc);
[714]310}
[109]311
[899]312NeuroClass *Neuro::getClass()
[109]313{
[714]314        checkClass();
315        return myclass;
[109]316}
317
[899]318void Neuro::setClass(NeuroClass *cl)
[109]319{
[714]320        myclass = cl;
321        myclassname = cl->getName();
322        knownclass = 1;
[109]323}
324
325SString Neuro::getClassName(int classindex)
326{
[714]327        NeuroClass *cl = NeuroLibrary::staticlibrary.getClass(classindex);
328        return cl ? cl->getName() : SString();
[109]329}
330
[899]331void Neuro::setDetails(const SString &details)
[109]332{
[714]333        int colon = details.indexOf(':');
334        if (colon >= 0) { myclassname = details.substr(0, colon); myclassparams = details.substr(colon + 1); }
335        else { myclassname = details; myclassparams = 0; }
336        knownclass = 0;
[109]337}
338
339SString Neuro::getDetails()
340{
[714]341        SString ret = getClassName();
342        if (myclassparams.len()) { if (!ret.len()) ret = "N"; ret += ":"; ret += myclassparams; }
343        return ret;
[109]344}
345
346void Neuro::checkClass()
347{
[714]348        if (knownclass) return;
349        myclass = getClass(myclassname);
350        knownclass = 1;
[109]351}
352
353SyntParam Neuro::classProperties(bool handle_defaults_when_saving)
354{
[714]355        NeuroClass *cl = getClass();
356        ParamEntry *pe = cl ? cl->getParamTab() : emptyParamTab;
357        return SyntParam(pe, &myclassparams, handle_defaults_when_saving);
[109]358}
359
360SString Neuro::getClassName()
361{
[714]362        return myclassname;
[109]363}
364
[899]365void Neuro::setClassName(const SString &clazz)
[109]366{
[714]367        myclassname = clazz;
368        knownclass = 0;
[109]369}
370
[899]371int Neuro::addInput(Neuro *child, double weight, const SString *info)
[109]372{
[714]373        inputs += NInput(child, weight, (info && (info->len())) ? new SString(*info) : 0);
374        child->parentcount++;
375        if (child->parentcount == 1) { child->parent = this; }
376        return inputs.size() - 1;
[109]377}
378
[899]379int Neuro::findInput(Neuro *child) const
[109]380{
[714]381        for (int i = 0; i < inputs.size(); i++)
382                if (inputs(i).n == child) return i;
383        return -1;
[109]384}
385
[899]386Neuro *Neuro::getInput(int i, double &weight) const
[109]387{
[714]388        if (i >= getInputCount()) return 0;
389        NInput &inp = inputs(i);
390        weight = inp.weight;
391        return inp.n;
[109]392}
393
394double Neuro::getInputWeight(int i) const
395{
[714]396        return inputs(i).weight;
[109]397}
398
[714]399void Neuro::setInputWeight(int i, double w)
[109]400{
[714]401        inputs(i).weight = w;
[109]402}
403
[899]404void Neuro::setInput(int i, Neuro *n)
[109]405{
[714]406        NInput &inp = inputs(i);
407        inp.n = n;
[109]408}
409
[899]410void Neuro::setInput(int i, Neuro *n, double w)
[109]411{
[714]412        NInput &inp = inputs(i);
413        inp.n = n;
414        inp.weight = w;
[109]415}
416
417void Neuro::removeInput(int refno)
418{
[714]419        Neuro *child = getInput(refno);
420        child->parentcount--;
421        if (child->parent == this) child->parent = 0;
422        SString *s = inputs(refno).info;
423        if (s) delete s;
424        inputs.remove(refno);
[109]425}
426
[899]427int Neuro::removeInput(Neuro *child)
[109]428{
[714]429        int i = findInput(child);
430        if (i >= 0) removeInput(i);
431        return i;
[109]432}
433
434int Neuro::getOutputsCount() const
435{
[714]436        int c = 0;
437        for (int i = 0; i < owner->getNeuroCount(); i++)
438                for (int j = 0; j < owner->getNeuro(i)->getInputCount(); j++) c += owner->getNeuro(i)->getInput(j) == this;
439        return c;
[109]440}
441
442int Neuro::isOldEffector()
443{
[714]444        static SString bend("|"), rot("@");
445        return ((getClassName() == bend) || (getClassName() == rot));
[109]446}
447
448int Neuro::isOldReceptor()
449{
[714]450        static SString g("G"), t("T"), s("S");
451        return ((getClassName() == g) || (getClassName() == t) || (getClassName() == s));
[109]452}
453
454int Neuro::isOldNeuron()
455{
[714]456        static SString n("N");
457        return (getClassName() == n);
[109]458}
459
460int Neuro::isNNConnection()
461{
[714]462        static SString conn("-");
463        return (getClassName() == conn);
[109]464}
465
[899]466int Neuro::findInputs(SList &result, const char *classname, const Part *part, const Joint *joint) const
[109]467{
[714]468        Neuro *nu;
469        SString cn(classname);
470        int n0 = result.size();
471        for (int i = 0; nu = getInput(i); i++)
[109]472        {
[714]473                if (part)
474                        if (nu->part != part) continue;
475                if (joint)
476                        if (nu->joint != joint) continue;
477                if (classname)
478                        if (nu->getClassName() != cn) continue;
[899]479                result += (void *)nu;
[109]480        }
[714]481        return result.size() - n0;
[109]482}
483
[899]484int Neuro::findOutputs(SList &result, const char *classname, const Part *part, const Joint *joint) const
[109]485{ // not very efficient...
[714]486        Neuro *nu, *inp;
487        SString cn(classname);
488        SList found;
489        int n0 = result.size();
490        for (int i = 0; nu = getModel().getNeuro(i); i++)
[109]491        {
[714]492                if (part)
493                        if (nu->part != part) continue;
494                if (joint)
495                        if (nu->joint != joint) continue;
496                if (classname)
497                        if (inp->getClassName() != cn) continue;
498                for (int j = 0; inp = nu->getInput(j); j++)
499                        if (inp == this)
[109]500                        {
[899]501                                result += (void *)nu;
502                                break;
[109]503                        }
504        }
[714]505        return result.size() - n0;
[109]506}
507
508void Neuro::get_inputCount(PARAMGETARGS)
[714]509{
510        ret->setInt(inputs.size());
511}
[109]512
[714]513void Neuro::p_getInputNeuroDef(ExtValue *args, ExtValue *ret)
[109]514{
[714]515        int i = args->getInt();
516        if ((i < 0) || (i >= inputs.size()))
517                ret->setEmpty();
518        else
519                ret->setObject(ExtObject(&Neuro::getStaticParam(), inputs(i).n));
[109]520}
521
[714]522void Neuro::p_getInputWeight(ExtValue *args, ExtValue *ret)
[109]523{
[714]524        int i = args->getInt();
525        if ((i < 0) || (i >= inputs.size()))
526                ret->setEmpty();
527        else
528                ret->setDouble(inputs(i).weight);
[109]529}
530
[714]531void Neuro::p_getInputNeuroIndex(ExtValue *args, ExtValue *ret)
[109]532{
[714]533        int i = args->getInt();
534        if ((i < 0) || (i >= inputs.size()))
535                ret->setInt(-1);
536        else
537                ret->setInt(inputs(i).n->refno);
[109]538}
539
540void Neuro::get_classObject(PARAMGETARGS)
541{
[288]542#ifndef SDK_WITHOUT_FRAMS
[714]543        NeuroClassExt::makeStaticObject(ret, getClass());
[109]544#endif
545}
546
547///////////////////////////////////////
548
549SString Part::getDefaultStyle()
[714]550{
551        return SString("part");
552}
[109]553SString Joint::getDefaultStyle()
[714]554{
555        return SString("joint");
556}
[109]557/*
558const SString& Neuro::getDefaultStyle()
559{static SString s("neuro"); return s;}
560const SString& NeuroItem::getDefaultStyle()
561{static SString s("neuroitem"); return s;}
562*/
563SString Neuro::getDefaultStyle()
[714]564{
565        return SString("neuro");
566}
[109]567
[714]568Part::Part(enum Shape s) :PartBase(getDefaultStyle())
[109]569{
[714]570        o = Orient_1;
571        p = Pt3D_0;
572        rot = Pt3D_0;
573        flags = 0;
574        defassign();
575        shape = s;
576        mass = 1;
[109]577}
578
[899]579void Part::operator=(const Part &src)
[109]580{
[714]581        p = src.p; o = src.o;
582        flags = src.flags;
583        mass = src.mass; density = src.density;
584        friction = src.friction;
585        ingest = src.ingest;
586        assim = src.assim;
587        size = src.size;
588        rot = src.rot;
589        refno = src.refno;
590        vcolor = src.vcolor;
591        vsize = src.vsize;
592        vis_style = src.vis_style;
593        shape = src.shape;
594        scale = src.scale;
595        hollow = src.hollow;
[109]596}
597
598void Part::setOrient(const Orient &_o)
599{
[714]600        o = _o;
601        rot.getAngles(o.x, o.z);
[109]602}
603
604void Part::setRot(const Pt3D &r)
605{
[714]606        rot = r;
607        o = Orient_1;
608        o.rotate(rot);
[109]609}
610
[714]611void Part::setPositionAndRotationFromAxis(const Pt3D &p1, const Pt3D &p2)
[109]612{
[714]613        Pt3D x = p2 - p1;
614        Pt3D dir(x.y, x.z, x.x);
[899]615        p = p1 + x * 0.5;
[714]616        rot.getAngles(x, dir);
[109]617}
618
[899]619Param &Part::getStaticParam()
[109]620{
[714]621        static Param p(f0_part_paramtab, 0, "Part");
622        return p;
[109]623}
624
625
626///////////////////////////
627
[714]628Joint::Joint() :PartBase(getDefaultStyle())
[109]629{
[714]630        rot = Pt3D_0;
631        defassign();
632        d.x = JOINT_DELTA_MARKER;
633        d.y = JOINT_DELTA_MARKER;
634        d.z = JOINT_DELTA_MARKER;
635        part1 = 0; part2 = 0;
636        flags = 0;
637        usedelta = 0;
[109]638}
639
[899]640void Joint::operator=(const Joint &src)
[109]641{
[714]642        rot = src.rot;
643        d = src.d;
644        shape = src.shape;
[915]645        hinge_pos = src.hinge_pos;
646        hinge_rot = src.hinge_rot;
[926]647        hinge_limit_x[0] = src.hinge_limit_x[0];
648        hinge_limit_x[1] = src.hinge_limit_x[1];
649        hinge_limit_y[0] = src.hinge_limit_y[0];
650        hinge_limit_y[1] = src.hinge_limit_y[1];
[714]651        stamina = src.stamina;
652        stif = src.stif; rotstif = src.rotstif;
653        vis_style = src.vis_style;
654        vcolor = src.vcolor;
655        part1 = 0; part2 = 0;
656        flags = src.flags;
657        usedelta = src.usedelta;
658        refno = src.refno;
[109]659}
660
[899]661void Joint::attachToParts(Part *p1, Part *p2)
[109]662{
[714]663        part1 = p1;
664        part2 = p2;
665        if (p1 && p2)
[109]666        {
[714]667                o = rot;
668                if (usedelta)
[109]669                {
[714]670                        p1->o.transform(p2->o, o);
671                        //              p2->o.x=p1->o/o.x; p2->o.y=p1->o/o.y; p2->o.z=p1->o/o.z;
672                        p2->p = p2->o.transform(d) + p1->p;
[109]673                }
674        }
675}
676
[714]677void Joint::attachToParts(int p1, int p2)
[109]678{
[714]679        attachToParts((p1 >= 0) ? owner->getPart(p1) : 0, (p2 >= 0) ? owner->getPart(p2) : 0);
[109]680}
681
682void Joint::resetDelta()
683{
[714]684        d = Pt3D(JOINT_DELTA_MARKER, JOINT_DELTA_MARKER, JOINT_DELTA_MARKER);
[109]685}
686
[114]687void Joint::resetDeltaMarkers()
[109]688{
[714]689        if (d.x == JOINT_DELTA_MARKER) d.x = 0;
690        if (d.y == JOINT_DELTA_MARKER) d.y = 0;
691        if (d.z == JOINT_DELTA_MARKER) d.z = 0;
[109]692}
693
[114]694void Joint::useDelta(bool use)
[109]695{
[714]696        usedelta = use;
[114]697}
698
699bool Joint::isDelta()
700{
[714]701        return usedelta;
[109]702}
703
[899]704Param &Joint::getStaticParam()
[109]705{
[714]706        static Param p(f0_joint_paramtab, 0, "Joint");
707        return p;
[109]708}
709
710/////////////////////////////////////////////////////////////////
711
712#include F0_CLASSES_FILE
713
714////////////////////////////////////////
715
[714]716ParamEntry Neuro::emptyParamTab[] =
[109]717{
[714]718        { "Undefined Neuro", 1, 0, "?", },
719        { 0, 0, 0, },
[109]720};
721
722Param Part::extraProperties()
723{
[714]724        return Param(f0_part_xtra_paramtab, this);
[109]725}
726
727Param Joint::extraProperties()
728{
[714]729        return Param(f0_joint_xtra_paramtab, this);
[109]730}
731
732Param Neuro::extraProperties()
733{
[714]734        return Param(f0_neuro_xtra_paramtab, this);
[109]735}
736
737Param Part::properties()
738{
[714]739        return Param(f0_part_paramtab, this);
[109]740}
741
742Param Joint::properties()
743{
[714]744        return Param(usedelta ? f0_joint_paramtab : f0_nodeltajoint_paramtab, this);
[109]745}
746
747Param Neuro::properties()
748{
[714]749        return Param(f0_neuro_paramtab, this);
[109]750}
751
[714]752class NeuroExtParamTab : public ParamTab
[109]753{
[714]754public:
755        NeuroExtParamTab() :ParamTab(f0_neuro_paramtab)
[109]756        {
757#define FIELDSTRUCT NeuroExt
[714]758                ParamEntry entry = { "class", 2, 0, "neuro class", "s", GETSET(neuroclass) };
[109]759#undef FIELDSTRUCT
[714]760                add(&entry);
[109]761
762#define FIELDSTRUCT Neuro
[714]763                ParamEntry entry2 = { "state", 2, 0, "state", "f", FIELD(state) };
[109]764#undef FIELDSTRUCT
[714]765                add(&entry2);
[109]766        }
767};
768
[899]769Param &Neuro::getStaticParam()
[109]770{
[714]771        static Param p(f0_neuro_paramtab, 0, "NeuroDef");
772        return p;
[109]773}
774
775////////////////////////
776
777NeuroConn::NeuroConn()
778{
[714]779        defassign();
[109]780}
781
782//////////////////////////////////////
783
784ParamEntry *NeuroExt::getParamTab()
785{
[714]786        static NeuroExtParamTab tab;
787        return tab.getParamTab();
[109]788}
789
790void NeuroExt::get_neuroclass(PARAMGETARGS)
[714]791{
792        ret->setString(getClassName());
793}
[109]794
795int NeuroExt::set_neuroclass(PARAMSETARGS)
[714]796{
797        setClassName(arg->getString()); return PSET_CHANGED;
798}
Note: See TracBrowser for help on using the repository browser.