protected BasicPrimitiveTessellator()
 {
     Positions = new Point3DCollection();
     Normals = new Vector3DCollection();
     Indices = new Int32Collection();
     TextureCoordinates = new Point2DCollection();
 }
예제 #2
0
파일: Mesh.cs 프로젝트: tgjones/meshellator
 public Mesh()
 {
     Positions = new Point3DCollection();
     Normals = new Vector3DCollection();
     TextureCoordinates = new Point3DCollection();
     Indices = new Int32Collection();
     Transform = new MatrixTransform(Matrix3D.Identity);
 }
예제 #3
0
 public Mesh()
 {
     Positions = new Point3DCollection();
     Normals = new Vector3DCollection();
     TextureCoordinates = new Point2DCollection();
     Indices = new IndexCollection();
     Material = new Material();
 }
예제 #4
0
 private static void AccumulateTriangleNormals(Int32Collection indices, Point3DCollection positions, Vector3D[] vertexNormals)
 {
     for (int i = 0; i < indices.Count; i += 3)
     {
         Point3D vector4 = positions[indices[i]];
         Point3D vector = positions[indices[i + 1]];
         Point3D vector3 = positions[indices[i + 2]];
         Vector3D vector2 = Vector3D.Normalize(Vector3D.Cross(vector3 - vector, vector - vector4));
         for (int j = 0; j < 3; j++)
             vertexNormals[indices[i + j]] += vector2;
     }
 }
예제 #5
0
        public FlightVisual3D(Point3D p1, Point3D p2)
        {
            var tube = new TubeVisual3D();

            tube.Material = MaterialHelper.CreateMaterial(Color.FromArgb(80, 255, 255, 255)); // Materials.Yellow;
            Children.Add(tube);
            Children.Add(new SphereVisual3D()
            {
                Center = p1, Radius = 100, Material = Materials.Green
            });
            Children.Add(new SphereVisual3D()
            {
                Center = p2, Radius = 100, Material = Materials.Red
            });

            double lat1, lon1, lat2, lon2;

            PointToLatLon(p1, out lat1, out lon1);
            PointToLatLon(p2, out lat2, out lon2);
            From = String.Format("{0:0.00} {1:0.00}", lat1, lon1);
            To   = String.Format("{0:0.00} {1:0.00}", lat2, lon2);

            CruisingSpeed = DefaultCruisingSpeed;
            double       cruisingRadius = EarthRadius + DefaultCruisingAltitude;
            double       takeoffLength  = DefaultTakeoffLength;
            double       groundRadius   = EarthRadius;
            const double tubeDiameter   = 60;

            var o  = new Point3D(0, 0, 0);
            var v1 = p1 - o;
            var v2 = p2 - o;
            var z  = Vector3D.CrossProduct(v1, v2);
            var x  = v1;
            var y  = Vector3D.CrossProduct(x, z);

            x.Normalize();
            y.Normalize();
            double v2X = Vector3D.DotProduct(v2, x);
            double v2Y = Vector3D.DotProduct(v2, y);
            double v2A = Math.Atan2(v2Y, v2X);

            const int n = 100;

            var pts = new Point3DCollection();

            double da = v2A / (n - 1);

            double distance      = cruisingRadius * Math.Abs(v2A);
            double landingLength = takeoffLength;

            double l = 0;

            for (int i = 0; i < n; i++)
            {
                double   a = i * da;
                Vector3D v = x * Math.Cos(a) + y * Math.Sin(a);
                double   r = cruisingRadius;

                //if (l < takeoffLength)
                //{
                //    r = groundRadius + Math.Sin(Math.PI/2*l/takeoffLength)*(cruisingRadius - groundRadius);
                //}
                //if (l > distance - landingLength)
                //{
                //    r = groundRadius + Math.Sin(Math.PI/2*(distance - l)/takeoffLength)*(cruisingRadius - groundRadius);
                //}

                r = groundRadius + Math.Sin(Math.PI * i / (n - 1)) * (cruisingRadius - groundRadius);

                var p = o + v * r;
                //  Children.Add(new SphereVisual3D() { Center = p, Radius = 60, Material = Materials.Gray});

                pts.Add(p);
                l += Math.Abs(cruisingRadius * da);
            }
            tube.Diameter = tubeDiameter;
            tube.ThetaDiv = 16;
            tube.Path     = pts;
            Distance      = distance;
        }
예제 #6
0
        public EmissiveMaterialExample()
        {
            // Declare scene objects.
            Viewport3D      myViewport3D    = new Viewport3D();
            Model3DGroup    myModel3DGroup  = new Model3DGroup();
            GeometryModel3D myGeometryModel = new GeometryModel3D();
            ModelVisual3D   myModelVisual3D = new ModelVisual3D();

            // Defines the camera used to view the 3D object. In order to view the 3D object,
            // the camera must be positioned and pointed such that the object is within view
            // of the camera.
            PerspectiveCamera myPCamera = new PerspectiveCamera();

            // Specify where in the 3D scene the camera is.
            myPCamera.Position = new Point3D(0, 0, 2);

            // Specify the direction that the camera is pointing.
            myPCamera.LookDirection = new Vector3D(0, 0, -1);

            // Define camera's horizontal field of view in degrees.
            myPCamera.FieldOfView = 60;

            // Asign the camera to the viewport
            myViewport3D.Camera = myPCamera;

            // Define the lights cast in the scene. Without light, the 3D object cannot
            // be seen. Note: to illuminate an object from additional directions, create
            // additional lights.
            DirectionalLight myDirectionalLight = new DirectionalLight();

            myDirectionalLight.Color     = Colors.White;
            myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61);

            myModel3DGroup.Children.Add(myDirectionalLight);

            // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet
            // is created.
            MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D();

            // Create a collection of normal vectors for the MeshGeometry3D.
            Vector3DCollection myNormalCollection = new Vector3DCollection();

            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myMeshGeometry3D.Normals = myNormalCollection;

            // Create a collection of vertex positions for the MeshGeometry3D.
            Point3DCollection myPositionCollection = new Point3DCollection();

            myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
            myMeshGeometry3D.Positions = myPositionCollection;

            // Create a collection of texture coordinates for the MeshGeometry3D.
            PointCollection myTextureCoordinatesCollection = new PointCollection();

            myTextureCoordinatesCollection.Add(new Point(0, 0));
            myTextureCoordinatesCollection.Add(new Point(1, 0));
            myTextureCoordinatesCollection.Add(new Point(1, 1));
            myTextureCoordinatesCollection.Add(new Point(1, 1));
            myTextureCoordinatesCollection.Add(new Point(0, 1));
            myTextureCoordinatesCollection.Add(new Point(0, 0));
            myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection;

            // Create a collection of triangle indices for the MeshGeometry3D.
            Int32Collection myTriangleIndicesCollection = new Int32Collection();

            myTriangleIndicesCollection.Add(0);
            myTriangleIndicesCollection.Add(1);
            myTriangleIndicesCollection.Add(2);
            myTriangleIndicesCollection.Add(3);
            myTriangleIndicesCollection.Add(4);
            myTriangleIndicesCollection.Add(5);
            myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection;

            // Apply the mesh to the geometry model.
            myGeometryModel.Geometry = myMeshGeometry3D;
            // The material property of GeometryModel3D specifies the material applied to the 3D object.
            // In this sample the material applied to the 3D object is made up of two materials layered
            // on top of each other - a DiffuseMaterial (gradient brush) with an EmissiveMaterial
            // layered on top (blue SolidColorBrush). The EmmisiveMaterial alters the appearance of
            // the gradient toward blue.

            // Create a horizontal linear gradient with four stops.
            LinearGradientBrush myHorizontalGradient = new LinearGradientBrush();

            myHorizontalGradient.StartPoint = new Point(0, 0.5);
            myHorizontalGradient.EndPoint   = new Point(1, 0.5);
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0));

            // Define material that will use the gradient.
            DiffuseMaterial myDiffuseMaterial = new DiffuseMaterial(myHorizontalGradient);

            // Add this gradient to a MaterialGroup.
            MaterialGroup myMaterialGroup = new MaterialGroup();

            myMaterialGroup.Children.Add(myDiffuseMaterial);

            // Define an Emissive Material with a blue brush.
            Color c = new Color();

            c.ScA = 1;
            c.ScB = 255;
            c.ScR = 0;
            c.ScG = 0;
            EmissiveMaterial myEmissiveMaterial = new EmissiveMaterial(new SolidColorBrush(c));

            // Add the Emmisive Material to the Material Group.
            myMaterialGroup.Children.Add(myEmissiveMaterial);

            // Add the composite material to the 3D model.
            myGeometryModel.Material = myMaterialGroup;
            // Apply a transform to the object. In this sample, a rotation transform is applied,
            // rendering the 3D object rotated.
            RotateTransform3D   myRotateTransform3D   = new RotateTransform3D();
            AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D();

            myAxisAngleRotation3d.Axis   = new Vector3D(0, 3, 0);
            myAxisAngleRotation3d.Angle  = 40;
            myRotateTransform3D.Rotation = myAxisAngleRotation3d;
            myGeometryModel.Transform    = myRotateTransform3D;

            // Add the geometry model to the model group.
            myModel3DGroup.Children.Add(myGeometryModel);

            // Add the group of models to the ModelVisual3d.
            myModelVisual3D.Content = myModel3DGroup;
            myViewport3D.Children.Add(myModelVisual3D);

            // Apply the viewport to the page so it will be rendered.
            this.Content = myViewport3D;
        }
예제 #7
0
        private bool preliminaryChecks()
        {
            //check if user origin was set
            //get the points collection for the Body (used for calculating number of isocenters)
            Point3DCollection pts = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "body").MeshGeometry.Positions;

            if (!selectedSS.Image.HasUserOrigin || !(selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "body").IsPointInsideSegment(selectedSS.Image.UserOrigin)))
            {
                MessageBox.Show("Did you forget to set the user origin? \nUser origin is NOT inside body contour! \nPlease fix and try again!");
                return(true);
            }

            //check if patient length is > 116cm, if so, check for matchline contour
            if ((pts.Max(p => p.Z) - pts.Min(p => p.Z)) > 1160.0 && !(selectedSS.Structures.Where(x => x.Id.ToLower() == "matchline").Any()))
            {
                //check to see if the user wants to proceed even though there is no matchplane contour or the matchplane contour exists, but is not filled
                VMATTBIautoPlan.confirmUI CUI = new VMATTBIautoPlan.confirmUI();
                CUI.message.Text = "No matchplane contour found even though patient length > 116.0 cm!" + Environment.NewLine + Environment.NewLine + "Continue?!";
                CUI.ShowDialog();
                if (!CUI.confirm)
                {
                    return(true);
                }

                //checks for LA16 couch and spinning manny couch/bolt will be performed at optimization stage
            }

            //calculate number of required isocenters
            if (!(selectedSS.Structures.Where(x => x.Id.ToLower() == "matchline").Any()))
            {
                //no matchline implying that this patient will be treated with VMAT only. For these cases the maximum number of allowed isocenters is 3.
                //the reason for the explicit statements calculating the number of isos and then truncating them to 3 was to account for patients requiring < 3 isos and if, later on, we want to remove the restriction of 3 isos
                numIsos = numVMATIsos = (int)Math.Ceiling(((pts.Max(p => p.Z) - pts.Min(p => p.Z)) / (400.0 - 20.0)));
                if (numIsos > 3)
                {
                    numIsos = numVMATIsos = 3;
                }
            }
            else
            {
                //matchline structure is present, but empty
                if (selectedSS.Structures.First(x => x.Id.ToLower() == "matchline").IsEmpty)
                {
                    VMATTBIautoPlan.confirmUI CUI = new VMATTBIautoPlan.confirmUI();
                    CUI.message.Text = "I found a matchline structure in the structure set, but it's empty!" + Environment.NewLine + Environment.NewLine + "Do you want to continue without using the matchline structure?!";
                    CUI.ShowDialog();
                    if (!CUI.confirm)
                    {
                        return(true);
                    }

                    //continue and ignore the empty matchline structure (same calculation as VMAT only)
                    numIsos = numVMATIsos = (int)Math.Ceiling(((pts.Max(p => p.Z) - pts.Min(p => p.Z)) / (400.0 - 20.0)));
                    if (numIsos > 3)
                    {
                        numIsos = numVMATIsos = 3;
                    }
                }
                //matchline structure is present and not empty
                else
                {
                    //get number of isos for PTV superior to matchplane (always truncate this value to a maximum of 3 isocenters)
                    numVMATIsos = (int)Math.Ceiling(((pts.Max(p => p.Z) - selectedSS.Structures.First(x => x.Id.ToLower() == "matchline").CenterPoint.z) / (400.0 - 20.0)));
                    if (numVMATIsos > 3)
                    {
                        numVMATIsos = 3;
                    }

                    //get number of iso for PTV inferior to matchplane
                    //if (selectedSS.Structures.First(x => x.Id.ToLower() == "matchline").CenterPoint.z - pts.Min(p => p.Z) - 3.0 <= (400.0 - 20.0)) numIsos = numVMATIsos + 1;

                    //5-20-2020 Nataliya said to only add a second legs iso if the extent of the TS_PTV_LEGS is > 40.0 cm
                    if (selectedSS.Structures.First(x => x.Id.ToLower() == "matchline").CenterPoint.z - pts.Min(p => p.Z) - 3.0 <= (400.0 - 0.0))
                    {
                        numIsos = numVMATIsos + 1;
                    }
                    else
                    {
                        numIsos = numVMATIsos + 2;
                    }
                    //MessageBox.Show(String.Format("{0}", selectedSS.Structures.First(x => x.Id.ToLower() == "matchline").CenterPoint.z - pts.Min(p => p.Z) - 3.0));
                }
            }

            //set isocenter names based on numIsos and numVMATIsos (determined these names from prior cases). Need to implement a more clever way to name the isocenters
            isoNames.Add("Head");
            if (numVMATIsos == 2)
            {
                isoNames.Add("Pelvis");
            }
            else if (numVMATIsos == 3 && numIsos > numVMATIsos)
            {
                isoNames.Add("Chest"); isoNames.Add("Pelvis");
            }
            //this could technically be an else statement, but I left it as an else-if statement so it's explicit what situation is being considered here
            else if (numVMATIsos == 3 && numIsos == numVMATIsos)
            {
                isoNames.Add("Pelvis"); isoNames.Add("Legs");
            }
            if (numIsos > numVMATIsos)
            {
                isoNames.Add("AP / PA upper legs");
                if (numIsos == numVMATIsos + 2)
                {
                    isoNames.Add("AP / PA lower legs");
                }
            }

            //check if selected structures are empty or of high-resolution (i.e., no operations can be performed on high-resolution structures)
            string           output            = "The following structures are high-resolution:" + System.Environment.NewLine;
            List <Structure> highResStructList = new List <Structure> {
            };
            List <Tuple <string, string, double> > highResSpareList = new List <Tuple <string, string, double> > {
            };

            foreach (Tuple <string, string, double> itr in spareStructList)
            {
                if (itr.Item2 == "Mean Dose < Rx Dose")
                {
                    if (selectedSS.Structures.First(x => x.Id == itr.Item1).IsEmpty)
                    {
                        MessageBox.Show(String.Format("Error! \nThe selected structure that will be subtracted from PTV_Body and TS_PTV_VMAT is empty! \nContour the structure and try again."));
                        return(true);
                    }
                    else if (selectedSS.Structures.First(x => x.Id == itr.Item1).IsHighResolution)
                    {
                        highResStructList.Add(selectedSS.Structures.First(x => x.Id == itr.Item1));
                        highResSpareList.Add(itr);
                        output += String.Format("{0}", itr.Item1) + System.Environment.NewLine;
                    }
                }
            }
            //if there are high resolution structures, they will need to be converted to default resolution.
            if (highResStructList.Count() > 0)
            {
                //ask user if they are ok with converting the relevant high resolution structures to default resolution
                output += "They must be converted to default resolution before proceeding!";
                VMATTBIautoPlan.confirmUI CUI = new VMATTBIautoPlan.confirmUI();
                CUI.message.Text = output + Environment.NewLine + Environment.NewLine + "Continue?!";
                CUI.message.Font = new System.Drawing.Font("Microsoft Sans Serif", 11F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                CUI.ShowDialog();
                if (!CUI.confirm)
                {
                    return(true);
                }

                int count = 0;
                foreach (Structure s in highResStructList)
                {
                    //get the high res structure mesh geometry
                    MeshGeometry3D mesh = s.MeshGeometry;
                    //get the start and stop image planes for this structure
                    int startSlice = (int)((mesh.Bounds.Z - selectedSS.Image.Origin.z) / selectedSS.Image.ZRes);
                    int stopSlice  = (int)(((mesh.Bounds.Z + mesh.Bounds.SizeZ) - selectedSS.Image.Origin.z) / selectedSS.Image.ZRes) + 1;
                    //create an Id for the low resolution struture that will be created. The name will be '_lowRes' appended to the current structure Id
                    string newName = s.Id + "_lowRes";
                    if (newName.Length > 16)
                    {
                        newName = newName.Substring(0, 16);
                    }
                    //add a new structure (default resolution by default)
                    Structure lowRes = null;
                    if (selectedSS.CanAddStructure("CONTROL", newName))
                    {
                        lowRes = selectedSS.AddStructure("CONTROL", newName);
                    }
                    else
                    {
                        MessageBox.Show(String.Format("Error! Cannot add new structure: {0}!\nCorrect this issue and try again!", newName.Substring(0, 16)));
                        return(true);
                    }

                    //foreach slice that contains contours, get the contours, and determine if you need to add or subtract the contours on the given image plane for the new low resolution structure. You need to subtract contours if the points lie INSIDE the current structure contour.
                    //We can sample three points (first, middle, and last points in array) to see if they are inside the current contour. If any of them are, subtract the set of contours from the image plane. Otherwise, add the contours to the image plane. NOTE: THIS LOGIC ASSUMES
                    //THAT YOU DO NOT OBTAIN THE CUTOUT CONTOUR POINTS BEFORE THE OUTER CONTOUR POINTS (it seems that ESAPI generally passes the main structure contours first before the cutout contours, but more testing is needed)
                    //string data = "";
                    for (int slice = startSlice; slice < stopSlice; slice++)
                    {
                        VVector[][] points = s.GetContoursOnImagePlane(slice);
                        for (int i = 0; i < points.GetLength(0); i++)
                        {
                            //for (int j = 0; j < points[i].GetLength(0); j++) data += String.Format("{0}, {1}, {2}", points[i][j].x, points[i][j].y, points[i][j].z) + System.Environment.NewLine;
                            if (lowRes.IsPointInsideSegment(points[i][0]) || lowRes.IsPointInsideSegment(points[i][points[i].GetLength(0) - 1]) || lowRes.IsPointInsideSegment(points[i][(int)(points[i].GetLength(0) / 2)]))
                            {
                                lowRes.SubtractContourOnImagePlane(points[i], slice);
                            }
                            else
                            {
                                lowRes.AddContourOnImagePlane(points[i], slice);
                            }
                            //data += System.Environment.NewLine;
                        }
                    }

                    //get the index of the high resolution structure in the structure sparing list and repace this entry with the newly created low resolution structure
                    int index = spareStructList.IndexOf(highResSpareList.ElementAt(count));
                    spareStructList.RemoveAt(index);
                    spareStructList.Insert(index, new Tuple <string, string, double>(newName, highResSpareList.ElementAt(count).Item2, highResSpareList.ElementAt(count).Item3));
                    count++;

                    //data += System.Environment.NewLine;
                    //points = lowRes.GetContoursOnImagePlane((int)((stopSlice + startSlice) / 2));
                    //for (int i = 0; i < points.GetLength(0); i++)
                    //{
                    //    for (int j = 0; j < points[i].GetLength(0); j++) data += String.Format("{0}, {1}, {2}", points[i][j].x, points[i][j].y, points[i][j].z) + System.Environment.NewLine;
                    //    //data += System.Environment.NewLine;
                    //}

                    //File.WriteAllText(@"\\enterprise.stanfordmed.org\depts\RadiationTherapy\Public\Users\ESimiele\vvectorData.txt", data);
                }
                //inform the main UI class that the UI needs to be updated
                updateSparingList = true;

                //string mod = "";
                //foreach (Tuple<string, string, double> itr in spareStructList) mod += String.Format("{0}, {1}, {2}", itr.Item1, itr.Item2, itr.Item3) + System.Environment.NewLine;
                //MessageBox.Show(test);
                //MessageBox.Show(mod);
            }
            return(false);
        }
예제 #8
0
        private static MeshGeometry3D RevitMeshToHelixMesh(Mesh rmesh, Octree.OctreeSearch.Octree octree, NodeModel node)
        {
            var builder = new MeshBuilder();
            var points  = new Point3DCollection();
            var tex     = new PointCollection();
            var norms   = new Vector3DCollection();
            var tris    = new List <int>();

            for (int i = 0; i < rmesh.NumTriangles; ++i)
            {
                var tri = rmesh.get_Triangle(i);

                //calculate the face normal by
                //getting the cross product of two edges
                var a       = tri.get_Vertex(0);
                var b       = tri.get_Vertex(1);
                var c       = tri.get_Vertex(2);
                var e1      = b - a;
                var e2      = c - a;
                var normXYZ = e1.CrossProduct(e2).Normalize();
                var normal  = new Vector3D(normXYZ.X, normXYZ.Y, normXYZ.Z);

                for (int j = 0; j < 3; j++)
                {
                    var new_point = RevitPointToWindowsPoint(tri.get_Vertex(j));

                    int foundIndex = -1;
                    for (int k = 0; k < points.Count; k++)
                    {
                        var testPt   = points[k];
                        var testNorm = norms[k];

                        if (new_point.X == testPt.X &&
                            new_point.Y == testPt.Y &&
                            new_point.Z == testPt.Z)
                        {
                            foundIndex = k;
                            //average the merged normals
                            norms[k] = (testNorm + normal) / 2;
                            break;
                        }
                    }

                    if (foundIndex != -1)
                    {
                        tris.Add(foundIndex);
                        continue;
                    }

                    tris.Add(points.Count);
                    points.Add(new_point);
                    norms.Add(normal);
                    tex.Add(new System.Windows.Point(0, 0));
                    octree.AddNode(new_point.X, new_point.Y, new_point.Z, node.GUID.ToString());
                }

                builder.Append(points, tris, norms, tex);
            }

            return(builder.ToMesh(true));
        }
예제 #9
0
        /// <summary>
        /// Updates the system.
        /// </summary>
        /// <param name="time">The time.</param>
        protected void Update(double time)
        {
            if (double.IsNaN(this.previousTime))
            {
                this.previousTime = time;
                return;
            }

            var deltaTime = time - this.previousTime;

            this.previousTime = time;

            this.particlesToEmit += deltaTime * this.EmitRate;
            while (this.particlesToEmit > 1)
            {
                this.EmitOne();
                this.particlesToEmit--;
            }

            var angularVelocity       = this.AngularVelocity * DegToRad;
            var velocityDamping       = this.VelocityDamping;
            var accelerationDirection = this.AccelerationDirection;

            accelerationDirection.Normalize();
            var acceleration          = this.Acceleration;
            var accelerationSpreading = this.AccelerationSpreading;
            var sizeRate    = this.SizeRate;
            var fadeOutTime = this.FadeOutTime;
            var lifeTime    = this.LifeTime;

            for (int i = 0; i < this.particles.Count; i++)
            {
                var p = this.particles[i];

                p.Age += deltaTime;
                if (p.Age > lifeTime)
                {
                    this.particles.RemoveAt(i);
                    i--;
                    continue;
                }

                var a = accelerationSpreading > 0 ? CreateRandomVector(accelerationDirection, accelerationSpreading) : accelerationDirection;
                p.Position += p.Velocity * deltaTime;
                p.Rotation += angularVelocity * deltaTime;
                p.Size     += sizeRate * deltaTime;
                p.Velocity  = (p.Velocity * velocityDamping) + (a * acceleration * deltaTime);
            }

            var alive = this.particles.Count;

            var positions          = this.mesh.Positions;
            var textureCoordinates = this.mesh.TextureCoordinates;
            var triangleIndices    = this.mesh.TriangleIndices;

            this.mesh.Positions          = null;
            this.mesh.TextureCoordinates = null;
            this.mesh.TriangleIndices    = null;

            this.AliveParticles = alive;

            if (positions == null)
            {
                positions          = new Point3DCollection(alive * 4);
                textureCoordinates = new PointCollection(alive * 4);
                triangleIndices    = new Int32Collection(alive * 6);
            }

            if (positions.Count != alive * 4)
            {
                int previousAliveParticles = positions.Count / 4;

                // allocate positions, texture coordinates and triangle indices (to make the updating code simpler)
                AdjustListLength(positions, alive * 4);
                AdjustListLength(textureCoordinates, alive * 4);
                AdjustListLength(triangleIndices, alive * 6);

                for (int i = previousAliveParticles; i < alive; i++)
                {
                    var i4 = i * 4;
                    var i6 = i * 6;

                    triangleIndices[i6]     = i4;
                    triangleIndices[i6 + 1] = i4 + 1;
                    triangleIndices[i6 + 2] = i4 + 2;
                    triangleIndices[i6 + 3] = i4 + 2;
                    triangleIndices[i6 + 4] = i4 + 3;
                    triangleIndices[i6 + 5] = i4;
                }
            }

            if (this.camera == null)
            {
                var viewport = this.GetViewport3D();
                this.camera = (ProjectionCamera)viewport.Camera;
            }

            // calculate coordinate system for particle planes
            // all particles are rendered on parallel planes to avoid transparency conflicts
            var cameraPosition = this.camera.Position;
            var upVector       = this.camera.UpDirection;
            var z = this.camera.LookDirection;

            var x = Vector3D.CrossProduct(z, upVector);
            var y = Vector3D.CrossProduct(x, z);

            x.Normalize();
            y.Normalize();

            // find alive particles and sort by distance from camera (projected to look direction, nearest particles last)
            var sortedParticles = this.particles.OrderBy(p => - Vector3D.DotProduct(p.Position - cameraPosition, this.camera.LookDirection));

            int j = 0;

            foreach (var p in sortedParticles)
            {
                var halfSize = p.Size * 0.5;
                var j4       = j * 4;
                j++;

                var cos = Math.Cos(p.Rotation);
                var sin = Math.Sin(p.Rotation);

                var p0  = new Point(halfSize * (cos + sin), halfSize * (sin - cos));
                var p1  = new Point(halfSize * (cos - sin), halfSize * (cos + sin));
                var p2  = new Point(-halfSize * (cos + sin), halfSize * (cos - sin));
                var p3  = new Point(halfSize * (sin - cos), -halfSize * (cos + sin));
                var pos = p.Position;
                positions[j4]     = pos + (x * p0.X) + (y * p0.Y);
                positions[j4 + 1] = pos + (x * p1.X) + (y * p1.Y);
                positions[j4 + 2] = pos + (x * p2.X) + (y * p2.Y);
                positions[j4 + 3] = pos + (x * p3.X) + (y * p3.Y);

                var opacity = 1d;
                if (fadeOutTime < 1 && p.Age > lifeTime * fadeOutTime)
                {
                    opacity = 1 - (((p.Age / lifeTime) - fadeOutTime) / (1 - fadeOutTime));
                }

                // update the texture coordinates with the current opacity of the particle
                int transparency = (int)((1 - opacity) * this.opacityLevels);
                var u0           = (double)transparency / this.opacityLevels;
                var u1           = (transparency + 1d) / this.opacityLevels;
                textureCoordinates[j4]     = new Point(u1, 1);
                textureCoordinates[j4 + 1] = new Point(u1, 0);
                textureCoordinates[j4 + 2] = new Point(u0, 0);
                textureCoordinates[j4 + 3] = new Point(u0, 1);
            }

            this.mesh.Positions          = positions;
            this.mesh.TextureCoordinates = textureCoordinates;
            this.mesh.TriangleIndices    = triangleIndices;
        }
예제 #10
0
        // this is legacy code from previous versions.
        // 
        public bool Read(string data, XbimMatrix3D? tr = null)
        {
            int version = 1;
            using (var sr = new StringReader(data))
            {
                Matrix3D? m3D = null;
                var r = new RotateTransform3D();
                if (tr.HasValue) //set up the windows media transforms
                {
                    m3D = new Matrix3D(tr.Value.M11, tr.Value.M12, tr.Value.M13, tr.Value.M14,
                                                  tr.Value.M21, tr.Value.M22, tr.Value.M23, tr.Value.M24,
                                                  tr.Value.M31, tr.Value.M32, tr.Value.M33, tr.Value.M34,
                                                  tr.Value.OffsetX, tr.Value.OffsetY, tr.Value.OffsetZ, tr.Value.M44);
                    r = tr.Value.GetRotateTransform3D();
                }
                var vertexList = new Point3DCollection(); //holds the actual positions of the vertices in this data set in the mesh
                var normalList = new Vector3DCollection(); //holds the actual normals of the vertices in this data set in the mesh
                string line;
                // Read and display lines from the data until the end of
                // the data is reached.
                while ((line = sr.ReadLine()) != null)
                {
                    var tokens = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (tokens.Length <= 1) 
                        continue;
                    var command = tokens[0].Trim().ToUpper();
                    switch (command)
                    {
                        case "P":
                            var pointCount = 512;

                            var faceCount = 128;

                            var triangleCount = 256;
                            var normalCount = 512;
                            if (tokens.Length > 0)
                                version = Int32.Parse(tokens[1]);
                            if (tokens.Length > 1)
                                pointCount = Int32.Parse(tokens[2]);
                            if (tokens.Length > 2) 
                                faceCount = Int32.Parse(tokens[3]);

                            if (tokens.Length > 3) 
                                triangleCount = Int32.Parse(tokens[4]);
                            if (tokens.Length > 4) 
                                normalCount = Math.Max(Int32.Parse(tokens[5]),pointCount); //can't really have less normals than points
                            vertexList = new Point3DCollection(pointCount);
                            normalList = new Vector3DCollection(normalCount);
                            //for efficienciency avoid continual regrowing
                            //this.Mesh.Positions = this.Mesh.Positions.GrowBy(pointCount);
                            //this.Mesh.Normals = this.Mesh.Normals.GrowBy(normalCount);
                            //this.Mesh.TriangleIndices = this.Mesh.TriangleIndices.GrowBy(triangleCount*3);
                            break;
                        case "F":
                            break;
                        case "V": //process vertices
                            for (int i = 1; i < tokens.Length; i++)
                            {
                                string[] xyz = tokens[i].Split(',');
                                Point3D p = new Point3D(Convert.ToDouble(xyz[0], CultureInfo.InvariantCulture),
                                    Convert.ToDouble(xyz[1], CultureInfo.InvariantCulture),
                                    Convert.ToDouble(xyz[2], CultureInfo.InvariantCulture));
                                if (m3D.HasValue)
                                    p = m3D.Value.Transform(p);
                                vertexList.Add(p);
                            }
                            break;
                        case "N": //processes normals
                            for (int i = 1; i < tokens.Length; i++)
                            {
                                string[] xyz = tokens[i].Split(',');
                                Vector3D v = new Vector3D(Convert.ToDouble(xyz[0], CultureInfo.InvariantCulture),
                                    Convert.ToDouble(xyz[1], CultureInfo.InvariantCulture),
                                    Convert.ToDouble(xyz[2], CultureInfo.InvariantCulture));
                                normalList.Add(v);
                            }
                            break;
                        case "T": //process triangulated meshes
                            var currentNormal = new Vector3D();
                            //each time we start a new mesh face we have to duplicate the vertices to ensure that we get correct shading of planar and non planar faces
                            var writtenVertices = new Dictionary<int, int>();

                            for (var i = 1; i < tokens.Length; i++)
                            {
                                var triangleIndices = tokens[i].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                if (triangleIndices.Length != 3) throw new Exception("Invalid triangle definition");
                                for (var t = 0; t < 3; t++)
                                {
                                    var indexNormalPair = triangleIndices[t].Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

                                    if (indexNormalPair.Length > 1) //we have a normal defined
                                    {
                                        if (version == 1)
                                        {
                                            var normalStr = indexNormalPair[1].Trim();
                                            switch (normalStr)
                                            {
                                                case "F": //Front
                                                    currentNormal = new Vector3D(0, -1, 0);
                                                    break;
                                                case "B": //Back
                                                    currentNormal = new Vector3D(0, 1, 0);
                                                    break;
                                                case "L": //Left
                                                    currentNormal = new Vector3D(-1, 0, 0);
                                                    break;
                                                case "R": //Right
                                                    currentNormal = new Vector3D(1, 0, 0);
                                                    break;
                                                case "U": //Up
                                                    currentNormal = new Vector3D(0, 0, 1);
                                                    break;
                                                case "D": //Down
                                                    currentNormal = new Vector3D(0, 0, -1);
                                                    break;
                                                default: //it is an index number
                                                    int normalIndex = int.Parse(indexNormalPair[1]);
                                                    currentNormal = normalList[normalIndex];
                                                    break;
                                            }
                                        }
                                        else //we have support for packed normals
                                        {
                                            var packedNormal = new XbimPackedNormal(ushort.Parse(indexNormalPair[1]));
                                            var n = packedNormal.Normal;
                                            currentNormal = new Vector3D(n.X, n.Y, n.Z);
                                        }
                                        if (tr.HasValue)
                                        {
                                            currentNormal = r.Transform(currentNormal);
                                        }
                                    }
                                    //now add the index
                                    var index = int.Parse(indexNormalPair[0]);

                                    int alreadyWrittenAt; //in case it is the first mesh
                                    if (!writtenVertices.TryGetValue(index, out alreadyWrittenAt)) //if we haven't  written it in this mesh pass, add it again unless it is the first one which we know has been written
                                    {
                                        //all vertices will be unique and have only one normal
                                        writtenVertices.Add(index, PositionCount);

                                        _unfrozenTriangleIndices.Add(PositionCount);
                                        _unfrozenPositions.Add(vertexList[index]);
                                        _unfrozenNormals.Add(currentNormal);

                                    }
                                    else //just add the index reference
                                    {
                                        if (_unfrozenNormals[alreadyWrittenAt] == currentNormal)
                                            _unfrozenTriangleIndices.Add(alreadyWrittenAt);
                                        else //we need another
                                        {
                                            _unfrozenTriangleIndices.Add(PositionCount);
                                            _unfrozenPositions.Add(vertexList[index]);
                                            _unfrozenNormals.Add(currentNormal);
                                        }
                                    }
                                   
                                }
                            }

                            break;
                        default:
                            throw new Exception("Invalid Geometry Command");
                    }
                }
            }
            return true;
        }
예제 #11
0
        protected override void BeginTransition3D(TransitionPresenter transitionElement, ContentPresenter oldContent, ContentPresenter newContent, Viewport3D viewport)
        {
            int  xparticles = 10, yparticles = 10;
            Size size = transitionElement.RenderSize;

            if (size.Width > size.Height)
            {
                yparticles = (int)(xparticles * size.Height / size.Width);
            }
            else
            {
                xparticles = (int)(yparticles * size.Width / size.Height);
            }

            MeshGeometry3D mesh       = CreateMesh(new Point3D(), new Vector3D(size.Width, 0, 0), new Vector3D(0, size.Height, 0), xparticles - 1, yparticles - 1, new Rect(0, 0, 1, 1));
            Brush          cloneBrush = CreateBrush(oldContent);
            Material       clone      = new DiffuseMaterial(cloneBrush);

            double ustep = size.Width / (xparticles - 1), vstep = size.Height / (yparticles - 1);

            Point3DCollection points = mesh.Positions;


            Point3DCollection oldPoints = points.Clone();

            double          timeStep = 1.0 / 30.0;
            DispatcherTimer timer    = new DispatcherTimer();

            timer.Interval = TimeSpan.FromSeconds(timeStep);
            double time     = 0;
            double duration = 2;

            timer.Tick += delegate
            {
                time = time + timeStep;
                Point   mousePos   = Mouse.GetPosition(viewport);
                Point3D mousePos3D = new Point3D(mousePos.X, mousePos.Y, -10);

                // Cloth physics based on work of Thomas Jakobsen http://www.ioi.dk/~thomas
                for (int i = 0; i < oldPoints.Count; i++)
                {
                    Point3D currentPoint = points[i];
                    Point3D newPoint     = currentPoint + 0.9 * (currentPoint - oldPoints[i]);

                    if (newPoint.Y > size.Height)
                    {
                        newPoint.Y = size.Height;
                    }

                    oldPoints[i] = newPoint;
                }

                //for (int j = 0; j < 5; j++)
                //for (int i = oldPoints.Count - 1; i > 0 ; i--)
                for (int a = yparticles - 1; a >= 0; a--)
                {
                    for (int b = xparticles - 1; b >= 0; b--)
                    {
                        int i = b * yparticles + a;
                        // constrain with point to the left
                        if (i > yparticles)
                        {
                            Constrain(oldPoints, i, i - yparticles, ustep);
                        }
                        // constrain with point to the top
                        if (i % yparticles != 0)
                        {
                            Constrain(oldPoints, i, i - 1, vstep);
                        }

                        // constrain the sides
                        if (a == 0)
                        {
                            oldPoints[i] = new Point3D(oldPoints[i].X, 0, oldPoints[i].Z);
                        }
                        if (a == yparticles - 1)
                        {
                            oldPoints[i] = new Point3D(oldPoints[i].X, size.Height, oldPoints[i].Z);
                        }

                        if (b == 0)
                        {
                            oldPoints[i] = new Point3D(0, a * size.Height / (yparticles - 1), 0);
                        }

                        if (b == xparticles - 1)
                        {
                            double angle = time / duration * Math.PI / (0.8 + 0.5 * (yparticles - (double)a) / yparticles);
                            oldPoints[i] = new Point3D(size.Width * Math.Cos(angle), a * size.Height / (yparticles - 1), -size.Width * Math.Sin(angle));
                        }
                    }
                }

                if (time > (duration - 0))
                {
                    timer.Stop();
                    EndTransition(transitionElement, oldContent, newContent);
                }

                // Swap position arrays
                mesh.Positions = oldPoints;
                oldPoints      = points;
                points         = mesh.Positions;
            };
            timer.Start();


            GeometryModel3D geo = new GeometryModel3D(mesh, clone);

            geo.BackMaterial = clone;
            ModelVisual3D model = new ModelVisual3D();

            model.Content = geo;
            viewport.Children.Add(model);
        }
예제 #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="args"></param>
        /// <param name="vertices"></param>
        /// <param name="normals"></param>
        /// <param name="indices"></param>
        /// <param name="textures"></param>
        protected override void Triangulate(DependencyPropertyChangedEventArgs args,
                                            Point3DCollection vertices,
                                            Vector3DCollection normals,
                                            Int32Collection indices,
                                            PointCollection textures)
        {
            // Clear all four collections.
            vertices.Clear();
            normals.Clear();
            indices.Clear();
            textures.Clear();

            double x, y, z;
            int    indexBase = 0;

            // Front side.
            // -----------
            z = Depth / 2;

            // Fill the vertices, normals, textures collections.
            for (int stack = 0; stack <= Stacks; stack++)
            {
                y = Height / 2 - stack * Height / Stacks;

                for (int slice = 0; slice <= Slices; slice++)
                {
                    x = -Width / 2 + slice * Width / Slices;
                    Point3D point = new Point3D(x, y, z);
                    vertices.Add(point);

                    normals.Add(point - new Point3D(x, y, 0));
                    textures.Add(new Point((double)slice / Slices,
                                           (double)stack / Stacks));
                }
            }

            // Fill the indices collection.
            for (int stack = 0; stack < Stacks; stack++)
            {
                for (int slice = 0; slice < Slices; slice++)
                {
                    indices.Add((stack + 0) * (Slices + 1) + slice);
                    indices.Add((stack + 1) * (Slices + 1) + slice);
                    indices.Add((stack + 0) * (Slices + 1) + slice + 1);

                    indices.Add((stack + 0) * (Slices + 1) + slice + 1);
                    indices.Add((stack + 1) * (Slices + 1) + slice);
                    indices.Add((stack + 1) * (Slices + 1) + slice + 1);
                }
            }

            // Rear side.
            // -----------
            indexBase = vertices.Count;
            z         = -Depth / 2;

            // Fill the vertices, normals, textures collections.
            for (int stack = 0; stack <= Stacks; stack++)
            {
                y = Height / 2 - stack * Height / Stacks;

                for (int slice = 0; slice <= Slices; slice++)
                {
                    x = Width / 2 - slice * Width / Slices;
                    Point3D point = new Point3D(x, y, z);
                    vertices.Add(point);

                    normals.Add(point - new Point3D(x, y, 0));
                    textures.Add(new Point((double)slice / Slices,
                                           (double)stack / Stacks));
                }
            }

            // Fill the indices collection.
            for (int stack = 0; stack < Stacks; stack++)
            {
                for (int slice = 0; slice < Slices; slice++)
                {
                    indices.Add(indexBase + (stack + 0) * (Slices + 1) + slice);
                    indices.Add(indexBase + (stack + 1) * (Slices + 1) + slice);
                    indices.Add(indexBase + (stack + 0) * (Slices + 1) + slice + 1);

                    indices.Add(indexBase + (stack + 0) * (Slices + 1) + slice + 1);
                    indices.Add(indexBase + (stack + 1) * (Slices + 1) + slice);
                    indices.Add(indexBase + (stack + 1) * (Slices + 1) + slice + 1);
                }
            }

            // Left side.
            // -----------
            indexBase = vertices.Count;
            x         = -Width / 2;

            // Fill the vertices, normals, textures collections.
            for (int stack = 0; stack <= Stacks; stack++)
            {
                y = Height / 2 - stack * Height / Stacks;

                for (int layer = 0; layer <= Layers; layer++)
                {
                    z = -Depth / 2 + layer * Depth / Layers;
                    Point3D point = new Point3D(x, y, z);
                    vertices.Add(point);

                    normals.Add(point - new Point3D(0, y, z));
                    textures.Add(new Point((double)layer / Layers,
                                           (double)stack / Stacks));
                }
            }

            // Fill the indices collection.
            for (int stack = 0; stack < Stacks; stack++)
            {
                for (int layer = 0; layer < Layers; layer++)
                {
                    indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer);
                    indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer);
                    indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer + 1);

                    indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer + 1);
                    indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer);
                    indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer + 1);
                }
            }

            // Right side.
            // -----------
            indexBase = vertices.Count;
            x         = Width / 2;

            // Fill the vertices, normals, textures collections.
            for (int stack = 0; stack <= Stacks; stack++)
            {
                y = Height / 2 - stack * Height / Stacks;

                for (int layer = 0; layer <= Layers; layer++)
                {
                    z = Depth / 2 - layer * Depth / Layers;
                    Point3D point = new Point3D(x, y, z);
                    vertices.Add(point);

                    normals.Add(point - new Point3D(0, y, z));
                    textures.Add(new Point((double)layer / Layers,
                                           (double)stack / Stacks));
                }
            }

            // Fill the indices collection.
            for (int stack = 0; stack < Stacks; stack++)
            {
                for (int layer = 0; layer < Layers; layer++)
                {
                    indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer);
                    indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer);
                    indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer + 1);

                    indices.Add(indexBase + (stack + 0) * (Layers + 1) + layer + 1);
                    indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer);
                    indices.Add(indexBase + (stack + 1) * (Layers + 1) + layer + 1);
                }
            }

            // Top side.
            // -----------
            indexBase = vertices.Count;
            y         = Height / 2;

            // Fill the vertices, normals, textures collections.
            for (int layer = 0; layer <= Layers; layer++)
            {
                z = -Depth / 2 + layer * Depth / Layers;

                for (int slice = 0; slice <= Slices; slice++)
                {
                    x = -Width / 2 + slice * Width / Slices;
                    Point3D point = new Point3D(x, y, z);
                    vertices.Add(point);

                    normals.Add(point - new Point3D(x, 0, z));
                    textures.Add(new Point((double)slice / Slices,
                                           (double)layer / Layers));
                }
            }

            // Fill the indices collection.
            for (int layer = 0; layer < Layers; layer++)
            {
                for (int slice = 0; slice < Slices; slice++)
                {
                    indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice);
                    indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice);
                    indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice + 1);

                    indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice + 1);
                    indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice);
                    indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice + 1);
                }
            }

            // Bottom side.
            // -----------
            indexBase = vertices.Count;
            y         = -Height / 2;

            // Fill the vertices, normals, textures collections.
            for (int layer = 0; layer <= Layers; layer++)
            {
                z = Depth / 2 - layer * Depth / Layers;

                for (int slice = 0; slice <= Slices; slice++)
                {
                    x = -Width / 2 + slice * Width / Slices;
                    Point3D point = new Point3D(x, y, z);
                    vertices.Add(point);

                    normals.Add(point - new Point3D(x, 0, z));
                    textures.Add(new Point((double)slice / Slices,
                                           (double)layer / Layers));
                }
            }

            // Fill the indices collection.
            for (int layer = 0; layer < Layers; layer++)
            {
                for (int slice = 0; slice < Slices; slice++)
                {
                    indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice);
                    indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice);
                    indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice + 1);

                    indices.Add(indexBase + (layer + 0) * (Slices + 1) + slice + 1);
                    indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice);
                    indices.Add(indexBase + (layer + 1) * (Slices + 1) + slice + 1);
                }
            }
        }
예제 #13
0
        public void Execute(ScriptContext context, Window window)
        {
            ////////////////////////////////////////////////
            // 1. Check for valid plan with structure set //
            ////////////////////////////////////////////////
            PlanSetup plan = context.PlanSetup;

            if (plan == null)
            {
                MessageBox.Show("Error: No plan loaded");
                return;
            }
            StructureSet structureSet = plan.StructureSet;

            if (structureSet == null)
            {
                MessageBox.Show("Error: No structure set loaded");
                return;
            }

            ////////////////////////////////////////////////////////////
            // 2. Load plan/structure data; calculate collision zones //
            ////////////////////////////////////////////////////////////
            Structure      bodyStructure = structureSet.Structures.FirstOrDefault(s => s.Id == "BODY");
            MeshGeometry3D bodyContour   = bodyStructure.MeshGeometry;
            Color          bodyColor     = bodyStructure.Color;

            MeshGeometry3D couchContour = new MeshGeometry3D();
            Color          couchColor   = new Color();

            foreach (var s in structureSet.Structures)
            {
                if (s.Id.Contains("CouchSurface"))
                {
                    Structure couchStructure = s;
                    couchContour = couchStructure.MeshGeometry;
                    couchColor   = couchStructure.Color;
                    break;
                }
            }

            VVector iso = plan.Beams.ElementAt(0).IsocenterPosition;

            double        radius = 380.0;
            double        r, ga;
            Point3D       p               = new Point3D();
            List <double> collisionAngles = new List <double>();

            for (int n = 0; n < bodyContour.Positions.Count(); n++)
            {
                p = bodyContour.Positions[n];
                r = Math.Sqrt(Math.Pow(p.X - iso.x, 2) + Math.Pow(p.Y - iso.y, 2));
                if (r >= radius)
                {
                    ga = (Math.Atan2(p.Y - iso.y, p.X - iso.x)) * (180.0 / Math.PI) + 90.0;
                    while (ga < 0.0)
                    {
                        ga += 360.0;
                    }
                    collisionAngles.Add(ga);
                }
            }
            for (int n = 0; n < couchContour.Positions.Count(); n++)
            {
                p = couchContour.Positions[n];
                r = Math.Sqrt(Math.Pow(p.X - iso.x, 2) + Math.Pow(p.Y - iso.y, 2));
                if (r >= radius)
                {
                    ga = (Math.Atan2(p.Y - iso.y, p.X - iso.x)) * (180.0 / Math.PI) + 90.0;
                    while (ga < 0.0)
                    {
                        ga += 360.0;
                    }
                    collisionAngles.Add(ga);
                }
            }
            double minVal = 0.0, maxVal = 0.0;

            if (collisionAngles.Count() > 0)
            {
                minVal = collisionAngles.Min();
                maxVal = collisionAngles.Max();
                string results = minVal.ToString("F1") + " - " + maxVal.ToString("F1");
                //MessageBox.Show(results);
            }

            ///////////////////////////////////
            // 3. Make collision zone visual //
            ///////////////////////////////////
            MeshGeometry3D linacZonePass  = new MeshGeometry3D();
            Color          linacColorPass = new Color();

            linacColorPass = Color.FromScRgb(0.6f, 0.5f, 0.5f, 0.5f);
            Point3DCollection  vertices   = new Point3DCollection();
            Vector3DCollection normals    = new Vector3DCollection();
            Int32Collection    indices    = new Int32Collection();
            int    numSpokes              = 100;
            double halfLength             = 150.0;
            double startAngle             = (maxVal - 90) * (Math.PI / 180.0);
            double dA = (360 - (maxVal - minVal)) / (double)(numSpokes);

            vertices.Add(new Point3D(iso.x + radius * Math.Cos(startAngle),
                                     iso.y + radius * Math.Sin(startAngle), -halfLength));
            vertices.Add(new Point3D(iso.x + radius * Math.Cos(startAngle),
                                     iso.y + radius * Math.Sin(startAngle), halfLength));
            normals.Add(new Vector3D(Math.Cos(startAngle), Math.Sin(startAngle), 0.0));
            normals.Add(new Vector3D(Math.Cos(startAngle), Math.Sin(startAngle), 0.0));
            for (int n = 1; n <= numSpokes; n++)
            {
                double angle = startAngle + Convert.ToDouble(n) * dA * (Math.PI / 180.0);
                vertices.Add(new Point3D(iso.x + radius * Math.Cos(angle),
                                         iso.y + radius * Math.Sin(angle), -halfLength));
                vertices.Add(new Point3D(iso.x + radius * Math.Cos(angle),
                                         iso.y + radius * Math.Sin(angle), halfLength));
                normals.Add(new Vector3D(Math.Cos(angle), Math.Sin(angle), 0.0));
                normals.Add(new Vector3D(Math.Cos(angle), Math.Sin(angle), 0.0));
                indices.Add(2 * (n - 1));
                indices.Add(2 * (n - 1) + 3);
                indices.Add(2 * (n - 1) + 1);
                indices.Add(2 * (n - 1));
                indices.Add(2 * (n - 1) + 2);
                indices.Add(2 * (n - 1) + 3);
            }
            //indices.Add(2*(numSpokes-1));
            //indices.Add(2*(numSpokes-1) + 1);
            //indices.Add(1);
            //indices.Add(2*(numSpokes-1));
            //indices.Add(1);
            //indices.Add(0);
            linacZonePass.Positions       = vertices;
            linacZonePass.Normals         = normals;
            linacZonePass.TriangleIndices = indices;

            MeshGeometry3D linacZoneFail  = new MeshGeometry3D();
            Color          linacColorFail = new Color();

            linacColorFail = Color.FromScRgb(1.0f, 1.0f, 0.0f, 0.0f);
            Point3DCollection  verticesF = new Point3DCollection();
            Vector3DCollection normalsF  = new Vector3DCollection();
            Int32Collection    indicesF  = new Int32Collection();

            //numSpokes = (maxVal - minVal) + 1;
            startAngle = (minVal - 90) * (Math.PI / 180.0);
            dA         = (maxVal - minVal) / (double)(numSpokes);
            verticesF.Add(new Point3D(iso.x + radius * Math.Cos(startAngle),
                                      iso.y + radius * Math.Sin(startAngle), -halfLength));
            verticesF.Add(new Point3D(iso.x + radius * Math.Cos(startAngle),
                                      iso.y + radius * Math.Sin(startAngle), halfLength));
            normalsF.Add(new Vector3D(Math.Cos(startAngle), Math.Sin(startAngle), 0.0));
            normalsF.Add(new Vector3D(Math.Cos(startAngle), Math.Sin(startAngle), 0.0));
            for (int n = 1; n <= numSpokes; n++)
            {
                double angle = startAngle + Convert.ToDouble(n) * dA * (Math.PI / 180.0);
                verticesF.Add(new Point3D(iso.x + radius * Math.Cos(angle),
                                          iso.y + radius * Math.Sin(angle), -halfLength));
                verticesF.Add(new Point3D(iso.x + radius * Math.Cos(angle),
                                          iso.y + radius * Math.Sin(angle), halfLength));
                normalsF.Add(new Vector3D(Math.Cos(angle), Math.Sin(angle), 0.0));
                normalsF.Add(new Vector3D(Math.Cos(angle), Math.Sin(angle), 0.0));
                indicesF.Add(2 * (n - 1));
                indicesF.Add(2 * (n - 1) + 3);
                indicesF.Add(2 * (n - 1) + 1);
                indicesF.Add(2 * (n - 1));
                indicesF.Add(2 * (n - 1) + 2);
                indicesF.Add(2 * (n - 1) + 3);
            }
            linacZoneFail.Positions       = verticesF;
            linacZoneFail.Normals         = normalsF;
            linacZoneFail.TriangleIndices = indicesF;

            //////////////////////////////////////
            // 4. Display results in new window //
            //////////////////////////////////////

            // 3D-view objects
            Model3DGroup    myModel3DGroup         = new Model3DGroup();
            GeometryModel3D bodyGeometryModel      = new GeometryModel3D();
            GeometryModel3D couchGeometryModel     = new GeometryModel3D();
            GeometryModel3D linacPassGeometryModel = new GeometryModel3D();
            GeometryModel3D linacFailGeometryModel = new GeometryModel3D();
            ModelVisual3D   myModelVisual3D        = new ModelVisual3D();

            // Defines the camera used to view the 3D object.
            PerspectiveCamera myPCamera = new PerspectiveCamera();

            cameraRadius = 1000.0;
            cameraTheta  = 90.0 * (Math.PI / 180.0);
            cameraPhi    = 0.0 * (Math.PI / 180.0);
            cv           = bodyStructure.CenterPoint;
            double cameraX = cv.x + cameraRadius * Math.Sin(cameraTheta) * Math.Cos(cameraPhi - Math.PI / 2.0);
            double cameraY = cv.y + cameraRadius * Math.Sin(cameraTheta) * Math.Sin(cameraPhi - Math.PI / 2.0);
            double cameraZ = cv.z + (cameraRadius * Math.Cos(cameraTheta));

            myPCamera.Position      = new Point3D(cameraX, cameraY, cameraZ);
            myPCamera.LookDirection = new Vector3D(cv.x - cameraX, cv.y - cameraY, cv.z - cameraZ);
            myPCamera.FieldOfView   = 60; // in degrees
            myPCamera.UpDirection   = new Vector3D(0.0, 0.0, 1.0);
            myViewport3D.Camera     = myPCamera;

            // Define directional lighting (points from camera to origin)
            DirectionalLight myDirectionalLight = new DirectionalLight();

            myDirectionalLight.Color     = Colors.White;
            myDirectionalLight.Direction = myPCamera.LookDirection;
            myModel3DGroup.Children.Add(myDirectionalLight);

            // Initialize body mesh
            bodyGeometryModel.Geometry = bodyContour;
            DiffuseMaterial bodyMaterial = new DiffuseMaterial(new SolidColorBrush(bodyColor));

            bodyGeometryModel.Material     = bodyMaterial;
            bodyGeometryModel.BackMaterial = bodyMaterial;
            myModel3DGroup.Children.Add(bodyGeometryModel);

            // Initialize couch mesh
            couchGeometryModel.Geometry = couchContour;
            DiffuseMaterial couchMaterial = new DiffuseMaterial(new SolidColorBrush(couchColor));

            couchGeometryModel.Material     = couchMaterial;
            couchGeometryModel.BackMaterial = couchMaterial;
            myModel3DGroup.Children.Add(couchGeometryModel);

            // Initialize linac mesh
            linacPassGeometryModel.Geometry = linacZonePass;
            DiffuseMaterial linacPassMaterial = new DiffuseMaterial(new SolidColorBrush(linacColorPass));

            linacPassGeometryModel.Material     = linacPassMaterial;
            linacPassGeometryModel.BackMaterial = linacPassMaterial;
            myModel3DGroup.Children.Add(linacPassGeometryModel);

            linacFailGeometryModel.Geometry = linacZoneFail;
            DiffuseMaterial linacFailMaterial = new DiffuseMaterial(new SolidColorBrush(linacColorFail));

            linacFailGeometryModel.Material     = linacFailMaterial;
            linacFailGeometryModel.BackMaterial = linacFailMaterial;
            myModel3DGroup.Children.Add(linacFailGeometryModel);

            myModelVisual3D.Content = myModel3DGroup;
            myViewport3D.Children.Add(myModelVisual3D);

            // Calculate beam collision table
            Grid beamGrid = MakeBeamGrid(context, plan, minVal, maxVal);

            var mainGrid             = new Grid();
            ColumnDefinition colDef1 = new ColumnDefinition();

            mainGrid.ColumnDefinitions.Add(colDef1);
            RowDefinition rowDef1 = new RowDefinition();
            RowDefinition rowDef2 = new RowDefinition();
            RowDefinition rowDef3 = new RowDefinition();
            RowDefinition rowDef4 = new RowDefinition();

            rowDef1.Height = new System.Windows.GridLength(32);
            rowDef2.Height = new System.Windows.GridLength(500);
            mainGrid.RowDefinitions.Add(rowDef1);
            mainGrid.RowDefinitions.Add(rowDef2);
            mainGrid.RowDefinitions.Add(rowDef3);
            mainGrid.RowDefinitions.Add(rowDef4);
            //mainGrid.ShowGridLines = true;

            TextBlock keyCommands = new TextBlock();

            keyCommands.Text                = "Q/W: Rotate\tZ/X: Zoom\tR: Reset View";
            keyCommands.FontSize            = 16;
            keyCommands.HorizontalAlignment = HorizontalAlignment.Center;
            Grid.SetRow(keyCommands, 0);
            Grid.SetColumn(keyCommands, 0);
            mainGrid.Children.Add(keyCommands);

            Grid.SetRow(myViewport3D, 1);
            Grid.SetColumn(myViewport3D, 0);
            mainGrid.Children.Add(myViewport3D);

            Grid.SetRow(beamGrid, 2);
            Grid.SetColumn(beamGrid, 0);
            mainGrid.Children.Add(beamGrid);

            TextBlock appNotes = new TextBlock();

            appNotes.Text = "**Extended gantry angles are not included in this calculation and are treated as unextended (e.g. 179.0E -> 179.0)";
            appNotes.HorizontalAlignment = HorizontalAlignment.Center;
            Grid.SetRow(appNotes, 3);
            Grid.SetColumn(appNotes, 0);
            mainGrid.Children.Add(appNotes);

            // Create window
            window.Title = "CollisionAvoid";
            //window.Closing += new System.ComponentModel.CancelEventHandler(OnWindowClosing);
            window.Height   = 800;
            window.Width    = 800;
            window.Content  = mainGrid;
            window.KeyDown += HandleKeyPressEvent;
        }
예제 #14
0
        public static Viewport3D RenderTest(Mesh3DExtended Mesh)
        {
            Mesh.CenterObject();

            // Declare scene objects.
            Viewport3D        viewport        = new Viewport3D();
            Model3DGroup      myModel3DGroup  = new Model3DGroup();
            GeometryModel3D   myGeometryModel = new GeometryModel3D();
            ModelVisual3D     myModelVisual3D = new ModelVisual3D();
            PerspectiveCamera myPCamera       = new PerspectiveCamera();

            // Setup camera.
            myPCamera.UpDirection   = new Vector3D(0, 0, 1);
            myPCamera.Position      = new Point3D(1, -1, 1.5f);
            myPCamera.LookDirection = new Vector3D(-1, 1, -1);
            myPCamera.FieldOfView   = 60;
            viewport.Camera         = myPCamera;

            // Lights
            DirectionalLight dirLightX   = new DirectionalLight(Colors.DarkGreen, new Vector3D(-1, 0, 0));
            DirectionalLight dirLightY   = new DirectionalLight(Colors.DarkRed, new Vector3D(0, 1, 0));
            DirectionalLight dirLightZ   = new DirectionalLight(Colors.DarkBlue, new Vector3D(0, 0, -1));
            DirectionalLight dirLightCam = new DirectionalLight(Colors.White, new Vector3D(-1, 1, -1));

            myModel3DGroup.Children.Add(dirLightX);
            myModel3DGroup.Children.Add(dirLightY);
            myModel3DGroup.Children.Add(dirLightZ);
            myModel3DGroup.Children.Add(dirLightCam);

            // Add the mesh.
            MeshGeometry3D    myMeshGeometry3D            = new MeshGeometry3D();
            Point3DCollection myPositionCollection        = new Point3DCollection();
            Int32Collection   myTriangleIndicesCollection = new Int32Collection();

            Mesh3DExtended.Triangle tri;
            int j = 0;

            for (int i = 0; i < Mesh.Triangles.Length; i++)
            {
                tri = Mesh.Triangles[i];
                myPositionCollection.Add(new Point3D(tri.v1.X, tri.v1.Y, tri.v1.Z));
                myPositionCollection.Add(new Point3D(tri.v2.X, tri.v2.Y, tri.v2.Z));
                myPositionCollection.Add(new Point3D(tri.v3.X, tri.v3.Y, tri.v3.Z));

                myTriangleIndicesCollection.Add(j++);
                myTriangleIndicesCollection.Add(j++);
                myTriangleIndicesCollection.Add(j++);
            }
            myMeshGeometry3D.Positions       = myPositionCollection;
            myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection;

            // Apply the mesh to the geometry model.
            myGeometryModel.Geometry = myMeshGeometry3D;

            // Define material and apply to the mesh geometries.
            DiffuseMaterial myMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.White));

            myGeometryModel.Material = myMaterial;

            // Transforms for scale and position.
            Transform3DGroup transformGroup = new Transform3DGroup();

            transformGroup.Children.Add(new TranslateTransform3D(new Vector3D(-Mesh.OffsetX, -Mesh.OffsetY, -Mesh.OffsetZ)));
            transformGroup.Children.Add(new ScaleTransform3D(Mesh.Scale, Mesh.Scale, Mesh.Scale));

            // Add the geometry model to the model group.
            myModel3DGroup.Children.Add(myGeometryModel);
            myModel3DGroup.Transform = transformGroup;

            // Add the group of models to the ModelVisual3d.
            myModelVisual3D.Content = myModel3DGroup;
            viewport.Children.Add(myModelVisual3D);

            return(viewport);
        }
예제 #15
0
        /// <summary>
        /// Camera frustum 3D graphics
        /// </summary>
        /// <param name="viewport">The viewport.</param>
        /// <param name="near">The near plane of the frustum.</param>
        /// <param name="far">The far plane of the frustum.</param>
        /// <param name="depthWidth">The width of the depth image.</param>
        /// <param name="depthHeight">The height of the depth image.</param>
        /// <param name="color">The color to draw the frustum.</param>
        /// <param name="thickness">The line thickness to use when drawing the frustum.</param>
        public void CreateFrustum3DGraphics(Viewport3D viewport, float near, float far, float depthWidth, float depthHeight, System.Windows.Media.Color color, int thickness)
        {
            if (null == viewport)
            {
                return;
            }

            this.graphicsViewport = viewport;

            // De-normalize default camera params
            float px = camParams.PrincipalPointX * depthWidth;
            float py = camParams.PrincipalPointY * depthHeight;

            float fx = camParams.FocalLengthX * depthWidth;
            float fy = camParams.FocalLengthY * depthHeight;

            float iflx = 1.0f / fx;
            float ifly = 1.0f / fy;

            this.CameraFrustum = new ScreenSpaceLines3D();

            this.CameraFrustum.Points = new Point3DCollection();
            Point3DCollection pts = this.CameraFrustum.Points;

            // Near plane rectangle
            pts.Add(Helper.BackProject(0, 0, near, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(depthWidth, 0, near, px, py, iflx, ifly));

            pts.Add(Helper.BackProject(depthWidth, 0, near, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(depthWidth, depthHeight, near, px, py, iflx, ifly));

            pts.Add(Helper.BackProject(depthWidth, depthHeight, near, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(0, depthHeight, near, px, py, iflx, ifly));

            pts.Add(Helper.BackProject(0, depthHeight, near, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(0, 0, near, px, py, iflx, ifly));

            // Far plane rectangle
            pts.Add(Helper.BackProject(0, 0, far, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(depthWidth, 0, far, px, py, iflx, ifly));

            pts.Add(Helper.BackProject(depthWidth, 0, far, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(depthWidth, depthHeight, far, px, py, iflx, ifly));

            pts.Add(Helper.BackProject(depthWidth, depthHeight, far, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(0, depthHeight, far, px, py, iflx, ifly));

            pts.Add(Helper.BackProject(0, depthHeight, far, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(0, 0, far, px, py, iflx, ifly));

            // Connecting lines
            pts.Add(Helper.BackProject(0, 0, near, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(0, 0, far, px, py, iflx, ifly));

            pts.Add(Helper.BackProject(depthWidth, 0, near, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(depthWidth, 0, far, px, py, iflx, ifly));

            pts.Add(Helper.BackProject(depthWidth, depthHeight, near, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(depthWidth, depthHeight, far, px, py, iflx, ifly));

            pts.Add(Helper.BackProject(0, depthHeight, near, px, py, iflx, ifly));
            pts.Add(Helper.BackProject(0, depthHeight, far, px, py, iflx, ifly));

            this.CameraFrustum.Thickness = thickness;
            this.CameraFrustum.Color     = color;

            // Add a fixed rotation around the Y axis to look back down +Z towards origin
            Matrix3D fixedRotY180 = new Matrix3D();

            fixedRotY180.Rotate(new Quaternion(new Vector3D(0, 1, 0), 180));
            this.cumulativeCameraFrustumTransform.Children.Add(new MatrixTransform3D(fixedRotY180));
            this.cumulativeCameraFrustumTransform.Children.Add(this.cameraFrustumTransform3D);

            this.CameraFrustum.Transform = this.cumulativeCameraFrustumTransform;
        }
예제 #16
0
        public void Render()
        {
            bool showPointCloud         = false;
            bool showKeyFrameTrajectory = false;
            bool showFrameTrajectory    = false;
            bool onlyNew = true;

            _SyncContext.Send(d =>
            {
                showPointCloud         = ShowPointCloud;
                showKeyFrameTrajectory = ShowKeyFrameTrajectory;
                showFrameTrajectory    = ShowFrameTrajectory;
                onlyNew = !(showPointCloud && Model != null && (Model as Model3DGroup).Children.Count == 0);
            }, null);

            if (_Map.HasFrames() || _Map.HasKeyFrames())
            {
                List <Vector3> pointsKeyFrame = new List <Vector3>();
                List <Vector3> pointsFrame    = new List <Vector3>();

                if (showKeyFrameTrajectory)
                {
                    pointsKeyFrame = _Map.GetTrajectory(TrajectoryType.Optimazation);
                }
                if (showFrameTrajectory)
                {
                    pointsFrame = _Map.GetTrajectory(TrajectoryType.PreOptimazation);
                }

                List <GeometryModel3D> pointClouds = new List <GeometryModel3D>();
                if (showPointCloud)
                {
                    pointClouds = _Map.GetPointCloud(onlyNew);
                }

                _SyncContext.Post(d =>
                {
                    TrajectoryKeyFrame = new Point3DCollection(pointsKeyFrame.SelectMany(c => new List <Point3D>()
                    {
                        new Point3D(c.X, c.Y, c.Z), new Point3D(c.X, c.Y, c.Z)
                    }));
                    if (TrajectoryKeyFrame.Count > 0)
                    {
                        TrajectoryKeyFrame.RemoveAt(0);
                    }

                    TrajectoryFrame = new Point3DCollection(pointsFrame.SelectMany(c => new List <Point3D>()
                    {
                        new Point3D(c.X, c.Y, c.Z), new Point3D(c.X, c.Y, c.Z)
                    }));
                    if (TrajectoryFrame.Count > 0)
                    {
                        TrajectoryFrame.RemoveAt(0);
                    }

                    CameraPosition = new MatrixTransform3D(_Map.LastTransformation().Matrix3D);

                    if (Model == null || !showPointCloud)
                    {
                        Model = new Model3DGroup();
                    }
                    foreach (GeometryModel3D pointCloud in pointClouds)
                    {
                        (Model as Model3DGroup).Children.Add(pointCloud);
                    }

                    if (ShowKeyFrameOrientations)
                    {
                        foreach (Visual3D visual3D in _Map.GetKeyFrameOrientations(CoordinateSystems.Count != 0))
                        {
                            CoordinateSystems.Add(visual3D);
                        }
                    }
                    else
                    {
                        CoordinateSystems.Clear();
                    }
                }, null);
            }
            else
            {
                _SyncContext.Post(d =>
                {
                    if (TrajectoryFrame != null && TrajectoryFrame.Count > 0)
                    {
                        TrajectoryFrame = new Point3DCollection();
                    }
                    if (TrajectoryKeyFrame != null && TrajectoryKeyFrame.Count > 0)
                    {
                        TrajectoryKeyFrame = new Point3DCollection();
                    }
                }, null);
            }
        }
예제 #17
0
 /// <summary>
 /// Removes the last point in the underlying PointGeomInfo collection.
 /// </summary>
 internal void RemoveLast()
 {
     _geomPoints.RemoveAt(_geomPoints.Count - 1);
     _visualPoints = null;
 }
예제 #18
0
 internal void Add(PointGeomInfo p)
 {
     _visualPoints = null;
     _geomPoints.Add(p);
 }
예제 #19
0
        MeshGeometry3D GenMesh()
        {   // 00 - 01 - 02 - 03 ...
            //    /    /
            // 10 - 11 - 12
            // Nx * Ny Points
            // triangles = (Nx-1)*(Ny-1) * 2
            int Nx = 20;
            int Ny = 5;
            // th = 180 ~ 0 dth = + 180/(Nx-1)
            double th0 = -180;
            double dth = (0 - 360.0) / (double)(Nx - 1);
            double x0  = 0.5;

            //double R0 = 0.5;
            Point3D[,] p3Dm2D = new Point3D[Nx, Ny];
            for (int i = 0; i < Nx; i++)
            {
                for (int j = 0; j < Ny; j++)
                {
                    // Rectangle

                    /* double x = 1.0 / (double)(Nx - 1) * i;
                     * double y = 1.0 / (double)(Ny - 1) * j;
                     * double z = 0; */
                    // Cylinder
                    double th = th0 + i * dth;
                    double x  = x0 + R0 * Math.Cos(th / 180 * Math.PI);
                    double y  = 1.0 / (double)(Ny - 1) * j;
                    double z  = R0 * Math.Sin(th / 180 * Math.PI);
                    p3Dm2D[i, j] = new Point3D(x, y, z);
                }
            }
            Point[,] pTexture = new Point[Nx, Ny];
            for (int i = 0; i < Nx; i++)
            {
                for (int j = 0; j < Ny; j++)
                {
                    pTexture[i, j] = new Point(1.0 / (double)(Nx - 1) * i, 1.0 - (1.0 / (double)(Ny - 1) * j));
                }
            }
            MeshGeometry3D    mesh1 = new MeshGeometry3D();
            Point3DCollection pts   = new Point3DCollection();

            for (int i = 0; i < Nx; i++)
            {
                for (int j = 0; j < Ny; j++)
                {
                    pts.Add(p3Dm2D[i, j]);
                }
            }
            PointCollection tpts = new PointCollection();

            for (int i = 0; i < Nx; i++)
            {
                for (int j = 0; j < Ny; j++)
                {
                    tpts.Add(pTexture[i, j]);
                }
            }
            Int32Collection tri = new Int32Collection();

            // (i,j)  (1)    i+1,j (2)
            //
            // i, j+1 (0)   i+1, j+1 (3)
            // tri 0,1,2,2,3,1
            for (int i = 0; i < Nx - 1; i++)
            {
                for (int j = 0; j < Ny - 1; j++)
                {
                    tri.Add(j + Ny * i);             //1
                    tri.Add(j + 1 + Ny * i);         //0

                    tri.Add(j + Ny * (i + 1));       //2

                    tri.Add((j + 1) + Ny * (i + 1)); //3
                    tri.Add(j + Ny * (i + 1));       //2
                    tri.Add(j + 1 + Ny * i);         //0
                }
            }
            mesh1.Positions          = pts;
            mesh1.TextureCoordinates = tpts;
            mesh1.TriangleIndices    = tri;

            return(mesh1);
        }
예제 #20
0
        public static Point3D GetCenter(Point3DCollection points)
        {
            Rect3D bounds = Extents(points);

            return(new Point3D(bounds.X + (bounds.SizeX / 2), bounds.Y + (bounds.SizeY / 2), bounds.Z + (bounds.SizeZ / 2)));
        }
예제 #21
0
        public void AddElement(string smodel, string simg, int simgid, int id, ModelUIElement3D mod)
        {
            if (simg == "")
            {
                simg = win.soureseDefaultB;
            }
            if (id == 0)
            {
                id = win.iddefaultB;
            }
            if (smodel == "")
            {
                return;
            }
            ModelImporter importer  = new ModelImporter();
            Material      material1 = new DiffuseMaterial(win.defcolor);

            importer.DefaultMaterial = material1;
            double maxx = 0;

            ModelUIElement3D[] masel = new ModelUIElement3D[4];
            masel[0] = win.selectedobject;
            masel[1] = win.twoselectedobject;
            masel[2] = win.threeselectedobject;
            masel[3] = win.fourselectedobject;
            int countmasel = 0;

            for (int i = 0; i < 4; i++)
            {
                if (masel[i] != null)
                {
                    countmasel++;
                }
            }
            for (int j = 0; j < countmasel; j++)
            {
                Model3DGroup model = importer.Load(smodel);
                int          idd   = win.rand.Next(0, 100000);
                for (int i = 0; i < model.Children.Count; i++)
                {
                    GeometryModel3D   gmodel = model.Children[i] as GeometryModel3D;
                    MeshGeometry3D    mmodel = (MeshGeometry3D)gmodel.Geometry;
                    Point3DCollection p3dc   = mmodel.Positions;
                }
                double xx = 9999;
                double yy = 9999;
                double zz = 9999;
                for (int i = 0; i < model.Children.Count; i++)
                {
                    GeometryModel3D   gmodel = model.Children[i] as GeometryModel3D;
                    MeshGeometry3D    mmodel = (MeshGeometry3D)gmodel.Geometry;
                    Point3DCollection p3dc   = mmodel.Positions;
                    if (gmodel.Bounds.SizeX > maxx)
                    {
                        maxx = gmodel.Bounds.SizeX;
                    }
                    if (gmodel.Bounds.SizeY > maxx)
                    {
                        maxx = gmodel.Bounds.SizeY;
                    }
                    if (gmodel.Bounds.SizeZ > maxx)
                    {
                        maxx = gmodel.Bounds.SizeZ;
                    }
                    if (gmodel.Bounds.X < xx)
                    {
                        xx = gmodel.Bounds.X;
                    }
                    if (gmodel.Bounds.Y < yy)
                    {
                        yy = gmodel.Bounds.Y;
                    }
                    if (gmodel.Bounds.Z < zz)
                    {
                        zz = gmodel.Bounds.Z;
                    }
                }
                for (int i = 0; i < model.Children.Count; i++)
                {
                    GeometryModel3D gmodel = new GeometryModel3D();
                    gmodel = model.Children[i] as GeometryModel3D;
                    MeshGeometry3D mmodel = (MeshGeometry3D)gmodel.Geometry;
                    gmodel.Material = new DiffuseMaterial(win.defcolor);
                    Point3DCollection p3dc = mmodel.Positions;
                    for (int ii = 0; ii < p3dc.Count; ii++)
                    {
                        Point3D tp = p3dc[ii];
                        tp.X     = tp.X / maxx;
                        tp.Y     = tp.Y / maxx;
                        tp.Z     = tp.Z / maxx;
                        p3dc[ii] = tp;
                    }
                    for (int ii = 0; ii < p3dc.Count; ii++)
                    {
                        Point3D tp = p3dc[ii];
                        tp.X     = tp.X - xx / maxx;
                        tp.Y     = tp.Y - yy / maxx;
                        tp.Z     = tp.Z - zz / maxx;
                        p3dc[ii] = tp;
                    }
                    ModelUIElement3D modelUI = new ModelUIElement3D();
                    modelUI.Model = gmodel;
                    _3DObject      tempmodel1 = win.CreatedElements[mod.GetHashCode()] as _3DObject;
                    ElementCabinet tempmodel  = new ElementCabinet(modelUI, 1, 1, 1, 0, 0, 0);
                    tempmodel.idtexture   = simgid;
                    tempmodel.groupel     = tempmodel1.groupel;
                    tempmodel.ingroupel   = "Element-" + idd;
                    tempmodel.iningroupel = "El";
                    tempmodel.hashtable   = win.CreatedElements;
                    win.CreatedElements.Add(modelUI.GetHashCode(), tempmodel);
                    win.container.Children.Add(modelUI);
                    modelUI.MouseUp    += win.ClickOnModel;
                    tempmodel.LenZ      = 2;
                    tempmodel.idelement = id;
                    ElementCabinet tmp = win.CreatedElements[masel[j].GetHashCode()] as ElementCabinet;
                    tempmodel.select = tmp;
                    tempmodel.changeObjectLen(0.1, 0.1, 0.1);
                    tempmodel.changeObjectPos(tmp.getPosX() + tmp.getLenX() / 2, tmp.getPosY() + tmp.getLenY() / 2, tmp.getPosZ() + tmp.getLenZ() / 2);
                    tempmodel.otsx = tmp.getLenX() / 2;
                    tempmodel.otsy = tmp.getLenY() / 2;
                    tempmodel.otsz = tmp.getLenZ() / 2;
                    tempmodel.thismodel.Material = new DiffuseMaterial(new SolidColorBrush(win.defcolor.Color));
                }
            }
        }
예제 #22
0
        public static Point3DCollection FromDatFile(string filename)
        {
            if (!System.IO.File.Exists(filename))
            {
                throw new Exception("File not found.");
            }
            BinaryReader br = null;

            try
            {
                br = new BinaryReader(System.IO.File.OpenRead(filename));
                try
                {
                    br.BaseStream.Seek(0, SeekOrigin.Begin);


                    bool headerCheck = false;
                    int  headerSize  = 0;
                    int  nextChar;
                    while (headerCheck == false)
                    {
                        nextChar = br.Read();
                        if (nextChar == -1)
                        {
                            throw new Exception("Invalid header in Poly file");
                        }
                        else if (nextChar == 0)
                        {
                            headerSize++;
                            headerCheck = true;
                        }
                        else
                        {
                            headerSize++;
                            if (headerSize == 10)
                            {
                                headerCheck = true;
                            }
                        }
                    }

                    br.BaseStream.Seek(0, SeekOrigin.Begin);
                    br.BaseStream.Position = headerSize;
                    int    readint     = br.ReadInt32();
                    string fileVersion = (string)br.ReadString();
                    if (fileVersion != "KICOdatV1")
                    {
                        throw new Exception("Unsupport Poly File version.");
                    }
                    int readintdummy1 = br.ReadInt32();
                    int readintdummy2 = br.ReadInt32();

                    int nodeCount = (int)br.ReadUInt32();

                    Point3DCollection points = new Point3DCollection(nodeCount);

                    for (int n = 0; n < nodeCount; n++)
                    {
                        double x = (double)br.ReadDouble();
                        double y = (double)br.ReadDouble();
                        double z = (double)br.ReadDouble();

                        points.Add(new Point3D(x, y, z));
                    }

                    return(points);
                }
                catch (Exception e)
                {
                    throw new Exception(string.Format("Error reading Mesh file.\n{0}", e.Message));
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                if (br != null)
                {
                    br.Close();
                    br = null;
                }
            }
        }
예제 #23
0
        public void receiveCurveFromMaya(string nodeName, int space, out Point3DCollection controlVertices,
                                         out List <double> weights, out List <double> knots, out int degree, out bool closed, out bool rational)
        {
            var dagnode = getDagNode(nodeName);
            var nc      = new MFnNurbsCurve(dagnode);

            var p_aCVs = new MPointArray();

            switch (space)
            {
            case 0:     //object
                nc.getCVs(p_aCVs, MSpace.Space.kObject);
                break;

            case 1:     //world
                nc.getCVs(p_aCVs, MSpace.Space.kWorld);
                break;

            default:
                nc.getCVs(p_aCVs, MSpace.Space.kWorld);
                break;
            }


            controlVertices = new Point3DCollection();
            weights         = new List <double>();
            if (MGlobal.isZAxisUp)
            {
                foreach (var p in p_aCVs)
                {
                    controlVertices.Add(new Point3D(p.x, p.y, p.z));
                    weights.Add(1.0);
                }
            }
            else
            {
                foreach (var p in p_aCVs)
                {
                    controlVertices.Add(new Point3D(p.x, -p.z, p.y));
                    weights.Add(1.0);
                }
            }

            double min = 0, max = 0;

            nc.getKnotDomain(ref min, ref max);
            var d_aKnots = new MDoubleArray();

            nc.getKnots(d_aKnots);

            knots = new List <double>();
            knots.Add(min);
            foreach (var d in d_aKnots)
            {
                knots.Add(d);
            }
            knots.Add(max);

            degree   = nc.degree;
            closed   = nc.form == MFnNurbsCurve.Form.kClosed ? true : false;
            rational = true;
        }
예제 #24
0
        /// <summary>
        /// Rounds a vertex of a triangle.
        /// </summary>
        /// <param name="pA">First point.</param>
        /// <param name="pB">Second point. Vertex to round</param>
        /// <param name="pC">Third point.</param>
        /// <param name="roundingRate">Vertex rounding rate. The value must be comprized between 0.0 and 0.5.</param>
        /// <returns></returns>
        public static Point3DCollection RoundCorner(Point3D pA, Point3D pB, Point3D pC, double roundingRate)
        {
            if (!((pA.Z == pB.Z) && (pB.Z == pC.Z))
                )
            {
                throw new ArgumentOutOfRangeException("pA");
            }

            if ((roundingRate < 0.0) ||
                (roundingRate > 0.5)
                )
            {
                throw new ArgumentOutOfRangeException("roundingRate");
            }

            Point3DCollection points = new Point3DCollection();

            int roundingDefinition = (int)(roundingRate * 40.0);

            Vector3D v1 = new Vector3D();

            v1   = pA - pB;
            v1.X = Math.Round(v1.X, 3);
            v1.Y = Math.Round(v1.Y, 3);
            v1.Z = Math.Round(v1.Z, 3);
            Point3D p1 = Point3D.Add(pB, Vector3D.Multiply(v1, roundingRate));

            Vector3D v2 = new Vector3D();

            v2   = pC - pB;
            v2.X = Math.Round(v2.X, 3);
            v2.Y = Math.Round(v2.Y, 3);
            v2.Z = Math.Round(v2.Z, 3);
            Point3D p2 = Point3D.Add(pB, Vector3D.Multiply(v2, roundingRate));

            // v1 is the normal vector for the linear curve
            // v1.X*x + v1.Y*y + c1 = 0;
            // p1 is owned by this curve so
            double c1 = -(v1.X * p1.X) - (v1.Y * p1.Y);

            // same for v2 and p2
            double c2 = -(v2.X * p2.X) - (v2.Y * p2.Y);

            // center for the arc that owns p1 and p2
            Point3D center = new Point3D();

            if (v1.Y == 0.0)
            {
                if (v1.X == 0.0)
                {
                    throw new InvalidOperationException();
                }
                center.X = -c1 / v1.X;
                if (v2.Y == 0.0)
                {
                    throw new InvalidOperationException();
                }
                else
                {
                    center.Y = (-c2 - v2.X * center.X) / v2.Y;
                }
            }
            else
            {
                if (v2.Y == 0.0)
                {
                    if (v2.X == 0.0)
                    {
                        throw new InvalidOperationException();
                    }
                    center.X = -c2 / v2.X;
                }
                else
                {
                    center.X = (c1 / v1.Y - c2 / v2.Y) / (v2.X / v2.Y - v1.X / v1.Y);
                }
                center.Y = (-c1 - v1.X * center.X) / v1.Y;
            }
            center.Z = pB.Z;

            // angle of the arc between p1 and p2
            // 360 - 180 - Vector3D.AngleBetween(v1, v2)
            double angleArc = GeometryHelper.DegreeToRadian(180 - Vector3D.AngleBetween(v1, v2));

            // angle of each part
            double angleStep = angleArc / roundingDefinition;

            Vector3D vRadius = p1 - center;

            double angleBaseDeg = Vector3D.AngleBetween(new Vector3D(1, 0, 0), vRadius);

            // necessar adjustment because of Vector3D.AngleBetween() - see documentation
            if (p1.Y < 0.0)
            {
                angleBaseDeg = 360 - angleBaseDeg;
            }
            double angleBase = GeometryHelper.DegreeToRadian(angleBaseDeg);

            points.Add(p1);
            // points of the arc
            for (int j = 1; j <= roundingDefinition - 1; j++)
            {
                double  angle = angleBase + (angleStep * j);
                Point3D p     = new Point3D();
                p.X = center.X + Math.Cos(angle) * vRadius.Length;
                p.Y = center.Y + Math.Sin(angle) * vRadius.Length;
                p.Z = pB.Z;
                points.Add(p);
            }
            points.Add(p2);

            return(points);
        }
 public static object StaticConvertCustomBinaryToObject(
     BinaryReader reader)
 {
     return(Point3DCollection.DeserializeFrom(reader));
 }
예제 #26
0
        public Hull(CreateHullData setup)
        {
            Point3DCollection points = new Point3DCollection();
            double            height = 0;
            double            width  = 0;
            double            Z      = 0;

            Bulkheads = new List <Bulkhead>();

            Timestamp = DateTime.Now;

            if (setup.IncludeBow)
            {
                points.Clear();
                Z     = 0;
                width = 0;
                for (int ii = 0; ii < setup.NumChines + 1; ii++)
                {
                    height = ii * setup.Height / setup.NumChines;
                    points.Add(new Point3D(width, height, Z));
                }
                Bulkheads.Add(new Bulkhead(points, Bulkhead.BulkheadType.BOW, setup.FlatBottom, setup.ClosedTop));
            }
            else
            {
                points.Clear();
                Z = setup.Height * Math.Cos(Math.PI / 180 * setup.TransomAngle);
                for (int ii = 0; ii < setup.NumChines + 1; ii++)
                {
                    if (ii == setup.NumChines && setup.ClosedTop)
                    {
                        width = 0;
                    }
                    else if (ii == 0 && setup.FlatBottom)
                    {
                        width = setup.Width / (setup.NumChines + 1);
                    }
                    else
                    {
                        width = ii * setup.Width / setup.NumChines;
                    }

                    height = ii * setup.Height / setup.NumChines;

                    points.Add(new Point3D(width, height, Z - height * Math.Cos(Math.PI / 180 * setup.TransomAngle)));
                }
                Bulkheads.Add(new Bulkhead(points, Bulkhead.BulkheadType.TRANSOM, setup.FlatBottom, setup.ClosedTop));
                CheckTransom();
            }

            // Vertical bulkheads
            while (Bulkheads.Count < setup.NumBulkheads - 1)
            {
                points.Clear();
                Z = Bulkheads.Count * setup.Length / (setup.NumBulkheads - 1);
                for (int ii = 0; ii < setup.NumChines + 1; ii++)
                {
                    if (ii == setup.NumChines && setup.ClosedTop)
                    {
                        width = 0;
                    }
                    else if (ii == 0 && setup.FlatBottom)
                    {
                        width = setup.Width / (setup.NumChines + 1);
                    }
                    else
                    {
                        width = ii * setup.Width / setup.NumChines;
                    }

                    height = ii * setup.Height / setup.NumChines;

                    points.Add(new Point3D(width, height, Z));
                }
                Bulkheads.Add(new Bulkhead(points, Bulkhead.BulkheadType.VERTICAL, setup.FlatBottom, setup.ClosedTop));
            }

            // Transom
            if (setup.IncludeTransom)
            {
                points.Clear();
                Z = setup.Length - setup.Height * Math.Cos(Math.PI / 180 * setup.TransomAngle);
                for (int ii = 0; ii < setup.NumChines + 1; ii++)
                {
                    if (ii == setup.NumChines && setup.ClosedTop)
                    {
                        width = 0;
                    }
                    else if (ii == 0 && setup.FlatBottom)
                    {
                        width = setup.Width / (setup.NumChines + 1);
                    }
                    else
                    {
                        width = ii * setup.Width / setup.NumChines;
                    }

                    height = ii * setup.Height / setup.NumChines;

                    points.Add(new Point3D(width, height, Z + height * Math.Cos(Math.PI / 180 * setup.TransomAngle)));
                }
                Bulkheads.Add(new Bulkhead(points, Bulkhead.BulkheadType.TRANSOM, setup.FlatBottom, setup.ClosedTop));
                CheckTransom();
            }
            else
            {
                points.Clear();
                Z     = setup.Length;
                width = 0;
                for (int ii = 0; ii < setup.NumChines + 1; ii++)
                {
                    height = ii * setup.Height / setup.NumChines;
                    points.Add(new Point3D(width, height, Z));
                }
                Bulkheads.Add(new Bulkhead(points, Bulkhead.BulkheadType.BOW, setup.FlatBottom, setup.ClosedTop));
            }

            SetBulkheadHandler();
        }
예제 #27
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="args"></param>
 /// <param name="vertices"></param>
 /// <param name="normals"></param>
 /// <param name="indices"></param>
 /// <param name="textures"></param>
 protected abstract void Triangulate(DependencyPropertyChangedEventArgs args,
                                     Point3DCollection vertices,
                                     Vector3DCollection normals,
                                     Int32Collection indices,
                                     PointCollection textures);
예제 #28
0
        // Calculates the Positions and Normals collections
        // ------------------------------------------------
        void GeneratePositions()
        {
            // Unhook Positions property and prepare for new points
            MeshGeometry3D    mesh   = (MeshGeometry3D)Geometry;
            Point3DCollection points = mesh.Positions;

            mesh.Positions = null;
            points.Clear();

            // Unhook Normals property and prepare for new vectors
            Vector3DCollection norms = mesh.Normals;

            mesh.Normals = null;
            norms.Clear();

            // Copy properties to local variables to improve speed
            Point3D point1  = Point1;
            Point3D point2  = Point2;
            double  radius1 = Radius1;
            double  radius2 = Radius2;
            int     slices  = Slices;
            int     stacks  = Stacks;

            // vectRearRadius always points towards -Z (when possible)
            Vector3D vectCylinder = point2 - point1;
            Vector3D vectRearRadius;

            if (vectCylinder.X == 0 && vectCylinder.Y == 0)
            {
                // Special case: set rear-radius vector
                vectRearRadius = new Vector3D(0, -1, 0);
            }
            else
            {
                // Find vector axis 90 degrees from cylinder where Z == 0
                rotate.Axis  = Vector3D.CrossProduct(vectCylinder, new Vector3D(0, 0, 1));
                rotate.Angle = -90;

                // Rotate cylinder 90 degrees to find radius vector
                vectRearRadius = vectCylinder * xform.Value;
                vectRearRadius.Normalize();
            }

            // Will rotate radius around cylinder axis
            rotate.Axis = vectCylinder;

            for (int i = 0; i <= slices; i++)
            {
                // Rotate rear-radius vector
                rotate.Angle = i * 360 / slices;
                Vector3D vectRadius = vectRearRadius * xform.Value;

                for (int j = 0; j <= stacks; j++)
                {
                    // Find points from top to bottom
                    Point3D pointCenter = point1 + j * (point2 - point1) / stacks;
                    double  radius      = radius1 + j * (radius2 - radius1) / stacks;
                    points.Add(pointCenter + radius * vectRadius);

                    norms.Add(vectRadius);
                }

                // Points on top and bottom
                points.Add(point1 + radius1 * vectRadius);
                points.Add(point2 + radius2 * vectRadius);

                // But normals point towards ends
                norms.Add(point1 - point2);
                norms.Add(point2 - point1);
            }

            // Add multiple center points on top and bottom ends
            for (int i = 0; i < slices; i++)
            {
                points.Add(point1);     // top end
                points.Add(point2);     // bottom end

                norms.Add(point1 - point2);
                norms.Add(point2 - point1);
            }
            // Set Normals and Positions properties from re-calced vectors
            mesh.Normals   = norms;
            mesh.Positions = points;
        }
예제 #29
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="args"></param>
        /// <param name="vertices"></param>
        /// <param name="normals"></param>
        /// <param name="indices"></param>
        /// <param name="textures"></param>
        protected override void Triangulate(DependencyPropertyChangedEventArgs args,
                                            Point3DCollection vertices,
                                            Vector3DCollection normals,
                                            Int32Collection indices,
                                            PointCollection textures)
        {
            // Clear all four collections.
            vertices.Clear();
            normals.Clear();
            indices.Clear();
            textures.Clear();

            double x, y;
            int    indexBase = 0;

            // Front side.
            // -----------

            // Fill the vertices, normals, textures collections.
            for (int stack = 0; stack <= Stacks; stack++)
            {
                y = Height / 2 - stack * Height / Stacks;

                for (int slice = 0; slice <= Slices; slice++)
                {
                    x = -Width / 2 + slice * Width / Slices;
                    Point3D point = new Point3D(x, y, 0);
                    vertices.Add(point);

                    normals.Add(point - new Point3D(x, y, 0));
                    textures.Add(new Point((double)slice / Slices,
                                           (double)stack / Stacks));
                }
            }

            // Fill the indices collection.
            for (int stack = 0; stack < Stacks; stack++)
            {
                for (int slice = 0; slice < Slices; slice++)
                {
                    indices.Add((stack + 0) * (Slices + 1) + slice);
                    indices.Add((stack + 1) * (Slices + 1) + slice);
                    indices.Add((stack + 0) * (Slices + 1) + slice + 1);

                    indices.Add((stack + 0) * (Slices + 1) + slice + 1);
                    indices.Add((stack + 1) * (Slices + 1) + slice);
                    indices.Add((stack + 1) * (Slices + 1) + slice + 1);
                }
            }

            // Rear side.
            // -----------
            indexBase = vertices.Count;

            // Fill the vertices, normals, textures collections.
            for (int stack = 0; stack <= Stacks; stack++)
            {
                y = Height / 2 - stack * Height / Stacks;

                for (int slice = 0; slice <= Slices; slice++)
                {
                    x = Width / 2 - slice * Width / Slices;
                    Point3D point = new Point3D(x, y, 0);
                    vertices.Add(point);

                    normals.Add(point - new Point3D(x, y, 0));
                    textures.Add(new Point((double)slice / Slices,
                                           (double)stack / Stacks));
                }
            }

            // Fill the indices collection.
            for (int stack = 0; stack < Stacks; stack++)
            {
                for (int slice = 0; slice < Slices; slice++)
                {
                    indices.Add(indexBase + (stack + 0) * (Slices + 1) + slice);
                    indices.Add(indexBase + (stack + 1) * (Slices + 1) + slice);
                    indices.Add(indexBase + (stack + 0) * (Slices + 1) + slice + 1);

                    indices.Add(indexBase + (stack + 0) * (Slices + 1) + slice + 1);
                    indices.Add(indexBase + (stack + 1) * (Slices + 1) + slice);
                    indices.Add(indexBase + (stack + 1) * (Slices + 1) + slice + 1);
                }
            }
        }
        private void Panelize(Hull hull)
        {
            Hull highResHull = hull.Copy();

            highResHull.PrepareChines(POINTS_PER_CHINE);

            int numPanels = highResHull.numChines() - 1;

            m_panels = new List <Panel>();

            for (int ii = 0; ii < numPanels; ii++)
            {
                Panel panel = new Panel(highResHull.GetChine(ii), highResHull.GetChine(ii + 1));
                panel.name = "Chine " + (ii + 1);
                m_panels.Add(panel);
            }

            //*********************************
            // bulkheads:
            int numBulkheads = hull.numBulkheads();

            if (hull.GetBulkhead(numBulkheads - 1).type == Bulkhead.BulkheadType.BOW)
            {
                numBulkheads--;
            }

            Hull fullHull = hull.CopyToFullHull();

            for (int bulkhead = 0; bulkhead < fullHull.numBulkheads(); bulkhead++)
            {
                int numChines = fullHull.numChines();

                if (fullHull.GetBulkhead(bulkhead).type != Bulkhead.BulkheadType.BOW)
                {
                    Bulkhead          bulk   = fullHull.GetBulkhead(bulkhead);
                    Point3DCollection points = new Point3DCollection();

                    Point3D basePoint = bulk.GetPoint(0);

                    for (int chine = 0; chine < numChines; chine++)
                    {
                        Point3D point = bulk.GetPoint(chine);
                        if (bulk.type == Bulkhead.BulkheadType.TRANSOM)
                        {
                            point.Y = basePoint.Y + (point.Y - basePoint.Y) / Math.Sin(bulk.TransomAngle);
                        }
                        points.Add(bulk.GetPoint(chine));
                    }

                    // close the shape
                    if (points[0].X != 0)
                    {
                        points.Add(points[0]);
                    }

                    Panel panel = new Panel(points);
                    panel.name = "Bulkhead " + (bulkhead + 1);
                    m_panels.Add(panel);
                }
            }
        }
예제 #31
0
        private bool createTSStructures()
        {
            if (RemoveOldTSStructures(TS_structures))
            {
                return(true);
            }

            if (scleroTrial)
            {
                if (RemoveOldTSStructures(scleroStructures))
                {
                    return(true);
                }
            }

            //determine if any TS structures need to be added to the selected structure set (i.e., were not present or were removed in the first foreach loop)
            //this is provided here to only add additional TS if they are relevant to the current case (i.e., it doesn't make sense to add the brain TS's if we
            //are not interested in sparing brain)
            foreach (Tuple <string, string, double> itr in spareStructList)
            {
                optParameters.Add(Tuple.Create(itr.Item1, itr.Item2));
                if (itr.Item1.ToLower().Contains("lungs"))
                {
                    foreach (Tuple <string, string> itr1 in TS_structures.Where(x => x.Item2.ToLower().Contains("lungs")))
                    {
                        AddTSStructures(itr1);
                    }
                    //do NOT add the scleroStructures to the addedStructures vector as these will be handled manually!
                    if (scleroTrial)
                    {
                        if (selectedSS.CanAddStructure("CONTROL", "Lung_Block_L"))
                        {
                            selectedSS.AddStructure("CONTROL", "Lung_Block_L");
                        }
                        if (selectedSS.CanAddStructure("CONTROL", "Lung_Block_R"))
                        {
                            selectedSS.AddStructure("CONTROL", "Lung_Block_R");
                        }
                        if (selectedSS.CanAddStructure("CONTROL", "Lungs_Eval"))
                        {
                            selectedSS.AddStructure("CONTROL", "Lungs_Eval");
                        }
                    }
                }
                else if (itr.Item1.ToLower().Contains("liver"))
                {
                    foreach (Tuple <string, string> itr1 in TS_structures.Where(x => x.Item2.ToLower().Contains("liver")))
                    {
                        AddTSStructures(itr1);
                    }
                }
                else if (itr.Item1.ToLower().Contains("brain"))
                {
                    foreach (Tuple <string, string> itr1 in TS_structures.Where(x => x.Item2.ToLower().Contains("brain")))
                    {
                        AddTSStructures(itr1);
                    }
                }
                else if (itr.Item1.ToLower().Contains("kidneys"))
                {
                    foreach (Tuple <string, string> itr1 in TS_structures.Where(x => x.Item2.ToLower().Contains("kidneys")))
                    {
                        AddTSStructures(itr1);
                    }
                    //do NOT add the scleroStructures to the addedStructures vector as these will be handled manually!
                    if (scleroTrial)
                    {
                        if (selectedSS.CanAddStructure("CONTROL", "Kidney_Block_R"))
                        {
                            selectedSS.AddStructure("CONTROL", "Kidney_Block_R");
                        }
                        if (selectedSS.CanAddStructure("CONTROL", "Kidney_Block_L"))
                        {
                            selectedSS.AddStructure("CONTROL", "Kidney_Block_L");
                        }
                    }
                }
            }

            if (scleroTrial)
            {
                foreach (Tuple <string, string> itr in scleroStructures)
                {
                    Structure tmp  = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == itr.Item2.ToLower());
                    Structure tmp1 = null;
                    if (itr.Item2.ToLower().Contains("lung_block_l"))
                    {
                        //AxisAlignedMargins(inner or outer margin, margin from negative x, margin for negative y, margin for negative z, margin for positive x, margin for positive y, margin for positive z)
                        tmp1 = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "lung_l");
                        if (tmp1 != null)
                        {
                            tmp.SegmentVolume = tmp1.AsymmetricMargin(new AxisAlignedMargins(
                                                                          StructureMarginGeometry.Inner,
                                                                          10.0,
                                                                          10.0,
                                                                          15.0,
                                                                          10.0,
                                                                          10.0,
                                                                          10.0));
                        }
                    }
                    else if (itr.Item2.ToLower().Contains("lung_block_r"))
                    {
                        tmp1 = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "lung_r");
                        if (tmp1 != null)
                        {
                            tmp.SegmentVolume = tmp1.AsymmetricMargin(new AxisAlignedMargins(
                                                                          StructureMarginGeometry.Inner,
                                                                          10.0,
                                                                          10.0,
                                                                          15.0,
                                                                          10.0,
                                                                          10.0,
                                                                          10.0));
                        }
                    }
                    else if (itr.Item2.ToLower().Contains("lungs_eval"))
                    {
                        tmp1 = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "lung_block_l");
                        Structure tmp2 = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "lung_block_r");
                        if (tmp1 != null && tmp2 != null)
                        {
                            tmp.SegmentVolume = tmp2.Or(tmp1.Margin(0.0));
                        }
                    }
                    else if (itr.Item2.ToLower().Contains("kidney_block_l"))
                    {
                        tmp1 = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "kidney_l");
                        if (tmp1 != null)
                        {
                            tmp.SegmentVolume = tmp1.AsymmetricMargin(new AxisAlignedMargins(
                                                                          StructureMarginGeometry.Outer,
                                                                          5.0,
                                                                          20.0,
                                                                          20.0,
                                                                          20.0,
                                                                          20.0,
                                                                          20.0));
                        }
                    }
                    else
                    {
                        tmp1 = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "kidney_r");
                        if (tmp1 != null)
                        {
                            tmp.SegmentVolume = tmp1.AsymmetricMargin(new AxisAlignedMargins(
                                                                          StructureMarginGeometry.Outer,
                                                                          20.0,
                                                                          20.0,
                                                                          20.0,
                                                                          5.0,
                                                                          20.0,
                                                                          20.0));
                        }
                    }
                }
            }

            //now contour the various structures
            foreach (string s in addedStructures)
            {
                Structure tmp = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == s.ToLower());
                //MessageBox.Show(s);
                if (!(s.ToLower().Contains("ptv")))
                {
                    Structure tmp1   = null;
                    double    margin = 0.0;
                    if (s.ToLower().Contains("human"))
                    {
                        tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "body");
                    }
                    else if (s.ToLower().Contains("lungs"))
                    {
                        if (selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "lungs_lowres") == null)
                        {
                            tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "lungs");
                        }
                        else
                        {
                            tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "lungs_lowres");
                        }
                    }
                    else if (s.ToLower().Contains("liver"))
                    {
                        if (selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "liver_lowres") == null)
                        {
                            tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "liver");
                        }
                        else
                        {
                            tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "liver_lowres");
                        }
                    }
                    else if (s.ToLower().Contains("kidneys"))
                    {
                        if (selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "kidneys_lowres") == null)
                        {
                            tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "kidneys");
                        }
                        else
                        {
                            tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "kidneys_lowres");
                        }
                    }
                    else if (s.ToLower().Contains("brain"))
                    {
                        if (selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "brain_lowres") == null)
                        {
                            tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "brain");
                        }
                        else
                        {
                            tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "brain_lowres");
                        }
                    }

                    //all structures in TS_structures and scleroStructures are inner margins, which is why the below code works.
                    int pos1 = s.IndexOf("-");
                    int pos2 = s.IndexOf("cm");
                    if (pos1 != -1 && pos2 != -1)
                    {
                        double.TryParse(s.Substring(pos1, pos2 - pos1), out margin);
                    }

                    //convert from cm to mm
                    tmp.SegmentVolume = tmp1.Margin(margin * 10);
                }
                else if (s.ToLower() == "ptv_body")
                {
                    //get the body contour and create the ptv structure using the user-specified inner margin
                    Structure tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "body");
                    tmp.SegmentVolume = tmp1.Margin(-targetMargin * 10);

                    //subtract all the structures the user wants to spare from PTV_Body
                    foreach (Tuple <string, string, double> spare in spareStructList)
                    {
                        if (spare.Item2 == "Mean Dose < Rx Dose")
                        {
                            if (spare.Item1.ToLower() == "kidneys" && scleroTrial)
                            {
                                tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "kidney_block_r");
                                tmp.SegmentVolume = tmp.Sub(tmp1.Margin(0.0));
                                tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "kidney_block_l");
                                tmp.SegmentVolume = tmp.Sub(tmp1.Margin(0.0));
                            }
                            else
                            {
                                tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == spare.Item1.ToLower());
                                tmp.SegmentVolume = tmp.Sub(tmp1.Margin((spare.Item3) * 10));
                            }
                        }
                    }
                }
                else if (s.ToLower() == "ts_ptv_vmat")
                {
                    //copy the ptv_body contour onto the TS_ptv_vmat contour
                    Structure tmp1 = selectedSS.Structures.First(x => x.Id.ToLower() == "ptv_body");
                    tmp.SegmentVolume = tmp1.Margin(0.0);

                    //matchplane exists and needs to be cut from TS_PTV_Body. Also remove all TS_PTV_Body segements inferior to match plane
                    if (selectedSS.Structures.Where(x => x.Id.ToLower() == "matchline").Any())
                    {
                        //find the image plane where the matchline is location. Record this value and break the loop. Also find the first slice where the ptv_body contour starts and record this value
                        Structure matchline      = selectedSS.Structures.First(x => x.Id.ToLower() == "matchline");
                        bool      lowLimNotFound = true;
                        int       lowLim         = -1;
                        if (!matchline.IsEmpty)
                        {
                            int matchplaneLocation = 0;
                            for (int i = 0; i != selectedSS.Image.ZSize - 1; i++)
                            {
                                if (matchline.GetContoursOnImagePlane(i).Any())
                                {
                                    matchplaneLocation = i;
                                    break;
                                }
                                if (lowLimNotFound && tmp1.GetContoursOnImagePlane(i).Any())
                                {
                                    lowLim         = i;
                                    lowLimNotFound = false;
                                }
                            }

                            if (selectedSS.Structures.Where(x => x.Id.ToLower() == "dummybox").Any())
                            {
                                selectedSS.RemoveStructure(selectedSS.Structures.First(x => x.Id.ToLower() == "dummybox"));
                            }
                            Structure dummyBox = selectedSS.AddStructure("CONTROL", "DummyBox");

                            //get min/max positions of ptv_body contour to contour the dummy box for creating TS_PTV_Legs
                            Point3DCollection ptv_bodyPts = tmp1.MeshGeometry.Positions;
                            double            xMax        = ptv_bodyPts.Max(p => p.X) + 50.0;
                            double            xMin        = ptv_bodyPts.Min(p => p.X) - 50.0;
                            double            yMax        = ptv_bodyPts.Max(p => p.Y) + 50.0;
                            double            yMin        = ptv_bodyPts.Min(p => p.Y) - 50.0;

                            //box with contour points located at (x,y), (x,0), (x,-y), (0,-y), (-x,-y), (-x,0), (-x, y), (0,y)
                            VVector[] pts = new[] {
                                new VVector(xMax, yMax, 0),
                                new VVector(xMax, 0, 0),
                                new VVector(xMax, yMin, 0),
                                new VVector(0, yMin, 0),
                                new VVector(xMin, yMin, 0),
                                new VVector(xMin, 0, 0),
                                new VVector(xMin, yMax, 0),
                                new VVector(0, yMax, 0)
                            };

                            //give 5cm margin on TS_PTV_LEGS (one slice of the CT should be 5mm) in case user wants to include flash up to 5 cm
                            for (int i = matchplaneLocation - 1; i > lowLim - 10; i--)
                            {
                                dummyBox.AddContourOnImagePlane(pts, i);
                            }

                            //do the structure manipulation
                            if (selectedSS.Structures.Where(x => x.Id.ToLower() == "ts_ptv_legs").Any())
                            {
                                selectedSS.RemoveStructure(selectedSS.Structures.First(x => x.Id.ToLower() == "ts_ptv_legs"));
                            }
                            Structure TS_legs = selectedSS.AddStructure("CONTROL", "TS_PTV_Legs");
                            TS_legs.SegmentVolume = dummyBox.And(tmp.Margin(0));
                            //subtract both dummybox and matchline from TS_PTV_VMAT
                            tmp.SegmentVolume = tmp.Sub(dummyBox.Margin(0.0));
                            tmp.SegmentVolume = tmp.Sub(matchline.Margin(0.0));
                            //remove the dummybox structure if flash is NOT being used as its no longer needed
                            if (!useFlash)
                            {
                                selectedSS.RemoveStructure(dummyBox);
                            }
                        }
                    }
                }
            }
            return(false);
        }
예제 #32
0
        /*
         * 绘画世界坐标
         */
        public ScreenSpaceLines3D DrawWroldLine()
        {
            Point3DCollection collection = new Point3DCollection();

            //X轴
            collection.Add(new Point3D(-worldLineLength, -worldLineLength, -worldLineLength));
            collection.Add(new Point3D(worldLineLength, -worldLineLength, -worldLineLength));
            //X轴箭头
            collection.Add(new Point3D(worldLineLength, 0 - worldLineLength, 0 - worldLineLength));
            collection.Add(new Point3D(worldLineLength - 3, 3 - worldLineLength, 0 - worldLineLength));
            collection.Add(new Point3D(worldLineLength, 0 - worldLineLength, 0 - worldLineLength));
            collection.Add(new Point3D(worldLineLength - 3, -3 - worldLineLength, 0 - worldLineLength));
            ////X标志
            collection.Add(new Point3D(worldLineLength, -worldLineLength - 5, -worldLineLength));
            collection.Add(new Point3D(worldLineLength + 3, -worldLineLength - 8, -worldLineLength));
            collection.Add(new Point3D(worldLineLength + 3, -worldLineLength - 5, -worldLineLength));
            collection.Add(new Point3D(worldLineLength, -worldLineLength - 8, -worldLineLength));

            //Y轴
            collection.Add(new Point3D(-worldLineLength, worldLineLength, -worldLineLength));
            collection.Add(new Point3D(-worldLineLength, -worldLineLength, -worldLineLength));

            collection.Add(new Point3D(0 - worldLineLength, worldLineLength, 0 - worldLineLength));
            collection.Add(new Point3D(3 - worldLineLength, worldLineLength - 3, 0 - worldLineLength));
            collection.Add(new Point3D(0 - worldLineLength, worldLineLength, 0 - worldLineLength));
            collection.Add(new Point3D(-3 - worldLineLength, worldLineLength - 3, 0 - worldLineLength));

            collection.Add(new Point3D(-11 - worldLineLength, worldLineLength, 0 - worldLineLength));
            collection.Add(new Point3D(-9 - worldLineLength, worldLineLength - 2, 0 - worldLineLength));
            collection.Add(new Point3D(-7 - worldLineLength, worldLineLength, 0 - worldLineLength));
            collection.Add(new Point3D(-9 - worldLineLength, worldLineLength - 2, 0 - worldLineLength));
            collection.Add(new Point3D(-9 - worldLineLength, worldLineLength - 2, 0 - worldLineLength));
            collection.Add(new Point3D(-9 - worldLineLength, worldLineLength - 5, 0 - worldLineLength));

            //Z轴
            collection.Add(new Point3D(-worldLineLength, -worldLineLength, worldLineLength));
            collection.Add(new Point3D(-worldLineLength, -worldLineLength, -worldLineLength));

            collection.Add(new Point3D(0 - worldLineLength, 0 - worldLineLength, worldLineLength));
            collection.Add(new Point3D(0 - worldLineLength, -3 - worldLineLength, worldLineLength - 3));
            collection.Add(new Point3D(0 - worldLineLength, 0 - worldLineLength, worldLineLength));
            collection.Add(new Point3D(0 - worldLineLength, 3 - worldLineLength, worldLineLength - 3));

            collection.Add(new Point3D(10 - worldLineLength, 0 - worldLineLength, worldLineLength));
            collection.Add(new Point3D(5 - worldLineLength, 0 - worldLineLength, worldLineLength));
            collection.Add(new Point3D(5 - worldLineLength, 0 - worldLineLength, worldLineLength));
            collection.Add(new Point3D(10 - worldLineLength, 0 - worldLineLength, worldLineLength - 4));
            collection.Add(new Point3D(10 - worldLineLength, 0 - worldLineLength, worldLineLength - 4));
            collection.Add(new Point3D(5 - worldLineLength, 0 - worldLineLength, worldLineLength - 4));


            //平面
            var tempLength = 5;

            while (tempLength < worldLineLength * 2)
            {
                collection.Add(new Point3D(-worldLineLength + tempLength, -worldLineLength, -worldLineLength));
                collection.Add(new Point3D(-worldLineLength + tempLength, worldLineLength, -worldLineLength));

                collection.Add(new Point3D(-worldLineLength, -worldLineLength + tempLength, -worldLineLength));
                collection.Add(new Point3D(worldLineLength, -worldLineLength + tempLength, -worldLineLength));
                tempLength += 5;
            }


            _worldLine.Points    = collection;
            _worldLine.Color     = Colors.LightSlateGray;
            _worldLine.Thickness = 2;
            return(_worldLine);
        }
        private void Machine_FileChanged()
        {
            try
            {
                ToolPath = GCodeFile.FromList(machine.File);
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);                 // prevents considerable increase in memory usage
            }
            catch (Exception ex)
            {
                MessageBox.Show("Could not parse GCode File, no preview/editing available\nrun this file at your own risk\n" + ex.Message);
            }

            if (Properties.Settings.Default.EnableCodePreview)
            {
                ToolPath.GetModel(ModelLine, ModelRapid, ModelArc);
            }

            LabelFileLength.Content   = machine.File.Count;
            LabelFileDuration.Content = ToolPath.TotalTime.ToString(@"hh\:mm\:ss");
            FileRunTime = TimeSpan.Zero;

            int digits = (int)Math.Ceiling(Math.Log10(machine.File.Count));

            string format = "D" + digits;


            ListViewFile.Items.Clear();

            for (int line = 0; line < machine.File.Count; line++)
            {
                TextBlock tb = new TextBlock()
                {
                    Text = $"{(line + 1).ToString(format)} : {machine.File[line]}"
                };

                if (machine.PauseLines[line])
                {
                    tb.Background = Brushes.YellowGreen;
                }

                ListViewFile.Items.Add(tb);
            }

            if (ToolPath.ContainsMotion)
            {
                ModelFileBoundary.Points.Clear();
                Point3DCollection boundary = new Point3DCollection();

                Vector3 MinPoint = ToolPath.MinFeed;
                Vector3 MaxPoint = ToolPath.MaxFeed;

                for (int ax = 0; ax < 3; ax++)
                {
                    for (int mask = 0; mask < 4; mask++)
                    {
                        Vector3 point = MinPoint;

                        for (int i = 0; i < 2; i++)
                        {
                            // binary integer logic? hell yeah!
                            if (((mask >> i) & 0x01) == 1)
                            {
                                point[(ax + i + 1) % 3] = MaxPoint[(ax + i + 1) % 3];
                            }
                        }

                        boundary.Add(point.ToPoint3D());

                        point[ax] = MaxPoint[ax];
                        boundary.Add(point.ToPoint3D());
                    }
                }

                ModelFileBoundary.Points = boundary;

                ModelTextMinPoint.Text     = string.Format(Constants.DecimalOutputFormat, "({0:0.###}, {1:0.###}, {2:0.###})", MinPoint.X, MinPoint.Y, MinPoint.Z);
                ModelTextMaxPoint.Text     = string.Format(Constants.DecimalOutputFormat, "({0:0.###}, {1:0.###}, {2:0.###})", MaxPoint.X, MaxPoint.Y, MaxPoint.Z);
                ModelTextMinPoint.Position = MinPoint.ToPoint3D();
                ModelTextMaxPoint.Position = MaxPoint.ToPoint3D();
                ModelFileBoundaryPoints.Points.Clear();
                ModelFileBoundaryPoints.Points.Add(MinPoint.ToPoint3D());
                ModelFileBoundaryPoints.Points.Add(MaxPoint.ToPoint3D());
            }
            else
            {
                ModelFileBoundary.Points.Clear();
                ModelFileBoundaryPoints.Points.Clear();
                ModelTextMinPoint.Text = "";
                ModelTextMaxPoint.Text = "";
            }
        }
예제 #34
0
        public Page1()
        {
            InitializeComponent();
            // Declare scene objects.
            Viewport3D      myViewport3D    = new Viewport3D();
            Model3DGroup    myModel3DGroup  = new Model3DGroup();
            GeometryModel3D myGeometryModel = new GeometryModel3D();
            ModelVisual3D   myModelVisual3D = new ModelVisual3D();
            // Defines the camera used to view the 3D object. In order to view the 3D object,
            // the camera must be positioned and pointed such that the object is within view
            // of the camera.
            PerspectiveCamera myPCamera = new PerspectiveCamera();

            // Specify where in the 3D scene the camera is.
            myPCamera.Position = new Point3D(0, 0, 2);

            // Specify the direction that the camera is pointing.
            myPCamera.LookDirection = new Vector3D(0, 0, -1);

            // Define camera's horizontal field of view in degrees.
            myPCamera.FieldOfView = 60;

            // Asign the camera to the viewport
            myViewport3D.Camera = myPCamera;
            // Define the lights cast in the scene. Without light, the 3D object cannot
            // be seen. Also, the direction of the lights affect shadowing. Note: to
            // illuminate an object from additional directions, create additional lights.
            DirectionalLight myDirectionalLight = new DirectionalLight();

            myDirectionalLight.Color     = Colors.White;
            myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61);

            myModel3DGroup.Children.Add(myDirectionalLight);

            // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet
            // is created.
            MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D();

            // Create a collection of normal vectors for the MeshGeometry3D.
            Vector3DCollection myNormalCollection = new Vector3DCollection();

            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myMeshGeometry3D.Normals = myNormalCollection;

            // Create a collection of vertex positions for the MeshGeometry3D.
            Point3DCollection myPositionCollection = new Point3DCollection();

            myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
            myMeshGeometry3D.Positions = myPositionCollection;

            // Create a collection of texture coordinates for the MeshGeometry3D.
            PointCollection myTextureCoordinatesCollection = new PointCollection();

            myTextureCoordinatesCollection.Add(new Point(0, 0));
            myTextureCoordinatesCollection.Add(new Point(5, 0));
            myTextureCoordinatesCollection.Add(new Point(5, 15));
            myTextureCoordinatesCollection.Add(new Point(5, 5));
            myTextureCoordinatesCollection.Add(new Point(0, 5));
            myTextureCoordinatesCollection.Add(new Point(0, 0));
            myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection;

            // Create a collection of triangle indices for the MeshGeometry3D.
            Int32Collection myTriangleIndicesCollection = new Int32Collection();

            myTriangleIndicesCollection.Add(0);
            myTriangleIndicesCollection.Add(1);
            myTriangleIndicesCollection.Add(2);
            //myTriangleIndicesCollection.Add(3);
            //myTriangleIndicesCollection.Add(4);
            //myTriangleIndicesCollection.Add(5);
            myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection;

            // Apply the mesh to the geometry model.
            myGeometryModel.Geometry = myMeshGeometry3D;

            // The material specifies the material applied to the 3D object. In this sample a
            // linear gradient covers the surface of the 3D object.

            // Create a horizontal linear gradient with four stops.
            LinearGradientBrush myHorizontalGradient = new LinearGradientBrush();

            myHorizontalGradient.StartPoint = new Point(0, 0.5);
            myHorizontalGradient.EndPoint   = new Point(1, 0.5);
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0));

            // Define material and apply to the mesh geometries.
            DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient);

            myGeometryModel.Material = myMaterial;

            // Apply a transform to the object. In this sample, a rotation transform is applied,
            // rendering the 3D object rotated.
            RotateTransform3D   myRotateTransform3D   = new RotateTransform3D();
            AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D();

            myAxisAngleRotation3d.Axis   = new Vector3D(0, 3, 0);
            myAxisAngleRotation3d.Angle  = 40;
            myRotateTransform3D.Rotation = myAxisAngleRotation3d;
            myGeometryModel.Transform    = myRotateTransform3D;

            // Add the geometry model to the model group.
            myModel3DGroup.Children.Add(myGeometryModel);

            // Add the group of models to the ModelVisual3d.
            myModelVisual3D.Content = myModel3DGroup;

            //
            myViewport3D.Children.Add(myModelVisual3D);

            // Apply the viewport to the page so it will be rendered.
            this.Content = myViewport3D;
        }