public static SceneInfo RootCollectionToRSMLScene(RootCollection collection)
        {
            SceneInfo scene = new SceneInfo()
            {
                Plants = new List <PlantInfo>()
            };

            foreach (RootBase rootBase in collection.RootTree)
            {
                // Each rootbase tree represents a plant in this image.
                if (rootBase is RootGroup)
                {
                    PlantInfo plant = new PlantInfo()
                    {
                        Roots = new List <RootInfo>(), RelativeID = rootBase.RelativeID
                    };
                    if (rootBase.Label != "")
                    {
                        plant.Label = rootBase.Label;
                    }

                    RootGroup group = rootBase as RootGroup;

                    // For each primary root
                    foreach (PrimaryRoot primary in group.Children)
                    {
                        RootInfo primaryRootInfo = new RootInfo()
                        {
                            Children   = new List <RootInfo>(),
                            RelativeID = primary.RelativeID,
                            RsmlID     = primary.RelativeID,
                            Polyline   = null,
                            Spline     = primary.Spline
                        };

                        if (primary.Label != "")
                        {
                            primaryRootInfo.Label = primary.Label;
                        }

                        foreach (LateralRoot lateral in primary.Children)
                        {
                            RootInfo lateralRootInfo = new RootInfo()
                            {
                                Children   = new List <RootInfo>(),
                                RelativeID = lateral.RelativeID,
                                RsmlID     = lateral.RelativeID,
                                Polyline   = null,
                                Spline     = lateral.Spline
                            };

                            if (lateral.Label != "")
                            {
                                lateralRootInfo.Label = lateral.Label;
                            }

                            primaryRootInfo.Children.Add(lateralRootInfo);
                        }

                        plant.Roots.Add(primaryRootInfo);
                    }

                    scene.Plants.Add(plant);
                }
            }

            return(scene);
        }
        public static RootCollection CreateRootSystem(LiveWirePathCollection pathCollection, RootTerminalCollection terminals, List <Color> colors, int splineResolution, double unitConversion)
        {
            Dictionary <int, Tuple <RootBase, int, int> > indexedRoots = new Dictionary <int, Tuple <RootBase, int, int> >();
            double        tension       = 0.5;
            HashSet <int> sourceIndexes = new HashSet <int>();

            for (int index = 0; index < pathCollection.Count; index++)
            {
                LiveWirePath currentPath = pathCollection[index];

                if (currentPath is LiveWirePrimaryPath)
                {
                    LiveWirePrimaryPath primaryLiveWire = currentPath as LiveWirePrimaryPath;

                    RootBase primary = new PrimaryRoot()
                    {
                        UnitConversionFactor = unitConversion
                    };
                    primary.RootIndex = index;

                    primary.Spline = new SampledSpline()
                    {
                        ControlPointSeparation = splineResolution, Tension = tension
                    };
                    primary.Spline.Initialise(primaryLiveWire.Path);

                    primary.Color = colors[index];

                    indexedRoots.Add(index, new Tuple <RootBase, int, int> (primary, primaryLiveWire.SourceIndex, -1));

                    sourceIndexes.Add(primaryLiveWire.SourceIndex);
                }
                else if (currentPath is LiveWireLateralPath)
                {
                    LiveWireLateralPath lateralLiveWire = currentPath as LiveWireLateralPath;

                    RootBase lateral = new LateralRoot()
                    {
                        UnitConversionFactor = unitConversion
                    };
                    lateral.RootIndex = index;
                    List <Point> path = lateralLiveWire.Path.ToList();
                    path.Reverse();
                    lateral.Spline = new SampledSpline()
                    {
                        ControlPointSeparation = splineResolution, Tension = tension
                    };
                    lateral.Spline.Initialise(path);

                    lateral.Color = colors[lateralLiveWire.TargetPoint.ParentIndex];

                    indexedRoots.Add(index, new Tuple <RootBase, int, int> (lateral, -1, lateralLiveWire.TargetPoint.ParentIndex));
                }
            }

            Dictionary <int, RootBase> plants = new Dictionary <int, RootBase>();

            foreach (int i in sourceIndexes)
            {
                RootBase plant = new RootGroup()
                {
                    UnitConversionFactor = unitConversion
                };
                plants.Add(i, plant);
            }

            // Create tree structure based on references
            List <RootBase> primaryRoots = new List <RootBase>();

            foreach (var pair in indexedRoots)
            {
                RootBase r = pair.Value.Item1;
                int      plantSourceIndex = pair.Value.Item2;
                int      parentIndex      = pair.Value.Item3;

                if (parentIndex == -1)
                {
                    // Add primary root to main list
                    plants[plantSourceIndex].Children.Add(r);
                }
                else
                {
                    // Add lateral to parent's children
                    indexedRoots[parentIndex].Item1.Children.Add(r);
                    r.Parent = indexedRoots[parentIndex].Item1;
                }
            }

            List <RootBase> plantList = plants.Values.ToList();

            int plantIndex = 1;

            foreach (RootBase plant in plantList)
            {
                plant.ID = plantIndex++;

                // Lateral angles can now be calculated
                MarkStartReferences(plant.Children);

                // Calculate IDs
                MarkIDs(plant.Children);

                // Mark primary parents
                MarkPrimaryParents(plant, plant.Children);

                // Mark convex hulls
                MarkConvexHulls(plant.Children);

                // Plant settings
                plant.Color = Color.FromArgb(255, 200, 200, 200);

                // Plant hull
                SetPlantHullPoints(plant);
            }

            // Create plant systems
            return(new RootCollection {
                RootTree = plantList
            });
        }