private string sceneJSON(List <GH_String> meshList, List <GH_String> meshMaterialList, List <GH_String> meshLayerList, List <GH_String> linesList, List <GH_String> linesMaterialList, List <GH_String> lineLayerList, List <GH_String> viewList, Dictionary <string, List <Element> > defLayers)
        {
            //create a dynamic object to populate
            dynamic jason = new ExpandoObject();

            //populate metadata object
            jason.metadata           = new ExpandoObject();
            jason.metadata.version   = 4.3;
            jason.metadata.type      = "Object";
            jason.metadata.generator = "vA3C_Grasshopper_Exporter";

            int size = meshList.Count + linesList.Count;

            //populate mesh geometries:
            jason.geometries = new object[size]; //array for geometry - both lines and meshes
            jason.materials  = new object[size]; //array for materials - both lines and meshes


            #region Mesh management
            int meshCounter = 0;
            Dictionary <string, object> MeshDict = new Dictionary <string, object>();
            Dictionary <string, va3cAttributesCatcher> attrDict = new Dictionary <string, va3cAttributesCatcher>();


            foreach (GH_String m in meshList)
            {
                bool alreadyExists = false;
                //deserialize the geometry and attributes, and add them to our object
                va3cGeometryCatcher   c  = JsonConvert.DeserializeObject <va3cGeometryCatcher>(m.Value);
                va3cAttributesCatcher ac = JsonConvert.DeserializeObject <va3cAttributesCatcher>(m.Value);
                jason.geometries[meshCounter] = c;
                attrDict.Add(c.uuid, ac);


                //now that we have different types of materials, we need to know which catcher to call
                //use the va3cBaseMaterialCatcher class to determine a material's type, then call the appropriate catcher
                //object mc;
                va3cBaseMaterialCatcher baseCatcher = JsonConvert.DeserializeObject <va3cBaseMaterialCatcher>(meshMaterialList[meshCounter].Value);
                if (baseCatcher.type == "MeshFaceMaterial")
                {
                    va3cMeshFaceMaterialCatcher mc = JsonConvert.DeserializeObject <va3cMeshFaceMaterialCatcher>(meshMaterialList[meshCounter].Value);

                    foreach (var existingMaterial in jason.materials)
                    {
                        try
                        {
                            if (existingMaterial.type == "MeshFaceMaterial")
                            {
                                //check if all the properties match a material that already exists
                                if (mc.materials == existingMaterial.materials)
                                {
                                    mc.uuid       = existingMaterial.uuid;
                                    alreadyExists = true;
                                    break;
                                }
                            }
                        }
                        catch { }
                    }
                    //only add it if it does not exist
                    if (!alreadyExists)
                    {
                        jason.materials[meshCounter] = mc;
                    }
                    MeshDict.Add(c.uuid, mc.uuid);
                }
                if (baseCatcher.type == "MeshPhongMaterial")
                {
                    va3cMeshPhongMaterialCatcher mc = JsonConvert.DeserializeObject <va3cMeshPhongMaterialCatcher>(meshMaterialList[meshCounter].Value);

                    foreach (var existingMaterial in jason.materials)
                    {
                        try
                        {
                            if (existingMaterial.type == "MeshPhongMaterial")
                            {
                                //check if all the properties match a material that already exists
                                if (mc.color == existingMaterial.color && mc.ambient == existingMaterial.ambient && mc.emissive == existingMaterial.emissive &&
                                    mc.side == existingMaterial.side && mc.opacity == existingMaterial.opacity && mc.shininess == existingMaterial.shininess &&
                                    mc.specular == existingMaterial.specular && mc.transparent == existingMaterial.transparent && mc.wireframe == existingMaterial.wireframe)
                                {
                                    mc.uuid       = existingMaterial.uuid;
                                    alreadyExists = true;
                                    break;
                                }
                            }
                        }
                        catch { }
                    }
                    //only add it if it does not exist
                    if (!alreadyExists)
                    {
                        jason.materials[meshCounter] = mc;
                    }


                    MeshDict.Add(c.uuid, mc.uuid);
                }
                if (baseCatcher.type == "MeshLambertMaterial")
                {
                    va3cMeshLambertMaterialCatcher mc = JsonConvert.DeserializeObject <va3cMeshLambertMaterialCatcher>(meshMaterialList[meshCounter].Value);

                    foreach (var existingMaterial in jason.materials)
                    {
                        try
                        {
                            if (existingMaterial.type == "MeshLambertMaterial")
                            {
                                //check if all the properties match a material that already exists
                                if (mc.color == existingMaterial.color && mc.ambient == existingMaterial.ambient && mc.emissive == existingMaterial.emissive &&
                                    mc.side == existingMaterial.side && mc.opacity == existingMaterial.opacity && mc.shading == existingMaterial.shading)
                                {
                                    mc.uuid       = existingMaterial.uuid;
                                    alreadyExists = true;
                                    break;
                                }
                            }
                        }
                        catch
                        {}
                    }
                    //only add it if it does not exist
                    if (!alreadyExists)
                    {
                        jason.materials[meshCounter] = mc;
                    }
                    MeshDict.Add(c.uuid, mc.uuid);
                }
                if (baseCatcher.type == "MeshBasicMaterial")
                {
                    va3cMeshBasicMaterialCatcher mc = JsonConvert.DeserializeObject <va3cMeshBasicMaterialCatcher>(meshMaterialList[meshCounter].Value);

                    foreach (var existingMaterial in jason.materials)
                    {
                        try
                        {
                            if (existingMaterial.type == "MeshBasicMaterial")
                            {
                                //check if all the properties match a material that already exists
                                if (
                                    mc.color == existingMaterial.color && mc.transparent == existingMaterial.transparent &&
                                    mc.side == existingMaterial.side && mc.opacity == existingMaterial.opacity)
                                {
                                    mc.uuid       = existingMaterial.uuid;
                                    alreadyExists = true;
                                    break;
                                }
                            }
                        }
                        catch
                        { }
                    }
                    //only add it if it does not exist
                    if (!alreadyExists)
                    {
                        jason.materials[meshCounter] = mc;
                    }
                    MeshDict.Add(c.uuid, mc.uuid);
                }
                meshCounter++;
            }



            #endregion

            #region Line management
            //populate line geometries
            int lineCounter         = meshCounter;
            int lineMaterialCounter = 0;
            Dictionary <string, object> LineDict = new Dictionary <string, object>();
            foreach (GH_String l in linesList)
            {
                bool alreadyExists = false;
                //deserialize the line and the material
                va3cLineCatcher lc = JsonConvert.DeserializeObject <va3cLineCatcher>(l.Value);
                va3cLineBasicMaterialCatcher lmc = JsonConvert.DeserializeObject <va3cLineBasicMaterialCatcher>(linesMaterialList[lineMaterialCounter].Value);
                //add the deserialized values to the jason object
                jason.geometries[lineCounter] = lc;


                foreach (var existingMaterial in jason.materials)
                {
                    try
                    {
                        if (existingMaterial.type == "LineBasicMaterial")
                        {
                            //check if all the properties match a material that already exists
                            if (
                                lmc.color == existingMaterial.color && lmc.linewidth == existingMaterial.linewidth &&
                                lmc.opacity == existingMaterial.opacity)
                            {
                                lmc.uuid      = existingMaterial.uuid;
                                alreadyExists = true;
                                break;
                            }
                        }
                    }
                    catch
                    { }
                }
                //only add it if it does not exist
                if (!alreadyExists)
                {
                    jason.materials[meshCounter + lineMaterialCounter] = lmc;
                }

                //populate dict to match up materials and lines
                LineDict.Add(lc.uuid, lmc.uuid);

                //increment counters
                lineCounter++;
                lineMaterialCounter++;
            }
            #endregion


            //make a new array that has the correct size according to the number of materials in the scene
            object[] myMaterials = jason.materials;
            myMaterials     = myMaterials.Where(mat => mat != null).ToArray();
            jason.materials = myMaterials;

            #region Camera management
            //populate line geometries
            int viewCounter = 0;

            Dictionary <string, List <object> > viewDict = new Dictionary <string, List <object> >();
            foreach (GH_String l in viewList)
            {
                //deserialize the line and the material
                va3cCameraCatcher lc = JsonConvert.DeserializeObject <va3cCameraCatcher>(l.Value);

                List <object> viewSettings = new List <object>();
                viewSettings.Add(lc.eye);
                viewSettings.Add(lc.target);

                viewDict.Add(lc.name, viewSettings);

                //increment counters
                viewCounter++;
            }
            #endregion

            jason.OOO = new ExpandoObject();
            //create scene:
            jason.OOO.uuid = System.Guid.NewGuid();
            jason.OOO.type = "Scene";
            int[] numbers = new int[16] {
                1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1
            };
            jason.OOO.matrix   = numbers;
            jason.OOO.children = new object[meshList.Count + linesList.Count];
            jason.OOO.userData = new ExpandoObject();



            //create childern
            //loop over meshes and lines
            int i = 0;
            foreach (var g in MeshDict.Keys) //meshes
            {
                jason.OOO.children[i]          = new ExpandoObject();
                jason.OOO.children[i].uuid     = Guid.NewGuid();
                jason.OOO.children[i].name     = "mesh" + i.ToString();
                jason.OOO.children[i].type     = "Mesh";
                jason.OOO.children[i].geometry = g;
                jason.OOO.children[i].material = MeshDict[g];
                jason.OOO.children[i].matrix   = numbers;
                jason.OOO.children[i].userData = attrDict[g].userData;
                i++;
            }
            int lineCount = 0;
            foreach (var l in LineDict.Keys)
            {
                jason.OOO.children[i]                = new ExpandoObject();
                jason.OOO.children[i].uuid           = Guid.NewGuid();
                jason.OOO.children[i].name           = "line " + i.ToString();
                jason.OOO.children[i].type           = "Line";
                jason.OOO.children[i].geometry       = l;
                jason.OOO.children[i].material       = LineDict[l];
                jason.OOO.children[i].matrix         = numbers;
                jason.OOO.children[i].userData       = new ExpandoObject();
                jason.OOO.children[i].userData.layer = lineLayerList[lineCount].Value;
                i++;
                lineCount++;
            }

            jason.OOO.userData.views = new object[viewList.Count];
            int j = 0;
            foreach (var n in viewDict.Keys)
            {
                jason.OOO.userData.views[j]        = new ExpandoObject();
                jason.OOO.userData.views[j].name   = n;
                jason.OOO.userData.views[j].eye    = viewDict[n][0];
                jason.OOO.userData.views[j].target = viewDict[n][1];

                j++;
            }

            jason.OOO.userData.layers = new object[defLayers.Keys.Count];
            int li = 0;
            foreach (var n in defLayers.Keys)
            {
                jason.OOO.userData.layers[li]      = new ExpandoObject();
                jason.OOO.userData.layers[li].name = n;
                li++;
            }


            return(JsonConvert.SerializeObject(jason));
        }
        private string sceneJSON(List <GH_String> meshList, List <GH_String> meshMaterialList, List <GH_String> linesList, List <GH_String> linesMaterialList)
        {
            //defense - if the material lists are longer than the geometry lists, trim them to be the same length
            if (meshMaterialList.Count > meshList.Count)
            {
                meshMaterialList.RemoveRange(meshList.Count - 1, meshMaterialList.Count - meshList.Count);
            }
            if (linesMaterialList.Count > linesList.Count)
            {
                linesMaterialList.RemoveRange(linesList.Count - 1, linesMaterialList.Count - linesList.Count);
            }

            //create a dynamic object to populate
            dynamic jason = new ExpandoObject();

            //populate metadata object
            jason.metadata           = new ExpandoObject();
            jason.metadata.version   = 4.3;
            jason.metadata.type      = "Object";
            jason.metadata.generator = "vA3C_Grasshopper_Exporter";

            //populate mesh geometries:
            jason.geometries = new object[meshList.Count + linesList.Count];   //array for geometry - both lines and meshes
            int meshCounter = 0;

            jason.materials = new object[meshMaterialList.Count + linesMaterialList.Count];  //array for materials - both lines and meshes
            int matCounter = 0;
            Dictionary <string, object> MeshDict = new Dictionary <string, object>();
            Dictionary <string, va3cAttributesCatcher> attrDict = new Dictionary <string, va3cAttributesCatcher>();

            foreach (GH_String m in meshList)
            {
                //get the last material if the list lengths don't match
                if (matCounter == meshMaterialList.Count)
                {
                    matCounter = meshMaterialList.Count - 1;
                }

                //deserialize the geometry and attributes, and add them to our object
                va3cGeometryCatcher   c  = JsonConvert.DeserializeObject <va3cGeometryCatcher>(m.Value);
                va3cAttributesCatcher ac = JsonConvert.DeserializeObject <va3cAttributesCatcher>(m.Value);
                jason.geometries[meshCounter] = c;
                attrDict.Add(c.uuid, ac);

                //now that we have different types of materials, we need to know which catcher to call
                //use the va3cBaseMaterialCatcher class to determine a material's type, then call the appropriate catcher
                //object mc;
                va3cBaseMaterialCatcher baseCatcher = JsonConvert.DeserializeObject <va3cBaseMaterialCatcher>(meshMaterialList[matCounter].Value);
                if (baseCatcher.type == "MeshFaceMaterial")
                {
                    va3cMeshFaceMaterialCatcher mc = JsonConvert.DeserializeObject <va3cMeshFaceMaterialCatcher>(meshMaterialList[matCounter].Value);
                    jason.materials[matCounter] = mc;
                    MeshDict.Add(c.uuid, mc.uuid);
                }
                if (baseCatcher.type == "MeshPhongMaterial")
                {
                    va3cMeshPhongMaterialCatcher mc = JsonConvert.DeserializeObject <va3cMeshPhongMaterialCatcher>(meshMaterialList[matCounter].Value);
                    jason.materials[matCounter] = mc;
                    MeshDict.Add(c.uuid, mc.uuid);
                }
                if (baseCatcher.type == "MeshLambertMaterial")
                {
                    va3cMeshLambertMaterialCatcher mc = JsonConvert.DeserializeObject <va3cMeshLambertMaterialCatcher>(meshMaterialList[matCounter].Value);
                    jason.materials[matCounter] = mc;
                    MeshDict.Add(c.uuid, mc.uuid);
                }
                if (baseCatcher.type == "MeshBasicMaterial")
                {
                    va3cMeshBasicMaterialCatcher mc = JsonConvert.DeserializeObject <va3cMeshBasicMaterialCatcher>(meshMaterialList[matCounter].Value);
                    jason.materials[matCounter] = mc;
                    MeshDict.Add(c.uuid, mc.uuid);
                }
                matCounter++;
                meshCounter++;
            }

            //populate line geometries
            int lineCounter         = meshCounter;
            int lineMaterialCounter = 0;
            Dictionary <string, object> LineDict = new Dictionary <string, object>();

            foreach (GH_String l in linesList)
            {
                //get the last material if the list lengths don't match
                if (lineMaterialCounter == linesMaterialList.Count)
                {
                    lineMaterialCounter = linesMaterialList.Count - 1;
                }

                //deserialize the line and the material
                va3cLineCatcher lc = JsonConvert.DeserializeObject <va3cLineCatcher>(l.Value);
                va3cLineBasicMaterialCatcher lmc =
                    JsonConvert.DeserializeObject <va3cLineBasicMaterialCatcher>(linesMaterialList[lineMaterialCounter].Value);
                //add the deserialized values to the jason object
                jason.geometries[lineCounter] = lc;
                jason.materials[matCounter + lineMaterialCounter] = lmc;

                //populate dict to match up materials and lines
                LineDict.Add(lc.uuid, lmc.uuid);

                //increment counters
                lineCounter++;
                lineMaterialCounter++;
            }


            jason.OOO = new ExpandoObject();
            //create scene:
            jason.OOO.uuid = System.Guid.NewGuid();
            jason.OOO.type = "Scene";
            int[] numbers = new int[16] {
                1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1
            };
            jason.OOO.matrix   = numbers;
            jason.OOO.children = new object[meshList.Count + linesList.Count];

            //create childern
            //loop over meshes and lines
            int i = 0;

            foreach (var g in MeshDict.Keys) //meshes
            {
                jason.OOO.children[i]          = new ExpandoObject();
                jason.OOO.children[i].uuid     = Guid.NewGuid();
                jason.OOO.children[i].name     = "mesh" + i.ToString();
                jason.OOO.children[i].type     = "Mesh";
                jason.OOO.children[i].geometry = g;
                jason.OOO.children[i].material = MeshDict[g];
                jason.OOO.children[i].matrix   = numbers;
                jason.OOO.children[i].userData = attrDict[g].userData;
                i++;
            }
            foreach (var l in LineDict.Keys)
            {
                jason.OOO.children[i]          = new ExpandoObject();
                jason.OOO.children[i].uuid     = Guid.NewGuid();
                jason.OOO.children[i].name     = "line " + i.ToString();
                jason.OOO.children[i].type     = "Line";
                jason.OOO.children[i].geometry = l;
                jason.OOO.children[i].material = LineDict[l];
                jason.OOO.children[i].matrix   = numbers;
                i++;
            }


            return(JsonConvert.SerializeObject(jason));
        }