public Asset(XElement node) { XElement xElement = node.Element(ColladaRoot.Namespace + "unit"); if (xElement != null) { XAttribute xAttribute = xElement.Attribute("meter"); if (xAttribute != null) { Meter = float.Parse(xAttribute.Value, CultureInfo.InvariantCulture); } } xElement = node.Element(ColladaRoot.Namespace + "up_axis"); if (xElement != null) { switch (xElement.Value) { case "X_UP": UpAxis = UpAxis.X_UP; break; case "Y_UP": UpAxis = UpAxis.Y_UP; break; case "Z_UP": UpAxis = UpAxis.Z_UP; break; } } }
public void ResetValues() { // LoaderModule = S3DFileParser.LoaderModule.Assimp FileLoaderModule = "#1"; FileExporterModule = "#0"; UpAxis = UpAxis.Y; }
/// <summary> /// Initializes a new instance of the <see cref="RobotObjectUpAxisChangedEventArgs"/> class. /// </summary> /// <param name="e">The event.</param> internal RobotObjectUpAxisChangedEventArgs(ExternalInterface.Event e) : base(e) { var objectUpAxisChanged = e.ObjectEvent.ObjectUpAxisChanged; ObjectId = (int)objectUpAxisChanged.ObjectId; RobotTimestamp = objectUpAxisChanged.Timestamp; UpAxis = (UpAxis)(int)objectUpAxisChanged.UpAxis; }
public VoxelizationInput() { m_voxelLevel = 6; m_minVolume = 0.65f; m_minOcclusion = 0.03f; m_type = OcclusionType.BoxExpansion; m_retriangulate = true; m_removeTop = false; m_removeBottom = false; m_upAxis = UpAxis.Y; m_windingOrder = WindingOrder.CounterClockwise; }
void initialize() { up_axis = UpAxis.YUp; handedness = Handedness.RightHanded; unit = 0.0f; }
/// <summary> /// Initializes a new instance of the <see cref="ObjectUpAxisChangedEventArgs" /> class. /// </summary> /// <param name="obj">The object.</param> /// <param name="e">The <see cref="RobotObjectUpAxisChangedEventArgs" /> instance containing the event data.</param> internal ObjectUpAxisChangedEventArgs(ObservableObject obj, RobotObjectUpAxisChangedEventArgs e) : base(obj) { RobotTimestamp = e.RobotTimestamp; UpAxis = e.UpAxis; }
static StlMesh[] ImportHardNormals(IEnumerable <Facet> faces, CoordinateSpace modelCoordinateSpace, UpAxis modelUpAxis, IndexFormat indexFormat) { var facets = faces as Facet[] ?? faces.ToArray(); int faceCount = facets.Length, f = 0; int maxFacetsPerMesh = indexFormat == IndexFormat.UInt32 ? MaxFacetsPerMesh32 : MaxFacetsPerMesh16; int maxVertexCount = maxFacetsPerMesh * 3; StlMesh[] meshes = new StlMesh[faceCount / maxFacetsPerMesh + 1]; for (int meshIndex = 0; meshIndex < meshes.Length; meshIndex++) { int len = System.Math.Min(maxVertexCount, (faceCount - f) * 3); StlVector3[] v = new StlVector3[len]; StlVector3[] n = new StlVector3[len]; int[] t = new int[len]; for (int it = 0; it < len; it += 3) { v[it] = facets[f].a; v[it + 1] = facets[f].b; v[it + 2] = facets[f].c; n[it] = facets[f].normal; n[it + 1] = facets[f].normal; n[it + 2] = facets[f].normal; t[it] = it + 0; t[it + 1] = it + 1; t[it + 2] = it + 2; f++; } if (modelCoordinateSpace == CoordinateSpace.Right) { for (int i = 0; i < len; i += 3) { v[i + 0] = Stl.ToCoordinateSpace(v[i + 0], CoordinateSpace.Left); v[i + 1] = Stl.ToCoordinateSpace(v[i + 1], CoordinateSpace.Left); v[i + 2] = Stl.ToCoordinateSpace(v[i + 2], CoordinateSpace.Left); n[i + 0] = Stl.ToCoordinateSpace(n[i + 0], CoordinateSpace.Left); n[i + 1] = Stl.ToCoordinateSpace(n[i + 1], CoordinateSpace.Left); n[i + 2] = Stl.ToCoordinateSpace(n[i + 2], CoordinateSpace.Left); var a = t[i + 2]; t[i + 2] = t[i]; t[i] = a; } } meshes[meshIndex] = new StlMesh { vertices = v, normals = n, triangles = t, indexFormat = indexFormat }; } return(meshes); }
/// <summary> /// Import an STL file. /// </summary> /// <param name="path">The path to load STL file from.</param> /// <returns></returns> public static Mesh[] Import(string path, CoordinateSpace space = CoordinateSpace.Right, UpAxis axis = UpAxis.Y, bool smooth = false, IndexFormat indexFormat = IndexFormat.UInt16) { IEnumerable <Facet> facets = null; if (IsBinary(path)) { try { facets = ImportBinary(path); } catch (System.Exception e) { UnityEngine.Debug.LogWarning(string.Format("Failed importing mesh at path {0}.\n{1}", path, e.ToString())); return(null); } } else { facets = ImportAscii(path); } StlMesh[] stlMeshes; if (smooth) { stlMeshes = ImportSmoothNormals(facets, space, axis, indexFormat); } else { stlMeshes = ImportHardNormals(facets, space, axis, indexFormat); } var meshes = new Mesh[stlMeshes.Length]; for (int i = 0; i < stlMeshes.Length; i++) { var mesh = new Mesh { vertices = Array.ConvertAll(stlMeshes[i].vertices, p => (Vector3)p), normals = Array.ConvertAll(stlMeshes[i].normals, p => (Vector3)p), triangles = stlMeshes[i].triangles, indexFormat = stlMeshes[i].indexFormat }; meshes[i] = mesh; } return(meshes); }
static StlMesh[] ImportSmoothNormals(IEnumerable <Facet> faces, CoordinateSpace modelCoordinateSpace, UpAxis modelUpAxis, IndexFormat indexFormat) { var facets = faces as Facet[] ?? faces.ToArray(); int maxVertexCount = indexFormat == IndexFormat.UInt32 ? MaxFacetsPerMesh32 * 3 : MaxFacetsPerMesh16 * 3; int triangleCount = facets.Length * 3; //Dictionary<StlVector3, StlVector3> smoothNormals = new Dictionary<StlVector3, StlVector3>(triangleCount / 2); //// In case meshes are split, we need to calculate smooth normals first //foreach(var face in faces) //{ // var x = (StlVector3) face.a; // var y = (StlVector3) face.b; // var z = (StlVector3) face.c; // var normal = face.normal; // if(smoothNormals.ContainsKey(x)) // smoothNormals[x] += normal; // else // smoothNormals.Add(x, normal); // if(smoothNormals.ContainsKey(y)) // smoothNormals[y] += normal; // else // smoothNormals.Add(y, normal); // if(smoothNormals.ContainsKey(z)) // smoothNormals[z] += normal; // else // smoothNormals.Add(z, normal); //} int numProcs = Environment.ProcessorCount; int concurrencyLevel = numProcs * 2; ConcurrentDictionary <StlVector3, StlVector3> smoothNormals = new ConcurrentDictionary <StlVector3, StlVector3>(concurrencyLevel, triangleCount / 2); // In case meshes are split, we need to calculate smooth normals first Parallel.ForEach(faces, (face) => { var x = face.a; var y = face.b; var z = face.c; var normal = face.normal; if (smoothNormals.ContainsKey(x)) { smoothNormals[x] += normal; } else { smoothNormals.TryAdd(x, normal); } if (smoothNormals.ContainsKey(y)) { smoothNormals[y] += normal; } else { smoothNormals.TryAdd(y, normal); } if (smoothNormals.ContainsKey(z)) { smoothNormals[z] += normal; } else { smoothNormals.TryAdd(z, normal); } }); List <StlMesh> meshes = new List <StlMesh>(); List <StlVector3> pos = new List <StlVector3>(Math.Min(maxVertexCount, triangleCount)); List <StlVector3> nrm = new List <StlVector3>(Math.Min(maxVertexCount, triangleCount)); List <int> tri = new List <int>(triangleCount); Dictionary <StlVector3, int> map = new Dictionary <StlVector3, int>(); int vertex = 0; StlVector3[] points = new StlVector3[3]; foreach (var face in facets) { if (vertex + 3 > maxVertexCount) { var mesh = new StlMesh { vertices = pos.ToArray(), normals = nrm.ToArray(), indexFormat = indexFormat }; if (modelCoordinateSpace == CoordinateSpace.Right) { tri.Reverse(); } mesh.triangles = tri.ToArray(); meshes.Add(mesh); vertex = 0; pos.Clear(); nrm.Clear(); tri.Clear(); map.Clear(); } points[0] = face.a; points[1] = face.b; points[2] = face.c; for (int i = 0; i < 3; i++) { int index = -1; var hash = points[i]; if (!map.TryGetValue(hash, out index)) { if (modelCoordinateSpace == CoordinateSpace.Right) { pos.Add(Stl.ToCoordinateSpace(points[i], CoordinateSpace.Left)); nrm.Add(Stl.ToCoordinateSpace(smoothNormals[hash].normalized, CoordinateSpace.Left)); } else { pos.Add(points[i]); nrm.Add(smoothNormals[hash].normalized); } tri.Add(vertex); map.Add(hash, vertex++); } else { tri.Add(index); } } } if (vertex > 0) { var mesh = new StlMesh { vertices = pos.ToArray(), normals = nrm.ToArray(), indexFormat = indexFormat }; if (modelCoordinateSpace == CoordinateSpace.Right) { tri.Reverse(); } mesh.triangles = tri.ToArray(); meshes.Add(mesh); vertex = 0; pos.Clear(); nrm.Clear(); tri.Clear(); map.Clear(); } return(meshes.ToArray()); }
/// <summary> /// Import an STL file. /// </summary> /// <param name="path">The path to load STL file from.</param> /// <returns></returns> public static Mesh[] Import(string path, CoordinateSpace space = CoordinateSpace.Right, UpAxis axis = UpAxis.Y, bool smooth = false, IndexFormat indexFormat = IndexFormat.UInt16) { IEnumerable <Facet> facets = null; if (IsBinary(path)) { try { facets = ImportBinary(path); } catch (System.Exception e) { UnityEngine.Debug.LogWarning(string.Format("Failed importing mesh at path {0}.\n{1}", path, e.ToString())); return(null); } } else { facets = ImportAscii(path); } if (smooth) { return(ImportSmoothNormals(facets, space, axis, indexFormat)); } return(ImportHardNormals(facets, space, axis, indexFormat)); }
static Mesh[] ImportSmoothNormals(IEnumerable<Facet> faces, CoordinateSpace modelCoordinateSpace, UpAxis modelUpAxis, IndexFormat indexFormat) { var facets = faces as Facet[] ?? faces.ToArray(); int maxVertexCount = indexFormat == IndexFormat.UInt32 ? MaxFacetsPerMesh32 * 3 : MaxFacetsPerMesh16 * 3; int triangleCount = facets.Length * 3; Dictionary<StlVector3, Vector3> smoothNormals = new Dictionary<StlVector3, Vector3>(triangleCount / 2); // In case meshes are split, we need to calculate smooth normals first foreach(var face in faces) { var x = (StlVector3) face.a; var y = (StlVector3) face.b; var z = (StlVector3) face.c; var normal = face.normal; if(smoothNormals.ContainsKey(x)) smoothNormals[x] += normal; else smoothNormals.Add(x, normal); if(smoothNormals.ContainsKey(y)) smoothNormals[y] += normal; else smoothNormals.Add(y, normal); if(smoothNormals.ContainsKey(z)) smoothNormals[z] += normal; else smoothNormals.Add(z, normal); } List<Mesh> meshes = new List<Mesh>(); List<Vector3> pos = new List<Vector3>(Math.Min(maxVertexCount, triangleCount)); List<Vector3> nrm = new List<Vector3>(Math.Min(maxVertexCount, triangleCount)); List<int> tri = new List<int>(triangleCount); Dictionary<StlVector3, int> map = new Dictionary<StlVector3, int>(); int vertex = 0; Vector3[] points = new Vector3[3]; foreach(var face in facets) { if(vertex + 3 > maxVertexCount) { var mesh = new Mesh { vertices = pos.ToArray(), normals = nrm.ToArray(), indexFormat = indexFormat }; if(modelCoordinateSpace == CoordinateSpace.Right) tri.Reverse(); mesh.triangles = tri.ToArray(); meshes.Add(mesh); vertex = 0; pos.Clear(); nrm.Clear(); tri.Clear(); map.Clear(); } points[0] = face.a; points[1] = face.b; points[2] = face.c; for(int i = 0; i < 3; i++) { int index = -1; var hash = (StlVector3) points[i]; if(!map.TryGetValue(hash, out index)) { if(modelCoordinateSpace == CoordinateSpace.Right) { pos.Add(Stl.ToCoordinateSpace(points[i], CoordinateSpace.Left)); nrm.Add(Stl.ToCoordinateSpace(smoothNormals[hash].normalized, CoordinateSpace.Left)); } else { pos.Add(points[i]); nrm.Add(smoothNormals[hash].normalized); } tri.Add(vertex); map.Add(hash, vertex++); } else { tri.Add(index); } } } if(vertex > 0) { var mesh = new Mesh { vertices = pos.ToArray(), normals = nrm.ToArray(), indexFormat = indexFormat }; if(modelCoordinateSpace == CoordinateSpace.Right) tri.Reverse(); mesh.triangles = tri.ToArray(); meshes.Add(mesh); vertex = 0; pos.Clear(); nrm.Clear(); tri.Clear(); map.Clear(); } return meshes.ToArray(); }
static Mesh[] ImportHardNormals(IEnumerable <Facet> faces, CoordinateSpace modelCoordinateSpace, UpAxis modelUpAxis, IndexFormat indexFormat) { var facets = faces as Facet[] ?? faces.ToArray(); int faceCount = facets.Length, f = 0; int maxFacetsPerMesh = indexFormat == IndexFormat.UInt32 ? MaxFacetsPerMesh32 : MaxFacetsPerMesh16; int maxVertexCount = maxFacetsPerMesh * 3; Mesh[] meshes = new Mesh[faceCount / maxFacetsPerMesh + 1]; for (int meshIndex = 0; meshIndex < meshes.Length; meshIndex++) { int len = System.Math.Min(maxVertexCount, (faceCount - f) * 3); Vector3[] v = new Vector3[len]; Vector3[] n = new Vector3[len]; int[] indices = new int[len * 3]; int[] t = new int[len]; for (int it = 0; it < len; it += 3) { v[it] = facets[f].a; v[it + 1] = facets[f].b; v[it + 2] = facets[f].c; n[it] = facets[f].normal; n[it + 1] = facets[f].normal; n[it + 2] = facets[f].normal; t[it] = it + 0; t[it + 1] = it + 1; t[it + 2] = it + 2; f++; } if (modelCoordinateSpace == CoordinateSpace.Right) { for (int i = 0; i < len; i += 3) { v[i + 0] = Stl.ToCoordinateSpace(v[i + 0], CoordinateSpace.Left); v[i + 1] = Stl.ToCoordinateSpace(v[i + 1], CoordinateSpace.Left); v[i + 2] = Stl.ToCoordinateSpace(v[i + 2], CoordinateSpace.Left); n[i + 0] = Stl.ToCoordinateSpace(n[i + 0], CoordinateSpace.Left); n[i + 1] = Stl.ToCoordinateSpace(n[i + 1], CoordinateSpace.Left); n[i + 2] = Stl.ToCoordinateSpace(n[i + 2], CoordinateSpace.Left); var a = t[i + 2]; t[i + 2] = t[i]; t[i] = a; } } // auto detect mesh winding via calculating the mesh's volume float volume = 0; for (int it = 0; it < len; it += 3) { Vector3 v1 = v[it]; Vector3 v2 = v[it + 1]; Vector3 v3 = v[it + 2]; Vector3 cross = Vector3.Cross(v1, v2); volume -= Vector3.Dot(cross, v3); } if (volume < 0) { for (int it = 0; it < len; it += 3) { indices[it * 3] = it; indices[it * 3 + 1] = it + 1; indices[it * 3 + 2] = it + 2; } } else { for (int it = 0; it < len; it += 3) { indices[it * 3] = it; indices[it * 3 + 1] = it + 2; indices[it * 3 + 2] = it + 1; } } Mesh mesh = new Mesh() { vertices = v, normals = n, triangles = t, indexFormat = indexFormat }; mesh.SetIndices(indices, MeshTopology.Triangles, 0); } return(meshes); }
private static bool ReadGeometry(string path, float scale, UpAxis axis, List <Vector3D> verts, List <Face> faces, ref int minZ, ref int maxZ) { using (StreamReader reader = File.OpenText(path)) { string line; int counter = 0; float picoarse = (float)Math.Round(Angle2D.PI, 3); while ((line = reader.ReadLine()) != null) { counter++; if (line.StartsWith("v ")) { string[] parts = line.Split(space, StringSplitOptions.RemoveEmptyEntries); float x, y, z; if (parts.Length != 4 || !float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out x) || !float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out y) || !float.TryParse(parts[3], NumberStyles.Float, CultureInfo.InvariantCulture, out z)) { MessageBox.Show("Failed to parse vertex definition at line " + counter + "!", "Terrain Importer", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } //apply up axis int px, py, pz; switch (axis) { case UpAxis.Y: px = (int)Math.Round(x * scale); py = (int)Math.Round(-z * scale); pz = (int)Math.Round(y * scale); break; case UpAxis.Z: px = (int)Math.Round(-x * scale); py = (int)Math.Round(-y * scale); pz = (int)Math.Round(z * scale); break; case UpAxis.X: px = (int)Math.Round(-y * scale); py = (int)Math.Round(-z * scale); pz = (int)Math.Round(x * scale); break; default: //same as UpAxis.Y px = (int)Math.Round(x * scale); py = (int)Math.Round(-z * scale); pz = (int)Math.Round(y * scale); break; } if (maxZ < pz) { maxZ = pz; } if (minZ > pz) { minZ = pz; } verts.Add(new Vector3D(px, py, pz)); } else if (line.StartsWith("f ")) { string[] parts = line.Split(space, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 4) { MessageBox.Show("Failed to parse face definition at line " + counter + ": only triangular faces are supported!", "Terrain Importer", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } //.obj vertex indices are 1-based int v1 = ReadVertexIndex(parts[1]) - 1; int v2 = ReadVertexIndex(parts[2]) - 1; int v3 = ReadVertexIndex(parts[3]) - 1; // Skip face if vertex indexes match if (verts[v1] == verts[v2] || verts[v1] == verts[v3] || verts[v2] == verts[v3]) { continue; } // Skip face if it's vertical Plane p = new Plane(verts[v1], verts[v2], verts[v3], true); if ((float)Math.Round(p.Normal.GetAngleZ(), 3) == picoarse) { continue; } faces.Add(new Face(verts[v3], verts[v2], verts[v1])); } } } return(true); }