Index: cpp/frams/model/model.h
===================================================================
--- cpp/frams/model/model.h	(revision 726)
+++ cpp/frams/model/model.h	(revision 732)
@@ -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-2018  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -15,6 +15,4 @@
 
 extern ParamEntry f0_model_paramtab[];
-
-//#define EASYMAPDEBUG
 
 enum ModelBuildStatus { empty, building, invalid, valid };
@@ -64,4 +62,8 @@
 	/// make model map in build()
 	bool autobuildmaps;
+	/// supports adding checkpoints
+	bool using_checkpoints;
+	/// means less strict validation
+	bool is_checkpoint;
 	/// valid if build from f0 genotype
 	int f0errorposition;
@@ -75,4 +77,5 @@
 	SList parts, joints, neurons;
 	char partmappingchanged;
+	vector<Model*> checkpoints;
 
 	void internalCopy(const Model &mod);
@@ -95,16 +98,14 @@
 		EDITING_CHECK, ///< Used in Model::validate(). Default validation - does not modify elements of the Model.
 		FINAL_CHECK,   ///< Used in Model::close() when a Model is built from a genotype. Like EDITING_CHECK, but also calculates Joint::d and Joint::rot.
-		LIVE_CHECK     ///< used in Model::close() when a Model is built from a Creature. Like FINAL_CHECK but does not limit joint length which could make some liveModels invalid.
+		LIVE_CHECK,     ///< used in Model::close() when a Model is built from a Creature. Like FINAL_CHECK but does not limit joint length which could make some liveModels invalid.
+		CHECKPOINT_CHECK     ///< used when storing checkpoint models. Like LIVE_CHECK, excluding consistency check (disjoint parts are acceptable)
 	};
 protected:
 	ShapeType shape;
 
-	void updateNeuroRefno(); // set Neuro::refno for all neurons
 	SString nameForErrors() const;
 	int internalcheck(CheckType check);
 
-	void moveNeuro(int oldpos, int newpos);
-
-	void init(const Geno &srcgen);
+	void init(const Geno &srcgen, bool _using_checkpoints, bool _is_checkpoint);
 	void init();
 
@@ -134,6 +135,11 @@
 	int getErrorPosition(bool includingwarnings = false);
 	ShapeType getShapeType() const { return shape; }
+	bool isUsingCheckpoints() const { return using_checkpoints; }
+	bool isCheckpoint() const { return is_checkpoint; }
 
 	void updateRefno(); // set ::refno for all elements
+
+	int getCheckpointCount();
+	Model* getCheckpoint(int i);
 
 	/// The bounding box size. Valid if the model is valid. Read only.
@@ -153,6 +159,6 @@
 	   @see getMap()
 	   */
-	Model(const Geno &src, bool buildmaps = false);
-	Model(const Model &mod, bool buildmaps = false);
+	Model(const Geno &src, bool buildmaps = false, bool _using_checkpoints = false, bool _is_checkpoint = false);
+	Model(const Model &mod, bool buildmaps = false, bool _using_checkpoints = false, bool _is_checkpoint = false);
 	/** duplicate the model.
 		the resulting object's status is 'building' (opened).
@@ -255,5 +261,5 @@
 	void clear();
 
-	enum ItemType { UnknownType,ModelType,PartType,JointType,NeuronType,NeuronConnectionType };
+	enum ItemType { UnknownType, ModelType, PartType, JointType, NeuronType, NeuronConnectionType, CheckpointType };
 	static ItemType itemTypeFromLinePrefix(const char* line);
 	/** Execute single line of <B>f0</B> genotype.
@@ -264,9 +270,9 @@
 		@param srcrange source genotype range which will be mapped to this element
 		*/
-	int addFromString(ItemType item_type,const SString &singleline, int line_num, const MultiRange* srcrange = NULL);
+	int addFromString(ItemType item_type, const SString &singleline, int line_num, const MultiRange* srcrange = NULL);
 	/** Execute single line of <B>f0</B> genotype - compatiblity variant */
-	int addFromString(ItemType item_type,const SString &singleline, const MultiRange* srcrange = NULL);
+	int addFromString(ItemType item_type, const SString &singleline, const MultiRange* srcrange = NULL);
 	/** Execute single line of <B>f0</B> genotype - low level variant, used by Model::build(), error messages returned as string instead of calling logger */
-	int addFromStringNoLog(ItemType item_type,const SString &singleline, SString& error_message, const MultiRange* srcrange = 0);
+	int addFromStringNoLog(ItemType item_type, const SString &singleline, SString& error_message, const MultiRange* srcrange = 0);
 
 	/// separate build stages (for future use)
@@ -289,5 +295,5 @@
 	/// or modify the model created from the genotype.
 	/// Between open() and close() the model is not fully usable.
-	void open();
+	void open(bool _using_checkpoints = false, bool _is_checkpoint = false);
 
 	/// Current model written as f0 genotype while building
@@ -379,19 +385,21 @@
 	void buildUsingSolidShapeTypes(const Model& src_ballandstick_shapes, Part::Shape use_shape = Part::SHAPE_CYLINDER, float thickness = 0.2);
 
-#ifdef EASYMAPDEBUG
-	static int partToMap(int i) {return 0+i;}
-	static int jointToMap(int i) {return 10+i;}
-	static int neuroToMap(int i) {return 20+i;}
-	static int mapToPart(int i) {return i-0;}
-	static int mapToJoint(int i) {return i-10;}
-	static int mapToNeuro(int i) {return i-20;}
-#else
-	static int partToMap(int i) { return 0x10000000 + i; }
-	static int jointToMap(int i) { return 0x20000000 + i; }
-	static int neuroToMap(int i) { return 0x30000000 + i; }
-	static int mapToPart(int i) { return i - 0x10000000; }
-	static int mapToJoint(int i) { return i - 0x20000000; }
-	static int mapToNeuro(int i) { return i - 0x30000000; }
-#endif
+protected:
+	static const int MODEL_MAPPING_OFFSET = 0x10000000;
+public:
+	static int elementToMap(ItemType t, int i);
+	struct TypeAndIndex
+	{
+		ItemType type; int index;
+		TypeAndIndex() :type(UnknownType), index(0) {}
+		TypeAndIndex(ItemType _type, int _index) :type(_type), index(_index) {}
+	};
+	static TypeAndIndex mapToElement(int i);
+	static int partToMap(int i);
+	static int jointToMap(int i);
+	static int neuroToMap(int i);
+	static int mapToPart(int i);
+	static int mapToJoint(int i);
+	static int mapToNeuro(int i);
 
 	static void makeGenToGenMap(MultiMap& result, const MultiMap& gen1tomodel, const MultiMap& gen2tomodel);
