Index: cpp/frams/genetics/f4/f4_conv.cpp
===================================================================
--- cpp/frams/genetics/f4/f4_conv.cpp	(revision 1248)
+++ cpp/frams/genetics/f4/f4_conv.cpp	(revision 1249)
@@ -124,5 +124,5 @@
 	// reset recursive traverse flags
 	for (int i = 0; i < cells->cell_count; i++)
-		cells->C[i]->recProcessedFlag = 0;
+		cells->C[i]->recurProcessedFlag = false;
 
 	open(using_checkpoints); // begin model build
@@ -131,5 +131,5 @@
 	for (int i = 0; i < cells->cell_count; i++)
 	{
-		int res = buildModelRec(cells->C[i]);
+		int res = buildModelRecur(cells->C[i]);
 		if (res)
 		{
@@ -166,19 +166,15 @@
 
 
-int f4_Model::buildModelRec(f4_Cell *C)
-{
-	int partidx;
-	int j, res;
-	MultiRange range;
-
-	if (C->recProcessedFlag)
+int f4_Model::buildModelRecur(f4_Cell *C)
+{
+	if (C->recurProcessedFlag)
 		// already processed
 		return 0;
 
 	// mark it processed
-	C->recProcessedFlag = 1;
+	C->recurProcessedFlag = true;
 
 	// make sure parent is a stick
-	if (NULL != C->dadlink)
+	if (C->dadlink != NULL)
 		if (C->dadlink->type != CELL_STICK)
 		{
@@ -187,13 +183,13 @@
 
 	// make sure its parent is processed first
-	if (NULL != C->dadlink)
-	{
-		res = buildModelRec(C->dadlink);
+	if (C->dadlink != NULL)
+	{
+		int res = buildModelRecur(C->dadlink);
 		if (res) return res;
 	}
 
 	char tmpLine[100];
-
-	range = C->genoRange;
+	MultiRange range = C->genoRange;
+
 	if (C->type == CELL_STICK)
 	{
@@ -208,8 +204,7 @@
 				//C->firstend.x, C->firstend.y, C->firstend.z
 			);
-			partidx = addFromString(PartType, tmpLine, &range);
-			if (partidx < 0) return -1;
+			jj_p1_refno = addFromString(PartType, tmpLine, &range);
+			if (jj_p1_refno < 0) return -1;
 			this->checkpoint();
-			jj_p1_refno = partidx;
 		}
 		else {
@@ -225,7 +220,6 @@
 			/*"vol=" 1.0/C->P.mass,*/ C->P.friction, C->P.ingestion, C->P.assimilation
 		);
-		partidx = addFromString(PartType, tmpLine, &range);
-		if (partidx < 0) return -2;
-		C->p2_refno = partidx;
+		C->p2_refno = addFromString(PartType, tmpLine, &range);
+		if (C->p2_refno < 0) return -2;
 
 		// new joint object
@@ -245,8 +239,7 @@
 			C->P.stamina
 		);
-		partidx = addFromString(JointType, tmpLine, &range);
-		if (partidx < 0) return -13;
+		C->joint_refno = addFromString(JointType, tmpLine, &range);
+		if (C->joint_refno < 0) return -13;
 		this->checkpoint();
-		C->joint_refno = partidx;
 	}
 
@@ -254,59 +247,47 @@
 	{
 		const char* nclass = C->neuclass->name.c_str();
-		int partno, jointno;
 		if (C->neuclass->getPreferredLocation() == 0)
 		{
-			if (strcmp(nclass, "N") == 0)
-			{
-				partno = C->dadlink->p2_refno;
-				if ((partno < 0) || (partno >= getPartCount())) return -21;
-				else sprintf(tmpLine, "p=%d,d=\"N:in=%g,fo=%g,si=%g\"", partno, C->inertia, C->force, C->sigmo);
-			}
+			if (strcmp(nclass, "N") == 0) //special case just to specify the only neuron properties supported by f4, i.e., the properties for neuron class 'N'
+				sprintf(tmpLine, "d=\"N:in=%g,fo=%g,si=%g\"", C->inertia, C->force, C->sigmo);
 			else
-			{
 				sprintf(tmpLine, "d=\"%s\"", nclass);
-			}
-			partidx = addFromString(NeuronType, tmpLine, &range);
-			if (partidx < 0) return -22;
+
+			C->neuro_refno = addFromString(NeuronType, tmpLine, &range);
+			if (C->neuro_refno < 0) return -22;
 			this->checkpoint();
-			C->neuro_refno = partidx;
 		}
 		else if (C->neuclass->getPreferredLocation() == 1) // attached to Part or have no required attachment - also part
 		{
-			partno = C->dadlink->p2_refno;
+			int partno = C->dadlink->p2_refno;
 			if ((partno < 0) || (partno >= getPartCount())) return -21;
 
-			if (strcmp(nclass, "N") == 0)
-				sprintf(tmpLine, "p=%d,d=\"N:in=%g,fo=%g,si=%g\"", partno, C->inertia, C->force, C->sigmo);
-			else
-				sprintf(tmpLine, "p=%d,d=\"%s\"", partno, nclass);
-
-			partidx = addFromString(NeuronType, tmpLine, &range);
-			if (partidx < 0) return -22;
+			sprintf(tmpLine, "p=%d,d=\"%s\"", partno, nclass);
+
+			C->neuro_refno = addFromString(NeuronType, tmpLine, &range);
+			if (C->neuro_refno < 0) return -22;
 			this->checkpoint();
-			C->neuro_refno = partidx;
 		}
 		else // attached to Joint, assume there are only three possibilities of getPreferredLocation()
 		{
-			jointno = C->dadlink->joint_refno;
+			int jointno = C->dadlink->joint_refno;
 
 			if (strcmp(nclass, "@") == 0)
 				sprintf(tmpLine, "j=%d,d=\"@:p=%g\"", jointno, C->P.muscle_power);
 			else if (strcmp(nclass, "|") == 0)
-				sprintf(tmpLine, "j=%d,d=\"|:p=%g,r=%g\"", jointno, C->P.muscle_power, C->mz);
+			{
+				sprintf(tmpLine, "j=%d,d=\"|:p=%g,r=%g\"", jointno, C->P.muscle_power, C->dadlink->P.muscle_bend_range); //Macko 2023-05 change: we take muscle_bend_range from dadlink, not from C, because we also assign this neuron to C->dadlink->joint_refno. Without this, for example in /*4*/<<X><<<<X>N:|>X>X>X>X the muscle is attached to the junction with 3 sticks, but gets range=33% as in a four-stick junction. f1 correctly sets range=0.5 for the analogous phenotype: X(X[|],X(X,X,X))
+			}
 			else
 				sprintf(tmpLine, "j=%d,d=\"%s\"", jointno, nclass);
 
-			partidx = addFromString(NeuronType, tmpLine, &range);
-			if (partidx < 0) return -32;
+			C->neuro_refno = addFromString(NeuronType, tmpLine, &range);
+			if (C->neuro_refno < 0) return -32;
 			this->checkpoint();
 		}
-		C->neuro_refno = partidx;
-		int n_refno = C->neuro_refno;
-
-		for (j = 0; j < C->conns_count; j++)
+		for (int j = 0; j < C->conns_count; j++)
 		{
 			if (C->conns[j]->from != NULL)
-				buildModelRec(C->conns[j]->from);
+				buildModelRecur(C->conns[j]->from);
 
 			tmpLine[0] = 0;
@@ -320,5 +301,5 @@
 			if (from >= 0)
 			{
-				sprintf(tmpLine, "%d,%d,%g", n_refno, from, C->conns[j]->weight);
+				sprintf(tmpLine, "%d,%d,%g", C->neuro_refno, from, C->conns[j]->weight);
 				if (addFromString(NeuronConnectionType, tmpLine, &range) < 0) return -35;
 				this->checkpoint();
Index: cpp/frams/genetics/f4/f4_conv.h
===================================================================
--- cpp/frams/genetics/f4/f4_conv.h	(revision 1248)
+++ cpp/frams/genetics/f4/f4_conv.h	(revision 1249)
@@ -83,5 +83,5 @@
 private:
 	f4_Cells *cells;
-	int        buildModelRec(f4_Cell *ndad);
+	int        buildModelRecur(f4_Cell *ndad);
 	/**
 	 * Get a cell which is a stick, by traversing dadlinks.
Index: cpp/frams/genetics/f4/f4_general.cpp
===================================================================
--- cpp/frams/genetics/f4/f4_general.cpp	(revision 1248)
+++ cpp/frams/genetics/f4/f4_general.cpp	(revision 1249)
@@ -12,4 +12,5 @@
 #include <frams/model/model.h> // for min and max attributes
 #include <common/nonstd_math.h>
+#include <algorithm> // std::min, std::max
 
 #ifdef DMALLOC
@@ -46,5 +47,5 @@
 	anglepos = nangle;
 	commacount = 0;
-	childcount = 0;
+	stickchildcount = 0;
 	P = newP;
 	rolling = 0;
@@ -65,5 +66,5 @@
 			//firstend = ndad->lastend;
 			//OM = ndad->OM;
-			ndad->childcount++;
+			ndad->stickchildcount++;
 		}
 		if (ndad->type == CELL_NEURON)
@@ -76,5 +77,5 @@
 	// adjust lastend
 	//lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len));
-	mz = 1;
+	P.muscle_bend_range = 1;
 }
 
@@ -96,5 +97,5 @@
 	anglepos = nangle;
 	commacount = 0;
-	childcount = 0;
+	stickchildcount = 0;
 	P = newP;
 	rolling = 0;
@@ -115,5 +116,5 @@
 			//firstend = ndad->lastend;
 			//OM = ndad->OM;
-			ndad->childcount++;
+			ndad->stickchildcount++;
 		}
 		if (ndad->type == CELL_NEURON)
@@ -126,5 +127,5 @@
 	// adjust lastend
 	//lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len));
-	mz = 1;
+	P.muscle_bend_range = 1;
 }
 
@@ -548,28 +549,31 @@
 
 
-void f4_Cell::adjustRec()
-{
-	//f4_OrientMat rot;
-	int i;
-
-	if (recProcessedFlag)
+void f4_Cell::adjustRecur()
+{
+	if (recurProcessedFlag)
 		// already processed
 		return;
 
 	// mark it processed
-	recProcessedFlag = 1;
+	recurProcessedFlag = true;
 
 	// make sure its parent is processed first
 	if (dadlink != NULL)
-		dadlink->adjustRec();
+		dadlink->adjustRecur();
 
 	// count children
-	childcount = 0;
-	for (i = 0; i < org->cell_count; i++)
+	stickchildcount = 0;
+	for (int i = 0; i < org->cell_count; i++)
 	{
 		if (org->C[i]->dadlink == this)
 			if (org->C[i]->type == CELL_STICK)
-				childcount++;
-	}
+				stickchildcount++;
+	}
+
+	if (dadlink == NULL)
+		P.muscle_bend_range = 1.0;
+	else
+		P.muscle_bend_range = 1.0 / std::max(1, dadlink->stickchildcount); //bend range in f1: 0, 1 (line XX[|]) -> 100%, 2 (Y-shape X(X[|],X)) -> 50%, 3 (cross X(X[|],X,X)) -> 33%
+	//MacKo 2023-05: but shouldn't this formula ^^ also take commacount into consideration, like in f1?
 
 	if (type == CELL_STICK)
@@ -580,5 +584,4 @@
 			// rotation due to rolling
 			xrot = rolling;
-			mz = 1;
 		}
 		else
@@ -589,5 +592,5 @@
 			Padj.propagateAlong(false);
 
-			//rot = Orient_1;
+			//f4_OrientMat rot = Orient_1;
 
 			// rotation due to rolling
@@ -612,5 +615,4 @@
 			// rotation in world coordinates
 			//OM =  ((f4_OrientMat)dadlink->OM) * OM;
-			mz = dadlink->mz / dadlink->childcount;
 		}
 		//Pt3D lastoffset = (Orient)OM * (Pt3D(1,0,0)*P.len);
@@ -737,12 +739,15 @@
 	// reset recursive traverse flags
 	for (int i = 0; i < cell_count; i++)
-		C[i]->recProcessedFlag = 0;
+		C[i]->recurProcessedFlag = false;
 	// process every cell
 	for (int i = 0; i < cell_count; i++)
-		C[i]->adjustRec();
+		C[i]->adjustRecur();
 
 	//DB( printf("Cell simulation done, %d cells. \n", nc); )
 
 	if (PRINT_CELLS_DEVELOPMENT) print_cells("Final");
+	if (PRINT_CELLS_DEVELOPMENT)
+		for (int i = 0; i < cell_count; i++)
+			printf("%d,%d,dad=%d\tstick_children=%d\tcommas=%d\t|:range=%g\n", i, C[i]->nr, C[i]->dadlink ? C[i]->dadlink->nr : -1, C[i]->stickchildcount, C[i]->commacount, C[i]->P.muscle_bend_range);
 
 	return errorcode;
Index: cpp/frams/genetics/f4/f4_general.h
===================================================================
--- cpp/frams/genetics/f4/f4_general.h	(revision 1248)
+++ cpp/frams/genetics/f4/f4_general.h	(revision 1249)
@@ -181,7 +181,7 @@
 	 * Adjusts properties of stick objects.
 	 */
-	void  adjustRec();
-
-	int        nr;                 ///<number of cell (seems to be used only in old f1 converter for neuron connections)
+	void  adjustRecur();
+
+	int        nr;                 ///<number of cell (seems to be used only in the approximate f1 converter for neuron connections)
 	int        type;               ///<type
 	f4_Cell *dadlink;              ///<pointer to cell parent
@@ -192,10 +192,10 @@
 	f4_Node *old_gcur;             ///<used externally by f4_Cells::oneStep() to track changes of gcur, i.e., to detect progress in cell development
 	repeat_stack repeat;           ///<stack holding repetition nodes and counters
-	int recProcessedFlag;          ///<used during recursive traverse
+	bool recurProcessedFlag;       ///<used during recursive traverse
 	MultiRange genoRange;          ///<remember the genotype codes affecting this cell so far
 
 	GeneProps    P;                ///<properties
 	int          anglepos;         ///<number of position within dad's children (,)
-	int          childcount;       ///<number of children
+	int          stickchildcount;  ///<number of children (sticks only)
 	int          commacount;       ///<number of postitions at lastend (>=childcount)
 	double       rolling;          ///<rolling angle ('R') (around x)
@@ -203,12 +203,11 @@
 	double       zrot;             ///<horizontal rotation angle due to branching (around z)
 
-	double       mz;               ///<freedom in z
 	int          p2_refno;         ///<the number of the last end part object, used in f0
 	int          joint_refno;      ///<the number of the joint object, used in f0
 	int          neuro_refno;      ///<the number of the neuro object, used in f0
 
-	double       inertia;          ///<inertia of neuron
-	double       force;            ///<force of neuron
-	double       sigmo;            ///<sigmoid of neuron
+	double       inertia;          ///<inertia of neuron N
+	double       force;            ///<force of neuron N
+	double       sigmo;            ///<sigmoid of neuron N
 	f4_CellConn *conns[F4_MAX_CELL_INPUTS]; ///<array of neuron connections
 	int          conns_count;      ///<number of connections
Index: cpp/frams/genetics/geneprops.h
===================================================================
--- cpp/frams/genetics/geneprops.h	(revision 1248)
+++ cpp/frams/genetics/geneprops.h	(revision 1249)
@@ -98,7 +98,7 @@
 
 /**
- * Contains physical, biological and other properties of
- * stick, except for rotation. The constructor initializes properties of sticks with
- * default values. In order to change a property of a stick, the executeModifier() method
+ * Contains physical, biological and other properties of a Part and a Joint (as handled
+ * by the f1 and f4 encodings), except for rotation. The constructor initializes properties with
+ * default values. In order to change a property, the executeModifier() method
  * should be called. Modification of length, curvedness and twist properties
  * usually affects further sticks, so new sticks should have properties of
