Exemple #1
0
        /// <summary>
        /// Set of lines in 3D space.
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="xAxis"></param>
        /// <param name="yAxis"></param>
        /// <param name="scale">Scaling the field extent.</param>
        /// <param name="field"></param>
        public LineBall(Plane plane, LineSet lines, RenderEffect effect = RenderEffect.DEFAULT, Colormap colormap = Colormap.Parula, bool flatten = false)
        {
            _thickness = lines.Thickness * plane.PointSize;
            _color = lines.Color;
            this._vertexSizeBytes = Marshal.SizeOf(typeof(Vector4));
            this._numVertices = lines.NumPoints * 2 - lines.Lines.Length * 2; // Linelist means, all points are there twice, minus the endpoints.
            if (_numVertices == 0)
                return;
            this._topology = PrimitiveTopology.LineList;

            // Setting up the vertex buffer.
            if (!flatten)
                GenerateGeometry(plane, lines);
            else
                GenerateGeometryFlatXY(plane, lines);

            //this._technique = _lineEffect.GetTechniqueByName("Render");
            UsedMap = colormap;
            _planeNormal = plane.ZAxis;
            _planeNormal.Normalize();
            _effect = _lineEffect;
            SetRenderEffect(effect);

            this._vertexLayout = new InputLayout(_device, _technique.GetPassByIndex(0).Description.Signature, new[] {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("SCALAR", 0, Format.R32_Float, 12, 0)
            });
        }
Exemple #2
0
        protected void MaskOnData()
        {
            if (_coherency == null || _selectionData == null)
            {
                return;
            }

            //Renderer.Singleton.Remove(_graph);
            //float dataRange = 80;
            //float rangeOffset = dataRange * 0.5f;

            //Graph2D[] maskGraph = new Graph2D[_coherency.Length];
            //for (int angle = 0; angle < maskGraph.Length; ++angle)
            //    maskGraph[angle] = Graph2D.Operate(_coherency[angle], _selectionData[angle], (b, a) => (Math.Max(0, a + rangeOffset + 1/*b*/ * (2 * dataRange))));

            //LineSet maskedLines = FieldAnalysis.WriteGraphToSun(maskGraph, new Vector3(_selection.X, _selection.Y, SliceTimeMain));
            //_graph = new LineBall(_graphPlane, maskedLines, LineBall.RenderEffect.HEIGHT, Colormap, true, SliceTimeMain);
            //_graph.LowerBound = SliceTimeMain;
            //_graph.UpperBound = SliceTimeMain + 4 * dataRange;
            //_graph.UsedMap = Colormap.ParulaSegmentation;

            LineSet lines = FieldAnalysis.WriteGraphToSun(_coherency, new Vector3(_selection.X, _selection.Y, SliceTimeMain));

            _graph            = new LineBall(_graphPlane, lines, LineBall.RenderEffect.HEIGHT, Colormap.Parula, true, SliceTimeMain);
            _graph.LowerBound = SliceTimeMain;
            _graph.UpperBound = SliceTimeMain + 80;

            // Compute area coherency.
            float overallCoherency = ComputeCoherency(_coherency, _selectionData);

            Console.WriteLine(String.Format("=== {0} Coherency is {1} / 80 = {2}===", _currentFileName, overallCoherency, overallCoherency / 80));
        }
Exemple #3
0
        /// <summary>
        /// Set of lines in 3D space.
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="xAxis"></param>
        /// <param name="yAxis"></param>
        /// <param name="scale">Scaling the field extent.</param>
        /// <param name="field"></param>
        public LineBall(Plane plane, LineSet lines, RenderEffect effect = RenderEffect.DEFAULT, Colormap colormap = Colormap.Parula, bool flatten = false, float flattenToTime = 0)
        {
            _thickness            = lines.Thickness * plane.PointSize;
            _color                = lines.Color;
            this._vertexSizeBytes = Marshal.SizeOf(typeof(Vector4));
            this._numVertices     = lines.NumPoints * 2 - lines.Lines.Length * 2; // Linelist means, all points are there twice, minus the endpoints.
            if (_numVertices == 0)
            {
                return;
            }
            this._topology = PrimitiveTopology.LineList;

            // Setting up the vertex buffer.
            if (!flatten)
            {
                GenerateGeometry(plane, lines);
            }
            else
            {
                GenerateGeometryFlatXY(plane, lines, flattenToTime);
            }

            //this._technique = _lineEffect.GetTechniqueByName("Render");
            UsedMap      = colormap;
            _planeNormal = plane.ZAxis;
            _planeNormal.Normalize();
            _effect = _lineEffect;
            SetRenderEffect(effect);

            this._vertexLayout = new InputLayout(_device, _technique.GetPassByIndex(0).Description.Signature, new[] {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("SCALAR", 0, Format.R32_Float, 12, 0)
            });
        }
Exemple #4
0
        protected void MaskOnData()
        {
            if (_dataGraph == null || _selectionData == null)
            {
                return;
            }

            Renderer.Singleton.Remove(_graph);
            float rangeOffset = _rangeGraphData * 0.5f;

            Graph2D[] maskGraph = new Graph2D[_dataGraph.Length];
            for (int angle = 0; angle < maskGraph.Length; ++angle)
            {
                maskGraph[angle] = Graph2D.Operate(_dataGraph[angle], _selectionData[angle], (b, a) => (Math.Max(0, a + rangeOffset + b * (2 * _rangeGraphData))));
            }

            LineSet maskedLines = FieldAnalysis.WriteGraphToSun(maskGraph, new Vector3(_selection.X, _selection.Y, SliceTimeMain));

            _graph            = new LineBall(_graphPlane, maskedLines, LineBall.RenderEffect.HEIGHT, Colormap, true, SliceTimeMain);
            _graph.LowerBound = _minGraphData;
            _graph.UpperBound = _minGraphData + 4 * _rangeGraphData;
            _graph.UsedMap    = Colormap.ParulaSegmentation;

            Renderer.Singleton.AddRenderable(_graph);
        }
Exemple #5
0
        public static void ReadFromFile(string file, out LineSet lineset)
        {
            Line[] lines;

            // Open the file. If it already exists, overwrite.
            using (FileStream fs = File.Open(@file, FileMode.Open))
            {
                using (BinaryReader reader = new BinaryReader(fs))
                {
                    // Write number of lines.
                    lines = new Line[reader.ReadInt32()];

                    // Write line lengths in order.
                    for (int l = 0; l < lines.Length; ++l)
                        lines[l] = new Line() { Positions = new Vector3[reader.ReadInt32()] };

                    // Write positions.
                    float x, y, z;
                    foreach (Line line in lines)
                    {
                        for(int v = 0; v < line.Length; ++v)
                        {
                            x = reader.ReadSingle();
                            y = reader.ReadSingle();
                            z = reader.ReadSingle();
                            line[v] = new Vector3(x, y, z);
                        }
                    }

                }
            }

            lineset = new LineSet(lines);
        }
Exemple #6
0
        public static void WriteToFile(string file, LineSet lines)
        {
            // Open the file. If it already exists, overwrite.
            using (FileStream fs = File.Open(@file, FileMode.Create))
            {
                using (BinaryWriter writer = new BinaryWriter(fs))
                {
                    // Write number of lines.
                    writer.Write(lines.Length);

                    // Write line lengths in order.
                    foreach (Line line in lines.Lines)
                    {
                        writer.Write(line.Length);
                    }

                    // Write positions.
                    foreach (Line line in lines.Lines)
                    {
                        foreach (Vector3 vec in line.Positions)
                        {
                            writer.Write(vec.X);
                            writer.Write(vec.Y);
                            writer.Write(vec.Z);
                        }
                    }
                }
            }
        }
Exemple #7
0
            public void IntegrateFurther(LineSet positions, float?maxTime = null)
            {
                try {
                    Debug.Assert(Field.NumVectorDimensions <= 3);

                    LineSet             result;
                    PointSet <EndPoint> ends = positions.GetAllEndPoints();
                    if (ends.Length == 0)
                    {
                        return;
                    }

                    //int validPoints = 0;
                    for (int index = 0; index < positions.Length; ++index)
                    {
                        if (positions[index].Length == 0 || ends[index] == null || (ends[index].Status != Status.BORDER && ends[index].Status != Status.TIME_BORDER && ends[index].Status != Status.OK))
                        {
                            continue;
                        }
                        StreamLine <Vector3> streamline = IntegrateLineForRendering(((Vec3)ends.Points[index].Position).ToVec(Field.NumVectorDimensions), maxTime);
                        positions[index].Positions   = positions.Lines[index].Positions.Concat(streamline.Points).ToArray();
                        positions[index].Status      = streamline.Status;
                        positions[index].LineLength += streamline.LineLength;

                        //if ((index) % (positions.Length / 10) == 0)
                        //    Console.WriteLine("Further integrated {0}/{1} lines. {2}%", index, positions.Length, ((float)index*100) / positions.Length);
                        //validPoints++;
                    }
                    //return new LineSet(lines) { Color = (Vector3)Direction };
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
        public override void ClickSelection(Vector2 point)
        {
            if(LineX > 0)
            {
                _lastSelection = (_lastSelection + 1) % LineX;
                Vec3 vec = new Vec3((Vec2)point, 0);
                if (_velocity.Grid.InGrid(vec))
                {
                    Vector3[] line = _integrator.IntegrateLineForRendering(vec).Points.ToArray();
                    Line newLine = new Line() { Positions = line };
                    var set = new LineSet(new Line[] { newLine }) { Color = _flipColor? Vector3.UnitX : Vector3.UnitZ};

                    set.Thickness *= 3;
                    var ball = new LineBall(Plane, set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                    _selections.Add(ball);

                    if (_selections.Count > LineX)
                    {
                        _selections.RemoveAt(0);
                        _selectionsAngle.RemoveAt(0);
                        _steadySelection.RemoveAt(0);
                    }

                    Graph2D[] angle = FieldAnalysis.GetDistanceToAngle(_core, Vector2.Zero, new LineSet(new Line[] { newLine }));
                    Debug.Assert(angle.Length == 1);

                    for(int p = 0; p < newLine.Length; ++p)
                    {
                    //    if(angle[0].X[p] > _velocity.Size.T - 1)
                    //    {
                    //        newLine.Resize(p);
                    //        break;
                    //    }

                        Vector3 sph = FieldAnalysis.SphericalPosition(_core[0], (float)(angle[0].X[p] * 0.5f / Math.PI), angle[0].Fx[p]);
                        newLine[p] = new Vector3(sph.X, sph.Y, angle[0].X[p] - angle[0].X[0]);
                    }
                    set = new LineSet(new Line[] { newLine }) { Color = _flipColor ? Vector3.UnitX : Vector3.UnitZ };
                    set.Thickness *= 3;
                    ball = new LineBall(Plane, set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                    _selectionsAngle.Add(ball);

                    _integrator.Field = _steadyField;
                    _integrator.MaxNumSteps = 50;
                    line = _integrator.IntegrateLineForRendering(new Vec2(vec.X, vec.Y)).Points.ToArray();
                    newLine = new Line() { Positions = line };
                    set = new LineSet(new Line[] { newLine }) { Color = _flipColor ? Vector3.UnitX : Vector3.UnitZ };
                    set.Thickness *= 3;
                    ball = new LineBall(new Plane(Plane, Vector3.UnitZ * 0.1f), set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                    _steadySelection.Add(ball);
                    _integrator.Field = _velocity;
                    _integrator.MaxNumSteps = 10000;

                    _flipColor = !_flipColor;
                    //var set = new LineSet(_selections.ToArray()) { Color = _selections.Count % 2 == 0 ? Vector3.UnitX : Vector3.UnitY };
                    //_lines = new LineBall(Plane, set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                }
            }
        }
Exemple #9
0
        public LineSet(LineSet cpy, int start = 0, int length = -1) : base()
        {
            int numLines = length > 0 ? length : cpy.Length - start;

            this.Color     = cpy.Color;
            this.Lines     = new Line[numLines];
            this.Thickness = cpy.Thickness;
            for (int line = 0; line < numLines; ++line)
            {
                Lines[line] = new Line(cpy.Lines[start + line]);
            }
        }
Exemple #10
0
        public override void EndSelection(Vector2[] corners)
        {
            if (_selectionData == null)
            {
                return;
            }

            _selectionLines = FieldAnalysis.WriteGraphToSun(_selectionData, new Vector3(_selection.X, _selection.Y, SliceTimeMain));
            WriteGraph(_currentFileName + "Selection", _selectedCore, _selectionData, _selectionLines);

            Renderer.Singleton.Remove(_mouseCloud);
            _mouseCircle = null;
        }
Exemple #11
0
        protected void GenerateGeometryFlatXY(Plane plane, LineSet lines, float toTime = 0)
        {
            // Write poition and UV-map data.
            var     stream = new DataStream(_numVertices * _vertexSizeBytes, true, true);
            Vector3 zAxis  = plane.ZAxis;

            LowerBound = lines.Lines[0].Positions[0][2];
            UpperBound = LowerBound;


            for (int index = 0; index < lines.Lines.Length; ++index)
            {
                Line line = lines.Lines[index];
                if (line.Length < 2)
                {
                    continue;
                }
                Debug.Assert(line.Length == lines.Lines[index].Length);
                stream.Write(new Vector4(plane.Origin + (plane.XAxis * line.Positions[0][0] + plane.YAxis * line.Positions[0][1] + plane.ZAxis * toTime), line.Positions[0][2]));
                for (int point = 1; point < line.Positions.Length - 1; ++point)
                {
                    Vector4 pos = new Vector4(plane.Origin + (plane.XAxis * line.Positions[point][0] + plane.YAxis * line.Positions[point][1] + plane.ZAxis * toTime), line.Positions[point][2]);
                    stream.Write(pos);
                    stream.Write(pos);

                    LowerBound = Math.Min(LowerBound, line.Positions[point][2]);
                    UpperBound = Math.Max(UpperBound, line.Positions[point][2]);
                }
                int end = line.Positions.Length - 1;
                stream.Write(new Vector4(plane.Origin + (plane.XAxis * line.Positions[end][0] + plane.YAxis * line.Positions[end][1] + plane.ZAxis * toTime), line.Positions[end][2]));
            }
            stream.Position = 0;

            // Create and fill buffer.
            _vertices = new Buffer(_device, stream, new BufferDescription()
            {
                BindFlags      = BindFlags.VertexBuffer,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags    = ResourceOptionFlags.None,
                SizeInBytes    = _numVertices * _vertexSizeBytes,
                Usage          = ResourceUsage.Default
            });
            stream.Dispose();
        }
Exemple #12
0
 public static void WriteHeightCSV(string file, LineSet lines)
 {
     // Open the file. If it already exists, overwrite.
     using (FileStream fs = File.Open(@file, FileMode.Create))
     {
         using (StreamWriter writer = new StreamWriter(fs))
         {
             // Write positions.
             foreach (Line line in lines.Lines)
             {
                 foreach (Vector3 vec in line.Positions)
                 {
                     writer.Write("{0},", vec.Z);
                 }
                 writer.Write('\n');
             }
         }
     }
 }
Exemple #13
0
        public TileSurface(LineSet lines)
        {
            // Assert "full" lineset.
            int length = lines[0].Length;
            #if DEBUG
            foreach (Line l in lines.Lines)
            {
                Debug.Assert(l.Length == length);
            }
            #endif
            Positions = new Vector3[length, lines.Length];

            for(int l = 0; l < lines.Length; ++l)
            {
                for (int p = 0; p < lines[l].Length; ++p)
                    Positions[p, l] = lines[l][p];

            }
        }
Exemple #14
0
            public LineSet[] Integrate <P>(PointSet <P> positions, bool forwardAndBackward = false, float?maxTime = null) where P : Point
            {
                Debug.Assert(Field.NumVectorDimensions <= 3);

                Line[] lines        = new Line[positions.Length];
                Line[] linesReverse = new Line[forwardAndBackward? positions.Length : 0];

                LineSet[] result = new LineSet[forwardAndBackward ? 2 : 1];

                for (int index = 0; index < positions.Length; ++index)
                {
                    StreamLine <Vector3> streamline = IntegrateLineForRendering(((Vec3)positions.Points[index].Position).ToVec(Field.NumVectorDimensions), maxTime);
                    lines[index]            = new Line();
                    lines[index].Positions  = streamline.Points.ToArray();
                    lines[index].Status     = streamline.Status;
                    lines[index].LineLength = streamline.LineLength;

                    //if ((index) % (positions.Length / 10) == 0)
                    //    Console.WriteLine("Integrated {0}/{1} lines. {2}%", index, positions.Length, ((float)index * 100) / positions.Length);
                }
                result[0] = new LineSet(lines)
                {
                    Color = (Vector3)Direction
                };

                if (forwardAndBackward)
                {
                    Direction = !Direction;
                    for (int index = 0; index < positions.Length; ++index)
                    {
                        StreamLine <Vector3> streamline = IntegrateLineForRendering((Vec3)positions.Points[index].Position, maxTime);
                        linesReverse[index]           = new Line();
                        linesReverse[index].Positions = streamline.Points.ToArray();
                    }
                    result[1] = new LineSet(linesReverse)
                    {
                        Color = (Vector3)Direction
                    };
                    Direction = !Direction;
                }
                return(result);
            }
Exemple #15
0
        public PointSet <Point> ColorCodeArbitrary(LineSet lines, PositionToColor func)
        {
            Point[] points;
            points = new Point[lines.NumExistentPoints];
            int idx = 0;

            foreach (Line line in lines.Lines)
            {
                foreach (Vector3 pos in line.Positions)
                {
                    points[idx] = new Point()
                    {
                        Position = pos, Color = func(this, pos), Radius = lines.Thickness
                    };
                    ++idx;
                }
            }

            return(new PointSet <Point>(points));
        }
Exemple #16
0
        public TileSurface(LineSet lines)
        {
            // Assert "full" lineset.
            int length = lines[0].Length;

#if DEBUG
            foreach (Line l in lines.Lines)
            {
                Debug.Assert(l.Length == length);
            }
#endif
            Positions = new Vector3[length, lines.Length];

            for (int l = 0; l < lines.Length; ++l)
            {
                for (int p = 0; p < lines[l].Length; ++p)
                {
                    Positions[p, l] = lines[l][p];
                }
            }
        }
Exemple #17
0
        public static void ReadFromFile(string file, out LineSet lineset)
        {
            Line[] lines;

            // Open the file. If it already exists, overwrite.
            using (FileStream fs = File.Open(@file, FileMode.Open))
            {
                using (BinaryReader reader = new BinaryReader(fs))
                {
                    // Write number of lines.
                    lines = new Line[reader.ReadInt32()];

                    // Write line lengths in order.
                    for (int l = 0; l < lines.Length; ++l)
                    {
                        lines[l] = new Line()
                        {
                            Positions = new Vector3[reader.ReadInt32()]
                        }
                    }
                    ;

                    // Write positions.
                    float x, y, z;
                    foreach (Line line in lines)
                    {
                        for (int v = 0; v < line.Length; ++v)
                        {
                            x       = reader.ReadSingle();
                            y       = reader.ReadSingle();
                            z       = reader.ReadSingle();
                            line[v] = new Vector3(x, y, z);
                        }
                    }
                }
            }

            lineset = new LineSet(lines);
        }
        public PlaygroundMapper(Plane plane)
            : base(new Plane(plane, 1), new Int2(NUM_CELLS))
        {
            Mapping = Map;
            _velocity = Tests.CreateBowl(new Vec2(NUM_CELLS/2, 0), NUM_CELLS, new Vec2(-10, 0), 22, 200);
            _selections = new List<LineBall>(10);
            _selectionsAngle = new List<LineBall>(10);
            _steadySelection = new List<LineBall>(10);

            // Core.
            _core = new Line() { Positions = new Vector3[] { new Vector3(50, 100, 0), new Vector3(155, 100, _velocity.Size.T-1) } };
            LineSet set = new LineSet(new Line[] { _core }) { Color = new Vector3(0.2f) };
            set.Thickness *= 3;
            _coreBall = new LineBall(plane, set, LineBall.RenderEffect.DEFAULT);

            // Straight core.
            set = new LineSet(new Line[] { new Line() { Positions = new Vector3[] { _core[0], _core[0] + Vector3.UnitZ * (_velocity.Size.T - 1) } } }) { Color = new Vector3(0.2f) };
            set.Thickness *= 3;
            _straightCoreBall = new LineBall(Plane, set);

            var center = Tests.CreatePerfect(new Vec2(0, 0), NUM_CELLS, new Vec2(0), 1, 200);
            _steadyField = center.GetTimeSlice(0); //[0] as ScalarField;
        }
        public PlaygroundMapper(Plane plane) : base(new Plane(plane, 1), new Int2(NUM_CELLS))
        {
            Mapping          = Map;
            _velocity        = Tests.CreateBowl(new Vec2(NUM_CELLS / 2, 0), NUM_CELLS, new Vec2(-10, 0), 22, 200);
            _selections      = new List <LineBall>(10);
            _selectionsAngle = new List <LineBall>(10);
            _steadySelection = new List <LineBall>(10);

            // Core.
            _core = new Line()
            {
                Positions = new Vector3[] { new Vector3(50, 100, 0), new Vector3(155, 100, _velocity.Size.T - 1) }
            };
            LineSet set = new LineSet(new Line[] { _core })
            {
                Color = new Vector3(0.2f)
            };

            set.Thickness *= 3;
            _coreBall      = new LineBall(plane, set, LineBall.RenderEffect.DEFAULT);

            // Straight core.
            set = new LineSet(new Line[] { new Line()
                                           {
                                               Positions = new Vector3[] { _core[0], _core[0] + Vector3.UnitZ * (_velocity.Size.T - 1) }
                                           } })
            {
                Color = new Vector3(0.2f)
            };
            set.Thickness    *= 3;
            _straightCoreBall = new LineBall(Plane, set);

            var center = Tests.CreatePerfect(new Vec2(0, 0), NUM_CELLS, new Vec2(0), 1, 200);

            _steadyField = center.GetTimeSlice(0); //[0] as ScalarField;
        }
Exemple #20
0
        public static void WriteHeightCSV(string file, LineSet lines)
        {
            // Open the file. If it already exists, overwrite.
            using (FileStream fs = File.Open(@file, FileMode.Create))
            {
                using (StreamWriter writer = new StreamWriter(fs))
                {
                    // Write positions.
                    foreach (Line line in lines.Lines)
                    {
                        foreach (Vector3 vec in line.Positions)
                        {
                            writer.Write("{0},", vec.Z);
                        }
                        writer.Write('\n');
                    }

                }
            }
        }
Exemple #21
0
        public static void WriteToFile(string file, LineSet lines)
        {
            // Open the file. If it already exists, overwrite.
            using (FileStream fs = File.Open(@file, FileMode.Create))
            {
                using (BinaryWriter writer = new BinaryWriter(fs))
                {
                    // Write number of lines.
                    writer.Write(lines.Length);

                    // Write line lengths in order.
                    foreach (Line line in lines.Lines)
                        writer.Write(line.Length);

                    // Write positions.
                    foreach(Line line in lines.Lines)
                    {
                        foreach(Vector3 vec in line.Positions)
                        {
                            writer.Write(vec.X);
                            writer.Write(vec.Y);
                            writer.Write(vec.Z);
                        }
                    }

                }
            }
        }
        public List<Renderable> ShowPaths()
        {
            bool mapLines = false;

            // Setup an integrator.
            VectorField.Integrator intVF = VectorField.Integrator.CreateIntegrator(Velocity, _currentSetting.IntegrationType);
            intVF.MaxNumSteps = 10000;
            intVF.StepSize = _currentSetting.StepSize;

            if (_lastSetting == null ||
                IntegrationTypeChanged ||
                StepSizeChanged)
            {
                // ~~~~~~~~~~~ Line Integration ~~~~~~~~~~~ \\
                // Clear the raw lines.
                int timeLength = Velocity.Size.T;
                _rawLines = new LineSet[Velocity.Size.T];

                // Initialize the firth
                _rawLines[0] = new LineSet(new Line[0]);
                ScalarField[] lengths = new ScalarField[timeLength];
                lengths[0] = new ScalarField(Velocity.ScalarsAsSFU[0].TimeSlices[0], (v, J) => 0);

                _minLength = new float[timeLength];
                _maxLength = new float[timeLength];

                // Integrate the path line segments between each neighboring pair of time slices.
                for (int time = 1; time < timeLength; ++time)
                {
                    _minLength[time] = float.MaxValue;
                    _maxLength[time] = float.MinValue;

                    // Integrate last points until next time slice.
                    _pathlineSegments[time-1] = intVF.Integrate(_intersectTimeSlices[time - 1], false, time)[0];
                    _pathlineSegments[time - 1].Color = Vector3.UnitZ * (float)time / timeLength;

                    //                    if(time == timeLength - 1)
                    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetValidEndPoints();//VectorField.Integrator.Status.BORDER);
                    //else
                    //    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetEndPoints(VectorField.Integrator.Status.TIME_BORDER);
                    _points[time] = new PointCloud(Plane, _intersectTimeSlices[time].ToBasicSet());

                    // Set all positions to 0, or invalid value.
                    lengths[time] = new ScalarField(lengths[time-1], (s, g) => s, false);
                    int i = 0;
                    for (int p = 0; p < _intersectTimeSlices[time].Points.Length; ++p)
                    {
                        EndPoint pP = _intersectTimeSlices[time].Points[p];
                        ++i;
                        // Map floating position to int position.
                        int iPos = _fieldPositionOfValidCell[p];
                        float timeStepped = (pP.Position.Z - (time-1));
                        lengths[time][iPos] += timeStepped > 0 ? pP.LengthLine / timeStepped : 0;
                        float tmp = lengths[time][iPos];
                        _minLength[time] = Math.Min(lengths[time][iPos], _minLength[time]);
                        _maxLength[time] = Math.Max(lengths[time][iPos], _maxLength[time]);

                        if (_minLength[time] < 0 || pP.Status != VectorField.Integrator.Status.TIME_BORDER)
                            i += 0;
                        //Console.WriteLine(lengths[time][iPos]);
                    }
                    Console.WriteLine("Integrated lines until time " + time);
                }

                lengths[0] = new VectorField(Velocity.GetTimeSlice(0), FieldAnalysis.VFLength, 1, false).Scalars[0] as ScalarField;
                _minLength[0] = 0;
                _maxLength[0] = RedSea.Singleton.NumTimeSlices;
                _pathLengths = new ScalarFieldUnsteady(lengths);
                mapLines = true;
            }

            if (_lastSetting == null ||
                SliceTimeMainChanged||
                ShaderChanged)
            {
                ScalarField f = _pathLengths.GetTimeSlice(_currentSetting.SliceTimeMain);
                f.TimeOrigin = 0;
                VectorField vecField;
                switch(_currentSetting.Shader)
                {
                    case FieldPlane.RenderEffect.LIC:
                        VectorField slice = Velocity.GetTimeSlice(0);
                        slice.TimeSlice = 0;
                        vecField = new VectorField(new Field[] { slice.Scalars[0], slice.Scalars[1], f });
                        break;
                    case FieldPlane.RenderEffect.LIC_LENGTH:
                        vecField = Velocity.GetTimeSlice(_currentSetting.SliceTimeMain);
                        vecField.TimeSlice = 0;
                        break;
                    default:
                    case FieldPlane.RenderEffect.COLORMAP:
                    case FieldPlane.RenderEffect.DEFAULT:
                        vecField = new VectorField(new Field[] { f });
                        break;
                }
                _plane = new FieldPlane(Plane, vecField /*Velocity.GetSlice(_currentSetting.SliceTimeReference)*/, _currentSetting.Shader);
            }

            // The line settings have changed. Create new renderables from the lines.
            if (mapLines || LineSettingChanged)
            {
                _lines = new Renderable[_pathlineSegments.Length];

                switch (_currentSetting.LineSetting)
                {
                    // Map the vertices to colored points.
                    case RedSea.DisplayLines.POINTS_2D_LENGTH:
                        for (int i = 0; i < _pathlineSegments.Length; ++i)
                        {
                            PointSet<Point> linePoints = Velocity.ColorCodeArbitrary(_pathlineSegments[i], RedSea.DisplayLineFunctions[(int)_currentSetting.LineSetting]);
                            _lines[i] = new PointCloud(Plane, linePoints);
                        }
                        break;

                    // Render as line.
                    default:
                    case RedSea.DisplayLines.LINE:
                        for (int i = 0; i < _pathlineSegments.Length; ++i)
                        {
                            _lines[i] = new LineBall(Plane, _pathlineSegments[i]);
                        }
                        break;
                }
            }

            // Set mapping values.
            //_plane.UpperBound = 0; //= (1 + _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.UpperBound = _currentSetting.WindowWidth + _currentSetting.WindowStart; ///= _currentSetting.SliceTimeMain;
            //_plane.LowerBound = 0; //= (1 - _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.LowerBound = _currentSetting.WindowStart; ///= _currentSetting.SliceTimeMain;
            _plane.UsedMap = _currentSetting.Colormap;
            _plane.SetRenderEffect(_currentSetting.Shader);

            List<Renderable> result = new List<Renderable>(50);
            result.Add(_plane);
            switch(_currentSetting.Tracking)
            {
                case RedSea.DisplayTracking.LINE:
                case RedSea.DisplayTracking.LINE_POINTS:
                    Renderable[] lines = new Renderable[_currentSetting.SliceTimeMain];
                    Array.Copy(_lines, lines, _currentSetting.SliceTimeMain);
                    result = result.Concat(lines).ToList();
                    break;
                case RedSea.DisplayTracking.POINTS:
                    result.Add(_points[_currentSetting.SliceTimeMain]);
                    break;
                case RedSea.DisplayTracking.LINE_SELECTION:
                    VectorField.StreamLine<Vector3> line = intVF.IntegrateLineForRendering(new Vec3(_startPoint.X, _startPoint.Y, 0));
                    LineSet set = new LineSet(new Line[] { new Line() { Positions = line.Points.ToArray() } });
                    if(_currentSetting.Flat)
                        set.FlattenLines(_currentSetting.SliceTimeMain);
                    result.Add(new LineBall(Plane, set));
                    break;
                default:
                    break;
            }

            return result;
        }
Exemple #23
0
        protected void BuildGraph()
        {
            // Compute ftle.
            if (LineX == 0)
            {
                return;
            }

            _graphData        = FieldAnalysis.WriteGraphToSun(_okubo, new Vector3(_selection.X, _selection.Y, 0));
            _graph            = new LineBall(_graphPlane, _graphData, LineBall.RenderEffect.HEIGHT, Colormap, Flat, SliceTimeMain);
            _graph.LowerBound = -0.05f;
            _graph.UpperBound = 0.05f;

            _rebuilt = false;

            // Load or compute selection by floodfill.
            Graph2D[] okuboSelection;
            LineSet   okuboLines;

            if (LoadGraph("OkuboSelection", _selectedCore, out okuboSelection, out okuboLines))
            {
                return;
            }

            // Floodfill.
            int            numAngles = _okubo.Length;
            int            numRadii  = _okubo[0].Length;
            HashSet <Int2> toFlood   = new HashSet <Int2>();

            okuboSelection = new Graph2D[numAngles];
            for (int angle = 0; angle < numAngles; ++angle)
            {
                toFlood.Add(new Int2(angle, 0));

                okuboSelection[angle] = new Graph2D(numRadii);
                for (int r = 1; r < numRadii; ++r)
                {
                    okuboSelection[angle].Fx[r] = 0;
                    okuboSelection[angle].X[r]  = _okubo[angle].X[r];
                }
            }

            while (toFlood.Count > 0)
            {
                Int2 current = toFlood.Last();
                toFlood.Remove(current);
                okuboSelection[current.X].Fx[current.Y] = 1;

                // In each direction, go negative and positive.
                for (int dim = 0; dim < 2; ++dim)
                {
                    for (int sign = -1; sign <= 1; sign += 2)
                    {
                        Int2 neighbor = new Int2(current);
                        neighbor[dim] += sign;

                        // Wrap angle around.
                        neighbor[0] = (neighbor[0] + numAngles) % numAngles;
                        if (neighbor.Y >= 0 && neighbor.Y < numRadii &&
                            _okubo[neighbor.X].Fx[neighbor.Y] <= 0 &&
                            okuboSelection[neighbor.X].Fx[neighbor.Y] == 0)
                        {
                            toFlood.Add(neighbor);
                        }
                    }
                }
            }

            LineSet sun = FieldAnalysis.WriteGraphToSun(okuboSelection, new Vector3(_selection, SliceTimeMain));

            WriteGraph("OkuboSelection", _selectedCore, okuboSelection, sun);
        }
Exemple #24
0
        public List <Renderable> CoherencyMap()
        {
            List <Renderable> renderables = new List <Renderable>(10);

            int numLines = LineX;

            #region BackgroundPlanes
            if (_lastSetting == null ||
                MeasureChanged ||
                SliceTimeMainChanged ||
                MemberMainChanged ||
                CoreChanged)
            {
                if (_lastSetting == null && _cores == null ||
                    CoreChanged ||
                    MemberMainChanged)
                {
                    // Trace / load cores.
                    TraceCore(MemberMain, SliceTimeMain);
                    if (_selectedCore >= 0)
                    {
                        ClickSelection(_selection);
                    }
                }

                // Computing which field to load as background.
                int totalTime = Math.Min(RedSea.Singleton.NumSubstepsTotal, SliceTimeMain);
                int time      = (totalTime * _everyNthTimestep) / RedSea.Singleton.NumSubsteps;
                int subtime   = (totalTime * _everyNthTimestep) % RedSea.Singleton.NumSubsteps;

                _timeSlice         = LoadPlane(MemberMain, time, subtime, true);
                _intersectionPlane = _timeSlice.GetIntersectionPlane();
            }

            if (_lastSetting == null || SliceTimeReferenceChanged)
            {
                // Reference slice.
                int totalTime = Math.Min(RedSea.Singleton.NumSubstepsTotal, SliceTimeReference);
                int time      = (totalTime * _everyNthTimestep) / RedSea.Singleton.NumSubsteps;
                int subtime   = (totalTime * _everyNthTimestep) % RedSea.Singleton.NumSubsteps;
                _compareSlice = LoadPlane(MemberMain, time, subtime, true);
            }

            if (_lastSetting == null ||
                ColormapChanged ||
                ShaderChanged ||
                WindowStartChanged ||
                WindowWidthChanged)
            {
                _timeSlice.SetRenderEffect(Shader);
                _timeSlice.UsedMap    = Colormap;
                _timeSlice.LowerBound = WindowStart;
                _timeSlice.UpperBound = WindowWidth + WindowStart;

                _compareSlice.SetRenderEffect(Shader);
                _compareSlice.UsedMap    = Colormap;
                _compareSlice.LowerBound = WindowStart;
                _compareSlice.UpperBound = WindowWidth + WindowStart;
            }

            // First item in list: plane.
            renderables.Add(_timeSlice);
            #endregion BackgroundPlanes

            // Add Point to indicate clicked position.
            //renderables.Add(new PointCloud(_linePlane, new PointSet<Point>(new Point[] { new Point() { Position = new Vector3(_selection, SliceTimeMain), Color = new Vector3(0.7f), Radius = 0.4f } })));
            bool rebuilt = false;

            if (_lastSetting == null ||
                DiffusionMeasureChanged)
            {
                switch (DiffusionMeasure)
                {
                case RedSea.DiffusionMeasure.FTLE:
                    _currentFileName = "FTLE";
                    break;

                case RedSea.DiffusionMeasure.Direction:
                    _currentFileName = "Okubo";
                    break;

                default:
                    _currentFileName = "Concentric";
                    break;
                }
            }

            // Recompute lines if necessary.
            if (numLines > 0 && (
                    _lastSetting == null ||
                    NumLinesChanged ||
                    _selectionChanged ||
                    SliceTimeMainChanged ||
                    DiffusionMeasureChanged))
            {
                _graph = null;
                // Load selection
                if (LoadGraph(_currentFileName + "Selection", out _selectionData))
                {
                    // Is there a drawing saved? If not, make a new empty graph.
                    if (!LoadGraph(_currentFileName + "Coherency", _selectedCore, out _coherency, out _graphData))
                    {
                        if (_coherency == null || _coherency.Length != _selectionData.Length)
                        {
                            _coherency = new Graph2D[_selectionData.Length];
                        }

                        for (int angle = 0; angle < _coherency.Length; ++angle)
                        {
                            _coherency[angle] = new Graph2D(_selectionData[angle].Length);
                            for (int rad = 0; rad < _coherency[angle].Length; ++rad)
                            {
                                _coherency[angle].X[rad]  = _selectionData[angle].X[rad];
                                _coherency[angle].Fx[rad] = 0;
                            }
                        }

                        IntegrateLines();
                    }
                    else
                    {
                        _stencilPathlines = new List <LineSet>(8);
                        for (int toTime = 10; toTime <= 80; toTime += 10)
                        {
                            string  pathlineName = RedSea.Singleton.DiskFileName + _currentFileName + string.Format("Pathlines_{0}_{1}.pathlines", SliceTimeMain, toTime);
                            LineSet paths;
                            GeometryWriter.ReadFromFile(pathlineName, out paths);
                            _stencilPathlines.Add(paths);
                        }
                    }
                    // Some weird things happening, maybe this solves offset drawing... It does.
                    LineSet coherencyLines = FieldAnalysis.WriteGraphToSun(_coherency, new Vector3(_selection.X, _selection.Y, SliceTimeMain));
                    _coherencyDisk = new LineBall(_graphPlane, coherencyLines, LineBall.RenderEffect.HEIGHT, Colormap, true, SliceTimeMain);
                    //_coherencyDisk.LowerBound = SliceTimeMain;
                    //_coherencyDisk.UpperBound = SliceTimeMain + 80;
                    MaskOnData();
                }

                _selectionChanged = false;
                rebuilt           = true;
            }

            // Recompute lines if necessary.
            if (numLines > 0 && (
                    _lastSetting == null ||
                    NumLinesChanged ||
                    FlatChanged ||
                    _selectionChanged ||
                    SliceTimeReferenceChanged ||
                    DiffusionMeasureChanged))
            {
                _selectionDistRef = null;
                // Load selection
                if (LoadGraph(_currentFileName + "Selection", _selectedCore, out _selectionDataRef, out _graphData, SliceTimeReference))
                {
                    // Some weird things happening, maybe this solves offset drawing... It does.
                    LineSet selectionLines = FieldAnalysis.WriteGraphToSun(_selectionDataRef, new Vector3(_selection.X, _selection.Y, SliceTimeReference));
                    _selectionDistRef            = new LineBall(_graphPlane, selectionLines, LineBall.RenderEffect.HEIGHT, Colormap.Gray, true, SliceTimeReference);
                    _selectionDistRef.LowerBound = SliceTimeReference;
                    _selectionDistRef.UpperBound = SliceTimeReference + 1;

                    if (SliceTimeReference % 10 == 0 && SliceTimeReference != 0)
                    {
                        _pathlinesTime        = _stencilPathlines[SliceTimeReference / 10 - 1];
                        _pathlines            = new LineBall(_graphPlane, _pathlinesTime, LineBall.RenderEffect.HEIGHT, Colormap.Heat, false);
                        _pathlines.LowerBound = SliceTimeMain;
                        _pathlines.UpperBound = 80;
                    }
                }

                _selectionChanged = false;
                rebuilt           = true;
            }

            // Add the lineball.
            if (_pathlines != null && !Flat)
            {
                renderables.Add(_pathlines);
            }
            if (_graph != null)
            {
                renderables.Add(_graph);
            }
            if (_selectionDistRef != null)
            {
                renderables.Add(_selectionDistRef);
            }
            //if (_coherencyDisk != null) // && !Graph && !Flat)
            //    renderables.Add(_coherencyDisk);
            //            if (_selectionDistRef != null && (Graph || Flat))
            //                renderables.Add(_selectionDistRef);
            //if (SliceTimeMain != SliceTimeReference)
            //    renderables.Add(_compareSlice);
            if (_selectedCore >= 0 && _coreBall != null && !Flat)
            {
                renderables.Add(_coreBall);
            }

            return(renderables);
        }
Exemple #25
0
        protected void IntegrateLines()
        {
            LineSet seeds = FieldAnalysis.WriteGraphToSun(_coherency, new Vector3(_selection.X, _selection.Y, SliceTimeMain));

            _stencilPathlines = new List <LineSet>(8);

            // ~~~~~~~~~~~~~~~~~~~~~~~~ Integrate Pathlines and Adapt ~~~~~~~~~~~~~~~~~~~~~~~~ \\
            // Setup integrator.
            Integrator pathlineIntegrator = Integrator.CreateIntegrator(null, IntegrationType, _cores[_selectedCore], _repulsion);

            pathlineIntegrator.Direction = Sign.POSITIVE;
            pathlineIntegrator.StepSize  = StepSize;

            // Count out the runs for debugging.
            int run = 0;

            // ~~~~~~~~~~~~~~~~~~~~~~~~ Integrate Pathlines  ~~~~~~~~~~~~~~~~~~~~~~~~ \\
            #region IntegratePathlines
            // Do we need to load a field first?
            if (_velocity.TimeOrigin > 0 || _velocity.TimeOrigin + _velocity.Size.T < 11)
            {
                LoadField(0, MemberMain, 11);
            }

            // Integrate first few steps.
            pathlineIntegrator.Field = _velocity;
            _stencilPathlines.Add(pathlineIntegrator.Integrate(seeds.ToPointSet(), false)[0]);

            //List<Tuple<Int2, Line>> indexedPathlines = new List<Tuple<Int2, Line>>();
            List <Int2> pathlineIndices = new List <Int2>();
            for (int a = 0; a < _coherency.Length; a++)
            {
                for (int r = 0; r < _coherency[0].Length; r++)
                {
                    pathlineIndices.Add(new Int2(a, r));
                }
            }

            // ~~~~~~~~~~~~~~~~~~~~~~~~ Filter and Repeat ~~~~~~~~~~~~~~~~~~~~~~~~ \\

            Graph2D[] interimSlice;
            for (int toTime = 10; toTime <= 80; toTime += 10)
            {
                if (!LoadGraph(_currentFileName + "Selection", _selectedCore, out interimSlice, out _graphData, toTime))
                {
                    continue;
                }

                Vector3 corePoint = (Vector3)_cores.Lines[_selectedCore].SampleZ(toTime);

                // ~~~~~~~~~~~~~~~~~~~~~~~~ Keep Only Those Inside ~~~~~~~~~~~~~~~~~~~~~~~~ \\
                List <Line> shrunkenLineSet  = new List <Line>();
                List <Int2> shrunkenIndexSet = new List <Int2>();

                Line[] lastLines = _stencilPathlines[_stencilPathlines.Count - 1].Lines;
                for (int lineIdx = 0; lineIdx < lastLines.Length; ++lineIdx)
                {
                    Line pathLine = lastLines[lineIdx];
                    Int2 lineIdx2 = pathlineIndices[lineIdx];
                    if (pathLine.Length < 1)
                    {
                        continue;
                    }

                    Vector2 endPos     = new Vector2(pathLine.Last.X, pathLine.Last.Y);
                    Int2    indexInSun = GetClosestIndex(interimSlice, new Vector2(corePoint.X, corePoint.Y), endPos);

                    if (indexInSun.X < 0 || indexInSun.X >= interimSlice.Length ||
                        indexInSun.Y < 0 || indexInSun.Y >= interimSlice[0].Length)
                    {
                        continue;
                    }

                    // Check against stencil data.
                    if (interimSlice[indexInSun.X].Fx[indexInSun.Y] != 1)
                    {
                        continue;
                    }

                    // Keep this pathline.
                    shrunkenLineSet.Add(pathLine);
                    shrunkenIndexSet.Add(lineIdx2);

                    // Update coherency map. Use max in case we ever add more in-between slices.
                    //Vector2 startPos = new Vector2(pathLine[0].X, pathLine[0].Y);
                    //indexInSun = GetClosestIndex(interimSlice, _selection, startPos);
                    //_coherency[indexInSun.X].Fx[indexInSun.Y] = Math.Max(_coherency[indexInSun.X].Fx[indexInSun.Y], toTime);
                    _coherency[lineIdx2.X].Fx[lineIdx2.Y] = Math.Max(_coherency[lineIdx2.X].Fx[lineIdx2.Y], toTime);
                }

                // Replace last line set in list with new, filtered version.
                _stencilPathlines[_stencilPathlines.Count - 1] = new LineSet(shrunkenLineSet.ToArray());
                pathlineIndices = shrunkenIndexSet;

                string pathlineName = RedSea.Singleton.DiskFileName + _currentFileName + string.Format("Pathlines_{0}_{1}.pathlines", SliceTimeMain, toTime);
                GeometryWriter.WriteToFile(pathlineName, _stencilPathlines[_stencilPathlines.Count - 1]);

                if (toTime == 80)
                {
                    break;
                }

                // Append integrated lines of next loaded vectorfield time slices.
                LoadField(toTime, MemberMain, 11);

                // Integrate further.
                pathlineIntegrator.Field = _velocity;
                _stencilPathlines.Add(new LineSet(_stencilPathlines[_stencilPathlines.Count - 1]));
                pathlineIntegrator.IntegrateFurther(_stencilPathlines[_stencilPathlines.Count - 1]);

                #endregion IntegratePathlines
            }

            // ~~~~~~~~~~~~~~~~~~~~~~~~ Write New Coherency Map to Disk ~~~~~~~~~~~~~~~~~~~~~~~~ \\
            LineSet coherencyLines = FieldAnalysis.WriteGraphToSun(_coherency, new Vector3(_selection, SliceTimeMain));
            WriteGraph(_currentFileName + "Coherency", _selectedCore, _coherency, coherencyLines);
        }
        public List <Renderable> ShowPaths()
        {
            bool mapLines = false;

            // Setup an integrator.
            VectorField.Integrator intVF = VectorField.Integrator.CreateIntegrator(Velocity, _currentSetting.IntegrationType);
            intVF.MaxNumSteps = 10000;
            intVF.StepSize    = _currentSetting.StepSize;

            if (_lastSetting == null ||
                IntegrationTypeChanged ||
                StepSizeChanged)
            {
                // ~~~~~~~~~~~ Line Integration ~~~~~~~~~~~ \\
                // Clear the raw lines.
                int timeLength = Velocity.Size.T;
                _rawLines = new LineSet[Velocity.Size.T];

                // Initialize the firth
                _rawLines[0] = new LineSet(new Line[0]);
                ScalarField[] lengths = new ScalarField[timeLength];
                lengths[0] = new ScalarField(Velocity.ScalarsAsSFU[0].TimeSlices[0], (v, J) => 0);

                _minLength = new float[timeLength];
                _maxLength = new float[timeLength];

                // Integrate the path line segments between each neighboring pair of time slices.
                for (int time = 1; time < timeLength; ++time)
                {
                    _minLength[time] = float.MaxValue;
                    _maxLength[time] = float.MinValue;

                    // Integrate last points until next time slice.
                    _pathlineSegments[time - 1]       = intVF.Integrate(_intersectTimeSlices[time - 1], false, time)[0];
                    _pathlineSegments[time - 1].Color = Vector3.UnitZ * (float)time / timeLength;

                    //                    if(time == timeLength - 1)
                    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetValidEndPoints();//VectorField.Integrator.Status.BORDER);
                    //else
                    //    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetEndPoints(VectorField.Integrator.Status.TIME_BORDER);
                    _points[time] = new PointCloud(Plane, _intersectTimeSlices[time].ToBasicSet());

                    // Set all positions to 0, or invalid value.
                    lengths[time] = new ScalarField(lengths[time - 1], (s, g) => s, false);
                    int i = 0;
                    for (int p = 0; p < _intersectTimeSlices[time].Points.Length; ++p)
                    {
                        EndPoint pP = _intersectTimeSlices[time].Points[p];
                        ++i;
                        // Map floating position to int position.
                        int   iPos        = _fieldPositionOfValidCell[p];
                        float timeStepped = (pP.Position.Z - (time - 1));
                        lengths[time][iPos] += timeStepped > 0 ? pP.LengthLine / timeStepped : 0;
                        float tmp = lengths[time][iPos];
                        _minLength[time] = Math.Min(lengths[time][iPos], _minLength[time]);
                        _maxLength[time] = Math.Max(lengths[time][iPos], _maxLength[time]);


                        if (_minLength[time] < 0 || pP.Status != VectorField.Integrator.Status.TIME_BORDER)
                        {
                            i += 0;
                        }
                        //Console.WriteLine(lengths[time][iPos]);
                    }
                    Console.WriteLine("Integrated lines until time " + time);
                }

                lengths[0]    = new VectorField(Velocity.GetTimeSlice(0), FieldAnalysis.VFLength, 1, false).Scalars[0] as ScalarField;
                _minLength[0] = 0;
                _maxLength[0] = RedSea.Singleton.NumTimeSlices;
                _pathLengths  = new ScalarFieldUnsteady(lengths);
                mapLines      = true;
            }

            if (_lastSetting == null ||
                SliceTimeMainChanged ||
                ShaderChanged)
            {
                ScalarField f = _pathLengths.GetTimeSlice(_currentSetting.SliceTimeMain);
                f.TimeOrigin = 0;
                VectorField vecField;
                switch (_currentSetting.Shader)
                {
                case FieldPlane.RenderEffect.LIC:
                    VectorField slice = Velocity.GetTimeSlice(0);
                    slice.TimeSlice = 0;
                    vecField        = new VectorField(new Field[] { slice.Scalars[0], slice.Scalars[1], f });
                    break;

                case FieldPlane.RenderEffect.LIC_LENGTH:
                    vecField           = Velocity.GetTimeSlice(_currentSetting.SliceTimeMain);
                    vecField.TimeSlice = 0;
                    break;

                default:
                case FieldPlane.RenderEffect.COLORMAP:
                case FieldPlane.RenderEffect.DEFAULT:
                    vecField = new VectorField(new Field[] { f });
                    break;
                }
                _plane = new FieldPlane(Plane, vecField /*Velocity.GetSlice(_currentSetting.SliceTimeReference)*/, _currentSetting.Shader);
            }

            // The line settings have changed. Create new renderables from the lines.
            if (mapLines || LineSettingChanged)
            {
                _lines = new Renderable[_pathlineSegments.Length];

                switch (_currentSetting.LineSetting)
                {
                // Map the vertices to colored points.
                case RedSea.DisplayLines.POINTS_2D_LENGTH:
                    for (int i = 0; i < _pathlineSegments.Length; ++i)
                    {
                        PointSet <Point> linePoints = Velocity.ColorCodeArbitrary(_pathlineSegments[i], RedSea.DisplayLineFunctions[(int)_currentSetting.LineSetting]);
                        _lines[i] = new PointCloud(Plane, linePoints);
                    }
                    break;

                // Render as line.
                default:
                case RedSea.DisplayLines.LINE:
                    for (int i = 0; i < _pathlineSegments.Length; ++i)
                    {
                        _lines[i] = new LineBall(Plane, _pathlineSegments[i]);
                    }
                    break;
                }
            }

            // Set mapping values.
            //_plane.UpperBound = 0; //= (1 + _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.UpperBound = _currentSetting.WindowWidth + _currentSetting.WindowStart; ///= _currentSetting.SliceTimeMain;
            //_plane.LowerBound = 0; //= (1 - _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.LowerBound = _currentSetting.WindowStart;                               ///= _currentSetting.SliceTimeMain;
            _plane.UsedMap    = _currentSetting.Colormap;
            _plane.SetRenderEffect(_currentSetting.Shader);

            List <Renderable> result = new List <Renderable>(50);

            result.Add(_plane);
            switch (_currentSetting.Tracking)
            {
            case RedSea.DisplayTracking.LINE:
            case RedSea.DisplayTracking.LINE_POINTS:
                Renderable[] lines = new Renderable[_currentSetting.SliceTimeMain];
                Array.Copy(_lines, lines, _currentSetting.SliceTimeMain);
                result = result.Concat(lines).ToList();
                break;

            case RedSea.DisplayTracking.POINTS:
                result.Add(_points[_currentSetting.SliceTimeMain]);
                break;

            case RedSea.DisplayTracking.LINE_SELECTION:
                VectorField.StreamLine <Vector3> line = intVF.IntegrateLineForRendering(new Vec3(_startPoint.X, _startPoint.Y, 0));
                LineSet set = new LineSet(new Line[] { new Line()
                                                       {
                                                           Positions = line.Points.ToArray()
                                                       } });
                if (_currentSetting.Flat)
                {
                    set.FlattenLines(_currentSetting.SliceTimeMain);
                }
                result.Add(new LineBall(Plane, set));
                break;

            default:
                break;
            }

            return(result);
        }
        protected void TubeToRenderables()
        {
            if (_tube.Count < 1)
                return;
            _tube = _tube.OrderBy(o => o[0].Z).ToList();

            //_boundaryBallSpacetime = new LineBall(new Plane(_graphPlane, Vector3.UnitZ * 0.01f), _boundariesSpacetime, LineBall.RenderEffect.HEIGHT, ColorMapping.GetComplementary(Colormap), Flat);
            LineSet rings = new LineSet(_tube.ToArray());
            rings.Thickness *= 0.5f;
            _boundaryBallSpacetime = new LineBall(_linePlane, rings, LineBall.RenderEffect.HEIGHT, ColorMapping.GetComplementary(Colormap), false);

            //if (_tube.Count > 1)
            //    _specialObject = new Mesh(_linePlane, new TileSurface(rings), Mesh.RenderEffect.DEFAULT, Colormap);
        }
        protected override void TraceCore(int member = 0, int startSubstep = 0)
        {
            int rad = NEIGHBOORHOOD_CP * (Core == CoreAlgorithm.ROUGH_STREAM_CONNECTION ? 4 : 1);
            string corename = RedSea.Singleton.CoreFileName + member + Core.ToString() + "cc.line";
            if (System.IO.File.Exists(corename))
            {
                GeometryWriter.ReadFromFile(corename, out _cores);
                LoadField(0, MemberMain, 1);
            }
            else
            {
                Vec3[] bases = new Vec3[] {
                    new Vec3(463.1f, 53.6f, 0),
                    new Vec3(366.4f, 34.4f, 0),
                    new Vec3(230.1f, 218.6f, 0)};

                if (Core == CoreAlgorithm.CLICK)
                {
                    Line[] lines = new Line[bases.Length];
                    for(int b = 0; b < bases.Length; ++b)
                        lines[b] = new Line() { Positions = new Vector3[] { (Vector3)bases[b], (Vector3)bases[b] + Vector3.UnitZ * (float)(RedSea.Singleton.NumSubstepsTotal / _everyNthTimestep) } };

                    _cores = new LineSet(lines);
                    LoadField(0, MemberMain, 1);
                    return;
                }

                int numSlices = RedSea.Singleton.NumSubstepsTotal / _everyNthTimestep;
                int stepSize = Core != CoreAlgorithm.ROUGH_STREAM_CONNECTION ? 1 : ROUGH_MULTIPLIER; // RedSea.Singleton.NumSubstepsTotal / _everyNthTimestep - 1;
                _cores = new LineSet(new Line[bases.Length]);
                for (int b = 0; b < _cores.Length; ++b)
                {
                    _cores[b] = new Line((int)Math.Ceiling((float)(numSlices -1)/ stepSize)+1);
                    //_cores[b][0] = (Vector3)bases[b];
                }

                int idx = 0;
                // Connect to other slices.
                for(int slice = 0; slice < numSlices; slice += stepSize)
                {
                    LoadField(Math.Min(slice, numSlices - 2), member, 2);

                    VectorField field = _velocity;
                    if (Core == CoreAlgorithm.PATHLINE)
                    {
                        var acc= new VectorFieldUnsteady(_velocity, FieldAnalysis.Acceleration, 2);
                        field = acc.GetTimeSlice(slice);
                    }
                    else
                    {
                        field = _velocity.GetTimeSlice(slice);
                    }

                    for (int b = 0; b < _cores.Length; ++b)
                    {
                        Vector3 lastCP = idx > 0? _cores[b][idx-1] : (Vector3)bases[b];
                        Int2 x = new Int2((int)lastCP.X - rad, (int)Math.Ceiling(lastCP.X) + rad);
                        Int2 y = new Int2((int)lastCP.Y - rad, (int)Math.Ceiling(lastCP.Y) + rad);
                        CriticalPointSet2D points = FieldAnalysis.ComputeCriticalPointsRegularSubdivision2DRange(field, x, y);

                        float minDist = float.MaxValue;
                        CriticalPoint2D nearest = null;

                        foreach(CriticalPoint2D point in points.Points)
                        {
                            float dist = (lastCP - point.Position).LengthSquared();
                            if(dist< minDist)
                            {
                                minDist = dist;
                                nearest = point;
                            }
                        }

                        _cores[b][idx] = nearest?.Position ?? lastCP;
                        _cores[b].Positions[idx].Z = slice;
                    }
                    idx++;

                    // Reverse-engineered: Always include the last possible slice.
                    if (slice + stepSize >= numSlices && slice + 1 < numSlices)
                        slice = numSlices - 1 - stepSize;
                }
                GeometryWriter.WriteToFile(corename, _cores);
            }
        }
Exemple #29
0
        protected void GenerateGeometryFlatXY(Plane plane, LineSet lines)
        {
            // Write poition and UV-map data.
            var stream = new DataStream(_numVertices * _vertexSizeBytes, true, true);
            Vector3 zAxis = plane.ZAxis;
            for (int index = 0; index < lines.Lines.Length; ++index)
            {
                Line line = lines.Lines[index];
                if (line.Length < 2)
                    continue;
                Debug.Assert(line.Length == lines.Lines[index].Length);
                stream.Write(new Vector4(plane.Origin + (plane.XAxis * line.Positions[0][0] + plane.YAxis * line.Positions[0][1] ), line.Positions[0][2]));
                for (int point = 1; point < line.Positions.Length - 1; ++point)
                {
                    Vector4 pos = new Vector4(plane.Origin + (plane.XAxis * line.Positions[point][0] + plane.YAxis * line.Positions[point][1]), line.Positions[point][2]);
                    stream.Write(pos);
                    stream.Write(pos);
                }
                int end = line.Positions.Length - 1;
                stream.Write(new Vector4(plane.Origin + (plane.XAxis * line.Positions[end][0] + plane.YAxis * line.Positions[end][1]), line.Positions[end][2]));
            }
            stream.Position = 0;

            // Create and fill buffer.
            _vertices = new Buffer(_device, stream, new BufferDescription()
            {
                BindFlags = BindFlags.VertexBuffer,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.None,
                SizeInBytes = _numVertices * _vertexSizeBytes,
                Usage = ResourceUsage.Default
            });
            stream.Dispose();
        }
        public override void ClickSelection(Vector2 point)
        {
            if (LineX > 0)
            {
                _lastSelection = (_lastSelection + 1) % LineX;
                Vec3 vec = new Vec3((Vec2)point, 0);
                if (_velocity.Grid.InGrid(vec))
                {
                    Vector3[] line    = _integrator.IntegrateLineForRendering(vec).Points.ToArray();
                    Line      newLine = new Line()
                    {
                        Positions = line
                    };
                    var set = new LineSet(new Line[] { newLine })
                    {
                        Color = _flipColor? Vector3.UnitX : Vector3.UnitZ
                    };

                    set.Thickness *= 3;
                    var ball = new LineBall(Plane, set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                    _selections.Add(ball);

                    if (_selections.Count > LineX)
                    {
                        _selections.RemoveAt(0);
                        _selectionsAngle.RemoveAt(0);
                        _steadySelection.RemoveAt(0);
                    }

                    Graph2D[] angle = FieldAnalysis.GetDistanceToAngle(_core, Vector2.Zero, new LineSet(new Line[] { newLine }));
                    Debug.Assert(angle.Length == 1);

                    for (int p = 0; p < newLine.Length; ++p)
                    {
                        Vector3 sph = FieldAnalysis.SphericalPosition(_core[0], (float)(angle[0].X[p] * 0.5f / Math.PI), angle[0].Fx[p]);
                        newLine[p] = new Vector3(sph.X, sph.Y, angle[0].X[p] - angle[0].X[0]);
                    }
                    set = new LineSet(new Line[] { newLine })
                    {
                        Color = _flipColor ? Vector3.UnitX : Vector3.UnitZ
                    };
                    set.Thickness *= 3;
                    ball           = new LineBall(Plane, set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                    _selectionsAngle.Add(ball);

                    _integrator.Field       = _steadyField;
                    _integrator.MaxNumSteps = 50;
                    line    = _integrator.IntegrateLineForRendering(new Vec2(vec.X, vec.Y)).Points.ToArray();
                    newLine = new Line()
                    {
                        Positions = line
                    };
                    set = new LineSet(new Line[] { newLine })
                    {
                        Color = _flipColor ? Vector3.UnitX : Vector3.UnitZ
                    };
                    set.Thickness *= 3;
                    ball           = new LineBall(new Plane(Plane, Vector3.UnitZ * 0.1f), set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                    _steadySelection.Add(ball);
                    _integrator.Field       = _velocity;
                    _integrator.MaxNumSteps = 10000;

                    _flipColor = !_flipColor;
                    //var set = new LineSet(_selections.ToArray()) { Color = _selections.Count % 2 == 0 ? Vector3.UnitX : Vector3.UnitY };
                    //_lines = new LineBall(Plane, set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                }
            }
        }
Exemple #31
0
        public List <Renderable> ComputeStatistics()
        {
            List <Renderable> result = new List <Renderable>(200);

            result.Add(new FieldPlane(Plane, Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), _currentSetting.Shader, _currentSetting.Colormap));

            if (!_initialized)
            {
                return(result);
            }



            result.Add(new LineBall(Plane, new LineSet(new Line[] { new Line()
                                                                    {
                                                                        Positions = new Vector3[] { _startSelection, _endSelection }
                                                                    } })));


            bool completelyNew = false;

            // ~~~~~~~~~~~~~~ Get new Start Points ~~~~~~~~~~~~~~ //
            if (_lastSetting == null ||
                SliceTimeMainChanged ||
                LineXChanged ||
                _selectionChanged)
            {
                int     numPoints   = _startSelection == null ? 0 : Math.Max(2, _currentSetting.LineX + 1);
                Point[] startPoints = new Point[numPoints];

                // Compute point positions (linear interpolation).
                for (int x = 0; x < numPoints; ++x)
                {
                    float t = (float)x / (numPoints - 1);
                    startPoints[x] = new Point()
                    {
                        Position = _startSelection * (1.0f - t) + _endSelection * t
                    };
                }
                _linePoints = new PointSet <Point>(startPoints);
                _values     = new float[_linePoints.Length];

                completelyNew = true;
            }

            // ~~~~~~~~~~~~ Compute Selected Measure ~~~~~~~~~~~~ //
            if (completelyNew ||
                MeasureChanged ||
                FlatChanged ||
                IntegrationTimeChanged ||
                IntegrationTypeChanged ||
                StepSizeChanged)
            {
                // ~~~~~~~~~~~~~ Compute Scalar FIeld ~~~~~~~~~~~~~~~ //
                ScalarField measure = null;
                switch (_currentSetting.Measure)
                {
                // Velocity Length / Pathline Length.
                case RedSea.Measure.VELOCITY:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.VFLength, 1).Scalars[0] as ScalarField;
                    break;

                case RedSea.Measure.SURFACE_HEIGHT:
                    break;

                case RedSea.Measure.SALINITY:
                    break;

                case RedSea.Measure.TEMPERATURE:
                    break;

                case RedSea.Measure.DIVERGENCE:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.Divergence, 1).Scalars[0] as ScalarField;
                    break;

                // Closeness of Pathline.
                case RedSea.Measure.DIVERGENCE_2D:
                    break;

                case RedSea.Measure.VORTICITY:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.Vorticity, 1).Scalars[0] as ScalarField;
                    break;

                case RedSea.Measure.SHEAR:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.Shear, 1).Scalars[0] as ScalarField;
                    break;
                }

                // ~~~~~~~~~~~~~~~~ Sample Field ~~~~~~~~~~~~~~~~~~~ //
                switch (_currentSetting.Measure)
                {
                // Velocity Length / Pathline Length.
                case RedSea.Measure.VELOCITY:
                    if (_currentSetting.IntegrationTime == 0)
                    {
                        for (int index = 0; index < _values.Length; ++index)
                        {
                            _values[index] = measure.Sample(((Vec3)_linePoints.Points[index].Position).ToVec2());
                        }
                    }
                    else
                    {
                        VectorField.Integrator integrator = VectorField.Integrator.CreateIntegrator(Velocity, _currentSetting.IntegrationType);
                        integrator.Direction = Sign.POSITIVE;
                        integrator.StepSize  = _currentSetting.StepSize;

                        LineSet line = integrator.Integrate(_linePoints, _currentSetting.Flat, _currentSetting.IntegrationTime)[0];
                        for (int index = 0; index < _values.Length; ++index)
                        {
                            _values[index] = line.Lines[index].LineLength;
                        }
                        result.Add(new LineBall(Plane, line));
                    }
                    break;

                // Simply sample a field.
                case RedSea.Measure.SURFACE_HEIGHT:
                case RedSea.Measure.SALINITY:
                case RedSea.Measure.TEMPERATURE:
                case RedSea.Measure.DIVERGENCE:
                case RedSea.Measure.VORTICITY:
                case RedSea.Measure.SHEAR:
                    for (int index = 0; index < _values.Length; ++index)
                    {
                        _values[index] = measure.Sample(((Vec3)_linePoints.Points[index].Position).ToVec2());
                    }
                    break;

                // Closeness of Pathline.
                case RedSea.Measure.DIVERGENCE_2D:

                    break;
                }
                completelyNew = true;
            }

            //if (completelyNew ||
            //    AlphaStableChanged ||
            //    LineSettingChanged)
            //{
            // ~~~~~~~~~~~~~~~~ Display the Graph ~~~~~~~~~~~~~~~ //
            result.Add(FieldAnalysis.BuildGraph(Plane, _linePoints, _values, _currentSetting.AlphaStable, _currentSetting.LineSetting));
            //}
            _selectionChanged = false;
            return(result);
        }