public override bool shoot(Hare.Geometry.Ray R, out double u, out double v, out int Poly_ID, out List <Hare.Geometry.Point> X_PT, out List <double> t, out List <int> code)
            {
                ///////////////////////
                //double L2 = (R.direction.x * R.direction.x + R.direction.y * R.direction.y + R.direction.z *R.direction.z);
                //if (L2 > 1.05 || L2 < 0.95)
                //{
                //    Rhino.RhinoApp.Write("Vectors have lost normalization...");
                //}
                ///////////////////////
                //R.direction.Normalize();
                ///////////////////////
                Hare.Geometry.X_Event X = new Hare.Geometry.X_Event();
                if (SP.Shoot(R, 0, out X))
                {
                    Poly_ID = X.Poly_id;
                    X_Event_NH XNH = X as X_Event_NH;
                    if (XNH != null)
                    {
                        X_PT = XNH.P_Points;
                        t    = XNH.t_trav;
                        code = XNH.SPCode;
                    }
                    else
                    {
                        X_PT = new List <Hare.Geometry.Point> {
                            X.X_Point
                        };
                        t = new List <double> {
                            X.t
                        };
                        code = new List <int> {
                            0
                        };
                    }

                    u = 0;
                    v = 0;
                    return(true);
                }
                Poly_ID = 0;
                X_PT    = new List <Hare.Geometry.Point>();
                //Rhino.RhinoDoc.ActiveDoc.Objects.Add(new Rhino.Geometry.LineCurve(Utilities.PachTools.HPttoRPt(R.origin), Utilities.PachTools.HPttoRPt(R.origin + R.direction)));
                t    = new List <double>();
                u    = 0;
                v    = 0;
                code = new List <int>()
                {
                    0
                };
                return(false);
            }
Exemplo n.º 2
0
            /// <summary>
            /// Fire a ray into the model.
            /// </summary>
            /// <param name="R"> The ray to be entered. Make certain the Ray has a unique Ray_ID variable. </param>
            /// <param name="top_index"> Indicates the topology the ray is to intersect. </param>
            /// <param name="Ret_Event"> The nearest resulting intersection information, if any. </param>
            /// <returns> Indicates whether or not an intersection was found. </returns>
            public override bool Shoot(Ray R, int top_index, out X_Event Ret_Event)//, On3dPoint EndPt, int Octave_in)
            {
                int X, Y, Z;
                ////////////////////////
                double VPrev = 0;

                ////////////////////////
                //Identify whether the Origin is inside the voxel grid...
                //Identify which voxel the Origin point is located in...
                X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x) / VoxelDims.x);
                Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y) / VoxelDims.y);
                Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z) / VoxelDims.z);

                double tDeltaX, tDeltaY, tDeltaZ;
                double tMaxX = 0, tMaxY = 0, tMaxZ = 0;

                int    stepX, stepY, stepZ, OutX, OutY, OutZ;
                double t_start = 0;

                if (X < 0 || X >= VoxelCtX || Y < 0 || Y >= VoxelCtY || Z < 0 || Z >= VoxelCtZ) //return false;
                {
                    if (!OBox.Intersect(R, ref t_start, ref R.origin))
                    {
                        Ret_Event = new X_Event();
                        return(false);
                    }
                    X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x + R.direction.x) / VoxelDims.x);
                    Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y + R.direction.y) / VoxelDims.y);
                    Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z + R.direction.z) / VoxelDims.z);
                }

                if (R.direction.x < 0)
                {
                    OutX    = -1;
                    stepX   = -1;
                    tMaxX   = (float)((Voxels[X, Y, Z].Min_PT.x - R.origin.x) / R.direction.x);
                    tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                }
                else
                {
                    OutX    = VoxelCtX;
                    stepX   = 1;
                    tMaxX   = (float)((Voxels[X, Y, Z].Max_PT.x - R.origin.x) / R.direction.x);
                    tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                }

                if (R.direction.y < 0)
                {
                    OutY    = -1;
                    stepY   = -1;
                    tMaxY   = (float)((Voxels[X, Y, Z].Min_PT.y - R.origin.y) / R.direction.y);
                    tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                }
                else
                {
                    OutY    = VoxelCtY;
                    stepY   = 1;
                    tMaxY   = (float)((Voxels[X, Y, Z].Max_PT.y - R.origin.y) / R.direction.y);
                    tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                }

                if (R.direction.z < 0)
                {
                    OutZ    = -1;
                    stepZ   = -1;
                    tMaxZ   = (float)((Voxels[X, Y, Z].Min_PT.z - R.origin.z) / R.direction.z);
                    tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                }
                else
                {
                    OutZ    = VoxelCtZ;
                    stepZ   = 1;
                    tMaxZ   = (float)((Voxels[X, Y, Z].Max_PT.z - R.origin.z) / R.direction.z);
                    tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                }

                List <double> t_list     = new List <double>();
                List <int>    Codes      = new List <int>();
                List <Point>  Path_pts   = new List <Point>();
                List <int>    voxelCodes = new List <int>();

                List <Point>  X_LIST  = new List <Point>();
                List <double> ulist   = new List <double>();
                List <double> vlist   = new List <double>();
                List <double> tlist   = new List <double>();
                List <int>    pidlist = new List <int>();

                while (true)
                {
                    //Check all polygons in the current voxel...
                    foreach (int i in Voxel_Inv[X, Y, Z, top_index])
                    {
                        if (Poly_Ray_ID[R.ThreadID, top_index][i] != R.Ray_ID)
                        {
                            Poly_Ray_ID[R.ThreadID, top_index][i] = R.Ray_ID;
                            Point Pt; double u = 0, v = 0, t = 0;
                            if (Model[top_index].intersect(i, R, out Pt, out u, out v, out t) && t > 0.0000000001)
                            {
                                X_LIST.Add(Pt);
                            }
                            ulist.Add(u); vlist.Add(v); tlist.Add(t); pidlist.Add(i);
                        }
                    }

                    for (int c = 0; c < X_LIST.Count; c++)
                    {
                        if (this.Voxels[X, Y, Z].IsPointInBox(X_LIST[c]))
                        {
                            int choice = c;
                            //Ret_Event = X_LIST[c];
                            for (int s = c; s < X_LIST.Count; s++)
                            {
                                if (tlist[s] < tlist[choice])
                                {
                                    choice = s;
                                    //Ret_Event = X_LIST[s];
                                }
                            }

                            Path_pts.Add(X_LIST[choice]);
                            t_list.Add(tlist[choice]);
                            Ret_Event = new X_Event_NH(Path_pts, ulist[choice], vlist[choice], t_list, pidlist[choice], Codes);
                            //Ret_Event.t += t_start;
                            return(true);
                        }
                    }

                    /////////////////////////////////////////
                    VPrev = Velocities[X, Y, Z];
                    /////////////////////////////////////////

                    //Find the Next Voxel...
                    /////////////////////////////////////////////////
                    if (tMaxX < tMaxY)
                    {
                        if (tMaxX < tMaxZ)
                        {
                            X += stepX;
                            if (X < 0 || X >= VoxelCtX)
                            {
                                Ret_Event = new X_Event();
                                return(false); /* outside grid */
                            }
                            tMaxX += tDeltaX;
                            if (VPrev != Velocities[X, Y, Z])
                            {
                                R.direction = XRefraction(R.direction, VPrev, Velocities[X, Y, Z]);
                                if (R.direction.x < 0)
                                {
                                    stepX = -1;
                                }
                                else
                                {
                                    stepX = 1;
                                }
                                if (R.direction.y < 0)
                                {
                                    stepY = -1;
                                }
                                else
                                {
                                    stepY = 1;
                                }
                                if (R.direction.z < 0)
                                {
                                    stepZ = -1;
                                }
                                else
                                {
                                    stepZ = 1;
                                }
                                tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                                tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                                tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                                t_list.Add(tDeltaX);
                                Codes.Add(VoxelCode(X, Y, Z));
                                R.origin += R.direction * tDeltaX;
                                Path_pts.Add(R.origin);
                                X_LIST.Clear();
                            }
                        }
                        else
                        {
                            Z += stepZ;

                            if (Z < 0 || Z >= VoxelCtZ)
                            {
                                Ret_Event = new X_Event();
                                return(false); /* outside grid */
                            }
                            tMaxZ += tDeltaZ;
                            if (VPrev != Velocities[X, Y, Z])
                            {
                                R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]);
                                if (R.direction.x < 0)
                                {
                                    stepX = -1;
                                }
                                else
                                {
                                    stepX = 1;
                                }
                                if (R.direction.y < 0)
                                {
                                    stepY = -1;
                                }
                                else
                                {
                                    stepY = 1;
                                }
                                if (R.direction.z < 0)
                                {
                                    stepZ = -1;
                                }
                                else
                                {
                                    stepZ = 1;
                                }
                                tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                                tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                                tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                                t_list.Add(tDeltaZ);
                                R.origin += R.direction * tDeltaZ;
                                Path_pts.Add(R.origin);
                                X_LIST.Clear();
                            }
                        }
                    }
                    else
                    {
                        if (tMaxY < tMaxZ)
                        {
                            Y += stepY;
                            if (Y < 0 || Y >= VoxelCtY)
                            {
                                Ret_Event = new X_Event();
                                return(false); /* outside grid */
                            }
                            tMaxY += tDeltaY;
                            if (VPrev != Velocities[X, Y, Z])
                            {
                                R.direction = YRefraction(R.direction, VPrev, Velocities[X, Y, Z]);
                                if (R.direction.x < 0)
                                {
                                    stepX = -1;
                                }
                                else
                                {
                                    stepX = 1;
                                }
                                if (R.direction.y < 0)
                                {
                                    stepY = -1;
                                }
                                else
                                {
                                    stepY = 1;
                                }
                                if (R.direction.z < 0)
                                {
                                    stepZ = -1;
                                }
                                else
                                {
                                    stepZ = 1;
                                }
                                tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                                tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                                tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                                t_list.Add(tDeltaY);
                                R.origin += R.direction * tDeltaY;
                                Path_pts.Add(R.origin);
                                X_LIST.Clear();
                            }
                        }
                        else
                        {
                            Z += stepZ;
                            if (Z < 0 || Z >= VoxelCtZ)
                            {
                                Ret_Event = new X_Event();
                                return(false); /* outside grid */
                            }
                            tMaxZ += tDeltaZ;

                            if (VPrev != Velocities[X, Y, Z])
                            {
                                R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]);
                                if (R.direction.x < 0)
                                {
                                    stepX = -1;
                                }
                                else
                                {
                                    stepX = 1;
                                }
                                if (R.direction.y < 0)
                                {
                                    stepY = -1;
                                }
                                else
                                {
                                    stepY = 1;
                                }
                                if (R.direction.z < 0)
                                {
                                    stepZ = -1;
                                }
                                else
                                {
                                    stepZ = 1;
                                }
                                tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                                tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                                tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                                t_list.Add(tDeltaZ);
                                R.origin += R.direction * tDeltaZ;
                                Path_pts.Add(R.origin);
                                X_LIST.Clear();
                            }
                        }
                    }
                }
            }
            /// <summary>
            /// Fire a ray into the model.
            /// </summary>
            /// <param name="R"> The ray to be entered. Make certain the Ray has a unique Ray_ID variable. </param>
            /// <param name="top_index"> Indicates the topology the ray is to intersect. </param>
            /// <param name="Ret_Event"> The nearest resulting intersection information, if any. </param>
            /// <returns> Indicates whether or not an intersection was found. </returns>
            public override bool Shoot(Ray R, int top_index, out X_Event Ret_Event)//, On3dPoint EndPt, int Octave_in)
            {
                int X, Y, Z;
                ////////////////////////
                double VPrev = 0;
                ////////////////////////
                //Identify whether the Origin is inside the voxel grid...
                //Identify which voxel the Origin point is located in...
                X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x) / VoxelDims.x);
                Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y) / VoxelDims.y);
                Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z) / VoxelDims.z);

                double tDeltaX, tDeltaY, tDeltaZ;
                double tMaxX = 0, tMaxY = 0, tMaxZ = 0;

                int stepX, stepY, stepZ, OutX, OutY, OutZ;
                double t_start = 0;

                if (X < 0 || X >= VoxelCtX || Y < 0 || Y >= VoxelCtY || Z < 0 || Z >= VoxelCtZ) //return false;
                {
                    if (!OBox.Intersect(R, ref t_start, ref R.origin))
                    {
                        Ret_Event = new X_Event();
                        return false; 
                    }
                    X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x + R.direction.x) / VoxelDims.x);
                    Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y + R.direction.y) / VoxelDims.y);
                    Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z + R.direction.z) / VoxelDims.z);
                }

                if (R.direction.x < 0)
                {
                    OutX = -1;
                    stepX = -1;
                    tMaxX = (float)((Voxels[X, Y, Z].Min_PT.x - R.origin.x) / R.direction.x);
                    tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                }
                else
                {
                    OutX = VoxelCtX;
                    stepX = 1;
                    tMaxX = (float)((Voxels[X, Y, Z].Max_PT.x - R.origin.x) / R.direction.x);
                    tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                }

                if (R.direction.y < 0)
                {
                    OutY = -1;
                    stepY = -1;
                    tMaxY = (float)((Voxels[X, Y, Z].Min_PT.y - R.origin.y) / R.direction.y);
                    tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                }
                else
                {
                    OutY = VoxelCtY;
                    stepY = 1;
                    tMaxY = (float)((Voxels[X, Y, Z].Max_PT.y - R.origin.y) / R.direction.y);
                    tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                }

                if (R.direction.z < 0)
                {
                    OutZ = -1;
                    stepZ = -1;
                    tMaxZ = (float)((Voxels[X, Y, Z].Min_PT.z - R.origin.z) / R.direction.z);
                    tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                }
                else
                {
                    OutZ = VoxelCtZ;
                    stepZ = 1;
                    tMaxZ = (float)((Voxels[X, Y, Z].Max_PT.z - R.origin.z) / R.direction.z);
                    tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                }

                List<double> t_list = new List<double>();
                List<int> Codes = new List<int>();
                List<Point> Path_pts = new List<Point>();
                List<int> voxelCodes = new List<int>();

                List<Point> X_LIST = new List<Point>();
                List<double> ulist = new List<double>();
                List<double> vlist = new List<double>();
                List<double> tlist = new List<double>();
                List<int> pidlist = new List<int>();

                while (true)
                {
                    //Check all polygons in the current voxel...
                    foreach (int i in Voxel_Inv[X, Y, Z, top_index])
                    {
                        if (Poly_Ray_ID[R.ThreadID, top_index][i] != R.Ray_ID)
                        {
                            Poly_Ray_ID[R.ThreadID, top_index][i] = R.Ray_ID;
                            Point Pt; double u=0, v=0, t=0;
                            if (Model[top_index].intersect(i, R, out Pt, out u, out v, out t) && t > 0.0000000001) X_LIST.Add(Pt); ulist.Add(u); vlist.Add(v); tlist.Add(t); pidlist.Add(i);
                        }
                    }

                    for (int c = 0; c < X_LIST.Count; c++)
                    {
                        if (this.Voxels[X, Y, Z].IsPointInBox(X_LIST[c]))
                        {
                            int choice = c;
                            //Ret_Event = X_LIST[c];
                            for (int s = c; s < X_LIST.Count; s++)
                            {
                                if (tlist[s] < tlist[choice])
                                {
                                    choice = s;
                                    //Ret_Event = X_LIST[s];
                                }
                            }

                            Path_pts.Add(X_LIST[choice]);
                            t_list.Add(tlist[choice]);
                            Ret_Event = new X_Event_NH(Path_pts, ulist[choice], vlist[choice], t_list, pidlist[choice], Codes);
                            //Ret_Event.t += t_start;
                            return true;
                        }
                    }

                    /////////////////////////////////////////
                    VPrev = Velocities[X, Y, Z];
                    /////////////////////////////////////////

                    //Find the Next Voxel...                    
                    /////////////////////////////////////////////////
                    if (tMaxX < tMaxY)
                    {
                        if (tMaxX < tMaxZ)
                        {
                            X += stepX;
                            if (X < 0 || X >= VoxelCtX)
                            {
                                Ret_Event = new X_Event();
                                return false; /* outside grid */
                            }
                            tMaxX += tDeltaX;
                            if (VPrev != Velocities[X, Y, Z])
                            {
                                R.direction = XRefraction(R.direction, VPrev, Velocities[X, Y, Z]);
                                if (R.direction.x < 0) { stepX = -1; }
                                else { stepX = 1; }
                                if (R.direction.y < 0) { stepY = -1; }
                                else { stepY = 1; }
                                if (R.direction.z < 0) { stepZ = -1; }
                                else { stepZ = 1; }
                                tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                                tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                                tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                                t_list.Add(tDeltaX);
                                Codes.Add(VoxelCode(X,Y,Z));
                                R.origin += R.direction * tDeltaX;
                                Path_pts.Add(R.origin);
                                X_LIST.Clear();
                            }
                        }
                        else
                        {
                            Z += stepZ;

                            if (Z < 0 || Z >= VoxelCtZ)
                            {
                                Ret_Event = new X_Event();
                                return false; /* outside grid */
                            }
                            tMaxZ += tDeltaZ;
                            if (VPrev != Velocities[X, Y, Z])
                            {
                                R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]);
                                if (R.direction.x < 0) { stepX = -1; }
                                else { stepX = 1; }
                                if (R.direction.y < 0) { stepY = -1; }
                                else { stepY = 1; }
                                if (R.direction.z < 0) { stepZ = -1; }
                                else { stepZ = 1; }
                                tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                                tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                                tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                                t_list.Add(tDeltaZ);
                                R.origin += R.direction * tDeltaZ;
                                Path_pts.Add(R.origin);
                                X_LIST.Clear();
                            }
                        }
                    }
                    else
                    {
                        if (tMaxY < tMaxZ)
                        {
                            Y += stepY;
                            if (Y < 0 || Y >= VoxelCtY)
                            {
                                Ret_Event = new X_Event();
                                return false; /* outside grid */
                            }
                            tMaxY += tDeltaY;
                            if (VPrev != Velocities[X, Y, Z])
                            {
                                R.direction = YRefraction(R.direction, VPrev, Velocities[X, Y, Z]);
                                if (R.direction.x < 0) { stepX = -1; }
                                else { stepX = 1; }
                                if (R.direction.y < 0) { stepY = -1; }
                                else { stepY = 1; }
                                if (R.direction.z < 0) { stepZ = -1; }
                                else { stepZ = 1; }
                                tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                                tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                                tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                                t_list.Add(tDeltaY);
                                R.origin += R.direction * tDeltaY;
                                Path_pts.Add(R.origin);
                                X_LIST.Clear();
                            }
                        }
                        else
                        {
                            Z += stepZ;
                            if (Z < 0 || Z >= VoxelCtZ)
                            {
                                Ret_Event = new X_Event();
                                return false; /* outside grid */
                            }
                            tMaxZ += tDeltaZ;

                            if (VPrev != Velocities[X, Y, Z])
                            {
                                R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]);
                                if (R.direction.x < 0) { stepX = -1; }
                                else { stepX = 1; }
                                if (R.direction.y < 0) { stepY = -1; }
                                else { stepY = 1; }
                                if (R.direction.z < 0) { stepZ = -1; }
                                else { stepZ = 1; }
                                tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX);
                                tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY);
                                tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ);
                                t_list.Add(tDeltaZ);
                                R.origin += R.direction * tDeltaZ;
                                Path_pts.Add(R.origin);
                                X_LIST.Clear();
                            }
                        }
                    }
                }
            }