예제 #1
0
        private InstancedMeshGeometryVisual3D AddInstancedTubePath(Point3DCollection spiralPositionCollection, Color4 tubeColor)
        {
            // Setup InstanceData
            var instanceData = new InstanceData[spiralPositionCollection.Count];

            // Convert to list of Vector3
            var dxCurvePositions = spiralPositionCollection.Select(p => p.ToVector3()).ToList();


            // NOTE:
            // When a tube path is created from a lot of positions,
            // then it is worth to transform the following loop into Parallel.For loop.

            var startPosition = dxCurvePositions[0];

            for (int i = 1; i < dxCurvePositions.Count; i++)
            {
                var endPosition = dxCurvePositions[i];

                var direction = endPosition - startPosition;
                var length    = direction.Length(); // length will be used for x scale

                var scale = new Vector3(length, 1, 1);

                //direction.Normalize(); // Because we already have length, we can quickly normalize with simply dividing by length
                direction /= length;

                instanceData[i].World        = Common.MatrixUtils.GetMatrixFromNormalizedDirection(direction, startPosition, scale);
                instanceData[i].DiffuseColor = Color4.White;

                startPosition = endPosition;
            }

            // Create tube mesh with normalized radius (=1) and from (0,0,0) to (1,0,0).
            // This mesh is then transformed to connect positions along the path
            var tubeLineMesh3D = new Ab3d.Meshes.TubeLineMesh3D(startPosition: new Point3D(0, 0, 0),
                                                                endPosition: new Point3D(1, 0, 0),
                                                                radius: 1,
                                                                segments: 8,
                                                                generateTextureCoordinates: false).Geometry;

            // Create InstancedMeshGeometryVisual3D
            var instancedMeshGeometryVisual3D = new InstancedMeshGeometryVisual3D(tubeLineMesh3D);

            instancedMeshGeometryVisual3D.InstancesData = instanceData;

            // Set IsSolidColorMaterial to render tube instances with solid color without any shading based on lighting
            instancedMeshGeometryVisual3D.IsSolidColorMaterial = true;

            // Add instancedMeshGeometryVisual3D to the scene
            MainViewport.Children.Add(instancedMeshGeometryVisual3D);

            return(instancedMeshGeometryVisual3D);
        }
예제 #2
0
        // This method created curve with tube lines but instead of using TubeLineVisual3D
        // here we create a series of MeshGeometry3D objects - one for each line segment.
        // Then we combine all those segments into one MeshGeometry3D and use it to create GeometryModel3D.
        // This can greatly improve performance because GeometryModel3D can be drawn with only one draw call on graphics card.
        // What is more is that the GeometryModel3D can be frozen.
        // This means that this method can be executed on background thread and then the GeometryModel3D can be passed to UI thread.
        private void CreateCurveWithMeshes()
        {
            // Create curve through those points
            var controlPoints = new Point3D[]
            {
                new Point3D(100, 50, 20),
                new Point3D(250, 50, 0),
                new Point3D(250, 50, 200),
                new Point3D(350, 50, 200)
            };

            var bezierCurve    = Ab3d.Utilities.BezierCurve.CreateFromCurvePositions(controlPoints); // To create curve through specified points we must first convert the points into a bezierCurve (curve that has tangents defined for each point)
            var curvePositions = bezierCurve.CreateBezierCurve(_curveSegmentsBetweenControlPoints);

            int selectedSegmentsCount = GetSelectedSegmentsCount();

            // meshes list will hold MeshGeometry3D for each curve segment
            var meshes = new List <MeshGeometry3D>(curvePositions.Count);

            Point3D previousCurvePosition = curvePositions[0];

            for (int i = 1; i < curvePositions.Count; i++)
            {
                Point3D curvePosition = curvePositions[i];

                var tubeLineMesh3D = new Ab3d.Meshes.TubeLineMesh3D(startPosition: previousCurvePosition,
                                                                    endPosition: curvePosition,
                                                                    radius: 1,
                                                                    segments: selectedSegmentsCount,
                                                                    generateTextureCoordinates: false);


                var meshGeometry = tubeLineMesh3D.Geometry;
                meshes.Add(meshGeometry);

                previousCurvePosition = curvePosition;
            }

            // Combine all meshes into one MeshGeometry3D
            var combinedMeshGeometry = Ab3d.Utilities.MeshUtils.CombineMeshes(meshes);

            // Create one GeometryModel3D
            var geometryModel3D = new GeometryModel3D(combinedMeshGeometry, CreateMaterial(Brushes.GreenYellow));

            geometryModel3D.Freeze();

            MeshTubeLinesVisual.Content = geometryModel3D;
        }
예제 #3
0
        private void CreateInstancedTubePath()
        {
            // Create curve through those points
            var controlPoints = new Point3D[]
            {
                new Point3D(-200, 50, 150),
                new Point3D(0, 50, 20),
                new Point3D(150, 50, 0),
                new Point3D(150, 50, 200),
                new Point3D(250, 50, 200)
            };

            // To create curve through specified points we must first convert the points into a bezierCurve (curve that has tangents defined for each point).
            // The curve is created with 10 points per segments - 10 points between two control points.
            var bezierCurve    = Ab3d.Utilities.BezierCurve.CreateFromCurvePositions(controlPoints);
            var curvePositions = bezierCurve.CreateBezierCurve(positionsPerSegment: 10);


            // Convert Point3D to Vector3
            var dxCurvePositions = curvePositions.Select(p => p.ToVector3()).ToList();

            // Setup InstanceData
            var instanceData = new InstanceData[curvePositions.Count];


            // NOTE:
            // When a tube path is created from a lot of positions,
            // then it is worth to transform the following loop into Parallel.For loop.

            var startPosition = dxCurvePositions[0];

            for (int i = 1; i < dxCurvePositions.Count; i++)
            {
                var endPosition = dxCurvePositions[i];

                var direction = endPosition - startPosition;
                var length    = direction.Length(); // length will be used for x scale

                var scale = new Vector3(length, 1, 1);

                //direction.Normalize(); // Because we already have length, we can quickly normalize with simply dividing by length
                direction /= length;

                instanceData[i].World        = Common.MatrixUtils.GetMatrixFromNormalizedDirection(direction, startPosition, scale);
                instanceData[i].DiffuseColor = Color4.White;

                startPosition = endPosition;
            }

            // Create tube mesh with normalized radius (=1) and from (0,0,0) to (1,0,0).
            // This mesh is then transformed to connect positions along the path
            var tubeLineMesh3D = new Ab3d.Meshes.TubeLineMesh3D(startPosition: new Point3D(0, 0, 0),
                                                                endPosition: new Point3D(1, 0, 0),
                                                                radius: 1,
                                                                segments: 8,
                                                                generateTextureCoordinates: false).Geometry;

            // Create InstancedMeshGeometryVisual3D
            var instancedMeshGeometryVisual3D = new InstancedMeshGeometryVisual3D(tubeLineMesh3D);

            instancedMeshGeometryVisual3D.InstancesData = instanceData;

            // Set IsSolidColorMaterial to render tube instances with solid color without any shading based on lighting
            instancedMeshGeometryVisual3D.IsSolidColorMaterial = true;

            // Add instancedMeshGeometryVisual3D to the scene
            MainViewport.Children.Add(instancedMeshGeometryVisual3D);
        }