AddTube() public method

Adds a tube with a custom section.
public AddTube ( IList path, IList values, IList diameters, IList section, bool isTubeClosed, bool isSectionClosed ) : void
path IList /// A list of points defining the centers of the tube. ///
values IList /// The texture coordinate X values (optional). ///
diameters IList /// The diameters (optional). ///
section IList /// The section to extrude along the tube path. ///
isTubeClosed bool /// If the tube is closed set to true . ///
isSectionClosed bool /// if set to true [is section closed]. ///
return void
        /// <summary>
        /// Do the tessellation and return the <see cref="MeshGeometry3D"/> .
        /// </summary>
        /// <returns>
        /// A triangular mesh geometry.
        /// </returns>
        protected override MeshGeometry3D Tessellate()
        {
            if (this.Path == null || this.Path.Count < 2)
            {
                return null;
            }

            // See also "The GLE Tubing and Extrusion Library":
            // http://linas.org/gle/
            // http://sharpmap.codeplex.com/Thread/View.aspx?ThreadId=18864
            var builder = new MeshBuilder(false, this.TextureCoordinates != null);

            var sectionXAxis = this.SectionXAxis;
            if (sectionXAxis.Length < 1e-6)
            {
                sectionXAxis = new Vector3D(1, 0, 0);
            }

            var forward = this.Path[1] - this.Path[0];
            var up = Vector3D.CrossProduct(forward, sectionXAxis);
            if (up.LengthSquared < 1e-6)
            {
                sectionXAxis = forward.FindAnyPerpendicular();
            }

            builder.AddTube(
                this.Path,
                this.Angles,
                this.TextureCoordinates,
                this.Diameters,
                this.Section,
                sectionXAxis,
                this.IsPathClosed,
                this.IsSectionClosed);

            // Add Caps if wanted and needed
            if (this.AddCaps && !this.IsPathClosed && builder.Positions.Count >= Section.Count)
            {
                var sCount = Section.Count;
                var normals = new Vector3D[sCount];
                var vertices = new Point3D[sCount];
                var pCount = Path.Count;

                //Add back cap
                var circleBack = builder.Positions.Skip(builder.Positions.Count - sCount).Take(sCount).ToArray();
                var normal = Path[pCount - 1] - Path[pCount - 2];
                normal.Normalize();
                for (int i = 0; i < normals.Length; ++i)
                {
                    normals[i] = normal;
                }
                builder.AddTriangleFan(circleBack, normals);
                //Add front cap
                var circleFront = builder.Positions.Take(sCount).ToArray();
                normal = Path[0] - Path[1];
                normal.Normalize();

                for (int i = 0; i < normals.Length; ++i)
                {
                    normals[i] = normal;
                }
                builder.AddTriangleFan(circleFront, normals);
            }

            return builder.ToMesh();
        }
示例#2
0
        private void CreateModel()
        {
            const double dt = 0.1;
            const int nSteps = 100;
            var mb = new MeshBuilder(true, true);
            for (double y0 = -5; y0 <= 5; y0 += 0.25)
            {
                var p0 = new Point(-3, y0);
                Point[] pts = Solve(Velocity, p0, dt, nSteps);
                var vel = new double[pts.Length];
                var diam = new double[pts.Length];
                int i = 0;
                var pts3d = new Point3D[pts.Length];
                double vmax = 0;
                foreach (Point pt in pts)
                {
                    pts3d[i] = new Point3D(pt.X, pt.Y, 0);
                    double v = Velocity(pt.X, pt.Y).Length;
                    if (v > vmax) vmax = v;
                    vel[i++] = v;
                }
                for (int j = 0; j < vel.Length; j++)
                    vel[j] /= vmax;
                for (int j = 0; j < vel.Length; j++)
                    diam[j] = 0.075;

                mb.AddTube(pts3d, vel, diam, 12, false);
            }

            this.StreamLinesModel = new GeometryModel3D();
            this.StreamLinesModel.Geometry = mb.ToMesh();
            this.StreamLinesModel.Material = Materials.Hue;
            this.StreamLinesModel.BackMaterial = Materials.Hue;
        }
示例#3
0
        void AddTube(List<Point3D> path, Color color)
        {
            var mb = new MeshBuilder();

            mb.AddTube(path, 0.1, 3, false);
            var geom = new GeometryModel3D { Geometry = mb.ToMesh(true), Material = MaterialHelper.CreateMaterial(color) };          // create a model
            var model = new ModelVisual3D();
            model.Content = geom;
            _Helix.Children.Add(model);
        }
示例#4
0
        public TubeSegment(Point3D startPoint, Point3D endPoint, double d1, double d2)
        {
            var meshBuilder = new MeshBuilder(false, false);

            var h1 = 0.1*d1;
            var h2 = 0.1*d2;

            var deltaStart = GeometryHelper.GetDeltaPoint(startPoint, endPoint, h1);
            var deltaEnd = GeometryHelper.GetDeltaPoint(endPoint, startPoint, h2);
            var points = new List<Point3D>() { deltaStart, deltaEnd };
            //var points = new List<Point3D>() { startPoint, endPoint };

            var dd1 = d1*0.9;
            var dd2 = d2*0.9;

            var diameters = new[] { dd1, dd2 };
            //var diameters = new[] { d1, d2 };
            meshBuilder.AddTube(points, new double[] { 0, 0 }, diameters, 10, false);

            Model = meshBuilder.ToMesh();
        }
        /// <summary>
        /// Place a tube down the center of the plot
        /// so all the arrows will connect to a center point (origin).
        /// </summary>
        /// <param name="numBins">Number of bins in the plot.</param>
        /// <returns>3D model of the center tube.</returns>
        private GeometryModel3D CreateOriginTube(int numBins)
        {
            double tubeDia = ARROW_HEAD_SIZE;       // Tube Diameter.  Same as Arrows.      Min = 0.1 Max = 1.0
            int tubeTheta = 30;                     // Tube ThetaDiv.                       Min = 3 Max = 100

            double xAxisLoc = 0;
            double yAxisLoc = 0;
            double zAxisLoc = 0;

            if (YAxis)
            {
                yAxisLoc = -numBins * TRANSLATION_SCALE;
            }
            else
            {
                xAxisLoc = numBins * TRANSLATION_SCALE;
            }

            // Create 2 points, the top and bottom
            List<Point3D> pts = new List<Point3D>();
            pts.Add(new Point3D(0, 0, 0));
            pts.Add(new Point3D(xAxisLoc, yAxisLoc, zAxisLoc));

            // Create the tube based off the points
            var mb = new MeshBuilder(false, false);
            mb.AddTube(pts, tubeDia, tubeTheta, true);
            Geometry3D geometry = mb.ToMesh();

            // Set the color
            Material material = MaterialHelper.CreateMaterial(Color.FromArgb(255, 255,250,213));
            material.Freeze();

            var model = new GeometryModel3D(geometry, material);

            return model;
        }
        private Model3D CreateModel()
        {
            var plotModel = new Model3DGroup();

            int rows = Points.GetUpperBound(0) + 1;
            int columns = Points.GetUpperBound(1) + 1;
            double minX = double.MaxValue;
            double maxX = double.MinValue;
            double minY = double.MaxValue;
            double maxY = double.MinValue;
            double minZ = double.MaxValue;
            double maxZ = double.MinValue;
            double minColorValue = double.MaxValue;
            double maxColorValue = double.MinValue;
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < columns; j++)
                {
                    double x = Points[i, j].X;
                    double y = Points[i, j].Y;
                    double z = Points[i, j].Z;
                    maxX = Math.Max(maxX, x);
                    maxY = Math.Max(maxY, y);
                    maxZ = Math.Max(maxZ, z);
                    minX = Math.Min(minX, x);
                    minY = Math.Min(minY, y);
                    minZ = Math.Min(minZ, z);
                    if (ColorValues != null)
                    {
                        maxColorValue = Math.Max(maxColorValue, ColorValues[i, j]);
                        minColorValue = Math.Min(minColorValue, ColorValues[i, j]);
                    }
                }

            // make color value 0 at texture coordinate 0.5
            if (Math.Abs(minColorValue) < Math.Abs(maxColorValue))
                minColorValue = -maxColorValue;
            else
                maxColorValue = -minColorValue;

            // set the texture coordinates by z-value or ColorValue
            var texcoords = new Point[rows,columns];
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < columns; j++)
                {
                    double u = (Points[i, j].Z - minZ)/(maxZ - minZ);
                    if (ColorValues != null)
                        u = (ColorValues[i, j] - minColorValue)/(maxColorValue - minColorValue);
                    texcoords[i, j] = new Point(u, u);
                }

            var surfaceMeshBuilder = new MeshBuilder();
            surfaceMeshBuilder.AddRectangularMesh(Points, texcoords);

            var surfaceModel = new GeometryModel3D(surfaceMeshBuilder.ToMesh(),
                                                   MaterialHelper.CreateMaterial(SurfaceBrush, null, null, 1, 0));
            surfaceModel.BackMaterial = surfaceModel.Material;

            var axesMeshBuilder = new MeshBuilder();
            for (double x = minX; x <= maxX; x += IntervalX)
            {
                double j = (x - minX)/(maxX - minX)*(columns - 1);
                var path = new List<Point3D> {new Point3D(x, minY, minZ)};
                for (int i = 0; i < rows; i++)
                {
                    path.Add(BilinearInterpolation(Points, i, j));
                }
                path.Add(new Point3D(x, maxY, minZ));

                axesMeshBuilder.AddTube(path, LineThickness, 9, false);
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(x.ToString(), Brushes.Black, true, FontSize,
                                                                           new Point3D(x, minY - FontSize*2.5, minZ),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }

            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("X-axis", Brushes.Black, true, FontSize,
                                                                           new Point3D((minX + maxX)*0.5,
                                                                                       minY - FontSize*6, minZ),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }

            for (double y = minY; y <= maxY; y += IntervalY)
            {
                double i = (y - minY)/(maxY - minY)*(rows - 1);
                var path = new List<Point3D> {new Point3D(minX, y, minZ)};
                for (int j = 0; j < columns; j++)
                {
                    path.Add(BilinearInterpolation(Points, i, j));
                }
                path.Add(new Point3D(maxX, y, minZ));

                axesMeshBuilder.AddTube(path, LineThickness, 9, false);
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(y.ToString(), Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize*3, y, minZ),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("Y-axis", Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize*10,
                                                                                       (minY + maxY)*0.5, minZ),
                                                                           new Vector3D(0, 1, 0), new Vector3D(-1, 0, 0));
                plotModel.Children.Add(label);
            }
            double z0 = (int) (minZ/IntervalZ)*IntervalZ;
            for (double z = z0; z <= maxZ + double.Epsilon; z += IntervalZ)
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(z.ToString(), Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize*3, maxY, z),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 0, 1));
                plotModel.Children.Add(label);
            }
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("Z-axis", Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize*10, maxY,
                                                                                       (minZ + maxZ)*0.5),
                                                                           new Vector3D(0, 0, 1), new Vector3D(1, 0, 0));
                plotModel.Children.Add(label);
            }


            var bb = new Rect3D(minX, minY, minZ, maxX - minX, maxY - minY, 0*(maxZ - minZ));
            axesMeshBuilder.AddBoundingBox(bb, LineThickness);

            var axesModel = new GeometryModel3D(axesMeshBuilder.ToMesh(), Materials.Black);

            plotModel.Children.Add(surfaceModel);
            plotModel.Children.Add(axesModel);

            return plotModel;
        }
示例#7
0
        private static void BuildRailing(
            MeshBuilder railingBuilder,
            List<Point3D> bases,
            double height,
            double diameter,
            int railings)
        {
            foreach (var point in bases)
            {
                railingBuilder.AddCylinder(point, point + new Vector3D(0, 0, height), diameter, 10);
            }

            for (int i = 1; i <= railings; i++)
            {
                var h = height * i / railings;
                var path = bases.Select(p => p + new Vector3D(0, 0, h)).ToArray();
                railingBuilder.AddTube(path, diameter, 10, false);
            }
        }
示例#8
0
        /// <summary>
        /// Creates a rather ugly visual representatino of the polyline.
        /// Fixed in size with respect to the model.
        /// </summary>
        /// <param name="highlighted">The destination visual component to replace the content of.</param>
        internal void SetToVisual(MeshVisual3D highlighted)
        {
            if (_geomPoints == null)
                return;

            var lines = new LinesVisual3D { Color = Colors.Yellow };
            var axesMeshBuilder = new MeshBuilder();

            List<Point3D> path = new List<Point3D>();
            foreach (var item in _geomPoints)
            {
                axesMeshBuilder.AddSphere(item.Point, 0.1);
                path.Add(item.Point);
            }
            if (_geomPoints.Count > 1)
            {
                double lineThickness = 0.05;
                axesMeshBuilder.AddTube(path, lineThickness, 9, false);
            }
            highlighted.Content = new GeometryModel3D(axesMeshBuilder.ToMesh(), Materials.Yellow);
        }
示例#9
0
        private void AppearanceChanged()
        {
            var builder = new MeshBuilder(false, true);

            // hard code a kerb section
            var section = new PointCollection();
            int m = 41;
            double n = 4;
            double a = this.Width / 2;
            double b = this.Height;
            for (int i = 0; i < m; i++)
            {
                double t = Math.PI * i / (m - 1);
                section.Add(new Point(
                    a * Math.Sign(Math.Cos(t)) * Math.Pow(Math.Abs(Math.Cos(t)), 2 / n),
                    -b * Math.Sign(Math.Sin(t)) * Math.Pow(Math.Abs(Math.Sin(t)), 2 / n)));
            }

            // calculate the texture coordinates
            var values = new List<double> { 0 };
            for (int i = 1; i < this.Positions.Count; i++)
            {
                var d = this.Positions[i - 1].DistanceTo(this.Positions[i]);
                values.Add(values[values.Count - 1] + (d / this.Length));
            }

            // create the extruded geometry
            builder.AddTube(this.Positions, null, values, null, section, new Vector3D(1, 0, 0), false, false);

            this.kerbModel.Geometry = builder.ToMesh();
        }
        private Model3D CreateModel()
        {
            if (Points == null || Points.Length == 0) return null;


            var plotModel = new Model3DGroup();

            int rows = Points.GetUpperBound(0) + 1;
            int columns = Points.GetUpperBound(1) + 1;
            double minX = double.MaxValue;
            double maxX = double.MinValue;
            double minY = double.MaxValue;
            double maxY = double.MinValue;
            double minZ = double.MaxValue;
            double maxZ = double.MinValue;
            double minColorValue = double.MaxValue;
            double maxColorValue = double.MinValue;
            minX = Points.OfType<Point3D>().Min(x => x.X);
            maxX = Points.OfType<Point3D>().Max(x => x.X);
            minY = Points.OfType<Point3D>().Min(x => x.Y);
            maxY = Points.OfType<Point3D>().Max(x => x.Y);
            minZ = Points.OfType<Point3D>().Min(x => x.Z);
            maxZ = Points.OfType<Point3D>().Max(x => x.Z);
            if (ColorValues != null) minColorValue = ColorValues.OfType<double>().Min(x => x);
            if (ColorValues != null) maxColorValue = ColorValues.OfType<double>().Max(x => x);

            if (Functions.Abs(minColorValue) < Functions.Abs(maxColorValue))
                minColorValue = -maxColorValue;
            else
                maxColorValue = -minColorValue;

            BitmapPixelMaker bm_maker =
                new BitmapPixelMaker(columns, rows);

            for (int ix = 0; ix < columns; ix++)
            {
                for (int iy = 0; iy < rows; iy++)
                {
                    try
                    {
                        byte red, green, blue;
                        MapRainbowColor(Points[ix, iy].Z, minZ, maxZ,
                            out red, out green, out blue);
                        bm_maker.SetPixel(ix, iy, red, green, blue, 255);
                    }
                    catch
                    {

                    }
                }
            }

            var texcoords = new Point[rows, columns];
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < columns; j++)
                {
                    texcoords[i, j] = new Point(i, j);
                }

            var surfaceMeshBuilder = new MeshBuilder();
            surfaceMeshBuilder.AddRectangularMesh(Points, texcoords);
            var surfaceModel = new GeometryModel3D(surfaceMeshBuilder.ToMesh(),
                MaterialHelper.CreateMaterial(new ImageBrush(bm_maker.MakeBitmap(128, 128)), null, null, 1, 0));
            surfaceModel.BackMaterial = surfaceModel.Material;

            var axesMeshBuilder = new MeshBuilder();
            for (double x = minX; x <= maxX; x += IntervalX)
            {
                double j = (x - minX) / (maxX - minX) * (columns - 1);
                var path = new List<Point3D> {new Point3D(x, minY, minZ)};
                for (int i = 0; i < rows; i++)
                {
                    path.Add(BilinearInterpolation(Points, i, j));
                }
                path.Add(new Point3D(x, maxY, minZ));

                axesMeshBuilder.AddTube(path, LineThickness, 9, false);
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(x.ToString(), Brushes.Black, true,
                    FontSize * 3,
                    new Point3D(x, minY - FontSize * 2.5, minZ),
                    new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("Axe réel", Brushes.Black, true,
                    FontSize * 10,
                    new Point3D((minX + maxX) * 0.25,
                        minY - FontSize * 6 - 0.5, minZ),
                    new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }
            for (double y = minY; y <= maxY; y += IntervalY)
            {
                double i = (y - minY) / (maxY - minY) * (rows - 1);
                var path = new List<Point3D> {new Point3D(minX, y, minZ)};
                for (int j = 0; j < columns; j++)
                {
                    path.Add(BilinearInterpolation(Points, i, j));
                }
                path.Add(new Point3D(maxX, y, minZ));

                axesMeshBuilder.AddTube(path, LineThickness, 9, false);
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(y.ToString(), Brushes.Black, true,
                    FontSize * 3,
                    new Point3D(minX - FontSize * 3, y, minZ),
                    new Vector3D(0, 1, 0), new Vector3D(1, 0, 0));
                plotModel.Children.Add(label);
            }
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("Axe imaginaire", Brushes.Black, true,
                    FontSize * 10,
                    new Point3D(minX - FontSize * 10,
                        (minY + maxY) * 0.5, minZ),
                    new Vector3D(0, 1, 0), new Vector3D(1, 0, 0));
                plotModel.Children.Add(label);
            }
            double z0 = (int) (minZ / IntervalZ) * IntervalZ;
            for (double z = z0; z <= maxZ + double.Epsilon; z += IntervalZ)
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(z.ToString(), Brushes.Black, true,
                    FontSize * 3,
                    new Point3D(minX - FontSize * 3, maxY, z),
                    new Vector3D(1, 0, 0), new Vector3D(0, 0, 1));
                plotModel.Children.Add(label);
            }
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("Module", Brushes.Black, true, FontSize * 10,
                    new Point3D(minX - FontSize * 10 - 1.5, maxY,
                        (minZ + maxZ) * 0.5),
                    new Vector3D(1, 0, 0), new Vector3D(0, 0, 1));
                plotModel.Children.Add(label);
            }
            var bb = new Rect3D(minX, minY, minZ, maxX - minX, maxY - minY, (maxZ - minZ));
            axesMeshBuilder.AddBoundingBox(bb, LineThickness);

            var axesModel = new GeometryModel3D(axesMeshBuilder.ToMesh(), Materials.Black);

            plotModel.Children.Add(surfaceModel);
            plotModel.Children.Add(axesModel);

            return plotModel;
        }
        /// <summary>
        /// This function contains all the "business logic" for constructing a SurfacePlot 3D. 
        /// </summary>
        /// <returns>A Model3DGroup containing all the component models (mesh, surface definition, grid objects, etc).</returns>
        private Model3DGroup CreateModel()
        {
            var newModelGroup = new Model3DGroup();
            double lineThickness = 0.01;
            double axesOffset = 0.05;

            // Get relevant constaints from the DataPoints object
            int numberOfRows = DataPoints.GetUpperBound(0) + 1;
            int numberOfColumns = DataPoints.GetUpperBound(1) + 1;

            // Determine the x, y, and z ranges of the DataPoints collection
            double minX = double.MaxValue;
            double maxX = double.MinValue;
            double minY = double.MaxValue;
            double maxY = double.MinValue;
            double minZ = double.MaxValue;
            double maxZ = double.MinValue;

            double minColorValue = double.MaxValue;
            double maxColorValue = double.MinValue;

            for (int i = 0; i < numberOfRows; i++)
            {
                for (int j = 0; j < numberOfColumns; j++)
                {
                    double x = DataPoints[i, j].X;
                    double y = DataPoints[i, j].Y;
                    double z = DataPoints[i, j].Z;
                    maxX = Math.Max(maxX, x);
                    maxY = Math.Max(maxY, y);
                    maxZ = Math.Max(maxZ, z);
                    minX = Math.Min(minX, x);
                    minY = Math.Min(minY, y);
                    minZ = Math.Min(minZ, z);
                    if (ColorValues != null)
                    {
                        maxColorValue = Math.Max(maxColorValue, ColorValues[i, j]);
                        minColorValue = Math.Min(minColorValue, ColorValues[i, j]);
                    }
                }
            }

            /* TEMP */
            int numberOfXAxisTicks = 10;
            int numberOfYAxisTicks = 10;
            int numberOfZAxisTicks = 5;
            double XAxisInterval = (maxX - minX) / numberOfXAxisTicks;
            double YAxisInterval = (maxY - minY) / numberOfYAxisTicks;
            double ZAxisInterval = (maxZ - minZ) / numberOfZAxisTicks;
            /* /TEMP */

            // Set color value to 0 at texture coordinate 0.5, with an even spread in either direction
            if (Math.Abs(minColorValue) < Math.Abs(maxColorValue)) { minColorValue = -maxColorValue; }
            else                                                   { maxColorValue = -minColorValue; }

            // Set the texture coordinates by either z-value or ColorValue
            var textureCoordinates = new Point[numberOfRows, numberOfColumns];
            for (int i = 0; i < numberOfRows; i++)
            {
                for (int j = 0; j < numberOfColumns; j++)
                {
                    double tc;
                    if (ColorValues != null) { tc = (ColorValues[i, j] - minColorValue) / (maxColorValue - minColorValue); }
                    else                     { tc = (DataPoints[i, j].Z - minZ) / (maxZ - minZ); }
                    textureCoordinates[i, j] = new Point(tc, tc);
                }
            }

            // Build the surface model (i.e. the coloured surface model)
            MeshBuilder surfaceModelBuilder = new MeshBuilder();
            surfaceModelBuilder.AddRectangularMesh(DataPoints, textureCoordinates);

            GeometryModel3D surfaceModel = new GeometryModel3D(surfaceModelBuilder.ToMesh(), MaterialHelper.CreateMaterial(SurfaceBrush, null, null, 1, 0));
            surfaceModel.BackMaterial = surfaceModel.Material;

            // Instantiate MeshBuilder objects for the Grid and SurfaceMeshLines meshes
            MeshBuilder surfaceMeshLinesBuilder = new MeshBuilder();
            MeshBuilder surfaceContourLinesBuilder = new MeshBuilder();
            MeshBuilder gridBuilder = new MeshBuilder();

            // Build the axes labels model (i.e. the object that holds the axes labels and ticks)
            ModelVisual3D axesLabelsModel = new ModelVisual3D();

            // Loop through x intervals - for the surface meshlines, the grid, and X axes ticks
            for (double x = minX; x <= maxX + 0.0001; x += XAxisInterval)
            {
                // Add surface mesh lines which denote intervals along the x-axis
                var surfacePath = new List<Point3D>();
                double i = (x - minX) / (maxX - minX) * (numberOfColumns - 1);
                for (int j = 0; j < numberOfColumns; j++)
                {
                    surfacePath.Add(DoBilinearInterpolation(DataPoints, i, j));
                }
                surfaceMeshLinesBuilder.AddTube(surfacePath, lineThickness, 9, false);

                // Axes labels
                BillboardTextVisual3D label = new BillboardTextVisual3D();
                label.Text = string.Format("{0:F2}", x);
                label.Position = new Point3D(x, minY - axesOffset, minZ - axesOffset);
                axesLabelsModel.Children.Add(label);

                // Grid lines
                var gridPath = new List<Point3D>();
                gridPath.Add(new Point3D(x, minY, minZ));
                gridPath.Add(new Point3D(x, maxY, minZ));
                gridPath.Add(new Point3D(x, maxY, maxZ));
                gridBuilder.AddTube(gridPath, lineThickness, 9, false);

            }

            // Loop through y intervals - for the surface meshlines, the grid, and Y axes ticks
            for (double y = minY; y <= maxY + 0.0001; y += YAxisInterval)
            {
                // Add surface mesh lines which denote intervals along the y-axis
                var path = new List<Point3D>();
                double j = (y - minY) / (maxY - minY) * (numberOfRows - 1);
                for (int i = 0; i < numberOfRows; i++)
                {
                    path.Add(DoBilinearInterpolation(DataPoints, i, j));
                }
                surfaceMeshLinesBuilder.AddTube(path, lineThickness, 9, false);

                // Axes labels
                BillboardTextVisual3D label = new BillboardTextVisual3D();
                label.Text = string.Format("{0:F2}", y);
                label.Position = new Point3D(minX - axesOffset, y, minZ - axesOffset);
                axesLabelsModel.Children.Add(label);

                // Grid lines
                var gridPath = new List<Point3D>();
                gridPath.Add(new Point3D(minX, y, minZ));
                gridPath.Add(new Point3D(maxX, y, minZ));
                gridPath.Add(new Point3D(maxX, y, maxZ));
                gridBuilder.AddTube(gridPath, lineThickness, 9, false);
            }

            // Loop through z intervals - for the grid, and Z axes ticks
            for (double z = minZ; z <= maxZ + 0.0001; z += ZAxisInterval)
            {
                // Grid lines
                var path = new List<Point3D>();
                path.Add(new Point3D(minX, maxY, z));
                path.Add(new Point3D(maxX, maxY, z));
                path.Add(new Point3D(maxX, minY, z));
                gridBuilder.AddTube(path, lineThickness, 9, false);

                // Axes labels
                BillboardTextVisual3D label = new BillboardTextVisual3D();
                label.Text = string.Format("{0:F2}", z);
                label.Position = new Point3D(minX - axesOffset, maxY + axesOffset, z);
                axesLabelsModel.Children.Add(label);
            }

            // Add axes labels
            BillboardTextVisual3D xLabel = new BillboardTextVisual3D();
            xLabel.Text = "X Axis";
            xLabel.Position = new Point3D((maxX - minX) / 2, minY - 3 * axesOffset, minZ - 5 * axesOffset);
            axesLabelsModel.Children.Add(xLabel);
            BillboardTextVisual3D yLabel = new BillboardTextVisual3D();
            yLabel.Text = "Y Axis";
            yLabel.Position = new Point3D(minX - 3 * axesOffset, (maxY - minY) / 2, minZ - 5 * axesOffset);
            axesLabelsModel.Children.Add(yLabel);
            BillboardTextVisual3D zLabel = new BillboardTextVisual3D();
            zLabel.Text = "Z Axis";
            zLabel.Position = new Point3D(minX - 5 * axesOffset, maxY + 5 * axesOffset, 0); // Note: trying to find the midpoint of minZ, maxZ doesn't work when minZ = -0.5 and maxZ = 0.5...
            axesLabelsModel.Children.Add(zLabel);

            // Create models from MeshBuilders
            GeometryModel3D surfaceMeshLinesModel = new GeometryModel3D(surfaceMeshLinesBuilder.ToMesh(), Materials.Black);
            GeometryModel3D gridModel = new GeometryModel3D(gridBuilder.ToMesh(), Materials.Black);

            // Update model group
            //this.Children.Add(axesLabelsModel);
            newModelGroup.Children.Add(surfaceModel);
            newModelGroup.Children.Add(surfaceMeshLinesModel);
            newModelGroup.Children.Add(gridModel);

            //ScaleTransform3D surfaceTransform = new ScaleTransform3D(20, 20, 20, 0, 0, 0);
            //newModelGroup.Transform = surfaceTransform;

            return newModelGroup;
        }
示例#12
0
        /// <summary>
        /// The create solution geometry.
        /// </summary>
        /// <param name="solution">The solution.</param>
        /// <param name="height">The height.</param>
        /// <param name="diameter">The diameter.</param>
        /// <returns>The solution tube geometry.</returns>
        private MeshGeometry3D CreateSolutionGeometry(IEnumerable<Cell> solution, double height = 0.25, double diameter = 0.25)
        {
            var builder = new MeshBuilder();
            var path = solution.Select(cell => this.GetPosition(cell, height)).ToList();

            var spline = CanonicalSplineHelper.CreateSpline(path, 0.7, null, false, 0.05);
            builder.AddTube(spline, diameter, 13, false);
            return builder.ToMesh();
        }
示例#13
0
        /// <summary>
        /// Do the tessellation and return the <see cref="MeshGeometry3D"/> .
        /// </summary>
        /// <returns>
        /// A triangular mesh geometry.
        /// </returns>
        protected override MeshGeometry3D Tessellate()
        {
            if (this.Path == null || this.Path.Count < 2)
            {
                return null;
            }

            // See also "The GLE Tubing and Extrusion Library":
            // http://linas.org/gle/
            // http://sharpmap.codeplex.com/Thread/View.aspx?ThreadId=18864
            var builder = new MeshBuilder(false, this.TextureCoordinates != null);

            var sectionXAxis = this.SectionXAxis;
            if (sectionXAxis.Length < 1e-6)
            {
                sectionXAxis = new Vector3D(1, 0, 0);
            }

            var forward = this.Path[1] - this.Path[0];
            var up = Vector3D.CrossProduct(forward, sectionXAxis);
            if (up.LengthSquared < 1e-6)
            {
                sectionXAxis = forward.FindAnyPerpendicular();
            }

            builder.AddTube(
                this.Path,
                this.Angles,
                this.TextureCoordinates,
                this.Diameters,
                this.Section,
                sectionXAxis,
                this.IsPathClosed,
                this.IsSectionClosed);
            return builder.ToMesh();
        }
示例#14
0
        private void UpdateModel()
        {
            // http://en.wikipedia.org/wiki/Lorenz_attractor
            Func<double[], double[]> lorenzAttractor = x =>
                                                           {
                                                               var dx = new double[3];
                                                               dx[0] = sigma * (x[1] - x[0]);
                                                               dx[1] = x[0] * (rho - x[2]) - x[1];
                                                               dx[2] = x[0] * x[1] - beta * x[2];
                                                               return dx;
                                                           };
            // solve the ODE
            var x0 = new[] { 0, 1, 1.05 };
            IEnumerable<double[]> solution = EulerSolver(lorenzAttractor, x0, 25);
            // todo: should have a better ODE solver (R-K(4,5)? http://www.mathworks.com/help/techdoc/ref/ode45.html)
            List<Point3D> path = solution.Select(x => new Point3D(x[0], x[1], x[2])).ToList();

            // create the WPF3D model
            var m = new Model3DGroup();
            var gm = new MeshBuilder();
            gm.AddTube(path, 0.8, 10, false);
            if (directionArrows)
            {
                // sphere at the initial point
                gm.AddSphere(path[0], 1);
                // arrow heads every 100 point
                for (int i = 100; i + 1 < path.Count; i += 100)
                {
                    gm.AddArrow(path[i], path[i + 1], 0.8);
                }
                // arrow head at the end
                Point3D p0 = path[path.Count - 2];
                Point3D p1 = path[path.Count - 1];
                var d = new Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
                d.Normalize();
                Point3D p2 = p1 + d * 2;
                gm.AddArrow(p1, p2, 0.8);
            }

            m.Children.Add(new GeometryModel3D(gm.ToMesh(), Materials.Gold));

            Model = m;
        }
        private Model3D CreateModel()
        {
           // if (Points ==null)

            var plotModel = new Model3DGroup();

            int rows = Points.GetUpperBound(0) + 1;
            int columns = Points.GetUpperBound(1) + 1;
            double minX = double.MaxValue;
            double maxX = double.MinValue;
            double minY = double.MaxValue;
            double maxY = double.MinValue;
            double minZ = double.MaxValue;
            double maxZ = double.MinValue;
            //double RealminX = double.MaxValue;
            //double RealmaxX = double.MinValue;
            //double RealminY = double.MaxValue;
            //double RealmaxY = double.MinValue;
            //double RealminZ = double.MaxValue;
            //double RealmaxZ = double.MinValue;

        
            #region Color things
            double minColorValue = double.MaxValue;
            double maxColorValue = double.MinValue;


            for (int i = 0; i < rows; i++)
                for (int j = 0; j < columns; j++)
                {
                    double x = Points[i, j].X;
                    double y = Points[i, j].Y;
                    double z = Points[i, j].Z;
                    maxX = Math.Max(maxX, x);
                    maxY = Math.Max(maxY, y);
                    maxZ = Math.Max(maxZ, z);
                    minX = Math.Min(minX, x);
                    minY = Math.Min(minY, y);
                    minZ = Math.Min(minZ, z);
                    if (ColorValues != null)
                    {
                        maxColorValue = Math.Max(maxColorValue, ColorValues[i, j]);
                        minColorValue = Math.Min(minColorValue, ColorValues[i, j]);
                    }
                }

            // make color value 0 at texture coordinate 0.5
            if (Math.Abs(minColorValue) < Math.Abs(maxColorValue))
                minColorValue = -maxColorValue;
            else
                maxColorValue = -minColorValue;

            #endregion

            // set the texture coordinates by z-value or ColorValue
            var texcoords = new Point[rows,columns];
            if (OriginalData == null || ColorCoding != ComplexPlainVisualizer.ColorCoding.Custom)
            {
                for (int i = 0; i < rows; i++)
                    for (int j = 0; j < columns; j++)
                    {

                        double u = (Points[i, j].Z - minZ) / (maxZ - minZ);
                        //double v = 
                        if (ColorValues != null)
                            u = (ColorValues[i, j] - minColorValue) / (maxColorValue - minColorValue);
                        texcoords[i, j] = new Point(u, u);
                    }
            }
            else
            {
                for (int i = 0; i < rows; i++)
                    for (int j = 0; j < columns; j++)
                    {
                        double u = MathUtil.Scale(minZ, maxZ, Math.Log10(OriginalData[i, j].Z), 0.5);
                        double v = OriginalData[i, j].W;
                        double uu = 0.5 + u * Math.Cos(v);
                        double vv = 0.5 + u * Math.Sin(v);
                        texcoords[i, j] = new Point(uu, vv);
                    }
            }

            if (AutoScale)
            {
                ScaleX =10 / Math.Abs(maxX - minX);
                ScaleY =10/ Math.Abs(maxY - minY);
                ScaleZ =5 / Math.Abs(maxZ - minZ);
            }

            var surfaceMeshBuilder = new MeshBuilder();
            surfaceMeshBuilder.AddRectangularMesh(Points, texcoords);
            surfaceMeshBuilder.Scale(ScaleX, ScaleY, ScaleZ);

            var surfaceModel = new GeometryModel3D(surfaceMeshBuilder.ToMesh(),
                                                   MaterialHelper.CreateMaterial(SurfaceBrush, null, null, 1, 0));
            surfaceModel.BackMaterial = surfaceModel.Material;

 
            //RealmaxX = maxX;
            //RealminX = minX;
            //RealmaxY = maxY;
            //RealminY = minY;
            //RealmaxZ = maxZ;
            //RealminZ = minZ;
            maxX *= ScaleX;
            minX *= ScaleX;
            maxY *= ScaleY;
            minY *= ScaleY;
            maxZ *= ScaleZ;
            minZ *= ScaleZ;

            IntervalX = (maxX - minX) / SubAxisCount;
            IntervalY = (maxY - minY) / SubAxisCount;
            IntervalZ = (maxZ - minZ) / SubAxisCount;
            
            #region eje x

            var axesMeshBuilder = new MeshBuilder();
            for (double x = minX; x <= maxX; x += IntervalX)
            {
                double j = (x - minX)/(maxX - minX)*(columns - 1);
                //var path = new List<Point3D> { new Point3D(x , minY , minZ) };
                var path = new List<Point3D> { new Point3D(x, minY , minZ) };
                for (int i = 0; i < rows; i++)
                {
                    Point3D p = BilinearInterpolation(Points, i, j);
                    p.X *= ScaleX;
                    p.Y *= ScaleY;
                    p.Z *= ScaleZ;
                    path.Add(p);
                }
                path.Add(new Point3D(x, maxY, minZ));

                axesMeshBuilder.AddTube(path, LineThickness, 9, false);
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(StringUtils.CodeString(x / ScaleX), Brushes.Black, true, FontSize,
                                                                           new Point3D(x, minY - FontSize * 2.5, minZ),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }

            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("X-axis", Brushes.Black, true, FontSize,
                                                                           new Point3D((minX + maxX)*0.5,
                                                                                       minY - FontSize * 6, minZ),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }

            #endregion


            #region eje y

            for (double y = minY; y <= maxY; y += IntervalY)
            {
                double i = (y - minY)/(maxY - minY)*(rows - 1);
                var path = new List<Point3D> {new Point3D(minX, y, minZ)};
                for (int j = 0; j < columns; j++)
                {
                    Point3D p = BilinearInterpolation(Points, i, j);
                    p.X *= ScaleX;
                    p.Y *= ScaleY;
                    p.Z *= ScaleZ;
                    path.Add(p);
                }
                path.Add(new Point3D(maxX, y, minZ));

                axesMeshBuilder.AddTube(path, LineThickness, 9, false);
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(StringUtils.CodeString(y / ScaleY), Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize * 3, y, minZ),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("Y-axis", Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize * 10,
                                                                                       (minY + maxY) * 0.5, minZ),
                                                                           new Vector3D(0, 1, 0), new Vector3D(-1, 0, 0));
                plotModel.Children.Add(label);
            }

            #endregion




            #region eje z


            double z0 = (int) (minZ/IntervalZ)*IntervalZ;
            for (double z = z0; z <= maxZ + double.Epsilon; z += IntervalZ)
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(StringUtils.CodeString(z / ScaleZ), Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize * 3, maxY, z),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 0, 1));
                plotModel.Children.Add(label);
            }
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("Z-axis", Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize * 10, maxY,
                                                                                       (minZ + maxZ)*0.5),
                                                                           new Vector3D(0, 0, 1), new Vector3D(1, 0, 0));
                plotModel.Children.Add(label);
            }

            #endregion

            var bb = new Rect3D(minX, minY, minZ, maxX - minX, maxY - minY, 0*(maxZ - minZ));
            axesMeshBuilder.AddBoundingBox(bb, LineThickness);

            var axesModel = new GeometryModel3D(axesMeshBuilder.ToMesh(), Materials.Black);

            plotModel.Children.Add(surfaceModel);
            plotModel.Children.Add(axesModel);

            return plotModel;
        }
示例#16
0
        /// <summary>
        /// Do the tesselation and return the <see cref="MeshGeometry3D"/> .
        /// </summary>
        /// <returns>
        /// A triangular mesh geometry.
        /// </returns>
        protected override MeshGeometry3D Tessellate()
        {
            if (this.Path == null)
            {
                return null;
            }

            var builder = new MeshBuilder(false, this.TextureCoordinates != null);
            builder.AddTube(
                this.Path,
                this.TextureCoordinates,
                this.Diameters,
                this.Section,
                this.IsPathClosed,
                this.IsSectionClosed);
            return builder.ToMesh();
        }
示例#17
0
文件: 3DView.cs 项目: litdev1/LitDev
        /// <summary>
        /// Add a tube geometry object.
        /// </summary>
        /// <param name="shapeName">The 3DView object.</param>
        /// <param name="path">A space or colon deliminated list of 3D point coordinates.</param>
        /// <param name="diameter">The tube diameter.</param>
        /// <param name="divisions">The tube radial divisions, default 10 (affects number of triangles and smoothness).</param>
        /// <param name="colour">A colour or gradient brush for the object.</param>
        /// <param name="materialType">A material for the object.
        /// The available options are:
        /// "E" Emmissive - constant brightness.
        /// "D" Diffusive - affected by lights.
        /// "S" Specular  - specular highlights.
        /// </param>
        /// <returns>The 3DView Geometry name.</returns>
        public static Primitive AddTube(Primitive shapeName, Primitive path, Primitive diameter, Primitive divisions, Primitive colour, Primitive materialType)
        {
            bool closed = false;
            UIElement obj;

            try
            {
                if (_objectsMap.TryGetValue((string)shapeName, out obj))
                {
                    InvokeHelperWithReturn ret = new InvokeHelperWithReturn(delegate
                    {
                        try
                        {
                            if (obj.GetType() == typeof(Viewport3D))
                            {
                                MeshBuilder builder = new MeshBuilder(true, true);
                                Point3DCollection pointCollection = new Point3DCollection();
                                string[] s = Utilities.getString(path).Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries);
                                for (int i = 0; i < s.Length; i += 3)
                                {
                                    pointCollection.Add(new Point3D(Utilities.getDouble(s[i]), Utilities.getDouble(s[i + 1]), Utilities.getDouble(s[i + 2])));
                                }
                                int thetaDiv = divisions < 2 ? 10 : (int)divisions;
                                builder.AddTube(pointCollection, diameter, thetaDiv, closed);
                                MeshGeometry3D mesh = builder.ToMesh();

                                Viewport3D viewport3D = (Viewport3D)obj;
                                return AddGeometry(viewport3D, mesh.Positions, mesh.TriangleIndices, mesh.Normals, mesh.TextureCoordinates, colour, materialType);
                            }
                        }
                        catch (Exception ex)
                        {
                            Utilities.OnError(Utilities.GetCurrentMethod(), ex);
                        }
                        return "";
                    });
                    return FastThread.InvokeWithReturn(ret).ToString();
                }
                else
                {
                    Utilities.OnShapeError(Utilities.GetCurrentMethod(), shapeName);
                }
            }
            catch (Exception ex)
            {
                Utilities.OnError(Utilities.GetCurrentMethod(), ex);
            }
            return "";
        }