/// <summary>
            /// Writes a Pac1 file. [Useable by scripts and interface components alike.]
            /// </summary>
            /// <param name="Direct_Data">Array of Completed Direct Sound Simulations Required</param>
            /// <param name="IS_Data">Array of Completed Image Source Simulations. Enter null if opted out.</param>
            /// <param name="Receiver">Array of Completed Ray-Tracing Simulation Receivers. Enter null if opted out.</param>
            public static void Write_Pac1(Direct_Sound[] Direct_Data, ImageSourceData[] IS_Data = null, Environment.Receiver_Bank[] Receiver = null)
            {
                System.Windows.Forms.SaveFileDialog sf = new System.Windows.Forms.SaveFileDialog();
                sf.DefaultExt = ".pac1";
                sf.AddExtension = true;
                sf.Filter = "Pachyderm Ray Data file (*.pac1)|*.pac1|" + "All Files|";

                if (sf.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    Write_Pac1(sf.FileName, Direct_Data, IS_Data, Receiver);
                }
            }
 public void GetSims(ref Direct_Sound[] D, ref ImageSourceData[] IS, ref Receiver_Bank[] RT)
 {
     if (Direct_Data != null) D = Direct_Data;
     if (IS_Data != null) IS = IS_Data;
     if (Receiver != null) RT = Receiver;
 }
            /// <summary>
            /// Approximation of the 5 second order ambisonics channels. (Fig8 3Axis and omni are the first four).
            /// </summary>
            /// <param name="Direct"></param>
            /// <param name="ISData"></param>
            /// <param name="RTData"></param>
            /// <param name="CO_Time"></param>
            /// <param name="Sampling_Frequency"></param>
            /// <param name="Rec_ID"></param>
            /// <param name="Start_at_Zero"></param>
            /// <param name="xpos_alt"></param>
            /// <param name="xpos_azi"></param>
            /// <param name="degrees"></param>
            /// <returns></returns>
            public static double[][] PTCurve_Ambisonics2(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Rec_ID, bool Start_at_Zero, double xpos_alt, double xpos_azi, bool degrees)
            {
                double[][] Histogram = new double[5][];
                if (RTData != null)
                {
                    double[][] hist_temp = RTData.Pressure_3Axis(Rec_ID);
                    Histogram[0] = new double[hist_temp[0].Length];
                    Histogram[1] = new double[hist_temp[0].Length];
                    Histogram[2] = new double[hist_temp[0].Length];
                    Histogram[3] = new double[hist_temp[0].Length];
                    Histogram[4] = new double[hist_temp[0].Length];
                    for (int i = 0; i < hist_temp[0].Length; i++)
                    {
                        Hare.Geometry.Vector Vpos = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(hist_temp[0][i], hist_temp[2][i], hist_temp[4][i]), xpos_azi, 0, true), 0, xpos_alt, true);
                        Hare.Geometry.Vector Vneg = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(-hist_temp[1][i], -hist_temp[3][i], -hist_temp[5][i]), xpos_azi, 0, true), 0, xpos_alt, true);
                        double magpos = Math.Sqrt(Vpos.x * Vpos.x + Vpos.y * Vpos.y + Vpos.z * Vpos.z);
                        double magneg = Math.Sqrt(Vneg.x * Vneg.x + Vneg.y * Vneg.y + Vneg.z * Vneg.z);
                        double phipos = Math.Asin(Vpos.z / magpos);
                        double phineg = Math.Asin(Vneg.z / magneg);
                        double thetapos = Math.Asin(Vpos.y / magpos / Math.Cos(phipos));
                        double thetaneg = Math.Asin(Vneg.y / magneg / Math.Cos(phineg));
                        double rt3_2 = Math.Sqrt(3) / 2;

                        double sin2phpos = Math.Sin(2 * phipos);
                        double sin2phneg = Math.Sin(2 * phineg);
                        double cossqphpos = Math.Cos(phipos) * Math.Cos(phipos);
                        double cossqphneg = Math.Cos(phineg) * Math.Cos(phineg);

                        Histogram[0][i] = magpos * (3 * (Math.Sin(phipos) * Math.Sin(phipos) - 1) / 2 + magneg * 3 * Math.Sin(phineg) * Math.Sin(phineg) - 1) / 2;
                        Histogram[1][i] = rt3_2 * (Math.Cos(thetapos) * sin2phpos * magpos + Math.Cos(thetaneg) * sin2phneg * magneg);
                        Histogram[2][i] = rt3_2 * (Math.Sin(thetapos) * sin2phpos * magpos + Math.Sin(thetaneg) * sin2phneg * magneg);
                        Histogram[3][i] = rt3_2 * (Math.Cos(2 * thetapos) * cossqphpos * magpos + Math.Cos(2 * thetaneg) * cossqphneg * magneg);
                        Histogram[4][i] = rt3_2 * (Math.Sin(2 * thetapos) * cossqphpos * magpos + Math.Sin(2 * thetaneg) * cossqphneg * magneg);
                    }
                }
                else
                {
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[4] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[5] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                }

                if (Direct != null && Direct.IsOccluded(Rec_ID))
                {
                    int D_Start = 0;
                    if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                    double[][] V = Direct.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, true);
                    for (int i = 0; i < V.Length; i++)
                    {
                        double mag = Math.Sqrt(V[i][0] * V[i][0] + V[i][1] * V[i][1] + V[i][2] * V[i][2]);
                        double phi = Math.Asin(V[i][2] / mag);
                        double theta = Math.Asin(V[i][1] / mag / Math.Cos(phi));
                        double rt3_2 = Math.Sqrt(3) / 2;

                        double sin2phi = Math.Sin(2 * phi);
                        double cossqphi = Math.Cos(phi) * Math.Cos(phi);

                        Histogram[0][i + D_Start] += mag * 3 * (Math.Sin(phi) * Math.Sin(phi) - 1) / 2;
                        Histogram[1][i + D_Start] += rt3_2 * Math.Cos(theta) * sin2phi * mag;
                        Histogram[2][i + D_Start] += rt3_2 * Math.Sin(theta) * sin2phi * mag;
                        Histogram[3][i + D_Start] += rt3_2 * Math.Cos(2 * theta) * cossqphi * mag;
                        Histogram[4][i + D_Start] += rt3_2 * Math.Sin(2 * theta) * cossqphi * mag;
                    }
                }

                if (ISData != null)
                {
                    foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                    {
                        if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                        {
                            int R_Start = (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);

                            double[][] V = value.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, Sampling_Frequency);

                            Hare.Geometry.Vector dir = value.Path[0][value.Path[0].Length - 1] - value.Path[0][value.Path[0].Length - 2];
                            dir.Normalize();
                            for (int i = 0; i < V.Length; i++)
                            {
                                double mag = Math.Sqrt(V[i][0] * V[i][0] + V[i][1] * V[i][1] + V[i][2] * V[i][2]);
                                double phi = Math.Asin(V[i][2] / mag);
                                double theta = Math.Asin(V[i][1] / mag / Math.Cos(phi));
                                double rt3_2 = Math.Sqrt(3) / 2;

                                double sin2phi = Math.Sin(2 * phi);
                                double cossqphi = Math.Cos(phi) * Math.Cos(phi);

                                Histogram[0][i + R_Start] += mag * 3 * (Math.Sin(phi) * Math.Sin(phi) - 1) / 2;
                                Histogram[1][i + R_Start] += rt3_2 * Math.Cos(theta) * sin2phi * mag;
                                Histogram[2][i + R_Start] += rt3_2 * Math.Sin(theta) * sin2phi * mag;
                                Histogram[3][i + R_Start] += rt3_2 * Math.Cos(2 * theta) * cossqphi * mag;
                                Histogram[4][i + R_Start] += rt3_2 * Math.Sin(2 * theta) * cossqphi * mag;
                            }
                        }
                    }
                }
                return Histogram;
            }
            public static double[][] PTCurve_Ambisonics3(IEnumerable<Direct_Sound> Direct, IEnumerable<ImageSourceData> ISData, IEnumerable<Environment.Receiver_Bank> RTData, double CO_Time_ms, int Sampling_Frequency, int Rec_ID, List<int> SrcIDs, bool StartAtZero, double alt, double azi, bool degrees)
            {
                double[][] Histogram = new double[7][];

                    if (Direct == null) Direct = new Direct_Sound[SrcIDs[SrcIDs.Count - 1] + 1];
                    if (ISData == null) ISData = new ImageSourceData[SrcIDs[SrcIDs.Count - 1] + 1];
                    if (RTData == null) RTData = new Environment.Receiver_Bank[SrcIDs[SrcIDs.Count - 1] + 1];

                    double maxdelay = 0;
                    List<double> delays = new List<double>();

                    if (Direct.ElementAt<Direct_Sound>(0) != null)
                    {
                        foreach (Direct_Sound d in Direct)
                        {
                            delays.Add(d.Delay_ms);
                            maxdelay = Math.Max(maxdelay, d.Delay_ms);
                        }
                    }
                    else if (RTData.ElementAt<Receiver_Bank>(0) != null)
                    {
                        foreach (Receiver_Bank r in RTData)
                        {
                            delays.Add(r.delay_ms);
                            maxdelay = Math.Max(maxdelay, r.delay_ms);
                        }
                    }
                    maxdelay *= Sampling_Frequency / 1000;

                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096 + (int)Math.Ceiling(maxdelay)];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096 + (int)Math.Ceiling(maxdelay)];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096 + (int)Math.Ceiling(maxdelay)];
                    Histogram[3] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096 + (int)Math.Ceiling(maxdelay)];
                    Histogram[4] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096 + (int)Math.Ceiling(maxdelay)];
                    Histogram[5] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096 + (int)Math.Ceiling(maxdelay)];
                    Histogram[6] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096 + (int)Math.Ceiling(maxdelay)];

                    foreach (int s in SrcIDs)
                    {
                        double[][] IR = PTCurve_Ambisonics3(Direct.ElementAt<Direct_Sound>(s), ISData.ElementAt<ImageSourceData>(s), RTData.ElementAt<Receiver_Bank>(s), CO_Time_ms, Sampling_Frequency, Rec_ID, StartAtZero, alt, azi, degrees);
                        for (int d = 0; d < IR.Length; d++)
                        {
                            for (int i = 0; i < IR[0].Length; i++)
                            {
                                Histogram[d][i + (int)Math.Ceiling(delays[s] / 1000 * Sampling_Frequency)] += IR[d][i];
                            }
                        }
                    }

                    return Histogram;
            }
            public static double[][] PTCurve_Fig8_3Axis(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Rec_ID, bool Start_at_Zero, double xpos_alt, double xpos_azi, bool degrees)
            {
                double[][] Histogram = new double[3][];
                if (RTData != null)
                {
                    double[][] hist_temp = RTData.Pressure_3Axis(Rec_ID);
                    Histogram[0] = new double[hist_temp[0].Length];
                    Histogram[1] = new double[hist_temp[0].Length];
                    Histogram[2] = new double[hist_temp[0].Length];
                    for (int i = 0; i < hist_temp[0].Length; i++)
                    {
                        Hare.Geometry.Vector V = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(hist_temp[0][i] - hist_temp[1][i], hist_temp[2][i] - hist_temp[3][i], hist_temp[4][i] - hist_temp[5][i]), xpos_azi, 0, true), 0, xpos_alt, true);
                        Histogram[0][i] = V.x;
                        Histogram[1][i] = V.y;
                        Histogram[2][i] = V.z;
                    }
                }
                else
                {
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                }

                if (Direct != null && Direct.IsOccluded(Rec_ID))
                {
                    int D_Start = 0;
                    if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                    double[][] V = Direct.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, true);
                    for (int i = 0; i < V.Length; i++)
                    {
                        Histogram[0][D_Start + i] += V[i][0];
                        Histogram[1][D_Start + i] += V[i][1];
                        Histogram[2][D_Start + i] += V[i][2];
                    }
                }

                if (ISData != null)
                {
                    foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                    {
                        if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                        {
                            int R_Start = (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);

                            double[][] V = value.Dir_Pressure(Rec_ID, xpos_alt, xpos_azi, degrees, Sampling_Frequency);

                            Hare.Geometry.Vector dir = value.Path[0][value.Path[0].Length - 1] - value.Path[0][value.Path[0].Length - 2];
                            dir.Normalize();
                            for (int i = 0; i < value.Pressure.Length; i++)
                            {
                                Histogram[0][R_Start + i] += V[i][0];
                                Histogram[1][R_Start + i] += V[i][1];
                                Histogram[2][R_Start + i] += V[i][2];
                            }
                        }
                    }
                }
                return Histogram;
            }
            /// <summary>
            /// Writes a Pac1 file. [Useable by scripts and interface components alike.]
            /// </summary>
            /// <param name="filename">The location of the final saved file...</param>
            /// <param name="Direct_Data">Array of Completed Direct Sound Simulations Required</param>
            /// <param name="IS_Data">Array of Completed Image Source Simulations. Enter null if opted out.</param>
            /// <param name="Receiver">Array of Completed Ray-Tracing Simulation Receivers. Enter null if opted out.</param>
            public static void Write_Pac1(string filename, Direct_Sound[] Direct_Data, ImageSourceData[] IS_Data = null, Environment.Receiver_Bank[] Receiver = null)
            {
                if (Direct_Data == null && IS_Data == null && IS_Data == null && Receiver != null)
                {
                    System.Windows.Forms.MessageBox.Show("There is no simulated data to save.");
                    return;
                }

                Pachyderm_Acoustic.UI.PachydermAc_PlugIn plugin = Pachyderm_Acoustic.UI.PachydermAc_PlugIn.Instance;

                System.IO.FileStream file = System.IO.File.Open(filename, System.IO.FileMode.Create);
                if (file.CanWrite)
                {
                    System.IO.BinaryWriter sw = new System.IO.BinaryWriter(file);
                    //1. Date & Time
                    sw.Write(System.DateTime.Now.ToString());
                    //2. Plugin Version... if less than 1.1, assume only 1 source.
                    sw.Write(plugin.Version);
                    //3. Cut off Time (seconds) and SampleRate
                    sw.Write((double)Receiver[0].CO_Time);//CO_TIME.Value);
                    sw.Write(Receiver[0].SampleRate);
                    //4.0 Source Count(int)
                    Rhino.Geometry.Point3d[] SRC;
                    plugin.SourceOrigin(out SRC);
                    sw.Write(SRC.Length);
                    for (int i = 0; i < SRC.Length; i++)
                    {
                        //4.1 Source Location x (double)
                        sw.Write(SRC[i].X);
                        //4.2 Source Location y (double)
                        sw.Write(SRC[i].Y);
                        //4.3 Source Location z (double)
                        sw.Write(SRC[i].Z);
                    }
                    //5. No of Receivers
                    sw.Write(Receiver[0].Rec_List.Length);

                    //6. Write the coordinates of each receiver point
                    //6b. Write the environmental characteristics at each receiver point (Rho * C); V2.0 only...
                    for (int q = 0; q < Receiver[0].Rec_List.Length; q++)
                    {
                        sw.Write(Receiver[0].Rec_List[q].H_Origin.x);
                        sw.Write(Receiver[0].Rec_List[q].H_Origin.y);
                        sw.Write(Receiver[0].Rec_List[q].H_Origin.z);
                        sw.Write(Receiver[0].Rec_List[q].Rho_C);
                    }

                    for (int s = 0; s < SRC.Length; s++)
                    {
                        if (Direct_Data != null)
                        {
                            //7. Write Direct Sound Data
                            Direct_Data[s].Write_Data(ref sw);
                        }

                        if (IS_Data[0] != null)
                        {
                            //8. Write Image Source Sound Data
                            IS_Data[s].Write_Data(ref sw);
                        }

                        if (Receiver != null)
                        {
                            //9. Write Ray Traced Sound Data
                            Receiver[s].Write_Data(ref sw);
                        }
                    }
                    sw.Write("End");
                    sw.Close();
                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("Cannot write to file. It may be open in another application.");
                    return;
                }
            }
            public static bool Read_Pac1(string filename, ref Direct_Sound[] Direct_Data, ref ImageSourceData[] IS_Data, ref Environment.Receiver_Bank[] Receiver)
            {
                System.IO.BinaryReader sr = new System.IO.BinaryReader(System.IO.File.Open(filename, System.IO.FileMode.Open));
                try
                {
                    //1. Date & Time
                    string Savedate = sr.ReadString();
                    //2. Plugin Version
                    string Pach_version = sr.ReadString();
                    //3. Cut off Time and SampleRate
                    double CO_TIME = sr.ReadDouble();
                    int SampleRate = sr.ReadInt32();
                    //4. Source Count
                    int SrcCt = 1;
                    if (double.Parse(Pach_version.Substring(0, 3)) >= 1.1) SrcCt = sr.ReadInt32();
                    //4.1 Source Location x
                    //4.2 Source Location y
                    //4.3 Source Location z
                    Hare.Geometry.Point[] SrcPt = new Hare.Geometry.Point[SrcCt];
                    for (int s = 0; s < SrcCt; s++) SrcPt[s] = new Hare.Geometry.Point(sr.ReadDouble(), sr.ReadDouble(), sr.ReadDouble());
                    //5. No of Receivers
                    int Rec_Ct = sr.ReadInt32();
                    //6. Write the coordinates of each receiver point
                    //6b. Write the environmental characteristics at each receiver point (Rho * C); V2.0 only...
                    Hare.Geometry.Point[] Recs = new Hare.Geometry.Point[Rec_Ct];
                    double[] Rho_C = new double[Rec_Ct];
                    for (int q = 0; q < Rec_Ct; q++)
                    {
                        Recs[q] = new Hare.Geometry.Point(sr.ReadDouble(), sr.ReadDouble(), sr.ReadDouble());
                        if (double.Parse(Pach_version.Substring(0, 3)) >= 2.0) Rho_C[q] = sr.ReadDouble();
                        else Rho_C[q] = 400;
                    }

                    Direct_Data = new Direct_Sound[SrcCt];
                    IS_Data = new ImageSourceData[SrcCt];
                    Receiver = new Environment.Receiver_Bank[SrcCt];

                    int DDCT = 0;
                    int ISCT = 0;
                    int RTCT = 0;
                    do
                    {
                        string readin = sr.ReadString();
                        switch (readin)
                        {
                            case "Direct_Sound":
                            case "Direct_Sound w sourcedata":
                                //9. Read Direct Sound Data
                                Direct_Data[DDCT] = Direct_Sound.Read_Data(ref sr, Recs, SrcPt[DDCT], Rho_C, Pach_version);
                                Direct_Data[DDCT].CO_Time = CO_TIME;
                                Direct_Data[DDCT].SampleFreq = (int)SampleRate;
                                DDCT++;
                                break;
                            case "Image-Source_Data":
                                //10. Read Image Source Sound Data
                                IS_Data[ISCT] = ImageSourceData.Read_Data(ref sr, Recs.Length, Direct_Data[DDCT - 1], false, ISCT, Pach_version);
                                ISCT++;
                                break;
                            case "Ray-Traced_Data":
                                //11. Read Ray Traced Sound Data
                                Receiver[RTCT] = Environment.Receiver_Bank.Read_Data(ref sr, Rec_Ct, Recs, Rho_C, Direct_Data[RTCT].Delay_ms, ref SampleRate, Pach_version);
                                RTCT++;
                                break;
                            case "End":
                                sr.Close();
                                return true;
                        }
                    } while (true);
                }
                catch (System.Exception X)
                {
                    sr.Close();
                    System.Windows.Forms.MessageBox.Show("File Read Failed...", String.Format("Results file was corrupt or incomplete. We apologize for this inconvenience. Please report this to the software author. It will be much appreciated. \r\n Exception Message: {0}. \r\n Method: {1}" , X.Message, X.TargetSite));
                    return false;
                }
            }
            /// <summary>
            /// Takes ETC, and extrapolates a pressure domain impulse response.
            /// </summary>
            /// <param name="DirectIn"></param>
            /// <param name="SpecularIn"></param>
            /// <param name="DiffuseIn"></param>
            /// <param name="CutOffTime"></param>
            /// <param name="sample_frequency_out">The desired sample frequency.</param>
            /// <param name="Rec_ID">The index of the receiver.</param>
            /// <returns></returns>
            public static double[] Expand_Dir_Response(Direct_Sound[] DirectIn, ImageSourceData[] SpecularIn, Environment.Receiver_Bank[] DiffuseIn, double CutOffTime, int sample_frequency_out, int Rec_ID, List<int> SrcID, double alt, double azi, bool degrees)
            {
                Random Rnd = new Random();
                int length = (int)Math.Pow(2, 11);
                int sample_frequency_in = DiffuseIn[0].SampleRate;
                //fftwlib.fftw. FFT = new MathNet.Numerics.IntegralTransforms.Algorithms.DiscreteFourierTransform();
                double[] IR = new double[(int)Math.Floor(sample_frequency_out * CutOffTime) + 2 * (int)length];
                double[][] Octave_ETC = new double[8][];
                double BW = (double)sample_frequency_out / (double)sample_frequency_in;

                //Convert to Pressure & Interpolate full resolution IR
                for (int oct = 0; oct < 8; oct++)
                {
                    Octave_ETC[oct] = AcousticalMath.ETCurve_Directional(DirectIn, SpecularIn, DiffuseIn, CutOffTime, sample_frequency_in, oct, Rec_ID, SrcID, false, alt, azi, degrees);
                }

                return ETCToPTC(Octave_ETC, CutOffTime, sample_frequency_in, sample_frequency_out, DirectIn[0].Rho_C[Rec_ID]);
            }
            public static double[] PTCurve(Direct_Sound Direct, ImageSourceData ISData, Environment.Receiver_Bank RTData, double CO_Time_ms, int samplerate, int Octave, int Rec_ID, bool StartAtZero, Numerics.ComplexComponent Output_Type)
            {
                Direct_Sound[] ArrDirect = new Direct_Sound[1];
                    ArrDirect[0] = Direct;
                    ImageSourceData[] ArrIS = new ImageSourceData[1];
                    ArrIS[0] = ISData;
                    Environment.Receiver_Bank[] ArrRT = new Environment.Receiver_Bank[1];
                    ArrRT[0] = RTData;

                    double[] P;
                    PTCurve(ArrDirect, ArrIS, ArrRT, CO_Time_ms*0.001, samplerate, Rec_ID, 0, StartAtZero, out P);

                    double[] Pressure = new double[P.Length];
                    for (int i = 0; i < Pressure.Length; i++) Pressure[i] = P[i];
                    return Pressure;
            }
 public static double[] ETCurve(Direct_Sound Direct, ImageSourceData ISData, Environment.Receiver_Bank RTData, double CO_Time_ms, int samplerate, int Octave, int Rec_ID, bool StartAtZero)
 {
     Direct_Sound[] ArrDirect = new Direct_Sound[1];
         ArrDirect[0] = Direct;
         ImageSourceData[] ArrIS = new ImageSourceData[1];
         ArrIS[0] = ISData;
         Receiver_Bank[] ArrRT = new Environment.Receiver_Bank[1];
         ArrRT[0] = RTData;
         return ETCurve(ArrDirect, ArrIS, ArrRT, CO_Time_ms, samplerate, Octave, Rec_ID, 0, StartAtZero);
 }
            public static double[] PTCurve(Direct_Sound[] Direct, ImageSourceData[] ISData, Environment.Receiver_Bank[] RTData, double CO_Time_ms, int Sampling_Frequency, int Rec_ID, List<int> SrcIDs, bool StartAtZero)
            {
                if (Direct == null) Direct = new Direct_Sound[SrcIDs[SrcIDs.Count - 1] + 1];
                    if (ISData == null) ISData = new ImageSourceData[SrcIDs[SrcIDs.Count - 1] + 1];
                    if (RTData == null) RTData = new Environment.Receiver_Bank[SrcIDs[SrcIDs.Count - 1] + 1];

                    double maxdelay = 0;

                    List<double> delays = new List<double>();

                    if (Direct.ElementAt<Direct_Sound>(0) != null)
                    {
                        foreach (Direct_Sound d in Direct)
                        {
                            delays.Add(d.Delay_ms);
                            maxdelay = Math.Max(maxdelay, d.Delay_ms);
                        }
                    }
                    else if (RTData.ElementAt<Receiver_Bank>(0) != null)
                    {
                        foreach (Receiver_Bank r in RTData)
                        {
                            delays.Add(r.delay_ms);
                            maxdelay = Math.Max(maxdelay, r.delay_ms);
                        }
                    }

                    maxdelay *= Sampling_Frequency / 1000;

                    double[] Histogram = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096*2 + (int)Math.Ceiling(maxdelay)];

                    foreach (int s in SrcIDs)
                    {
                        double[] P;
                        PTCurve(Direct, ISData, RTData, CO_Time_ms, Sampling_Frequency, Rec_ID, s, StartAtZero, out P);
                        for (int i = 0; i < P.Length; i++)
                        {
                            Histogram[i + (int)Math.Ceiling(delays[s] /1000 * Sampling_Frequency)] += P[i];
                        }
                    }
                    return Histogram;
            }
            public static double[] SPLTCurve_Pressure(Direct_Sound[] Direct, ImageSourceData[] ISData, Environment.Receiver_Bank[] RTData, double CO_Time, int samplerate, int Octave, int Rec_ID, int SrcID, bool Start_at_Zero)
            {
                double[] P;//, Imag;
                    PTCurve(Direct, ISData, RTData, CO_Time, samplerate, Rec_ID, SrcID, Start_at_Zero, out P);//, out Imag);
                    float[] Pressure = new float[P.Length];

                    double[] SPL = new double[Pressure.Length];

                    for (int i = 0; i < Pressure.Length; i++)
                    {
                        SPL[i] = SPL_Pressure(Pressure[i]);
                    }
                    return SPL;
            }
            /// <summary>
            /// Calculates SPL-time curve from simulation output.
            /// </summary>
            /// <param name="Direct"></param>
            /// <param name="ISData"></param>
            /// <param name="RTData"></param>
            /// <param name="CO_Time"></param>
            /// <param name="samplerate"></param>
            /// <param name="Octave">the chosen octave band.</param>
            /// <param name="Rec_ID">the id of the selected receiver.</param>
            /// <returns></returns>
            public static double[] SPLTCurve_Intensity(Direct_Sound[] Direct, ImageSourceData[] ISData, Environment.Receiver_Bank[] RTData, double CO_Time, int samplerate, int Octave, int Rec_ID, int SrcID, bool Start_at_Zero)
            {
                double[] Energy = ETCurve(Direct, ISData, RTData, CO_Time, samplerate, Octave, Rec_ID, SrcID, Start_at_Zero);
                    double[] SPL = new double[Energy.Length];

                    for (int i = 0; i < Energy.Length; i++)
                    {
                        SPL[i] = SPL_Intensity(Energy[i]);
                    }
                    return SPL;
            }
            public static double[] PTCurve_Directional(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[] Histogram;
                if (RTData != null)
                {
                    int[] ids = new int[3];
                    ids[0] = (azi > 90 && azi < 270) ? 1 : 0;
                    ids[0] = (azi <= 180) ? 3 : 4;
                    ids[0] = (alt > 0) ? 4 : 5;
                    double[][] hist_temp = RTData.Pressure_3Axis(Rec_ID);
                    Histogram = new double[hist_temp[0].Length];
                    for (int i = 0; i < hist_temp[0].Length; i++)
                    {
                        Hare.Geometry.Vector V = PachTools.Rotate_Vector(PachTools.Rotate_Vector(new Hare.Geometry.Vector(hist_temp[ids[0]][i], hist_temp[ids[1]][i], hist_temp[ids[2]][i]), azi, 0, true), 0, alt, true);
                        Histogram[i] = V.x;
                    }
                }
                else
                {
                    Histogram = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency) + 4096];
                }

                if (Direct != null && Direct.IsOccluded(Rec_ID))
                {
                    int D_Start = 0;
                    if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                    double[][] V = Direct.Dir_Pressure(Rec_ID, alt, azi, degrees, false);
                    for (int i = 0; i < V.Length; i++)
                    {
                        Histogram[D_Start + i] += V[i][0];
                    }
                }

                if (ISData != null)
                {
                    foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                    {
                        if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                        {
                            int R_Start = (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);

                            double[] V = value.Dir_Pressure(Rec_ID, alt, azi, degrees, false, Sampling_Frequency);
                            for (int i = 0; i < value.Pressure.Length; i++)
                            {
                                Histogram[R_Start + i] += V[i];
                            }
                        }
                    }
                }
                return Histogram;
            }
            public void GetSims(ref Hare.Geometry.Point[] Src, ref Hare.Geometry.Point[] Rec, ref Direct_Sound[] D, ref ImageSourceData[] IS, ref Receiver_Bank[] RT)
            {
                Src = new Hare.Geometry.Point[Source.Length];
                for (int i = 0; i < Source.Length; i++) Src[i] = Source[i].H_Origin();
                Rec = Recs;

                if (Direct_Data != null) D = Direct_Data;
                if (IS_Data != null) IS = IS_Data;
                if (Receiver != null) RT = Receiver;
            }
            public static double[] Expand_Response(Direct_Sound[] DirectIn, ImageSourceData[] SpecularIn, Environment.Receiver_Bank[] DiffuseIn, double CutOffTime, int sample_frequency_out, int Rec_ID, List<int> SrcID)
            {
                int length = (int)Math.Pow(2, 11);
                int sample_frequency_in = DiffuseIn[0].SampleRate;
                double[] IR = new double[(int)Math.Floor(sample_frequency_out * CutOffTime) + 2 * (int)length];
                double[][] Octave_ETC = new double[8][];
                double BW = (double)sample_frequency_out / (double)sample_frequency_in;

                //Convert to Pressure & Interpolate full resolution IR
                for (int oct = 0; oct < 8; oct++)
                {
                    Octave_ETC[oct] = AcousticalMath.ETCurve(DirectIn, SpecularIn, DiffuseIn, CutOffTime, sample_frequency_in, oct, Rec_ID, SrcID, false);
                }

                return ETCToPTC(Octave_ETC, CutOffTime, sample_frequency_in, sample_frequency_out, DirectIn[0].Rho_C[Rec_ID]);
            }
            /// <summary>
            /// Calculates Energy-time curve from simulation output.
            /// </summary>
            /// <param name="Direct"></param>
            /// <param name="ISData"></param>
            /// <param name="RTData"></param>
            /// <param name="CO_Time"></param>
            /// <param name="Sampling_Frequency"></param>
            /// <param name="Octave">the chosen octave band.</param>
            /// <param name="Rec_ID">the id of the selected receiver.</param>
            /// <returns></returns>
            public static double[] ETCurve(Direct_Sound[] Direct, ImageSourceData[] ISData, Environment.Receiver_Bank[] RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, int Src_ID, bool Start_at_Zero)
            {
                double[] Histogram = null;
                    if (RTData[Src_ID] != null)
                    {
                        Histogram = RTData[Src_ID].GetEnergyHistogram(Octave, Rec_ID);
                    }
                    else
                    {
                        Histogram = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    }

                    if (Direct[Src_ID] != null && Direct[Src_ID].IsOccluded(Rec_ID))
                    {
                        int D_Start = 0;
                        if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct[Src_ID].Time(Rec_ID) * Sampling_Frequency);
                        for (int i = 0; i < Direct[Src_ID].Io[Rec_ID].GetLength(0); i++)
                        {
                            double DirectValue = 0;
                            switch (Octave)
                            {
                                case 8:
                                    DirectValue = Direct[Src_ID].EnergySum(Rec_ID,i);
                                    break;
                                default:
                                    DirectValue = Direct[Src_ID].EnergyValue(Octave, Rec_ID)[i];
                                    break;
                            }
                            Histogram[D_Start + i] += DirectValue;
                        }
                    }

                    if (ISData[Src_ID] != null)
                    {
                        switch (Octave)
                        {
                            case 8:
                                foreach (Deterministic_Reflection value in ISData[Src_ID].Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                                    {
                                        for (int oct = 0; oct < 8; oct++)
                                        {
                                            double[] e = value.Energy(oct);
                                            for (int t = 0; t < e.Length; t++) Histogram[(int)Math.Ceiling(Sampling_Frequency * value.TravelTime) + t] += e[t];
                                        }
                                    }
                                }
                                break;
                            default:
                                foreach (Deterministic_Reflection value in ISData[Src_ID].Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                                    {
                                        double[] e = value.Energy(Octave);
                                        for(int t = 0; t < e.Length; t++) Histogram[(int)Math.Ceiling(Sampling_Frequency * value.TravelTime) + t] += e[t];
                                    }
                                }
                                break;
                        }
                    }
                    return Histogram;
            }
            /// <summary>
            /// Writes a Pac1 file. [Useable by scripts and interface components alike.]
            /// </summary>
            /// <param name="Direct_Data">Empty array of Direct Sound Simulations Required</param>
            /// <param name="IS_Data">Empty array of Image Source Simulations. Enter null if opted out.</param>
            /// <param name="Receiver">Empty array of Ray-Tracing Simulation Receivers. Enter null if opted out.</param>
            public static bool Read_Pac1(ref Direct_Sound[] Direct_Data, ref ImageSourceData[] IS_Data, ref Environment.Receiver_Bank[] Receiver)
            {
                System.Windows.Forms.OpenFileDialog sf = new System.Windows.Forms.OpenFileDialog();
                    sf.DefaultExt = ".pac1";
                    sf.AddExtension = true;
                    sf.Filter = "Pachyderm Simulation (*.pac1)|*.pac1|" + "All Files|";
                    if (sf.ShowDialog() != System.Windows.Forms.DialogResult.OK) return false;

                    return Read_Pac1(sf.FileName, ref Direct_Data, ref IS_Data, ref Receiver);
            }
            /// <summary>
            /// Calculates pressure impulse response from simulation output.
            /// </summary>
            /// <param name="Direct"></param>
            /// <param name="ISData"></param>
            /// <param name="RTData"></param>
            /// <param name="CO_Time"></param>
            /// <param name="Sampling_Frequency"></param>
            /// <param name="Octave">the chosen octave band.</param>
            /// <param name="Rec_ID">the id of the selected receiver.</param>
            /// <returns></returns>
            public static void PTCurve(Direct_Sound[] Direct, ImageSourceData[] ISData, Environment.Receiver_Bank[] RTData, double CO_Time_ms, int Sampling_Frequency, int Rec_ID, int Src_ID, bool Start_at_Zero, out double[] P)
            {
                if (RTData[Src_ID] != null)
                    {
                        RTData[Src_ID].GetPressure(Rec_ID, out P);//8,
                    }
                    else
                    {
                        P = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    }

                    if (Direct[Src_ID] != null && Direct[Src_ID].IsOccluded(Rec_ID))
                    {
                        int D_Start = 0;
                        if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct[Src_ID].Time(Rec_ID) * Sampling_Frequency);

                        for (int i = 0; i < Direct[Src_ID].P[Rec_ID].GetLength(0); i++)
                        {
                            P[D_Start + i] += Direct[Src_ID].P[Rec_ID][i];
                        }
                    }

                    if (ISData[Src_ID] != null)
                    {
                        foreach (Deterministic_Reflection value in ISData[Src_ID].Paths[Rec_ID])
                        {
                            if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < P.Length - 1)
                            {
                                int end = value.Pressure.Length < P.Length - (int)Math.Ceiling(Sampling_Frequency * value.TravelTime) ? value.Pressure.Length : P.Length - (int)Math.Ceiling(Sampling_Frequency * value.TravelTime);
                                for (int t = 0; t < end; t++) P[(int)Math.Ceiling(Sampling_Frequency * value.TravelTime) + t] += (float)value.Pressure[t];
                            }
                        }
                    }
            }
            public static double[][] ETCurve_1d(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[][] Histogram = new double[3][];
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    if (RTData != null)
                    {
                        for (int i = 0; i < Histogram[0].Length; i++)
                        {
                            Hare.Geometry.Vector Vpos = RTData.Directions_Pos(Octave, i, Rec_ID, alt, azi, degrees);
                            Hare.Geometry.Vector Vneg = RTData.Directions_Neg(Octave, i, Rec_ID, alt, azi, degrees);

                            double E = RTData.Rec_List[Rec_ID].Energy(i, Octave);
                            Hare.Geometry.Vector VTot = new Hare.Geometry.Vector(Math.Abs(Vpos.x) - Math.Abs(Vneg.x), Math.Abs(Vpos.y) - Math.Abs(Vneg.y), Math.Abs(Vpos.z) - Math.Abs(Vneg.z));
                            VTot.Normalize();
                            VTot *= E;

                            Histogram[0][i] = VTot.x;
                            Histogram[1][i] = VTot.y;
                            Histogram[2][i] = VTot.z;
                        }
                    }

                    if (Direct != null && Direct.IsOccluded(Rec_ID))
                    {
                        int D_Start = 0;
                        if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                        Hare.Geometry.Vector[] DirectValue;
                        switch (Octave)
                        {
                            case 8:
                                DirectValue = Direct.Dir_Energy_Sum(Rec_ID, alt, azi, degrees);
                                break;
                            default:
                                DirectValue = Direct.Dir_Energy(Octave, Rec_ID, alt, azi, degrees);
                                break;
                        }

                        for (int i = 0; i < DirectValue.Length; i++)
                        {
                            Histogram[0][D_Start + i] += Math.Abs(DirectValue[i].x);
                            Histogram[1][D_Start + i] += Math.Abs(DirectValue[i].y);
                            Histogram[2][D_Start + i] += Math.Abs(DirectValue[i].z);
                        }
                    }

                    if (ISData != null)
                    {
                        switch (Octave)
                        {
                            case 8:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Sum = value.Dir_EnergySum(alt, azi, degrees);
                                        for (int i = 0; i < E_Sum.Length; i++)
                                        {
                                            Histogram[0][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].x);
                                            Histogram[1][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].y);
                                            Histogram[2][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].z);
                                        }
                                    }
                                }
                                break;
                            default:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Dir = value.Dir_Energy(Octave, alt, azi, degrees);
                                        for (int i = 0; i < E_Dir.Length; i++)
                                        {
                                            Histogram[0][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].x);
                                            Histogram[1][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].y);
                                            Histogram[2][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].z);
                                        }
                                    }
                                }
                                break;
                        }
                    }
                    return Histogram;
            }
            public static double[] ETCurve_Directional(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[] Histogram = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    if (RTData != null)
                    {
                        for (int i = 0; i < Histogram.Length; i++)
                        {
                            Hare.Geometry.Vector Vpos = RTData.Directions_Pos(Octave, i, Rec_ID, alt, azi, degrees);
                            Hare.Geometry.Vector Vneg = RTData.Directions_Neg(Octave, i, Rec_ID, alt, azi, degrees);

                            double E = RTData.Rec_List[Rec_ID].Energy(i, Octave);
                            Hare.Geometry.Vector VTot = new Hare.Geometry.Vector(Math.Abs(Vpos.x) - Math.Abs(Vneg.x), Math.Abs(Vpos.y) - Math.Abs(Vneg.y), Math.Abs(Vpos.z) - Math.Abs(Vneg.z));

                            if (Vpos.x > 0)
                            {
                                Histogram[i] += Math.Abs(Vpos.x);
                            }
                            if (Vneg.x > 0)
                            {
                                Histogram[i] += Math.Abs(Vneg.x);
                            }

                            double L = VTot.Length();
                            if (L > 0) Histogram[i] *= E / L;

                            if (AcousticalMath.SPL_Intensity(Histogram[i]) > 200)
                            {
                                Rhino.RhinoApp.Write("Super high SPLs... what's going on, man?");
                            }
                        }
                    }

                    if (Direct != null && Direct.IsOccluded(Rec_ID))
                    {
                        int D_Start = 0;
                        if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                        Hare.Geometry.Vector[] DirectValue;
                        switch (Octave)
                        {
                            case 8:
                                DirectValue = Direct.Dir_Energy_Sum(Rec_ID, alt, azi, degrees);
                                break;
                            default:
                                DirectValue = Direct.Dir_Energy(Octave, Rec_ID, alt, azi, degrees);
                                break;
                        }

                        for (int i = 0; i < DirectValue.Length; i++)
                        {
                            if (DirectValue[i].x > 0) Histogram[D_Start + i] += Math.Abs(DirectValue[i].x);
                        }
                    }

                    if (ISData != null)
                    {
                        switch (Octave)
                        {
                            case 8:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Sum = value.Dir_EnergySum(alt, azi, degrees);
                                        for (int i = 0; i < E_Sum.Length; i++)
                                        {
                                            if (E_Sum[i].x > 0) Histogram[(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i)] += Math.Abs(E_Sum[i].x);
                                        }
                                    }
                                }
                                break;
                            default:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram.Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Dir = value.Dir_Energy(Octave, alt, azi, degrees);
                                        for (int i = 0; i < E_Dir.Length; i++)
                                        {
                                            if (E_Dir[i].x > 0) Histogram[(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i)] += Math.Abs(E_Dir[i].x);
                                        }
                                    }
                                }
                                break;
                        }
                    }
                    return Histogram;
            }
Esempio n. 22
0
            public static bool Read_Pac1(string filename, ref Direct_Sound[] Direct_Data, ref ImageSourceData[] IS_Data, ref Environment.Receiver_Bank[] Receiver)
            {
                System.IO.BinaryReader sr = new System.IO.BinaryReader(System.IO.File.Open(filename, System.IO.FileMode.Open));
                try
                {
                    //1. Date & Time
                    string Savedate = sr.ReadString();
                    //2. Plugin Version
                    string Pach_version = sr.ReadString();
                    //3. Cut off Time and SampleRate
                    double CO_TIME    = sr.ReadDouble();
                    int    SampleRate = sr.ReadInt32();
                    //4. Source Count
                    int SrcCt = 1;
                    if (double.Parse(Pach_version.Substring(0, 3)) >= 1.1)
                    {
                        SrcCt = sr.ReadInt32();
                    }
                    //4.1 Source Location x
                    //4.2 Source Location y
                    //4.3 Source Location z
                    Hare.Geometry.Point[] SrcPt = new Hare.Geometry.Point[SrcCt];
                    for (int s = 0; s < SrcCt; s++)
                    {
                        SrcPt[s] = new Hare.Geometry.Point(sr.ReadDouble(), sr.ReadDouble(), sr.ReadDouble());
                    }
                    //5. No of Receivers
                    int Rec_Ct = sr.ReadInt32();
                    //6. Write the coordinates of each receiver point
                    //6b. Write the environmental characteristics at each receiver point (Rho * C); V2.0 only...
                    Hare.Geometry.Point[] Recs = new Hare.Geometry.Point[Rec_Ct];
                    double[] Rho_C             = new double[Rec_Ct];
                    for (int q = 0; q < Rec_Ct; q++)
                    {
                        Recs[q] = new Hare.Geometry.Point(sr.ReadDouble(), sr.ReadDouble(), sr.ReadDouble());
                        if (double.Parse(Pach_version.Substring(0, 3)) >= 2.0)
                        {
                            Rho_C[q] = sr.ReadDouble();
                        }
                        else
                        {
                            Rho_C[q] = 400;
                        }
                    }

                    Direct_Data = new Direct_Sound[SrcCt];
                    IS_Data     = new ImageSourceData[SrcCt];
                    Receiver    = new Environment.Receiver_Bank[SrcCt];

                    int DDCT = 0;
                    int ISCT = 0;
                    int RTCT = 0;
                    do
                    {
                        string readin = sr.ReadString();
                        switch (readin)
                        {
                        case "Direct_Sound":
                        case "Direct_Sound w sourcedata":
                            //9. Read Direct Sound Data
                            Direct_Data[DDCT]            = Direct_Sound.Read_Data(ref sr, Recs, SrcPt[DDCT], Rho_C, Pach_version);
                            Direct_Data[DDCT].CO_Time    = CO_TIME;
                            Direct_Data[DDCT].SampleFreq = (int)SampleRate;
                            DDCT++;
                            break;

                        case "Image-Source_Data":
                            //10. Read Image Source Sound Data
                            IS_Data[ISCT] = ImageSourceData.Read_Data(ref sr, Recs.Length, Direct_Data[DDCT - 1], false, ISCT, Pach_version);
                            ISCT++;
                            break;

                        case "Ray-Traced_Data":
                            //11. Read Ray Traced Sound Data
                            Receiver[RTCT] = Environment.Receiver_Bank.Read_Data(ref sr, Direct_Data[RTCT].SWL, Rec_Ct, Recs, Rho_C, Direct_Data[RTCT].Delay_ms, ref SampleRate, Pach_version);
                            RTCT++;
                            break;

                        case "End":
                            sr.Close();
                            return(true);
                        }
                    } while (true);
                }
                catch (System.Exception X)
                {
                    sr.Close();
                    System.Windows.Forms.MessageBox.Show("File Read Failed...", String.Format("Results file was corrupt or incomplete. We apologize for this inconvenience. Please report this to the software author. It will be much appreciated. \r\n Exception Message: {0}. \r\n Method: {1}", X.Message, X.TargetSite));
                    return(false);
                }
            }
Esempio n. 23
0
            /// <summary>
            /// Writes a Pac1 file. [Useable by scripts and interface components alike.]
            /// </summary>
            /// <param name="filename">The location of the final saved file...</param>
            /// <param name="Direct_Data">Array of Completed Direct Sound Simulations Required</param>
            /// <param name="IS_Data">Array of Completed Image Source Simulations. Enter null if opted out.</param>
            /// <param name="Receiver">Array of Completed Ray-Tracing Simulation Receivers. Enter null if opted out.</param>
            public static void Write_Pac1(string filename, ref Direct_Sound[] Direct_Data, ref ImageSourceData[] IS_Data, ref Environment.Receiver_Bank[] Receiver)
            {
                if (Direct_Data == null && IS_Data == null && IS_Data == null && Receiver != null)
                {
                    System.Windows.Forms.MessageBox.Show("There is no simulated data to save.");
                    return;
                }
                
                Pachyderm_Acoustic.UI.PachydermAc_PlugIn plugin = Pachyderm_Acoustic.UI.PachydermAc_PlugIn.Instance;

                //use StreamWriter to write to csv files
                System.IO.StreamWriter sw = System.IO.File.CreateText(filename);

                //1. Date & Time
                sw.WriteLine("Current Date and Time");
                sw.WriteLine(System.DateTime.Now.ToString());

                //2. Plugin Version... if less than 1.1, assume only 1 source.
                sw.WriteLine("Plugin Version");
                sw.WriteLine(plugin.Version);

                //3. Cut off Time (seconds) and SampleRate
                sw.WriteLine("Cut off Time");
                sw.WriteLine((double)Receiver[0].CO_Time);//CO_TIME.Value);
                sw.WriteLine("Sample Rate");
                sw.WriteLine(Receiver[0].SampleRate);

                //4.0 Source Count(int)
                Rhino.Geometry.Point3d[] SRC;
                plugin.SourceOrigin(out SRC);
                sw.WriteLine("Source Count");
                sw.WriteLine(SRC.Length);

                //4 Source Location x,y,z (double)
                sw.WriteLine("Source Location : x y z");
                for (int i = 0; i < SRC.Length; i++)
                    sw.WriteLine(Helper_Functions.ConvertToCSVString(SRC[i].X, SRC[i].Y, SRC[i].Z));

                //5. No of Receivers
                sw.WriteLine("Number of Receivers");
                sw.WriteLine(Receiver[0].Rec_List.Length);

                //6. Write the coordinates of each receiver point
                //6b. Write the environmental characteristics at each receiver point (Rho * C); V2.0 only...
                for (int q = 0; q < Receiver[0].Rec_List.Length; q++)
                {
                    string origin_and_rhoC = Helper_Functions.ConvertToCSVString(
                        Receiver[0].Rec_List[q].H_Origin.x,
                        Receiver[0].Rec_List[q].H_Origin.y,
                        Receiver[0].Rec_List[q].H_Origin.z,
                        Receiver[0].Rec_List[q].Rho_C);
                    sw.WriteLine(origin_and_rhoC);
                }

                for (int s = 0; s < SRC.Length; s++)
                {
                    if (Direct_Data != null)
                    {
                        //7. Write Direct Sound Data
                        Direct_Data[s].Write_Data(ref sw);
                    }

                    if (IS_Data[0] != null)
                    {
                        //8. Write Image Source Sound Data
                        IS_Data[s].Write_Data(ref sw);
                    }

                    if (Receiver != null)
                    {
                        //9. Write Ray Traced Sound Data
                        Receiver[s].Write_Data(ref sw);
                    }
                }
                sw.Write("End");
                sw.Close();
            }