/// <summary> /// Parallel Computing Setup for Code to Execute. /// </summary> /// <param name="pointCloud">ByRef PointCloud to Execute Code on.</param> /// <returns></returns> public override bool Execute(ref PointCloud pointCloud) { //Set Global Variables LastPercentReported = 0; PointCounter = 0; Dict_Utils.CastDictionary_ToArrayDouble(ref pointCloud); GlobalCloud = pointCloud; NewCloud = (PointCloud)pointCloud.Duplicate(); // Setup the cancellation mechanism. po.CancellationToken = cts.Token; //Create Partitions for multithreading. var rangePartitioner = System.Collections.Concurrent.Partitioner.Create(0, GlobalCloud.Count, (int)Math.Ceiling((double)GlobalCloud.Count / ProcCount)); //Run MultiThreaded Loop. Parallel.ForEach(rangePartitioner, po, (rng, loopState) => { //Initialize Local Variables. /// Get Index for Processor to be able to merge clouds in ProcesserIndex order in the end. int MyIndex = (int)(rng.Item1 / Math.Ceiling(((double)GlobalCloud.Count / ProcCount))); /// Initialize Partial PointCloud PointCloud MyCloud = new PointCloud(); /// Get Total Count Fraction to calculate Operation Percentage. double totc = (double)1 / GlobalCloud.Count; //Loop over individual RangePartitions per processor. for (int i = rng.Item1; i < rng.Item2; i++) { //Operation Percentage Report ///Safe Counter Increment. Interlocked.Increment(ref PointCounter); ///Calculate and Report Percentage. if (LastPercentReported < ((PointCounter * totc) * 100)) { LastPercentReported = (int)(5 * Math.Ceiling((double)(PointCounter * totc) * 20)); this.ReportPercent = LastPercentReported; } // Color color = NewCloud[i].Color; Color newCol = Color_Utils.Blend(color, insV_Color, insV_Pct); NewCloud[i].Color = newCol; // } //Enable Parrallel Computing Cancellation po.CancellationToken.ThrowIfCancellationRequested(); } ); //Dispose of Global Clouds. GlobalCloud.Dispose(); pointCloud.Dispose(); //Set OutputCloud pointCloud = (PointCloud)NewCloud.Duplicate(); //Dispose of PointCloud Pieces and NewCloud. GlobalCloud.Dispose(); NewCloud.Dispose(); //Return True on Finish return(true); }
/// <summary> /// /// </summary> /// <param name="PointCloud"></param> /// <param name="Message"></param> /// <returns></returns> public override bool Execute(ref PointCloud pointCloud) { #region - Initialize Execution //Set Global Variables LastPercentReported = 0; PointCounter = 0; NewCloud = new PointCloud(); CloudPieces = null; CloudPieces = new PointCloud[ProcCount]; GlobalCloud = pointCloud; // Setup the cancellation mechanism. po.CancellationToken = cts.Token; //Create Partitions for multithreading. var rangePartitioner = System.Collections.Concurrent.Partitioner.Create(0, GlobalCloud.Count, (int)Math.Ceiling((double)GlobalCloud.Count / ProcCount)); Dict_Utils.CastDictionary_ToArrayDouble(ref GlobalCloud); //// //Initialize ColorGradient Interval Itv = new Interval(); Bitmap bmp = new Bitmap(1000, 1); Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); System.Drawing.Drawing2D.ColorBlend cb = new System.Drawing.Drawing2D.ColorBlend(); float[] pos = new float[insV_Colors.Count]; for (int i = 0; i <= pos.Length - 1; i += 1) { pos[i] = (float)insV_Values[i]; } Color[] colors = insV_Colors.ToArray(); Array.Sort(pos, colors); Array.Sort(pos, pos); float[] normpos = new float[insV_Colors.Count]; Itv = new Interval(pos[0], pos[pos.Length - 1]); for (int i = 0; i <= normpos.Length - 1; i += 1) { normpos[i] = (float)Itv.NormalizedParameterAt(pos[i]); } cb.Positions = normpos; cb.Colors = colors; System.Drawing.Drawing2D.LinearGradientBrush lin = new System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.Black, Color.Black, 0, false); lin.LinearColors = colors; lin.InterpolationColors = cb; ColVal = null; ColVal = new Color[bmp.Width]; int counter = 0; using (Graphics g = Graphics.FromImage(bmp)) { g.FillRectangle(lin, rect); for (int i = 0; i <= bmp.Width - 1; i += 1) { Color col = bmp.GetPixel(i, 0); ColVal[counter] = col; counter += 1; } } //// //Get Dictionary Values from PointCloud List <double> DictVal = new List <double>(); DictVal.AddRange((double[])GlobalCloud.UserDictionary[insV_Key]); //Get idx to multiply with for normalized values. int idx = ColVal.Length - 1; //Run MultiThreaded Loop. Parallel.ForEach(rangePartitioner, po, (rng, loopState) => { //Initialize Local Variables. /// Get Index for Processor to be able to merge clouds in ProcesserIndex order in the end. int MyIndex = (int)(rng.Item1 / Math.Ceiling(((double)GlobalCloud.Count / ProcCount))); /// Initialize Partial PointCloud PointCloud MyCloud = new PointCloud(); /// Get Total Count Fraction to calculate Operation Percentage. double totc = (double)1 / GlobalCloud.Count; //Loop over individual RangePartitions per processor. for (int i = rng.Item1; i < rng.Item2; i++) { //Operation Percentage Report ///Safe Counter Increment. Interlocked.Increment(ref PointCounter); ///Calculate and Report Percentage. if (LastPercentReported < ((PointCounter * totc) * 100)) { LastPercentReported = (int)(5 * Math.Ceiling((double)(PointCounter * totc) * 20)); this.ReportPercent = LastPercentReported; } #endregion - End of Initialize Execution #region - Code to Process on PointCloud. double thisnorm = new double(); if (insV_Step <= 0.0) { thisnorm = Itv.NormalizedParameterAt(DictVal[i]); } else { thisnorm = Itv.NormalizedParameterAt((Math.Floor((DictVal[i] - Itv[0]) / insV_Step) * insV_Step) + Itv[0]); } Color col = new Color(); if (thisnorm < (0.0000000)) { col = ColVal.First(); } else if (thisnorm > (1.0000000)) //+ Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) { col = ColVal.Last(); } else { col = ColVal[(int)(thisnorm * idx)]; } if (insV_ColPct >= 0.0) { col = Color_Utils.Blend(GlobalCloud[i].Color, col, insV_ColPct); } MyCloud.Add(GlobalCloud[i].Location, col); #endregion - End of Code to Process on PointCloud. #region - Finalize Execution } //Add MyCloud to CloudPieces at ProcesserIndex. CloudPieces[(int)MyIndex] = MyCloud; //Enable Parrallel Computing Cancellation po.CancellationToken.ThrowIfCancellationRequested(); } ); //Merge PointCloud Pieces into One PointCloud. Cloud_Utils.MergeClouds(ref NewCloud, CloudPieces); //Set UserDictionary from DictionaryLists. Dict_Utils.SetUserDict_FromOtherCloud(ref NewCloud, GlobalCloud); //Set ColorGradient UserData List <double> gradVals = new List <double>(); List <Color> gradCols = new List <Color>(); if (insV_Step > 0.00) { for (int i = 0; i < pos.Length; i++) { double gradVal = (Math.Floor((pos[i] - Itv[0]) / insV_Step) * insV_Step) + Itv[0]; if (!gradVals.Contains(gradVal)) { Color gradCol = ColVal[(int)(Itv.NormalizedParameterAt(gradVal) * idx)]; gradVals.Add(gradVal); gradCols.Add(gradCol); } } double lastVal = (Math.Ceiling((pos[pos.Length - 1] - Itv[0]) / insV_Step) * insV_Step) + Itv[0]; if (!gradVals.Contains(lastVal)) { Color gradCol = ColVal[(int)(Itv.NormalizedParameterAt(pos[pos.Length - 1]) * idx)]; gradVals.Add(lastVal); gradCols.Add(gradCol); } } else { gradVals = insV_Values; gradCols = insV_Colors; } Color_Utils.Set_ColorGradient_Dict(ref NewCloud, gradCols, gradVals); //Dispose of Global Clouds. GlobalCloud.Dispose(); pointCloud.Dispose(); //Set OutputCloud pointCloud = (PointCloud)NewCloud.Duplicate(); //Dispose of PointCloud Pieces and NewCloud. CloudPieces = null; NewCloud.Dispose(); #endregion - End of Finalize Execution //Return True on Finish return(true); }