/// <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(); Array.Resize(ref Distances, pointCloud.Count); Array.Resize(ref ApproachAngle, pointCloud.Count); double halfpi = Math.PI / 2; // 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; } // PointCloudItem GlobalCloudItem = GlobalCloud[i]; Point3d p3 = GlobalCloudItem.Location; Point3d pm = new Point3d(); Vector3d pv = new Vector3d(); insV_Mesh.ClosestPoint(p3, out pm, out pv, 0); double d = p3.DistanceTo(pm); if (Vector3d.VectorAngle(pv, new Vector3d(pm - p3)) < halfpi) { d = -d; } Distances[i] = d; if (insV_ApproachAngle) { Point3d pos = (Point3d)insV_PositionPt; Vector3d scanVec = new Vector3d(p3 - pos); double appA = Math.Abs(halfpi - Vector3d.VectorAngle(pv, scanVec)); ApproachAngle[i] = appA; } } //Enable Parrallel Computing Cancellation po.CancellationToken.ThrowIfCancellationRequested(); } ); //Dispose of Global Clouds. GlobalCloud.Dispose(); pointCloud.Dispose(); //Set OutputCloud NewCloud.UserDictionary.Set(insV_Key, Distances); NewCloud.UserDictionary.Set(insV_AngleKey, ApproachAngle); //Colorize if (insV_Colorize) { List <double> colorValues = Color_Utils.ColorValues_Std_negpos(NewCloud, insV_Key); List <Color> Colors = Color_Utils.ColorGradient_Std_BtoR(); Instruction.Instr_Dict_Color col = new Instruction.Instr_Dict_Color(insV_Key, colorValues, Colors, -1, 0.00); Boolean ColResult = col.Execute(ref NewCloud); //Set ColorGradient UserData Color_Utils.Set_ColorGradient_Dict(ref NewCloud, Colors, colorValues); } pointCloud = (PointCloud)NewCloud.Duplicate(); //Dispose of PointCloud Pieces and NewCloud. GlobalCloud.Dispose(); NewCloud.Dispose(); //Return True on Finish return(true); }
/// <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) { //Initialize Input Variables, Persistent in ComponentChange. List <double> pars = new List <double>(); List <Color> cols = new List <Color>(); string strdc = null; double colPct = 0.00; double step = 0.0; if (!DA.GetData("Key", ref strdc)) { return; } if (!DA.GetDataList("Values", pars)) { return; } if (!DA.GetDataList("Colors", cols)) { return; } if (!DA.GetData("BlendPct", ref colPct)) { return; } DA.GetData("StepSize", ref step); if (colPct > 1.00) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Color Blending Percentage cannot be above 1.00."); } //Excute Instruction ///If Component is set as Instruction. if (isInstruction) { DA.SetData("Instr", new Instruction.Instr_Dict_Color(strdc, pars, cols, step, colPct)); } else ///If Component is set to StandAlone. { ///Initialize PointCloud Input Variable. GH_Cloud pointCloud = null; if (!DA.GetData("Cloud", ref pointCloud)) { return; } ///Duplicate GH Cloud. GH_Cloud newGHCloud = pointCloud.DuplicateCloud(); PointCloud newCloud = newGHCloud.Value; ///Execute Instruction. Instruction.Instr_Dict_Color inst = new Instruction.Instr_Dict_Color(strdc, pars, cols, step, colPct); Boolean Result = inst.Execute(ref newCloud); ///Set New Output Cloud newGHCloud.Value = newCloud; DA.SetData("Cloud", newGHCloud); //Add RuntimeMessage: ComponentChange. AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "'Right Click' to Switch between StandAlone and Instruction Component."); } }
/// <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(); tree = insV_KDTree.Value.Item1; cloudTo = insV_KDTree.Value.Item2.Value; pts = pointCloud.GetPoints(); Array.Resize(ref Distances, pointCloud.Count); // 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++) { //Point to measure From var p = pts[i]; //Range var r = Double.MaxValue; //Get one Nearest Neighbor (Part of KDTree.dll) var ns = tree.NearestNeighbors(new double[] { p.X, p.Y, p.Z }, insV_Amount, r); //The index of the Nearest Point in the PointCloud to Measure To. var indList = ns.ToList(); double D = 0.0; foreach (int idx in indList) { //Distance between Point measured From to Point meassured To. //Point meassured From. Point3d P2 = cloudTo[idx].Location; //Distance betwen Points //double D = fastDist(p, P2); //Cumulative Distance D = D + p.DistanceTo(P2); } //Average distances double aveD = D / indList.Count; //Add Distances to Array. Distances[i] = aveD; } //Enable Parrallel Computing Cancellation po.CancellationToken.ThrowIfCancellationRequested(); } ); //Dispose of Global Clouds. GlobalCloud.Dispose(); pointCloud.Dispose(); //Set OutputCloud NewCloud.UserDictionary.Set(insV_Key, Distances); //Colorize if (insV_Colorize) { List <double> colorValues = Color_Utils.ColorValues_Std_pos(NewCloud, insV_Key); List <Color> Colors = Color_Utils.ColorGradient_Std_GtoR(); Instruction.Instr_Dict_Color col = new Instruction.Instr_Dict_Color(insV_Key, colorValues, Colors, -1, 0.00); Boolean ColResult = col.Execute(ref NewCloud); //Set ColorGradient UserData Color_Utils.Set_ColorGradient_Dict(ref NewCloud, Colors, colorValues); } pointCloud = (PointCloud)NewCloud.Duplicate(); //Dispose of PointCloud Pieces and NewCloud. GlobalCloud.Dispose(); NewCloud.Dispose(); //Return True on Finish return(true); }