Example #1
0
        public override Grasshopper.GUI.Canvas.GH_ObjectResponse RespondToMouseDoubleClick(Grasshopper.GUI.Canvas.GH_Canvas sender, Grasshopper.GUI.GH_CanvasMouseEvent e)
        {
            // Read in Cluster number slider
            List <IGH_Param> sliderListClust = new List <IGH_Param>();

            foreach (IGH_Param src2 in MyComponent.Params.Input[4].Sources)
            {
                sliderListClust.Add(src2);
            }
            Grasshopper.Kernel.Special.GH_NumberSlider clusterSlider = (Grasshopper.Kernel.Special.GH_NumberSlider)sliderListClust[0];



            if (!MyComponent.ClusterDone)

            {
                //run clustering process
                KMeans kmeans = new KMeans(MyComponent.numClusters);


                double[][] data    = MyComponent.DesignMap.Select(a => a.ToArray()).ToArray();
                double[]   weights = null;

                // int[] labels = kmeans.Learn(data,weights);

                for (int i = 0; i < data.Count(); i++)
                {
                    data[i] = data[i].Take(data[i].Count() - MyComponent.numObjs).ToArray();
                }


                int[] labels = kmeans.Compute(data);

                LabelsList = labels.OfType <int>().ToList();


                // Set cluster slider bounds, values to default while clustering is run
                clusterSlider.TrySetSliderValue((decimal)0);
                clusterSlider.Slider.Minimum = ((decimal)0);
                clusterSlider.Slider.Maximum = ((decimal)MyComponent.numClusters);


                // list management
                this.DesignMap = MyComponent.DesignMap;
                this.numVars   = MyComponent.numVars;

                // create Sorted list
                for (int i = 0; i < MyComponent.numClusters; i++)
                {
                    DesignMapSorted.Add(new List <List <double> >());
                    for (int j = 0; j < DesignMap.Count; j++)
                    {
                        if (LabelsList[j] == i)
                        {
                            DesignMapSorted[i].Add(DesignMap[j]);
                        }
                    }
                }

                for (int i = 0; i < MyComponent.numClusters; i++)
                {
                    ClusterAves.Add(new List <double>());
                    ClusterMaxs.Add(new List <double>());
                    ClusterMins.Add(new List <double>());

                    double[] sum     = new double[numVars];
                    double[] average = new double[numVars];
                    double[] max     = new double[numVars];
                    double[] min     = new double[numVars];

                    for (int l = 0; l < numVars; l++)

                    {
                        sum[l] = 0;
                        max[l] = double.MinValue;
                        min[l] = double.MaxValue;
                    }

                    for (int j = 0; j < DesignMapSorted[i].Count; j++)

                    {
                        for (int k = 0; k < numVars; k++)

                        {
                            sum[k] = sum[k] + DesignMapSorted[i][j][k];

                            if (DesignMapSorted[i][j][k] > max[k])

                            {
                                max[k] = DesignMapSorted[i][j][k];
                            }
                            else if (DesignMapSorted[i][j][k] < min[k])

                            {
                                min[k] = DesignMapSorted[i][j][k];
                            }

                            average[k] = sum[k] / DesignMapSorted[i].Count;
                        }
                    }

                    for (int k = 0; k < numVars; k++)
                    {
                        ClusterAves[i].Add(average[k]);
                        ClusterMaxs[i].Add(max[k]);
                        ClusterMins[i].Add(min[k]);
                    }
                }


                ClusterAves.Insert(0, MyComponent.VarsVals);
                ClusterMaxs.Insert(0, MyComponent.MaxVals);
                ClusterMins.Insert(0, MyComponent.MinVals);


                //for (int i = 0; i < DesignMapSorted.Count; i++)

                //{
                //LabelsList[i] = LabelsList[i] + 1;
                //}
            }



            List <IGH_Param> sliderList = new List <IGH_Param>();

            foreach (IGH_Param src in MyComponent.Params.Input[0].Sources)
            {
                sliderList.Add(src);
            }

            for (int i = 0; i < numVars; i++)
            {
                if (MyComponent.index != 0)

                {
                    Grasshopper.Kernel.Special.GH_NumberSlider nslider = (Grasshopper.Kernel.Special.GH_NumberSlider)sliderList[i];

                    double adjmin = ClusterMins[MyComponent.index][i] + (1 - MyComponent.flexibility) * (ClusterAves[MyComponent.index][i] - ClusterMins[MyComponent.index][i]);
                    double adjmax = ClusterMaxs[MyComponent.index][i] - (1 - MyComponent.flexibility) * (ClusterMaxs[MyComponent.index][i] - ClusterAves[MyComponent.index][i]);

                    nslider.TrySetSliderValue((decimal)ClusterAves[MyComponent.index][i]);
                    nslider.Slider.Minimum = ((decimal)adjmin);
                    nslider.Slider.Maximum = ((decimal)adjmax);
                }
                else
                {
                    Grasshopper.Kernel.Special.GH_NumberSlider nslider = (Grasshopper.Kernel.Special.GH_NumberSlider)sliderList[i];

                    nslider.TrySetSliderValue((decimal)ClusterAves[MyComponent.index][i]);
                    nslider.Slider.Minimum = ((decimal)ClusterMins[MyComponent.index][i]);
                    nslider.Slider.Maximum = ((decimal)ClusterMaxs[MyComponent.index][i]);
                }
            }

            MyComponent.ClusterDone = true;
            Grasshopper.Instances.ActiveCanvas.Document.NewSolution(true);

            return(base.RespondToMouseDoubleClick(sender, e));
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // Read in slider properties
            readSlidersList();
            List <double> variables = new List <double>();

            if (!DA.GetDataList(0, variables))
            {
                return;
            }
            numVars = variables.Count;

            // Read in design map
            var map = new GH_Structure <GH_Number>();

            if (!DA.GetDataTree(1, out map))
            {
                return;
            }
            this.DesignMap = StructureToListOfLists(map);

            numObjs = DesignMap[0].Count - numVars;

            // Take in other inputs
            if (!DA.GetData(2, ref numClusters))
            {
                return;
            }
            if (!DA.GetData(3, ref flexibility))
            {
                return;
            }
            if (!DA.GetData(4, ref index))
            {
                return;
            }

            // If button is clicked, run clustering
            if (Run(DA, 5))

            {
                //run clustering process
                KMeans kmeans = new KMeans(numClusters);

                double[][] data    = DesignMap.Select(a => a.ToArray()).ToArray();
                double[]   weights = null;

                // int[] labels = kmeans.Learn(data,weights);

                for (int i = 0; i < data.Count(); i++)
                {
                    data[i] = data[i].Take(data[i].Count() - numObjs).ToArray();
                }


                int[] labels = kmeans.Compute(data);

                LabelsList = labels.OfType <int>().ToList();

                // create Sorted list
                for (int i = 0; i < numClusters; i++)
                {
                    DesignMapSorted.Add(new List <List <double> >());
                    for (int j = 0; j < DesignMap.Count; j++)
                    {
                        if (LabelsList[j] == i)
                        {
                            DesignMapSorted[i].Add(DesignMap[j]);
                        }
                    }
                }

                // Calculate min/max/average for each cluster
                for (int i = 0; i < numClusters; i++)
                {
                    ClusterAves.Add(new List <double>());
                    ClusterMaxs.Add(new List <double>());
                    ClusterMins.Add(new List <double>());

                    double[] sum     = new double[numVars];
                    double[] average = new double[numVars];
                    double[] max     = new double[numVars];
                    double[] min     = new double[numVars];

                    for (int l = 0; l < numVars; l++)

                    {
                        sum[l] = 0;
                        max[l] = double.MinValue;
                        min[l] = double.MaxValue;
                    }

                    for (int j = 0; j < DesignMapSorted[i].Count; j++)

                    {
                        for (int k = 0; k < numVars; k++)

                        {
                            sum[k] = sum[k] + DesignMapSorted[i][j][k];

                            if (DesignMapSorted[i][j][k] > max[k])

                            {
                                max[k] = DesignMapSorted[i][j][k];
                            }
                            else if (DesignMapSorted[i][j][k] < min[k])

                            {
                                min[k] = DesignMapSorted[i][j][k];
                            }

                            average[k] = sum[k] / DesignMapSorted[i].Count;
                        }
                    }

                    for (int k = 0; k < numVars; k++)
                    {
                        ClusterAves[i].Add(average[k]);
                        ClusterMaxs[i].Add(max[k]);
                        ClusterMins[i].Add(min[k]);
                    }
                }


                ClusterAves.Insert(0, VarsVals);
                ClusterMaxs.Insert(0, MaxVals);
                ClusterMins.Insert(0, MinVals);
                ClusterDone = true;
            }



            // Create list of cluster labels
            List <List <double> > averageTree = new List <List <Double> >();

            ClusterLabelsList = LabelsList;

            if (ClusterDone & !propCalculated)
            {
                labelstree.Add(LabelsList);

                for (int i = 0; i < numClusters; i++)
                {
                    DesignMapSorted.Add(new List <List <double> >());
                    for (int j = 0; j < DesignMap.Count; j++)
                    {
                        if (ClusterLabelsList[j] == i)
                        {
                            DesignMapSorted[i].Add(DesignMap[j]);
                        }
                    }
                }

                // Shift indices of labels from 0-numbering to 1-numbering (so that "0" will be original inputs)
                if (ClusterDone && !indexShifted)

                {
                    for (int i = 0; i < labelstree[0].Count; i++)
                    {
                        labelstree[0][i] = labelstree[0][i] + 1;
                    }

                    indexShifted = true;
                    //DA.SetDataTree(0, ListOfListsToTree<int>(labelstree));
                }

                ClusterAves.Clear();
                ClusterMaxs.Clear();
                ClusterMins.Clear();
                ClusterObjs.Clear();

                // Add original inputs of variable sliders to cluster lists, so that "0" will reset to original design space
                ClusterAves.Add(new List <double>());
                ClusterMaxs.Add(new List <double>());
                ClusterMins.Add(new List <double>());

                for (int k = 0; k < numVars; k++)
                {
                    ClusterAves[0].Add(VarsVals[k]);
                    ClusterMaxs[0].Add(MaxVals[k]);
                    ClusterMins[0].Add(MinVals[k]);
                }

                // Add cluster properties to lists for outputs and cycling through clusters (in Component Attributes)
                for (int i = 0; i < numClusters; i++)
                {
                    ClusterAves.Add(new List <double>());
                    ClusterMaxs.Add(new List <double>());
                    ClusterMins.Add(new List <double>());
                    ClusterObjs.Add(new List <double>());

                    double[] sum     = new double[numVars];
                    double[] average = new double[numVars];
                    double[] max     = new double[numVars];
                    double[] min     = new double[numVars];

                    double[] sumObj     = new double[numObjs];
                    double[] averageObj = new double[numObjs];
                    double[] maxObj     = new double[numObjs];
                    double[] minObj     = new double[numObjs];


                    // Capture average, max, min for variables
                    for (int l = 0; l < numVars; l++)

                    {
                        sum[l] = 0;
                        max[l] = double.MinValue;
                        min[l] = double.MaxValue;
                    }

                    for (int l = 0; l < numObjs; l++)

                    {
                        sumObj[l] = 0;
                        maxObj[l] = double.MinValue;
                        minObj[l] = double.MaxValue;
                    }

                    for (int j = 0; j < DesignMapSorted[i].Count; j++)
                    {
                        for (int k = 0; k < numVars; k++)
                        {
                            sum[k] = sum[k] + DesignMapSorted[i][j][k];

                            if (DesignMapSorted[i][j][k] > max[k])
                            {
                                max[k] = DesignMapSorted[i][j][k];
                            }
                            else if (DesignMapSorted[i][j][k] < min[k])
                            {
                                min[k] = DesignMapSorted[i][j][k];
                            }

                            average[k] = sum[k] / DesignMapSorted[i].Count;
                        }
                    }


                    // Capture objective value averages

                    for (int j = 0; j < DesignMapSorted[i].Count; j++)

                    {
                        for (int k = 0; k < numObjs; k++)

                        {
                            sumObj[k] = sumObj[k] + DesignMapSorted[i][j][k + numVars];

                            if (DesignMapSorted[i][j][k + numVars] > maxObj[k])

                            {
                                maxObj[k] = DesignMapSorted[i][j][k + numVars];
                            }
                            else if (DesignMapSorted[i][j][k + numVars] < minObj[k])

                            {
                                minObj[k] = DesignMapSorted[i][j][k + numVars];
                            }

                            averageObj[k] = sumObj[k] / DesignMapSorted[i].Count;
                        }
                    }

                    for (int k = 0; k < numVars; k++)
                    {
                        ClusterAves[i + 1].Add(average[k]);
                        ClusterMaxs[i + 1].Add(max[k]);
                        ClusterMins[i + 1].Add(min[k]);
                    }

                    for (int k = 0; k < numObjs; k++)
                    {
                        ClusterObjs[i].Add(averageObj[k]);
                    }
                }

                propCalculated = true;
            }

            // Set all outputs
            if (ClusterDone & propCalculated)
            {
                DA.SetDataTree(0, ListOfListsToTree <int>(labelstree));
                DA.SetDataTree(1, ListOfListsToTree <Double>(ClusterAves));
                DA.SetDataTree(2, ListOfListsToTree <Double>(ClusterMins));
                DA.SetDataTree(3, ListOfListsToTree <Double>(ClusterMaxs));
                DA.SetDataTree(4, ListOfListsToTree <Double>(ClusterObjs));
            }
        }