private static void AddCircleInZCross(MeshBuilder mb, Point3D centre, double radius, int div) { var points = MeshBuilder.GetCircle(div); var vectors = new Point3DCollection(); var normals = new Vector3DCollection(); var textures = new PointCollection(); vectors.Add(new Point3D(centre.X, centre.Y, 0)); normals.Add(new Vector3D(0, 0, 1)); textures.Add(new Point(0.5, 0.5)); for (int i = 0; i < points.Count - 1; i++) { vectors.Add(new Point3D(points[i].X * radius + centre.X, points[i].Y * radius + centre.Y, centre.Z)); normals.Add(new Vector3D(0, 0, -1)); textures.Add(new Point(points[i].X * 0.5 + 0.5, points[i].Y * 0.5 + 0.5)); vectors.Add(new Point3D(points[i + 1].X * radius + centre.X, points[i + 1].Y * radius + centre.Y, centre.Z)); normals.Add(new Vector3D(0, 0, 01)); textures.Add(new Point(points[i + 1].X * 0.5 + 0.5, points[i + 1].Y * 0.5 + 0.5)); } mb.AddTriangleFan(vectors, normals, textures); }
public static MeshGeometry3D CreateRectangle(double height, double width) { var vertices = new Point3DCollection(); var normals = new Vector3DCollection(); var facets = new Int32Collection(); var textureCoords = new PointCollection(); vertices.Add(new Point3D(-width / 2, 0, -height / 2)); vertices.Add(new Point3D(-width / 2, 0, height / 2)); vertices.Add(new Point3D(width / 2, 0, -height / 2)); vertices.Add(new Point3D(width / 2, 0, height / 2)); normals.Add(new Vector3D(0, -1, 0)); normals.Add(new Vector3D(0, -1, 0)); normals.Add(new Vector3D(0, -1, 0)); normals.Add(new Vector3D(0, -1, 0)); textureCoords.Add(new Point(1,1)); textureCoords.Add(new Point(1, 0)); textureCoords.Add(new Point(0,1)); textureCoords.Add(new Point(0,0)); facets.Add(0); facets.Add(1); facets.Add(2); facets.Add(3); facets.Add(2); facets.Add(1); var rectangle = new MeshGeometry3D(); rectangle.Positions = vertices; rectangle.Normals = normals; rectangle.TriangleIndices = facets; rectangle.TextureCoordinates = textureCoords; return rectangle; }
public static Vector3DCollection CombineVectorCollection(Vector3DCollection initialVectors, List<XbimVector3D> points) { var ret = new Vector3DCollection(initialVectors.Count + points.Count); foreach (var enumVector in initialVectors) { ret.Add(enumVector); } foreach (var enumPoint in points) { ret.Add(new Vector3D(enumPoint.X, enumPoint.Y, enumPoint.Z)); } return ret; }
protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); MeshGeometry3D mesh = MeshGenerator.Geometry; foreach (Point3D vertex in mesh.Positions) vertices.Add(vertex); foreach (Vector3D normal in mesh.Normals) normals.Add(normal); foreach (int index in mesh.TriangleIndices) indices.Add(index); foreach (Point texture in mesh.TextureCoordinates) textures.Add(texture); }
/// <summary> /// Calculates the normal vectors. /// </summary> /// <param name="positions"> /// The positions. /// </param> /// <param name="triangleIndices"> /// The triangle indices. /// </param> /// <returns> /// Collection of normal vectors. /// </returns> public static Vector3DCollection CalculateNormals(IList<Point3D> positions, IList<int> triangleIndices) { var normals = new Vector3DCollection(positions.Count); for (int i = 0; i < positions.Count; i++) { normals.Add(new Vector3D()); } for (int i = 0; i < triangleIndices.Count; i += 3) { int index0 = triangleIndices[i]; int index1 = triangleIndices[i + 1]; int index2 = triangleIndices[i + 2]; var p0 = positions[index0]; var p1 = positions[index1]; var p2 = positions[index2]; Vector3D u = p1 - p0; Vector3D v = p2 - p0; Vector3D w = Vector3D.CrossProduct(u, v); w.Normalize(); normals[index0] += w; normals[index1] += w; normals[index2] += w; } for (int i = 0; i < normals.Count; i++) { var w = normals[i]; w.Normalize(); normals[i] = w; } return normals; }
public static Vector3DCollection GetVectorCollection(List<XbimVector3D> points) { var ret = new Vector3DCollection(points.Count); foreach (var enumPoint in points) { ret.Add(new Vector3D(enumPoint.X, enumPoint.Y, enumPoint.Z)); } return ret; }
public Vector3DCollection GenerateNormals() { Vector3DCollection vectors=new Vector3DCollection(); Vector3D vector; for(int i=0;i<VertexNormals.Count;i++) { vector=new Vector3D(VertexNormals[i].Normal.X,VertexNormals[i].Normal.Y,VertexNormals[i].Normal.Z); vectors.Add(vector); } return vectors; }
public static void AddGeometry(this ModelVisual3D visual, GeometryModel3D geometry) { if (visual.Content == null) visual.Content = geometry; else { if (visual.Content is Model3DGroup) { GeometryModel3D m3d = (GeometryModel3D)((Model3DGroup)visual.Content).Children.First(); MeshGeometry3D main = (MeshGeometry3D)(m3d.Geometry); MeshGeometry3D toAdd = (MeshGeometry3D)(geometry.Geometry); Point3DCollection pc = new Point3DCollection(main.Positions.Count + toAdd.Positions.Count); foreach (var pt in main.Positions) pc.Add(pt); foreach (var pt in toAdd.Positions) { pc.Add(geometry.Transform.Transform(pt)); } main.Positions = pc; Vector3DCollection vc = new Vector3DCollection(main.Normals.Count + toAdd.Normals.Count); foreach (var v in main.Normals) vc.Add(v); foreach (var norm in toAdd.Normals) vc.Add(norm); main.Normals = vc; int maxIndices = main.Positions.Count; //we need to increment all indices by this amount foreach (var i in toAdd.TriangleIndices) main.TriangleIndices.Add(i + maxIndices); Int32Collection tc = new Int32Collection(main.TriangleIndices.Count + toAdd.TriangleIndices.Count); foreach (var i in main.TriangleIndices) tc.Add(i); foreach (var i in toAdd.TriangleIndices) tc.Add(i + maxIndices); main.TriangleIndices = tc; } //it is not a group but now needs to be else { Model3DGroup m3dGroup = new Model3DGroup(); m3dGroup.Children.Add(visual.Content); m3dGroup.Children.Add(geometry); visual.Content = m3dGroup; } } }
public static void AddCylindarZ(this MeshBuilder mb, Point3D bottomCentre, double radius, double length, int div) { var points = MeshBuilder.GetCircle(div); var vectors = new Point3DCollection(); var normals = new Vector3DCollection(); var textures = new PointCollection(); for (int i = 0; i < points.Count; i++) { var p = points[i]; vectors.Add(new Point3D(p.X * radius + bottomCentre.X, p.Y * radius + bottomCentre.Y, bottomCentre.Z)); vectors.Add(new Point3D(p.X * radius + bottomCentre.X, p.Y * radius + bottomCentre.Y, bottomCentre.Z + length)); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, 1)); textures.Add(new Point((double)i / (div - 1), 0)); textures.Add(new Point((double)i / (div - 1), 1)); } mb.AddTriangleStrip(vectors, normals, textures); }
public static void AddCircleInZCross(this MeshBuilder mb, Point3D centre, double radius, int div, bool reversed) { var points = MeshBuilder.GetCircle(div); var vectors = new Point3DCollection(); var normals = new Vector3DCollection(); var textures = new PointCollection(); vectors.Add(centre); normals.Add(new Vector3D(0, 0, 1)); textures.Add(new Point(0.5, 0.5)); for (int i = 0; i < points.Count; i++) { var p = reversed ? points[points.Count - 1 - i] : points[i]; vectors.Add(new Point3D(p.X * radius + centre.X, p.Y * radius + centre.Y, centre.Z)); normals.Add(new Vector3D(0, 0, -1)); textures.Add(new Point(p.X * 0.5 + 0.5, p.Y * 0.5 + 0.5)); } mb.AddTriangleFan(vectors, normals, textures); }
public TriangleMeshAdapater(MFnMesh mesh) { MIntArray indices = new MIntArray(); MIntArray triangleCounts = new MIntArray(); MPointArray points = new MPointArray(); mesh.getTriangles(triangleCounts, indices); mesh.getPoints(points); // Get the triangle indices Indices = new Int32Collection((int)indices.length); for (int i = 0; i < indices.length; ++i) Indices.Add(indices[i]); // Get the control points (vertices) Points = new Point3DCollection((int)points.length); for (int i = 0; i < (int)points.length; ++i) { MPoint pt = points[i]; Points.Add(new Point3D(pt.x, pt.y, pt.z)); } // Get the number of triangle faces and polygon faces Debug.Assert(indices.length % 3 == 0); int triFaces = (int)indices.length / 3; int polyFaces = mesh.numPolygons; // We have normals per polygon, we want one per triangle. Normals = new Vector3DCollection(triFaces); int nCurrentTriangle = 0; // Iterate over each polygon for (int i = 0; i < polyFaces; ++i) { // Get the polygon normal var maya_normal = new MVector(); mesh.getPolygonNormal((int)i, maya_normal); System.Windows.Media.Media3D.Vector3D normal = new System.Windows.Media.Media3D.Vector3D(maya_normal.x, maya_normal.y, maya_normal.z); // Iterate over each tri in the current polygon int nTrisAtFace = triangleCounts[i]; for (int j = 0; j < nTrisAtFace; ++j) { Debug.Assert(nCurrentTriangle < triFaces); Normals.Add(normal); nCurrentTriangle++; } } Debug.Assert(nCurrentTriangle == triFaces); }
/// <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(); // Fill the vertices, normals, and textures collections. for (int stack = 0; stack <= Stacks; stack++) { double y = Length - stack * Length / Stacks; for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -Radius * Math.Sin(theta); double z = -Radius * Math.Cos(theta); normals.Add(new Vector3D(x, 0, z)); vertices.Add(new Point3D(x, y, z)); 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); } } }
public ArrayList decode() { ArrayList array = new ArrayList(); _mesh = new Point3DCollection(); _normals = new Vector3DCollection(); array.Add(_mesh); array.Add(_normals); for (int i = 0; i < _parser.numTriangles; i++) { ArrayList collection = _parser.index(i); _mesh.Add((Point3D)collection[INDEX_VERTEX0]); _mesh.Add((Point3D)collection[INDEX_VERTEX1]); _mesh.Add((Point3D)collection[INDEX_VERTEX2]); _normals.Add((Vector3D)collection[INDEX_NORMAL]); } return array; }
[FriendAccessAllowed] // Built into Core, also used by Framework. internal static object DeserializeFrom(BinaryReader reader) { // Get the size. uint count = reader.ReadUInt32() ; Vector3DCollection collection = new Vector3DCollection( (int) count) ; for ( uint i = 0; i < count ; i ++ ) { Vector3D point = new Vector3D( XamlSerializationHelper.ReadDouble( reader ), XamlSerializationHelper.ReadDouble( reader ) , XamlSerializationHelper.ReadDouble( reader ) ) ; collection.Add( point ); } return collection ; }
public static MeshGeometry3D CreateMesh(int xVertices, int yVertices) { Vector3DCollection normals = new Vector3DCollection(); PointCollection textCoords = new PointCollection(); for (int y = 0; y < yVertices; y++) { for (int x = 0; x < xVertices; x++) { // Normals Vector3D n1 = new Vector3D(0, 0, 1); normals.Add(n1); // Texture Coordinates textCoords.Add(GetTextureCoordinate(xVertices, yVertices, y, x)); } } Int32Collection indices = GetTriangleIndices(xVertices, yVertices); MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Normals = normals; mesh.TriangleIndices = indices; mesh.TextureCoordinates = textCoords; return mesh; }
public void CreateMesh() { Point3DCollection point3DCollection = new Point3DCollection(); //Front point3DCollection.Add(new Point3D(m_min.X, m_min.Y, m_min.Z)); point3DCollection.Add(new Point3D(m_max.X, m_min.Y, m_min.Z)); point3DCollection.Add(new Point3D(m_max.X, m_max.Y, m_min.Z)); point3DCollection.Add(new Point3D(m_min.X, m_max.Y, m_min.Z)); //Back point3DCollection.Add(new Point3D(m_min.X, m_min.Y, m_max.Z)); point3DCollection.Add(new Point3D(m_max.X, m_min.Y, m_max.Z)); point3DCollection.Add(new Point3D(m_max.X, m_max.Y, m_max.Z)); point3DCollection.Add(new Point3D(m_min.X, m_max.Y, m_max.Z)); //Left point3DCollection.Add(new Point3D(m_min.X, m_min.Y, m_max.Z)); point3DCollection.Add(new Point3D(m_min.X, m_min.Y, m_min.Z)); point3DCollection.Add(new Point3D(m_min.X, m_max.Y, m_min.Z)); point3DCollection.Add(new Point3D(m_min.X, m_max.Y, m_max.Z)); //Right point3DCollection.Add(new Point3D(m_max.X, m_min.Y, m_max.Z)); point3DCollection.Add(new Point3D(m_max.X, m_min.Y, m_min.Z)); point3DCollection.Add(new Point3D(m_max.X, m_max.Y, m_min.Z)); point3DCollection.Add(new Point3D(m_max.X, m_max.Y, m_max.Z)); //Bottom point3DCollection.Add(new Point3D(m_min.X, m_min.Y, m_max.Z)); point3DCollection.Add(new Point3D(m_max.X, m_min.Y, m_max.Z)); point3DCollection.Add(new Point3D(m_max.X, m_min.Y, m_min.Z)); point3DCollection.Add(new Point3D(m_min.X, m_min.Y, m_min.Z)); //Top point3DCollection.Add(new Point3D(m_min.X, m_max.Y, m_max.Z)); point3DCollection.Add(new Point3D(m_max.X, m_max.Y, m_max.Z)); point3DCollection.Add(new Point3D(m_max.X, m_max.Y, m_min.Z)); point3DCollection.Add(new Point3D(m_min.X, m_max.Y, m_min.Z)); Vector3DCollection normals = new Vector3DCollection(); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, 1)); normals.Add(new Vector3D(0, 0, -1)); normals.Add(new Vector3D(0, 0, -1)); normals.Add(new Vector3D(0, 0, -1)); normals.Add(new Vector3D(0, 0, -1)); normals.Add(new Vector3D(-1, 0, 0)); normals.Add(new Vector3D(-1, 0, 0)); normals.Add(new Vector3D(-1, 0, 0)); normals.Add(new Vector3D(-1, 0, 0)); normals.Add(new Vector3D(1, 0, 0)); normals.Add(new Vector3D(1, 0, 0)); normals.Add(new Vector3D(1, 0, 0)); normals.Add(new Vector3D(1, 0, 0)); normals.Add(new Vector3D(0, -1, 0)); normals.Add(new Vector3D(0, -1, 0)); normals.Add(new Vector3D(0, -1, 0)); normals.Add(new Vector3D(0, -1, 0)); normals.Add(new Vector3D(0, 1, 0)); normals.Add(new Vector3D(0, 1, 0)); normals.Add(new Vector3D(0, 1, 0)); normals.Add(new Vector3D(0, 1, 0)); Int32Collection triangles = new Int32Collection(); //for (int i = 1; i < 6; i += 2) //{ // triangles.Add(0 + (i * 4)); // triangles.Add(1 + (i * 4)); // triangles.Add(3 + (i * 4)); // triangles.Add(1 + (i * 4)); // triangles.Add(2 + (i * 4)); // triangles.Add(3 + (i * 4)); //} //for (int i = 0; i < 6; i += 2) //{ // triangles.Add(3 + (i * 4)); // triangles.Add(1 + (i * 4)); // triangles.Add(0 + (i * 4)); // triangles.Add(3 + (i * 4)); // triangles.Add(2 + (i * 4)); // triangles.Add(1 + (i * 4)); //} for (int i = 0; i < 6; i++) { triangles.Add(0 + (i * 4)); triangles.Add(1 + (i * 4)); triangles.Add(0 + (i * 4)); triangles.Add(1 + (i * 4)); triangles.Add(2 + (i * 4)); triangles.Add(1 + (i * 4)); triangles.Add(2 + (i * 4)); triangles.Add(3 + (i * 4)); triangles.Add(2 + (i * 4)); triangles.Add(3 + (i * 4)); triangles.Add(0 + (i * 4)); triangles.Add(3 + (i * 4)); } MeshGeometry3D meshGeometry3D = new MeshGeometry3D { Positions = point3DCollection, Normals = normals, TriangleIndices = triangles }; m_geometryModel3D = new GeometryModel3D(); GeometryModel3D.Geometry = meshGeometry3D.ToWireframe(0.1); GeometryModel3D.Material = new DiffuseMaterial(new SolidColorBrush(m_color)); }
protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); Point3D[,] faces = Faces; PointCollection texturesBase = TextureCoordinates; int indexTextures = 0; for (int face = 0; face < faces.GetLength(0); face++) { Vector3D normal = Vector3D.CrossProduct(faces[face, 1] - faces[face, 0], faces[face, 2] - faces[face, 0]); // For faces that are triangles. if (faces.GetLength(1) == 3) { int indexBase = vertices.Count; for (int i = 0; i < 3; i++) { vertices.Add(faces[face, i]); normals.Add(normal); indices.Add(indexBase + i); if (texturesBase != null && texturesBase.Count > 0) { textures.Add(texturesBase[indexTextures]); indexTextures = (indexTextures + 1) % texturesBase.Count; } } if (Slices > 1) TriangleSubdivide(vertices, normals, indices, textures); } // For faces that are not triangles. else { for (int i = 0; i < faces.GetLength(1) - 1; i++) { int indexBase = vertices.Count; int num = faces.GetLength(1) - 1; vertices.Add(faces[face, 0]); vertices.Add(faces[face, i + 1]); vertices.Add(faces[face, (i + 1) % num + 1]); if (texturesBase != null && texturesBase.Count >= faces.GetLength(1)) { textures.Add(texturesBase[indexTextures + 0]); textures.Add(texturesBase[indexTextures + i + 1]); textures.Add(texturesBase[indexTextures + (i + 1) % num + 1]); } normals.Add(normal); normals.Add(normal); normals.Add(normal); indices.Add(indexBase + 0); indices.Add(indexBase + 1); indices.Add(indexBase + 2); if (Slices > 1) TriangleSubdivide(vertices, normals, indices, textures); } if (texturesBase != null && texturesBase.Count > 0) indexTextures = (indexTextures + faces.GetLength(1)) % texturesBase.Count; } } }
/// <summary> /// /// </summary> /// <param name="args"> /// The DependencyPropertyChangedEventArgs object originally /// passed to the PropertyChanged handler that initiated this /// recalculation. /// </param> /// <param name="vertices"> /// The Point3DCollection corresponding to the Positions property /// of the MeshGeometry3D. /// </param> /// <param name="normals"> /// The Vector3DCollection corresponding to the Normals property /// of the MeshGeometry3D. /// </param> /// <param name="indices"> /// The Int32Collection corresponding to the TriangleIndices /// property of the MeshGeometry3D. /// </param> /// <param name="textures"> /// The PointCollection corresponding to the TextureCoordinates /// property of the MeshGeometry3D. /// </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(); // Loop for outside (side = 1) and inside (side = -1). for (int side = 1; side >= -1; side -= 2) { int offset = vertices.Count; // Begin at the top end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double y = Length; double radius = Radius + side * stack * Thickness / 2 / EndStacks; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -radius * Math.Sin(theta); double z = -radius * Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(0, side, 0)); textures.Add(new Point((double)slice / Slices, Fold * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } offset = vertices.Count; // Length of the tube: Fill in the collections. for (int stack = 0; stack <= Stacks; stack++) { double y = Length - stack * Length / Stacks; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -(Radius + side * Thickness / 2) * Math.Sin(theta); double z = -(Radius + side * Thickness / 2) * Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(side * x, 0, side * z)); textures.Add(new Point((double)slice / Slices, Fold + (1 - 2 * Fold) * stack / Stacks)); if (stack < Stacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } offset = vertices.Count; // Finish with the bottom end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double y = 0; double radius = Radius + side * Thickness / 2 * (1 - (double)stack / EndStacks); int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -radius * Math.Sin(theta); double z = -radius * Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(0, -side, 0)); textures.Add(new Point((double)slice / Slices, (1 - Fold) + Fold * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } } }
/// <summary> /// /// </summary> /// <param name="vertices"></param> /// <param name="normals"></param> /// <param name="indices"></param> /// <param name="textures"></param> protected void TriangleSubdivide(Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { for (int i = 0; i < 3; i++) { verticesBase[2 - i] = vertices[vertices.Count - 1]; normalsBase[2 - i] = normals[vertices.Count - 1]; texturesBase[2 - i] = textures[vertices.Count - 1]; vertices.RemoveAt(vertices.Count - 1); normals.RemoveAt(normals.Count - 1); indices.RemoveAt(indices.Count - 1); textures.RemoveAt(textures.Count - 1); } int indexStart = vertices.Count; for (int slice = 0; slice <= Slices; slice++) { double weight = (double)slice / Slices; Point3D vertex1 = Point3DWeight(verticesBase[0], verticesBase[1], weight); Point3D vertex2 = Point3DWeight(verticesBase[0], verticesBase[2], weight); Vector3D normal1 = Vector3DWeight(normalsBase[0], normalsBase[1], weight); Vector3D normal2 = Vector3DWeight(normalsBase[0], normalsBase[2], weight); Point texture1 = PointWeight(texturesBase[0], texturesBase[1], weight); Point texture2 = PointWeight(texturesBase[0], texturesBase[2], weight); for (int i = 0; i <= slice; i++) { weight = (double)i / slice; if (Double.IsNaN(weight)) weight = 0; vertices.Add(Point3DWeight(vertex1, vertex2, weight)); normals.Add(Vector3DWeight(normal1, normal2, weight)); textures.Add(PointWeight(texture1, texture2, weight)); } } for (int slice = 0; slice < Slices; slice++) { int base1 = (slice + 1) * slice / 2; int base2 = base1 + slice + 1; for (int i = 0; i <= 2 * slice; i++) { int half = i / 2; if ((i & 1) == 0) // even { indices.Add(indexStart + base1 + half); indices.Add(indexStart + base2 + half); indices.Add(indexStart + base2 + half + 1); } else // odd { indices.Add(indexStart + base1 + half); indices.Add(indexStart + base2 + half + 1); indices.Add(indexStart + base1 + half + 1); } } } }
private Model3DGroup GenerateTileStitching(PointCloudTileSource tileSource, TileInfo3D tileInfo) { PointCloudTile tile = tileInfo.Tile; MeshGeometry3D mesh = GetTileMeshGeometry(tileInfo.CurrentGeometry); Grid<float> grid = tileInfo.CurrentGrid; //Model3DGroup stitchingGroup = new Model3DGroup(); bool hasTop = false; bool hasLeft = false; Point3D topCornerPoint = default(Point3D); Point3D leftCornerPoint = default(Point3D); Vector3D topCornerNormal = default(Vector3D); Vector3D leftCornerNormal = default(Vector3D); // connect to left tile (if available) if (tile.Col > 0) { PointCloudTile leftTile = tileSource.TileSet.GetTile(tile.Row, tile.Col - 1); TileInfo3D leftTileInfo = null; if (leftTile != null && m_tileInfo.TryGetValue(leftTile, out leftTileInfo) && leftTileInfo.CurrentGrid == grid) { MeshGeometry3D leftMesh = GetTileMeshGeometry(leftTileInfo.CurrentGeometry); int leftPositionsStart = leftMesh.Positions.Count - grid.SizeY; hasLeft = true; leftCornerPoint = leftMesh.Positions[leftPositionsStart]; leftCornerNormal = leftMesh.Normals[leftPositionsStart]; if (!tileInfo.HasStitching(TileStitchingEdge.Left)) { MeshGeometry3D stitchingMesh = new MeshGeometry3D(); int positionCount = grid.SizeY * 2; Point3DCollection positions = new Point3DCollection(positionCount); Vector3DCollection normals = new Vector3DCollection(positionCount); for (int edgePosition = 0; edgePosition < grid.SizeY; edgePosition++) { positions.Add(leftMesh.Positions[leftPositionsStart + edgePosition]); normals.Add(leftMesh.Normals[leftPositionsStart + edgePosition]); positions.Add(mesh.Positions[edgePosition]); normals.Add(mesh.Normals[edgePosition]); } stitchingMesh.Positions = positions; stitchingMesh.Normals = normals; Int32Collection indices = new Int32Collection((grid.SizeY - 1) * 6); for (int i = 0; i < grid.SizeY - 1; i++) { int j = 2 * i; indices.Add(j); indices.Add(j + 1); indices.Add(j + 2); indices.Add(j + 2); indices.Add(j + 1); indices.Add(j + 3); } stitchingMesh.TriangleIndices = indices; stitchingMesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(stitchingMesh, m_overallCenteredExtent, MathUtils.ZAxis); GeometryModel3D stitchingModel = new GeometryModel3D(stitchingMesh, m_overviewMaterial); stitchingModel.Freeze(); tileInfo.UpdateStitching(stitchingModel, leftTileInfo.CurrentGrid, TileStitchingEdge.Left); //stitchingGroup.Children.Add(stitchingModel); } } } // connect to top tile (if available) if (tile.Row > 0) { PointCloudTile topTile = tileSource.TileSet.GetTile(tile.Row - 1, tile.Col); TileInfo3D topTileInfo = null; if (topTile != null && m_tileInfo.TryGetValue(topTile, out topTileInfo) && topTileInfo.CurrentGrid == grid) { MeshGeometry3D topMesh = GetTileMeshGeometry(topTileInfo.CurrentGeometry); hasTop = true; topCornerPoint = topMesh.Positions[grid.SizeY - 1]; topCornerNormal = topMesh.Normals[grid.SizeY - 1]; if (!tileInfo.HasStitching(TileStitchingEdge.Top)) { MeshGeometry3D stitchingMesh = new MeshGeometry3D(); int positionCount = grid.SizeX * 2; Point3DCollection positions = new Point3DCollection(positionCount); Vector3DCollection normals = new Vector3DCollection(positionCount); for (int edgePosition = 0; edgePosition < mesh.Positions.Count; edgePosition += grid.SizeY) { positions.Add(topMesh.Positions[edgePosition + grid.SizeY - 1]); normals.Add(topMesh.Normals[edgePosition + grid.SizeY - 1]); positions.Add(mesh.Positions[edgePosition]); normals.Add(mesh.Normals[edgePosition]); } stitchingMesh.Positions = positions; stitchingMesh.Normals = normals; Int32Collection indices = new Int32Collection((grid.SizeX - 1) * 6); for (int i = 0; i < grid.SizeX - 1; i++) { int j = 2 * i; indices.Add(j); indices.Add(j + 2); indices.Add(j + 1); indices.Add(j + 2); indices.Add(j + 3); indices.Add(j + 1); } stitchingMesh.TriangleIndices = indices; stitchingMesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(stitchingMesh, m_overallCenteredExtent, MathUtils.ZAxis); GeometryModel3D stitchingModel = new GeometryModel3D(stitchingMesh, m_overviewMaterial); stitchingModel.Freeze(); tileInfo.UpdateStitching(stitchingModel, topTileInfo.CurrentGrid, TileStitchingEdge.Top); //stitchingGroup.Children.Add(stitchingModel); } } } // connect to top left tile (if available) if (hasTop && hasLeft && !tileInfo.HasStitching(TileStitchingEdge.TopLeft)) { PointCloudTile topleftTile = tileSource.TileSet.GetTile(tile.Row - 1, tile.Col - 1); TileInfo3D topleftTileInfo = null; if (topleftTile != null && m_tileInfo.TryGetValue(topleftTile, out topleftTileInfo)) { MeshGeometry3D topleftMesh = GetTileMeshGeometry(topleftTileInfo.CurrentGeometry); MeshGeometry3D stitchingMesh = new MeshGeometry3D(); Point3DCollection positions = new Point3DCollection(4); Vector3DCollection normals = new Vector3DCollection(4); { positions.Add(topleftMesh.Positions[topleftMesh.Positions.Count - 1]); normals.Add(topleftMesh.Normals[topleftMesh.Positions.Count - 1]); positions.Add(topCornerPoint); normals.Add(topCornerNormal); positions.Add(leftCornerPoint); normals.Add(leftCornerNormal); positions.Add(mesh.Positions[0]); normals.Add(mesh.Normals[0]); } stitchingMesh.Positions = positions; stitchingMesh.Normals = normals; Int32Collection indices = new Int32Collection(6); indices.Add(0); indices.Add(1); indices.Add(2); indices.Add(2); indices.Add(1); indices.Add(3); stitchingMesh.TriangleIndices = indices; stitchingMesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(stitchingMesh, m_overallCenteredExtent, MathUtils.ZAxis); GeometryModel3D stitchingModel = new GeometryModel3D(stitchingMesh, m_overviewMaterial); stitchingModel.Freeze(); tileInfo.UpdateStitching(stitchingModel, topleftTileInfo.CurrentGrid, TileStitchingEdge.TopLeft); //stitchingGroup.Children.Add(stitchingModel); } } return tileInfo.GetNewStitching(); }
/// <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) { vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); Vector3D normal = new Vector3D(0, 0, 1); double angleInner = 2 * Math.PI / Sides; double radius = Length / 2 / Math.Sin(angleInner / 2); double angle = 3 * Math.PI / 2 + angleInner / 2; double xMin = 0, xMax = 0, yMin = 0, yMax = 0; for (int side = 0; side < Sides; side++) { double x = Math.Cos(angle); double y = Math.Sin(angle); xMin = Math.Min(xMin, x); xMax = Math.Max(xMax, x); yMin = Math.Min(yMin, y); yMax = Math.Max(yMax, y); angle += angleInner; } angle = 3 * Math.PI / 2 + angleInner / 2; for (int side = 0; side < Sides; side++) { vertices.Add(new Point3D(0, 0, 0)); textures.Add(new Point(-xMin / (xMax - xMin), yMax / (yMax - yMin))); normals.Add(normal); double x = Math.Cos(angle); double y = Math.Sin(angle); vertices.Add(new Point3D(x, y, 0)); textures.Add(new Point((x - xMin) / (xMax - xMin), (yMax - y) / (yMax - yMin))); normals.Add(normal); angle += angleInner; x = Math.Cos(angle); y = Math.Sin(angle); vertices.Add(new Point3D(x, y, 0)); textures.Add(new Point((x - xMin) / (xMax - xMin), (yMax - y) / (yMax - yMin))); normals.Add(normal); int index = vertices.Count - 3; indices.Add(index); indices.Add(index + 1); indices.Add(index + 2); if (Slices > 1) TriangleSubdivide(vertices, normals, indices, textures); } }
public static void DrawLibGGraphicItem(NodeModel node, object geom, string tag, RenderDescription rd, Octree.OctreeSearch.Octree octree) { var selected = DynamoSelection.Instance.Selection.Contains(node); var g = geom as GraphicItem; if (g is CoordinateSystem) { #region draw coordinate systems var line_strip_vertices = g.line_strip_vertices_threadsafe(); for (int i = 0; i < line_strip_vertices.Count; i += 6) { var p1 = new Point3D( line_strip_vertices[i], line_strip_vertices[i + 1], line_strip_vertices[i + 2]); var p2 = new Point3D( line_strip_vertices[i + 3], line_strip_vertices[i + 4], line_strip_vertices[i + 5]); if (i < 6) { rd.XAxisPoints.Add(p1); rd.XAxisPoints.Add(p2); } else if (i >= 6 && i < 12) { rd.YAxisPoints.Add(p1); rd.YAxisPoints.Add(p2); } else { rd.ZAxisPoints.Add(p1); rd.ZAxisPoints.Add(p2); } } #endregion } else { #region draw points var point_vertices = g.point_vertices_threadsafe(); for (int i = 0; i < point_vertices.Count; i += 3) { var pos = new Point3D(point_vertices[i], point_vertices[i + 1], point_vertices[i + 2]); if (selected) { rd.SelectedPoints.Add(pos); } else { rd.Points.Add(pos); } if (node.DisplayLabels) { rd.Text.Add(new BillboardTextItem { Text = tag, Position = pos }); } } #endregion #region draw lines FloatList line_strip_vertices = g.line_strip_vertices_threadsafe(); for (int i = 0; i < line_strip_vertices.Count-3; i += 3) { var start = new Point3D( line_strip_vertices[i], line_strip_vertices[i + 1], line_strip_vertices[i + 2]); var end = new Point3D( line_strip_vertices[i + 3], line_strip_vertices[i + 4], line_strip_vertices[i + 5]); //draw a label at the start of the curve if (node.DisplayLabels && i == 0) { rd.Text.Add(new BillboardTextItem { Text = tag, Position = start }); } if (selected) { rd.SelectedLines.Add(start); rd.SelectedLines.Add(end); } else { rd.Lines.Add(start); rd.Lines.Add(end); } } #endregion #region draw surface //var sw = new Stopwatch(); //sw.Start(); var builder = new MeshBuilder(); var points = new Point3DCollection(); var tex = new PointCollection(); var norms = new Vector3DCollection(); var tris = new List<int>(); FloatList triangle_vertices = g.triangle_vertices_threadsafe(); FloatList triangle_normals = g.triangle_normals_threadsafe(); for (int i = 0; i < triangle_vertices.Count; i+=3) { var new_point = new Point3D(triangle_vertices[i], triangle_vertices[i + 1], triangle_vertices[i + 2]); var normal = new Vector3D(triangle_normals[i], triangle_normals[i + 1], triangle_normals[i + 2]); //find a matching point //compare the angle between the normals //to discern a 'break' angle for adjacent faces //int foundIndex = -1; //for (int j = 0; j < points.Count; j++) //{ // var testPt = points[j]; // var testNorm = norms[j]; // var ang = Vector3D.AngleBetween(normal, testNorm); // if (new_point.X == testPt.X && // new_point.Y == testPt.Y && // new_point.Z == testPt.Z && // ang > 90.0000) // { // foundIndex = j; // 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.AddTriangles(points, norms, tex); builder.Append(points, tris, norms, tex); //sw.Stop(); //Debug.WriteLine(string.Format("{0} elapsed for drawing geometry.", sw.Elapsed)); //don't add empty meshes if (builder.Positions.Count > 0) { if (selected) { rd.SelectedMeshes.Add(builder.ToMesh(true)); } else { rd.Meshes.Add(builder.ToMesh(true)); } } #endregion } }
/// <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(); // Begin at the top end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double y = Length; double radius = stack * Radius / EndStacks; int top = (stack + 0) * (Slices + 1); int bot = (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -radius * Math.Sin(theta); double z = -radius * Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(0, 1, 0)); textures.Add(new Point((double)slice / Slices, Fold * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { if (stack != 0) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); } indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } int offset = vertices.Count; // Length of the cylinder: Fill in the collections. for (int stack = 0; stack <= Stacks; stack++) { double y = Length - stack * Length / Stacks; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -Radius * Math.Sin(theta); double z = -Radius * Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(x, 0, z)); textures.Add(new Point((double)slice / Slices, Fold + (1 - 2 * Fold) * stack / Stacks)); if (stack < Stacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } offset = vertices.Count; // Finish with the bottom end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double y = 0; double radius = (EndStacks - stack) * Radius / EndStacks; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { double theta = slice * 2 * Math.PI / Slices; double x = -radius * Math.Sin(theta); double z = -radius * Math.Cos(theta); vertices.Add(new Point3D(x, y, z)); normals.Add(new Vector3D(0, -1, 0)); textures.Add(new Point((double)slice / Slices, (1 - Fold) + Fold * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); if (stack != EndStacks - 1) { indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } } }
private void AddFace(string values) { // A polygonal face. The numbers are indexes into the arrays of vertex positions, // texture coordinates, and normals respectively. A number may be omitted if, // for example, texture coordinates are not being defined in the model. // There is no maximum number of vertices that a single polygon may contain. // The .obj file specification says that each face must be flat and convex. var fields = values.Split(' '); var pts = new Point3DCollection(); var tex = new PointCollection(); var norm = new Vector3DCollection(); foreach (var field in fields) { if (String.IsNullOrEmpty(field)) continue; var ff = field.Split('/'); int vi = int.Parse(ff[0]); int vti = ff.Length > 1 && ff[1].Length > 0 ? int.Parse(ff[1]) : -1; int vni = ff.Length > 2 && ff[2].Length > 0 ? int.Parse(ff[2]) : -1; pts.Add(Points[vi - 1]); if (vti >= 0) tex.Add(TexCoords[vti - 1]); if (vni >= 0) norm.Add(Normals[vni - 1]); } if (tex.Count == 0) tex = null; if (norm.Count == 0) norm = null; // QUAD if (pts.Count == 4) { CurrentGroup.MeshBuilder.AddQuads(pts, norm, tex); return; } // TRIANGLE if (pts.Count == 3) { CurrentGroup.MeshBuilder.AddTriangles(pts, norm, tex); return; } // POLYGONS (flat and convex) var poly3D = new Polygon3D(pts); // Transform the polygon to 2D var poly2D = poly3D.Flatten(); // Triangulate var tri = poly2D.Triangulate(); if (tri != null) { // Add the triangle indices with the 3D points var mesh = new MeshBuilder(); mesh.Append(pts, tri); CurrentGroup.MeshBuilder.Append(mesh); } }
/// <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); } } }
protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); // vectRearRadius 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; // Begin at the top end. Fill the collections. for (int stack = 0; stack <= EndStacks; stack++) { double radius = stack * Radius1 / EndStacks; Vector3D vectRadius = radius * vectRearRadius; int top = (stack + 0) * (Slices + 1); int bot = (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { rotate.Angle = slice * 360.0 / Slices; vertices.Add(Point1 + vectRadius * xform.Value); normals.Add(-vectCylinder); textures.Add(new Point((double)slice / Slices, Fold1 * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { if (stack != 0) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); } indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } int offset = vertices.Count; // Go down length of cylinder and fill in the collections. for (int stack = 0; stack <= Stacks; stack++) { double radius = ((Stacks - stack) * Radius1 + stack * Radius2) / Stacks; Vector3D vectRadius = radius * vectRearRadius; Point3D center = (Point3D) (Point1 + stack * vectCylinder / Stacks); int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { rotate.Angle = slice * 360.0 / Slices; Vector3D normal = vectRadius * xform.Value; normals.Add(normal); vertices.Add(center + normal); textures.Add(new Point((double)slice / Slices, Fold1 + (Fold2 - Fold1) * stack / Stacks)); if (stack < Stacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } offset = vertices.Count; // Finish with bottom. for (int stack = 0; stack <= EndStacks; stack++) { double radius = Radius2 * (1 - (double)stack / EndStacks); Vector3D vectRadius = radius * vectRearRadius; int top = offset + (stack + 0) * (Slices + 1); int bot = offset + (stack + 1) * (Slices + 1); for (int slice = 0; slice <= Slices; slice++) { rotate.Angle = slice * 360.0 / Slices; vertices.Add(Point2 + vectRadius * xform.Value); normals.Add(vectCylinder); textures.Add(new Point((double)slice / Slices, Fold2 + (1 - Fold2) * stack / EndStacks)); if (stack < EndStacks && slice < Slices) { indices.Add(top + slice); indices.Add(bot + slice); indices.Add(top + slice + 1); if (stack != EndStacks - 1) { indices.Add(top + slice + 1); indices.Add(bot + slice); indices.Add(bot + slice + 1); } } } } }
private void CreateFaceModels(IFCItem item, Vector3D center) { while (item != null) { if (item.ifcID != IntPtr.Zero && item.noVerticesForFaces != 0 && item.noPrimitivesForFaces != 0) { var positions = new Point3DCollection(); var normals = new Vector3DCollection(); if (item.verticesForFaces != null) { for (int i = 0; i < item.noVerticesForFaces; i++) { var point = new Point3D(item.verticesForFaces[6 * i + 0] - center.X, item.verticesForFaces[6 * i + 1] - center.Y, item.verticesForFaces[6 * i + 2] - center.Z); var normal = new Vector3D(item.verticesForFaces[6 * i + 3], item.verticesForFaces[6 * i + 4], item.verticesForFaces[6 * i + 5]); positions.Add(point); normals.Add(normal); } Debug.Assert(item.verticesForFaces.Length == item.noVerticesForFaces * 6); } var indices = new Int32Collection(); if (item.indicesForFaces != null) { for (int i = 0; i < 3 * item.noPrimitivesForFaces; i++) { indices.Add(item.indicesForFaces[i]); } } MeshGeometry3D meshGeometry = new MeshGeometry3D(); meshGeometry.Positions = positions; meshGeometry.Normals = normals; meshGeometry.TriangleIndices = indices; MeshGeometryVisual3D mesh = new MeshGeometryVisual3D(); mesh.MeshGeometry = meshGeometry; item.Mesh3d = mesh; _meshToIfcItems[mesh] = item; #if DEBUG OutputObj(item.ifcID.ToString(), meshGeometry); #endif FillMeshByIfcColor(item); hVp3D.Children.Add(mesh); } CreateFaceModels(item.child, center); item = item.next; } }
public static Model3D CreateModel3D(List<Mesh> meshGroups, BitmapSource texture, AnimData pose, int frame) { GeometryModel3D model = new GeometryModel3D(); var mesh3D = new MeshGeometry3D(); int numVertices = 0; foreach (var meshGroup in meshGroups) { numVertices += meshGroup.Positions.Count; } var triangleIndices = new Int32Collection(); var positions = new Point3DCollection(numVertices); var normals = new Vector3DCollection(numVertices); var uvCoords = new PointCollection(numVertices); int vstart = 0; foreach (var meshGroup in meshGroups) { Boolean hasVertexWeights = meshGroup.vertexWeights.Count > 0; int vwNum = 0; VertexWeight vw = new VertexWeight(); if (meshGroup.vertexWeights.Count > 0) { vw = meshGroup.vertexWeights[vwNum]; } int vnum = 0; foreach (var vertex in meshGroup.Positions) { var point = vertex; if (frame >= 0 && pose != null) { if (vw.endVertex < vnum) { ++vwNum; vw = meshGroup.vertexWeights[vwNum]; if (vnum < vw.startVertex || vnum > vw.endVertex) { Debug.Fail("Vertex " + vnum + " out of range of bone weights " + vw.startVertex + " -> " + vw.endVertex); } } int bone1No = vw.bone1; Point3D bindingPos1 = pose.bindingPose[bone1No]; AnimMeshPose bone1Pose = pose.perFrameFKPoses[frame, bone1No]; var joint1Pos = bone1Pose.Position; if (vw.bone2 == 0xFF) { if (bone1No == 1) { bone1No = 1; } Matrix3D m = Matrix3D.Identity; m.Translate(new Vector3D(-bindingPos1.X, -bindingPos1.Y, -bindingPos1.Z)); // Inverse binding matrix m.Rotate(bone1Pose.Rotation); m.Translate(new Vector3D(bone1Pose.Position.X, bone1Pose.Position.Y, bone1Pose.Position.Z)); point = m.Transform(point); } else { // multi-bone int bone2No = vw.bone2; Point3D bindingPos2 = pose.bindingPose[bone2No]; AnimMeshPose bone2Pose = pose.perFrameFKPoses[frame, bone2No]; double boneSum = vw.boneWeight1 + vw.boneWeight2; double bone1Coeff = vw.boneWeight1 / boneSum; double bone2Coeff = vw.boneWeight2 / boneSum; Matrix3D m = Matrix3D.Identity; m.Translate(new Vector3D(-bindingPos1.X, -bindingPos1.Y, -bindingPos1.Z)); // Inverse binding matrix m.Rotate(bone1Pose.Rotation); m.Translate(new Vector3D(bone1Pose.Position.X, bone1Pose.Position.Y, bone1Pose.Position.Z)); var point1 = m.Transform(point); // Now rotate Matrix3D m2 = Matrix3D.Identity; m2.Translate(new Vector3D(-bindingPos2.X, -bindingPos2.Y, -bindingPos2.Z)); // Inverse binding matrix m2.Rotate(bone2Pose.Rotation); m2.Translate(new Vector3D(bone2Pose.Position.X, bone2Pose.Position.Y, bone2Pose.Position.Z)); var point2 = m2.Transform(point); point = new Point3D(point1.X * bone1Coeff + point2.X * bone2Coeff, point1.Y * bone1Coeff + point2.Y * bone2Coeff, point1.Z * bone1Coeff + point2.Z * bone2Coeff); } } positions.Add(point); ++vnum; } foreach (var normal in meshGroup.Normals) { normals.Add(normal); } foreach (var ti in meshGroup.TriangleIndices) { triangleIndices.Add(ti+vstart); } foreach (var uv in meshGroup.TextureCoordinates) { uvCoords.Add(uv); } vstart += meshGroup.Positions.Count; } mesh3D.TriangleIndices = triangleIndices; mesh3D.Positions = positions; mesh3D.TextureCoordinates = uvCoords; mesh3D.Normals = normals; model.Geometry = mesh3D; var dm = new DiffuseMaterial(); if (texture != null && texture.Width > 0 && texture.Height > 0) { var ib = new ImageBrush(texture); ib.ViewportUnits = BrushMappingMode.Absolute; // May be needed at a later point //ib.TileMode = TileMode.Tile; dm.Brush = ib; } else { var dg = new DrawingGroup(); // Background dg.Children.Add(new GeometryDrawing() { Brush = new SolidColorBrush(Colors.Black), Geometry = new RectangleGeometry(new Rect(0, 0, 2, 2)) }); // Tiles dg.Children.Add(new GeometryDrawing() { Brush = new SolidColorBrush(Colors.Violet), Geometry = new RectangleGeometry(new Rect(0, 0, 1, 1)) }); dg.Children.Add(new GeometryDrawing() { Brush = new SolidColorBrush(Colors.Violet), Geometry = new RectangleGeometry(new Rect(1, 1, 1, 1)) }); dm.Brush = new DrawingBrush(dg){ TileMode = TileMode.Tile, Transform = new ScaleTransform(0.1,0.1)}; } model.Material = dm; return model; }
public MeshGeometry3D createAlternativeMesh() { //this.mesh is the relevant mesh that we are setting. //Define list of triangle indices over the whole model. var triangleIndices = new List<int>(); //Define Vector3D normals. Vector3DCollection myNormalCollection = new Vector3DCollection(); myNormalCollection.Add(new Vector3D(0, 0, 1)); myNormalCollection.Add(new Vector3D(0, 1, 1)); myNormalCollection.Add(new Vector3D(1, 1, 1)); //iterate over each 3 points and create a triangle with the relevant indices. for (int i = 0; i < this.cloudList[0].Count-3; i+=3) { this.mesh.Positions.Add(this.cloudList[0][i]); this.mesh.Positions.Add(this.cloudList[0][i + 1]); this.mesh.Positions.Add(this.cloudList[0][i + 2]); //set triangle normals on the mesh. triangleIndices.Add(0); triangleIndices.Add(1); triangleIndices.Add(2); } return new MeshGeometry3D() { Positions = new Point3DCollection(this.cloudList[0]), //TextureCoordinates = new System.Windows.Media.PointCollection(this.textureCoordinates), TriangleIndices = new Int32Collection(triangleIndices), Normals = myNormalCollection }; }
protected override void Triangulate(DependencyPropertyChangedEventArgs args, Point3DCollection vertices, Vector3DCollection normals, Int32Collection indices, PointCollection textures) { vertices.Clear(); normals.Clear(); indices.Clear(); textures.Clear(); // Copy properties to local variables to improve speed int slices = Slices; int stacks = Stacks; double radius = Radius; Point3D ctr = Center; double lat1 = Math.Max(LatitudeFrom, LatitudeTo); // default is 90 double lat2 = Math.Min(LatitudeFrom, LatitudeTo); // default is -90 double lng1 = LongitudeFrom; // default is -180 double lng2 = LongitudeTo; // default is 180 for (int lat = 0; lat <= stacks; lat++) { double degrees = lat1 - lat * (lat1 - lat2) / stacks; double angle = Math.PI * degrees / 180; double y = radius * Math.Sin(angle); double scale = Math.Cos(angle); for (int lng = 0; lng <= slices; lng++) { double diff = lng2 - lng1; if (diff < 0) diff += 360; degrees = lng1 + lng * diff / slices; angle = Math.PI * degrees / 180; double x = radius * scale * Math.Sin(angle); double z = radius * scale * Math.Cos(angle); Vector3D vect = new Vector3D(x, y, z); vertices.Add(ctr + vect); normals.Add(vect); textures.Add(new Point((double)lng / slices, (double)lat / stacks)); } } for (int lat = 0; lat < stacks; lat++) { int start = lat * (slices + 1); int next = start + slices + 1; for (int lng = 0; lng < slices; lng++) { indices.Add(start + lng); indices.Add(next + lng); indices.Add(next + lng + 1); indices.Add(start + lng); indices.Add(next + lng + 1); indices.Add(start + lng + 1); } } }