protected BasicPrimitiveTessellator() { Positions = new Point3DCollection(); Normals = new Vector3DCollection(); Indices = new Int32Collection(); TextureCoordinates = new Point2DCollection(); }
public Mesh() { Positions = new Point3DCollection(); Normals = new Vector3DCollection(); TextureCoordinates = new Point3DCollection(); Indices = new Int32Collection(); Transform = new MatrixTransform(Matrix3D.Identity); }
public Mesh() { Positions = new Point3DCollection(); Normals = new Vector3DCollection(); TextureCoordinates = new Point2DCollection(); Indices = new IndexCollection(); Material = new Material(); }
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; } }
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; }
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; }
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); }
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)); }
/// <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; }
// 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; }
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); }
/// <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); } } }
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; }
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); }
/// <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; }
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); } }
/// <summary> /// Removes the last point in the underlying PointGeomInfo collection. /// </summary> internal void RemoveLast() { _geomPoints.RemoveAt(_geomPoints.Count - 1); _visualPoints = null; }
internal void Add(PointGeomInfo p) { _visualPoints = null; _geomPoints.Add(p); }
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); }
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))); }
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)); } } }
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; } } }
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; }
/// <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)); }
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(); }
/// <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);
// 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; }
/// <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); } } }
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); }
/* * 绘画世界坐标 */ 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 = ""; } }
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; }