Index: cpp/frams/config/f0-SDK.def
===================================================================
--- cpp/frams/config/f0-SDK.def	(revision 931)
+++ cpp/frams/config/f0-SDK.def	(revision 932)
@@ -106,7 +106,7 @@
 PROP(Vstyle,2,0,vis_style,s,0,0,neuro,vis_style)
 PROP(getInputCount,0,1+2,`input count',d,,,,inputCount,GETONLY)
-PROP(getInputNeuroDef,0,1+2,`get input neuron',p oNeuroDef(d),,,,p_getInputNeuroDef,PROCEDURE)
-PROP(getInputNeuroIndex,0,1+2,`get input neuron index',p d(d),,,,p_getInputNeuroIndex,PROCEDURE)
-PROP(getInputWeight,0,1+2,`get input weight',p f(d),,,,p_getInputWeight,PROCEDURE)
+PROP(getInputNeuroDef,0,0,`get input neuron',p oNeuroDef(d),,,,p_getInputNeuroDef,PROCEDURE)
+PROP(getInputNeuroIndex,0,0,`get input neuron index',p d(d),,,,p_getInputNeuroIndex,PROCEDURE)
+PROP(getInputWeight,0,0,`get input weight',p f(d),,,,p_getInputWeight,PROCEDURE)
 PROP(classObject,0,1+2,`neuron class',oNeuroClass,,,,classObject,GETONLY)
 ENDCLASS
@@ -158,4 +158,5 @@
 
 NEUROCLASS(BendMuscle,|,Bend muscle,,1,0,2)
+SHAPETYPE(BallAndStickShapeType)
 VISUALHINTS(DontShowClass+EffectorClass+V1BendMuscle+AtFirstPart)
 SYMBOL(`6,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,3,65,56,49,29,57,24,72,50,4,68,53,70,53,70,55,68,55,68,53,5,50,21,60,15,70,14,79,15,87,20,81,10,1,86,20,77,21')
@@ -165,4 +166,5 @@
 
 NEUROCLASS(RotMuscle,@,Rotation muscle,,1,0,2)
+SHAPETYPE(BallAndStickShapeType)
 VISUALHINTS(DontShowClass+EffectorClass+V1RotMuscle+AtFirstPart)
 SYMBOL(`5,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,1,69,10,77,17,10,59,15,57,17,57,22,60,26,69,27,78,26,82,21,82,16,79,12,69,10,80,6,3,65,50,65,20,75,20,75,50')
@@ -171,4 +173,5 @@
 
 NEUROCLASS(SolidMuscle,M,Muscle,,1,0,2)
+SHAPETYPE(SolidsShapeType)
 VISUALHINTS(EffectorClass+AtFirstPart+SolidMuscleFlag)
 SYMBOL(`6,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,3,65,56,49,29,57,24,72,50,4,68,53,70,53,70,55,68,55,68,53,5,50,21,60,15,70,14,79,15,87,20,81,10,1,86,20,77,21')
@@ -190,9 +193,11 @@
 
 NEUROCLASS(Sticky,Sti,Sticky [EXPERIMENTAL!],,1,0,1)
+SHAPETYPE(BallAndStickShapeType)
 VISUALHINTS(EffectorClass)
 ENDNEUROCLASS
 
 NEUROCLASS(LinearMuscle,LMu,Linear muscle [EXPERIMENTAL!],,1,0,2)
-VISUALHINTS(EffectorClass)
+SHAPETYPE(BallAndStickShapeType)
+VISUALHINTS(EffectorClass+LinearMuscleFlag)
 NEUROPROP(p,0,0,power,f,0.01,1.0,1.0,power)
 ENDNEUROCLASS
Index: cpp/frams/config/f0.def
===================================================================
--- cpp/frams/config/f0.def	(revision 931)
+++ cpp/frams/config/f0.def	(revision 932)
@@ -158,4 +158,5 @@
 
 NEUROCLASS(BendMuscle,|,Bend muscle,,1,0,2)
+SHAPETYPE(BallAndStickShapeType)
 VISUALHINTS(DontShowClass+EffectorClass+V1BendMuscle+AtFirstPart)
 SYMBOL(`6,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,3,65,56,49,29,57,24,72,50,4,68,53,70,53,70,55,68,55,68,53,5,50,21,60,15,70,14,79,15,87,20,81,10,1,86,20,77,21')
@@ -165,4 +166,5 @@
 
 NEUROCLASS(RotMuscle,@,Rotation muscle,,1,0,2)
+SHAPETYPE(BallAndStickShapeType)
 VISUALHINTS(DontShowClass+EffectorClass+V1RotMuscle+AtFirstPart)
 SYMBOL(`5,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,1,69,10,77,17,10,59,15,57,17,57,22,60,26,69,27,78,26,82,21,82,16,79,12,69,10,80,6,3,65,50,65,20,75,20,75,50')
@@ -171,4 +173,5 @@
 
 NEUROCLASS(SolidMuscle,M,Muscle,,1,0,2)
+SHAPETYPE(SolidsShapeType)
 VISUALHINTS(EffectorClass+AtFirstPart+SolidMuscleFlag)
 SYMBOL(`6,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,3,65,56,49,29,57,24,72,50,4,68,53,70,53,70,55,68,55,68,53,5,50,21,60,15,70,14,79,15,87,20,81,10,1,86,20,77,21')
@@ -209,8 +212,10 @@
 
 NEUROCLASS(Sticky,Sti,Sticky [EXPERIMENTAL!],,1,0,1)
+SHAPETYPE(BallAndStickShapeType)
 VISUALHINTS(EffectorClass)
 ENDNEUROCLASS
 
 NEUROCLASS(LinearMuscle,LMu,Linear muscle [EXPERIMENTAL!],,1,0,2)
+SHAPETYPE(BallAndStickShapeType)
 VISUALHINTS(EffectorClass+LinearMuscleFlag)
 NEUROPROP(p,0,0,power,f,0.01,1.0,1.0,power)
Index: cpp/frams/model/defassign-f0-SDK.h
===================================================================
--- cpp/frams/model/defassign-f0-SDK.h	(revision 931)
+++ cpp/frams/model/defassign-f0-SDK.h	(revision 932)
@@ -25,4 +25,5 @@
 vcolor.z=1.0;
 }
+
 
 
@@ -119,4 +120,5 @@
 
 
+
 void Neuro::defassign()
 {
@@ -126,4 +128,5 @@
 vis_style="neuro";
 }
+
 
 
@@ -184,2 +187,3 @@
 
 
+
Index: cpp/frams/model/f0-SDK-classes.h
===================================================================
--- cpp/frams/model/f0-SDK-classes.h	(revision 931)
+++ cpp/frams/model/f0-SDK-classes.h	(revision 932)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -172,7 +172,7 @@
  {"Vstyle",2,0,"vis_style","s 0 0 neuro",FIELD(vis_style),},
  {"getInputCount",0,1+2,"input count","d",GETONLY(inputCount),},
- {"getInputNeuroDef",0,1+2,"get input neuron","p oNeuroDef(d)",PROCEDURE(p_getInputNeuroDef),},
- {"getInputNeuroIndex",0,1+2,"get input neuron index","p d(d)",PROCEDURE(p_getInputNeuroIndex),},
- {"getInputWeight",0,1+2,"get input weight","p f(d)",PROCEDURE(p_getInputWeight),},
+ {"getInputNeuroDef",0,0,"get input neuron","p oNeuroDef(d)",PROCEDURE(p_getInputNeuroDef),},
+ {"getInputNeuroIndex",0,0,"get input neuron index","p d(d)",PROCEDURE(p_getInputNeuroIndex),},
+ {"getInputWeight",0,0,"get input weight","p f(d)",PROCEDURE(p_getInputWeight),},
  {"classObject",0,1+2,"neuron class","oNeuroClass",GETONLY(classObject),},
  {0,0,0,}
Index: cpp/frams/model/model.h
===================================================================
--- cpp/frams/model/model.h	(revision 931)
+++ cpp/frams/model/model.h	(revision 932)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2019  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -93,5 +93,5 @@
 
 public:
-	enum ShapeType { SHAPE_UNKNOWN, SHAPE_ILLEGAL, SHAPE_BALL_AND_STICK, SHAPE_SOLIDS };
+	enum ShapeType { SHAPE_BALL_AND_STICK = 0, SHAPE_SOLIDS = 1, SHAPE_UNKNOWN, SHAPE_ILLEGAL };
 	/// used in internalCheck()
 	enum CheckType {
Index: cpp/frams/model/modelparts.cpp
===================================================================
--- cpp/frams/model/modelparts.cpp	(revision 931)
+++ cpp/frams/model/modelparts.cpp	(revision 932)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2019  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -98,5 +98,5 @@
 NeuroClass::NeuroClass(ParamEntry *_props, SString _description,
 	int _prefinputs, int _prefoutput, int _preflocation,
-	int *_vectordata, bool own_vd, int vhints)
+	int *_vectordata, bool own_vd, int vhints, int sup_shapes)
 	:ownedvectordata(own_vd),
 	name(_props->name), longname(_props->id), description(_description),
@@ -105,4 +105,5 @@
 	prefoutput(_prefoutput),
 	preflocation(_preflocation),
+	supported_shape_types(sup_shapes),
 	vectordata(_vectordata),
 	visualhints(vhints), impl_count(0),/*impl(0),*/active(1), genactive(0)
Index: cpp/frams/model/modelparts.h
===================================================================
--- cpp/frams/model/modelparts.h	(revision 931)
+++ cpp/frams/model/modelparts.h	(revision 932)
@@ -124,8 +124,10 @@
 	class Pt3D d;		///< position delta between parts
 	class Pt3D rot;	///< orientation delta between parts expressed as 3 angles
-	enum Shape { SHAPE_BALL_AND_STICK = 0, ///<  old Framsticks compatible, creates a physical rod between parts (cylinder or cuboid), do not mix with part.shape>0
-		     SHAPE_FIXED = 1, ///< merge parts into one physical entity
-		     SHAPE_HINGE_X = 2, ///< hinge connection, revolving around X axis defined by hinge_pos and hinge_rot
-		     SHAPE_HINGE_XY = 3 }; ///< double hinge connection, revolving around X and Y axes defined by hinge_pos and hinge_rot
+	enum Shape {
+		SHAPE_BALL_AND_STICK = 0, ///<  old Framsticks compatible, creates a physical rod between parts (cylinder or cuboid), do not mix with part.shape>0
+		SHAPE_FIXED = 1, ///< merge parts into one physical entity
+		SHAPE_HINGE_X = 2, ///< hinge connection, revolving around X axis defined by hinge_pos and hinge_rot
+		SHAPE_HINGE_XY = 3 ///< double hinge connection, revolving around X and Y axes defined by hinge_pos and hinge_rot
+	};
 	paInt shape;///< values of type Shape (paInt for integration with Param)
 	class Pt3D hinge_pos; ///< hinge position (relative to part1) for HINGE_X and HINGE_XY
@@ -199,4 +201,9 @@
 	paInt prefinputs, prefoutput;
 	paInt preflocation;
+
+	static constexpr int SUPPORTED_SHAPE_BALL_AND_STICK = 1;
+	static constexpr int SUPPORTED_SHAPE_SOLIDS = 2;
+	static constexpr int SUPPORTED_SHAPE_ALL = SUPPORTED_SHAPE_BALL_AND_STICK | SUPPORTED_SHAPE_SOLIDS;
+	paInt supported_shape_types; //< bitfield of 'Model::shape' values: NeuroClass::SUPPORTED_SHAPE_xxx = 1 << Model::SHAPE_xxx
 	int *vectordata;
 	paInt visualhints;
@@ -212,5 +219,5 @@
 	NeuroClass();
 	NeuroClass(ParamEntry *_props, SString _description,
-		int _prefinputs, int _prefoutput, int _preflocation, int *_vectordata, bool own_vd = 1, int vhints = 0);
+		int _prefinputs, int _prefoutput, int _preflocation, int *_vectordata, bool own_vd = 1, int vhints = 0, int sup_shapes = NeuroClass::SUPPORTED_SHAPE_ALL);
 	/** class name for use in Neuro::setClassName(), Neuro::setDetails() (former 'moredata' field),
 		eg. "N","-",G" */
@@ -248,4 +255,5 @@
 		}
 		*/
+	int getSupportedShapeTypes() { return (int)supported_shape_types; }
 	int *getSymbolGlyph()
 	{
Index: cpp/frams/neuro/neurocls-f0-SDK-library.h
===================================================================
--- cpp/frams/neuro/neurocls-f0-SDK-library.h	(revision 931)
+++ cpp/frams/neuro/neurocls-f0-SDK-library.h	(revision 932)
@@ -12,5 +12,5 @@
 
 
-     
+      
 static ParamEntry NI_StdNeuron_tab[]={
 {"Neuron",1, 4 ,"N",},
@@ -22,7 +22,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_StdNeuron_tab,"Standard neuron",-1,1,0, NULL,false, 2));
-
-     
+addClass(new NeuroClass(NI_StdNeuron_tab,"Standard neuron",-1,1,0, NULL,false, 2, 3));
+
+      
 static ParamEntry NI_StdUNeuron_tab[]={
 {"Unipolar neuron [EXPERIMENTAL!]",1, 4 ,"Nu",},
@@ -33,7 +33,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_StdUNeuron_tab,"Works like standard neuron (N) but the output value is scaled to 0...+1 instead of -1...+1.\nHaving 0 as one of the saturation states should help in \"gate circuits\", where input signal is passed through or blocked depending on the other singal.",-1,1,0, NULL,false, 0));
-
-     static int Gyro_xy[]={83,8,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,12,43,24,48,24,48,19,38,19,38,24,43,24,43,54,48,54,48,64,43,69,38,64,38,54,43,54,5,63,69,58,74,48,79,38,79,28,74,23,69,1,43,79,43,74,1,23,69,26,66,1,63,69,60,66,1,55,76,53,73,1,31,75,33,72};   
+addClass(new NeuroClass(NI_StdUNeuron_tab,"Works like standard neuron (N) but the output value is scaled to 0...+1 instead of -1...+1.\nHaving 0 as one of the saturation states should help in \"gate circuits\", where input signal is passed through or blocked depending on the other singal.",-1,1,0, NULL,false, 0, 3));
+
+      static int Gyro_xy[]={83,8,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,12,43,24,48,24,48,19,38,19,38,24,43,24,43,54,48,54,48,64,43,69,38,64,38,54,43,54,5,63,69,58,74,48,79,38,79,28,74,23,69,1,43,79,43,74,1,23,69,26,66,1,63,69,60,66,1,55,76,53,73,1,31,75,33,72};   
 static ParamEntry NI_Gyro_tab[]={
 {"Gyroscope",1, 0 ,"G",},
@@ -42,7 +42,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_Gyro_tab,"Equilibrium sensor.\n0=the stick is horizontal\n+1/-1=the stick is vertical",0,1,2, Gyro_xy,false, 32));
-
-     static int Touch_xy[]={43,2,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,11,75,50,65,50,60,55,55,45,50,55,45,45,40,50,35,50,30,45,25,50,30,55,35,50};   
+addClass(new NeuroClass(NI_Gyro_tab,"Equilibrium sensor.\n0=the stick is horizontal\n+1/-1=the stick is vertical",0,1,2, Gyro_xy,false, 32, 3));
+
+      static int Touch_xy[]={43,2,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,11,75,50,65,50,60,55,55,45,50,55,45,45,40,50,35,50,30,45,25,50,30,55,35,50};   
 static ParamEntry NI_Touch_tab[]={
 {"Touch",1, 1 ,"T",},
@@ -52,7 +52,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_Touch_tab,"Touch sensor.\n-1=no contact\n0=just touching\n>0=pressing, value depends on the force applied",0,1,1, Touch_xy,false, 32));
-
-     static int Smell_xy[]={64,5,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,3,10,40,15,45,15,55,10,60,5,20,30,25,35,30,45,30,55,25,65,20,70,4,15,35,20,40,22,50,20,60,15,65,5,75,50,50,50,45,45,40,50,45,55,50,50};   
+addClass(new NeuroClass(NI_Touch_tab,"Touch sensor.\n-1=no contact\n0=just touching\n>0=pressing, value depends on the force applied",0,1,1, Touch_xy,false, 32, 3));
+
+      static int Smell_xy[]={64,5,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,3,10,40,15,45,15,55,10,60,5,20,30,25,35,30,45,30,55,25,65,20,70,4,15,35,20,40,22,50,20,60,15,65,5,75,50,50,50,45,45,40,50,45,55,50,50};   
 static ParamEntry NI_Smell_tab[]={
 {"Smell",1, 0 ,"S",},
@@ -61,7 +61,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_Smell_tab,"Smell sensor. Aggregated \"smell of energy\" experienced from all energy objects (creatures and food pieces).\nClose objects have bigger influence than the distant ones: for each energy source, its partial feeling is proportional to its energy/(distance^2)",0,1,1, Smell_xy,false, 32));
-
-     static int Const_xy[]={29,4,4,26,27,26,73,73,73,73,27,26,27,1,73,50,100,50,1,56,68,46,68,2,41,47,51,32,51,68};   
+addClass(new NeuroClass(NI_Smell_tab,"Smell sensor. Aggregated \"smell of energy\" experienced from all energy objects (creatures and food pieces).\nClose objects have bigger influence than the distant ones: for each energy source, its partial feeling is proportional to its energy/(distance^2)",0,1,1, Smell_xy,false, 32, 3));
+
+      static int Const_xy[]={29,4,4,26,27,26,73,73,73,73,27,26,27,1,73,50,100,50,1,56,68,46,68,2,41,47,51,32,51,68};   
 static ParamEntry NI_Const_tab[]={
 {"Constant",1, 0 ,"*",},
@@ -70,39 +70,42 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_Const_tab,"Constant value",0,1,0, Const_xy,false, 1));
-
-     static int BendMuscle_xy[]={63,6,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,3,65,56,49,29,57,24,72,50,4,68,53,70,53,70,55,68,55,68,53,5,50,21,60,15,70,14,79,15,87,20,81,10,1,86,20,77,21};   
+addClass(new NeuroClass(NI_Const_tab,"Constant value",0,1,0, Const_xy,false, 1, 3));
+
+      static int BendMuscle_xy[]={63,6,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,3,65,56,49,29,57,24,72,50,4,68,53,70,53,70,55,68,55,68,53,5,50,21,60,15,70,14,79,15,87,20,81,10,1,86,20,77,21};   
 static ParamEntry NI_BendMuscle_tab[]={
 {"Bend muscle",1, 2 ,"|",},
 
 
+
 {"p",0,0,"power","f 0.01 1.0 0.25",},
 {"r",0,0,"bending range","f 0.0 1.0 1.0",},
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_BendMuscle_tab,"",1,0,2, BendMuscle_xy,false, 2+16+64+4));
-
-     static int RotMuscle_xy[]={62,5,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,1,69,10,77,17,10,59,15,57,17,57,22,60,26,69,27,78,26,82,21,82,16,79,12,69,10,80,6,3,65,50,65,20,75,20,75,50};   
+addClass(new NeuroClass(NI_BendMuscle_tab,"",1,0,2, BendMuscle_xy,false, 2+16+64+4, 1));
+
+      static int RotMuscle_xy[]={62,5,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,1,69,10,77,17,10,59,15,57,17,57,22,60,26,69,27,78,26,82,21,82,16,79,12,69,10,80,6,3,65,50,65,20,75,20,75,50};   
 static ParamEntry NI_RotMuscle_tab[]={
 {"Rotation muscle",1, 1 ,"@",},
 
 
+
 {"p",0,0,"power","f 0.01 1.0 1.0",},
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_RotMuscle_tab,"",1,0,2, RotMuscle_xy,false, 2+16+128+4));
-
-     static int SolidMuscle_xy[]={63,6,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,3,65,56,49,29,57,24,72,50,4,68,53,70,53,70,55,68,55,68,53,5,50,21,60,15,70,14,79,15,87,20,81,10,1,86,20,77,21};   
+addClass(new NeuroClass(NI_RotMuscle_tab,"",1,0,2, RotMuscle_xy,false, 2+16+128+4, 1));
+
+      static int SolidMuscle_xy[]={63,6,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,3,65,56,49,29,57,24,72,50,4,68,53,70,53,70,55,68,55,68,53,5,50,21,60,15,70,14,79,15,87,20,81,10,1,86,20,77,21};   
 static ParamEntry NI_SolidMuscle_tab[]={
 {"Muscle",1, 2 ,"M",},
 
 
+
 {"p",0,0,"power","f 0.01 1.0 1.0",},
 {"a",0,0,"axis","d 0 1 0",},
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_SolidMuscle_tab,"",1,0,2, SolidMuscle_xy,false, 16+4+512));
-
-     static int Diff_xy[]={24,3,3,25,0,25,100,75,50,25,0,1,75,50,100,50,3,44,42,51,57,36,57,44,42};   
+addClass(new NeuroClass(NI_SolidMuscle_tab,"",1,0,2, SolidMuscle_xy,false, 16+4+512, 2));
+
+      static int Diff_xy[]={24,3,3,25,0,25,100,75,50,25,0,1,75,50,100,50,3,44,42,51,57,36,57,44,42};   
 static ParamEntry NI_Diff_tab[]={
 {"Differentiate",1, 0 ,"D",},
@@ -110,7 +113,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_Diff_tab,"Calculate the difference between the current and previous input value. Multiple inputs are aggregated with respect to their weights",-1,1,0, Diff_xy,false, 0));
-
-     static int FuzzyNeuro_xy[]={44,5,2,30,65,37,37,44,65,3,37,65,44,37,51,37,58,65,2,51,65,58,37,65,65,6,100,50,70,50,70,25,25,10,25,90,70,75,70,50,1,70,65,25,65};   
+addClass(new NeuroClass(NI_Diff_tab,"Calculate the difference between the current and previous input value. Multiple inputs are aggregated with respect to their weights",-1,1,0, Diff_xy,false, 0, 3));
+
+      static int FuzzyNeuro_xy[]={44,5,2,30,65,37,37,44,65,3,37,65,44,37,51,37,58,65,2,51,65,58,37,65,65,6,100,50,70,50,70,25,25,10,25,90,70,75,70,50,1,70,65,25,65};   
 static ParamEntry NI_FuzzyNeuro_tab[]={
 {"Fuzzy system [EXPERIMENTAL!]",1, 4 ,"Fuzzy",},
@@ -122,24 +125,26 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_FuzzyNeuro_tab,"Refer to publications to learn more about this neuron.",-1,1,0, FuzzyNeuro_xy,false, 0));
-
-     
+addClass(new NeuroClass(NI_FuzzyNeuro_tab,"Refer to publications to learn more about this neuron.",-1,1,0, FuzzyNeuro_xy,false, 0, 3));
+
+      
 static ParamEntry NI_Sticky_tab[]={
 {"Sticky [EXPERIMENTAL!]",1, 0 ,"Sti",},
 
- 
-{0,0,0,},};
-addClass(new NeuroClass(NI_Sticky_tab,"",1,0,1, NULL,false, 16));
-
-     
+
+ 
+{0,0,0,},};
+addClass(new NeuroClass(NI_Sticky_tab,"",1,0,1, NULL,false, 16, 1));
+
+      
 static ParamEntry NI_LinearMuscle_tab[]={
 {"Linear muscle [EXPERIMENTAL!]",1, 1 ,"LMu",},
 
+
 {"p",0,0,"power","f 0.01 1.0 1.0",},
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_LinearMuscle_tab,"",1,0,2, NULL,false, 16));
-
-     
+addClass(new NeuroClass(NI_LinearMuscle_tab,"",1,0,2, NULL,false, 16+256, 1));
+
+      
 static ParamEntry NI_WaterDetect_tab[]={
 {"Water detector",1, 0 ,"Water",},
@@ -147,7 +152,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_WaterDetect_tab,"Output signal:\n0=on or above water surface\n1=under water (deeper than 1)\n0..1=in the transient area just below water surface",0,1,1, NULL,false, 32));
-
-     
+addClass(new NeuroClass(NI_WaterDetect_tab,"Output signal:\n0=on or above water surface\n1=under water (deeper than 1)\n0..1=in the transient area just below water surface",0,1,1, NULL,false, 32, 3));
+
+      
 static ParamEntry NI_Energy_tab[]={
 {"Energy level",1, 0 ,"Energy",},
@@ -155,7 +160,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_Energy_tab,"The current energy level divided by the initial energy level.\nUsually falls from initial 1.0 down to 0.0 and then the creature dies. It can rise above 1.0 if enough food is ingested",0,1,0, NULL,false, 32));
-
-     static int Channelize_xy[]={57,10,4,25,0,25,100,75,70,75,30,25,0,1,75,50,100,50,1,70,50,55,50,1,30,80,55,50,1,30,20,55,50,1,30,35,55,50,1,30,45,55,50,1,30,55,55,50,1,61,53,65,47,1,30,65,55,50};   
+addClass(new NeuroClass(NI_Energy_tab,"The current energy level divided by the initial energy level.\nUsually falls from initial 1.0 down to 0.0 and then the creature dies. It can rise above 1.0 if enough food is ingested",0,1,0, NULL,false, 32, 3));
+
+      static int Channelize_xy[]={57,10,4,25,0,25,100,75,70,75,30,25,0,1,75,50,100,50,1,70,50,55,50,1,30,80,55,50,1,30,20,55,50,1,30,35,55,50,1,30,45,55,50,1,30,55,55,50,1,61,53,65,47,1,30,65,55,50};   
 static ParamEntry NI_Channelize_tab[]={
 {"Channelize",1, 0 ,"Ch",},
@@ -163,7 +168,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_Channelize_tab,"Combines all input signals into a single multichannel output; Note: ChSel and ChMux are the only neurons which support multiple channels. Other neurons discard everything except the first channel.",-1,1,0, Channelize_xy,false, 0));
-
-     static int ChMux_xy[]={52,7,4,25,0,25,100,75,70,75,30,25,0,1,75,50,100,50,1,70,50,55,50,3,50,55,55,50,50,45,50,55,3,30,67,45,67,45,50,50,50,1,35,70,39,64,2,30,33,53,33,53,48};   
+addClass(new NeuroClass(NI_Channelize_tab,"Combines all input signals into a single multichannel output; Note: ChSel and ChMux are the only neurons which support multiple channels. Other neurons discard everything except the first channel.",-1,1,0, Channelize_xy,false, 0, 3));
+
+      static int ChMux_xy[]={52,7,4,25,0,25,100,75,70,75,30,25,0,1,75,50,100,50,1,70,50,55,50,3,50,55,55,50,50,45,50,55,3,30,67,45,67,45,50,50,50,1,35,70,39,64,2,30,33,53,33,53,48};   
 static ParamEntry NI_ChMux_tab[]={
 {"Channel multiplexer",1, 0 ,"ChMux",},
@@ -171,7 +176,7 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_ChMux_tab,"Outputs the selected channel from the second (multichannel) input. The first input is used as the selector value (-1=select first channel, .., 1=last channel)",2,1,0, ChMux_xy,false, 0));
-
-     static int ChSel_xy[]={41,6,4,25,0,25,100,75,70,75,30,25,0,1,75,50,100,50,1,70,50,55,50,3,50,55,55,50,50,45,50,55,1,30,50,50,50,1,35,53,39,47};   
+addClass(new NeuroClass(NI_ChMux_tab,"Outputs the selected channel from the second (multichannel) input. The first input is used as the selector value (-1=select first channel, .., 1=last channel)",2,1,0, ChMux_xy,false, 0, 3));
+
+      static int ChSel_xy[]={41,6,4,25,0,25,100,75,70,75,30,25,0,1,75,50,100,50,1,70,50,55,50,3,50,55,55,50,50,45,50,55,1,30,50,50,50,1,35,53,39,47};   
 static ParamEntry NI_ChSel_tab[]={
 {"Channel selector",1, 1 ,"ChSel",},
@@ -180,14 +185,14 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_ChSel_tab,"Outputs a single channel (selected by the \"ch\" parameter) from multichannel input",1,1,0, ChSel_xy,false, 0));
-
-     
+addClass(new NeuroClass(NI_ChSel_tab,"Outputs a single channel (selected by the \"ch\" parameter) from multichannel input",1,1,0, ChSel_xy,false, 0, 3));
+
+      
 static ParamEntry NI_Random_tab[]={
 {"Random noise",1, 0 ,"Rnd",},
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_Random_tab,"Generates random noise (subsequent random values in the range of -1..+1)",0,1,0, NULL,false, 0));
-
-     static int Sinus_xy[]={46,3,12,75,50,71,37,62,28,50,25,37,28,28,37,25,50,28,62,37,71,50,75,62,71,71,62,75,50,1,75,50,100,50,5,35,50,40,35,45,35,55,65,60,65,65,50};   
+addClass(new NeuroClass(NI_Random_tab,"Generates random noise (subsequent random values in the range of -1..+1)",0,1,0, NULL,false, 0, 3));
+
+      static int Sinus_xy[]={46,3,12,75,50,71,37,62,28,50,25,37,28,28,37,25,50,28,62,37,71,50,75,62,71,71,62,75,50,1,75,50,100,50,5,35,50,40,35,45,35,55,65,60,65,65,50};   
 static ParamEntry NI_Sinus_tab[]={
 {"Sinus generator",1, 2 ,"Sin",},
@@ -197,3 +202,3 @@
  
 {0,0,0,},};
-addClass(new NeuroClass(NI_Sinus_tab,"Output frequency = f0+input",1,1,0, Sinus_xy,false, 0));
+addClass(new NeuroClass(NI_Sinus_tab,"Output frequency = f0+input",1,1,0, Sinus_xy,false, 0, 3));
Index: cpp/frams/neuro/neurofactory.h
===================================================================
--- cpp/frams/neuro/neurofactory.h	(revision 931)
+++ cpp/frams/neuro/neurofactory.h	(revision 932)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -7,4 +7,5 @@
 
 #include <frams/model/modelparts.h>
+#include <frams/model/model.h>
 #include <map>
 
@@ -18,9 +19,9 @@
 	NeuroImpl* setImplementation(const SString& classname, NeuroImpl *ni, bool deleteold = 1);
 	NeuroImpl* getImplementation(NeuroClass *nc);
-	class NeuroImpl* createNeuroImpl(Neuro *n)
+	class NeuroImpl* createNeuroImpl(Neuro *n, Model::ShapeType shape_type)
 	{
-		NeuroClass *nc = n->getClass(); if (!nc) return 0; return createNeuroImpl(nc);
+		NeuroClass *nc = n->getClass(); if (!nc) return 0; return createNeuroImpl(nc, shape_type);
 	}
-	class NeuroImpl* createNeuroImpl(NeuroClass *nc);
+	class NeuroImpl* createNeuroImpl(NeuroClass *nc, Model::ShapeType shape_type);
 
 	void setStandardImplementation();
Index: cpp/frams/neuro/neuroimpl.cpp
===================================================================
--- cpp/frams/neuro/neuroimpl.cpp	(revision 931)
+++ cpp/frams/neuro/neuroimpl.cpp	(revision 932)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -46,5 +46,5 @@
 	, ChannelSpace *ch
 #endif
-	)
+)
 	:mod(model), config(conf),
 	isbuilt(1), errorcount(0)
@@ -69,5 +69,5 @@
 	for (i = 0; n = mod.getNeuro(i); i++)
 	{
-		ni = conf.factory->createNeuroImpl(n);
+		ni = conf.factory->createNeuroImpl(n, mod.getShapeType());
 		n->userdata[mytags_id] = ni;
 		if (!ni)
@@ -85,5 +85,5 @@
 	for (i = 0; n = mod.getNeuro(i); i++)
 	{
-		n->state += (rndDouble(1) - 0.5)*config.randominit;
+		n->state += (rndDouble(1) - 0.5) * config.randominit;
 		ni = (NeuroImpl*)n->userdata[mytags_id];
 		if (!ni) continue;
@@ -98,5 +98,5 @@
 		ni->status = NeuroImpl::InitOk;
 		int order = ni->getSimOrder();
-		if (order < 0) order = 0; else if (order>2) order = 2;
+		if (order < 0) order = 0; else if (order > 2) order = 2;
 		if (order < minorder) minorder = order;
 		if (order > maxorder) maxorder = order;
@@ -189,5 +189,5 @@
 double NeuroImpl::getNewState(int channel)
 {
-	if (neuro->flags&Neuro::HoldState) return getState(channel);
+	if (neuro->flags & Neuro::HoldState) return getState(channel);
 	if (channel >= channels) channel = channels - 1;
 	if (channel <= 0) { return newstate; }
@@ -204,5 +204,5 @@
 void NeuroImpl::commit()
 {
-	if (!(neuro->flags&Neuro::HoldState))
+	if (!(neuro->flags & Neuro::HoldState))
 	{
 		if (channels > 1)
@@ -211,8 +211,8 @@
 		if (owner->getConfig().nnoise > 0.0)
 		{
-			neuro->state += RndGen.GaussStd()*owner->getConfig().nnoise;
+			neuro->state += RndGen.GaussStd() * owner->getConfig().nnoise;
 			if (channels > 1)
 				for (int i = 0; i < chstate.size(); i++)
-					chstate(0) += RndGen.GaussStd()*owner->getConfig().nnoise;
+					chstate(0) += RndGen.GaussStd() * owner->getConfig().nnoise;
 		}
 	}
@@ -270,5 +270,5 @@
 	double w;
 	while (inp = neuro->getInput(startwith++, w))
-		sum += inp->state*w;
+		sum += inp->state * w;
 	return sum;
 }
Index: cpp/frams/neuro/neuroimpl.h
===================================================================
--- cpp/frams/neuro/neuroimpl.h	(revision 931)
+++ cpp/frams/neuro/neuroimpl.h	(revision 932)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -82,5 +82,5 @@
 		, ChannelSpace *ch = 0
 #endif
-		);
+	);
 	~NeuroNetImpl();
 	void simulateNeuroNet();
@@ -223,7 +223,7 @@
 	virtual int lateinit() { return 1; }
 	/** calculate 'newstate - implementation dependent */
-	virtual void go(){}
+	virtual void go() {}
 	/** for neurons doing some physical actions (called each simulation step when nnspeed!=1.0) */
-	virtual void goPhysics(){}
+	virtual void goPhysics() {}
 
 	int getSimOrder() { return simorder; }
@@ -287,6 +287,6 @@
 	PARAMGETDEF(cstate) { arg1->setDouble(neuro->state); }
 	PARAMSETDEF(cstate) { setCurrentState(arg1->getDouble()); return 0; }
-	PARAMGETDEF(hold) { arg1->setInt((neuro->flags&(Neuro::HoldState)) ? 1 : 0); }
-	PARAMSETDEF(hold) { neuro->flags = (neuro->flags&~Neuro::HoldState) | (arg1->getInt() ? Neuro::HoldState : 0); return 0; }
+	PARAMGETDEF(hold) { arg1->setInt((neuro->flags & (Neuro::HoldState)) ? 1 : 0); }
+	PARAMSETDEF(hold) { neuro->flags = (neuro->flags & ~Neuro::HoldState) | (arg1->getInt() ? Neuro::HoldState : 0); return 0; }
 	PARAMGETDEF(channels) { arg1->setInt(getChannelCount()); }
 	PARAMSETDEF(channels) { setChannelCount(arg1->getInt()); return 0; }
