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)); } }