/* * Copyright 2020 faddenSoft * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Diagnostics; namespace PluginCommon { /// /// Wireframe mesh with optional backface normals, for use with visualization generators. /// Call the various functions to add data, then call Validate() to check for broken /// references. /// [Serializable] public class VisWireframe : IVisualizationWireframe { public static VisParamDescr Param_IsPerspective(string uiLabel, bool defaultVal) { return new VisParamDescr(uiLabel, "_isPerspective", typeof(bool), 0, 0, 0, defaultVal); } public static VisParamDescr Param_IsBackfaceRemoved(string uiLabel, bool defaultVal) { return new VisParamDescr(uiLabel, "_isBackfaceRemoved", typeof(bool), 0, 0, 0, defaultVal); } public static VisParamDescr Param_EulerX(string uiLabel, int defaultVal) { return new VisParamDescr(uiLabel, "_eulerRotX", typeof(int), 0, 359, 0, defaultVal); } public static VisParamDescr Param_EulerY(string uiLabel, int defaultVal) { return new VisParamDescr(uiLabel, "_eulerRotY", typeof(int), 0, 359, 0, defaultVal); } public static VisParamDescr Param_EulerZ(string uiLabel, int defaultVal) { return new VisParamDescr(uiLabel, "_eulerRotZ", typeof(int), 0, 359, 0, defaultVal); } private List mVerticesX = new List(); private List mVerticesY = new List(); private List mVerticesZ = new List(); private List mEdges = new List(); private List mNormalsX = new List(); private List mNormalsY = new List(); private List mNormalsZ = new List(); private List mVertexFaces = new List(); private List mEdgeFaces = new List(); /// /// Constructor. Nothing much to do. /// public VisWireframe() { } /// /// Adds the vertex to the list. /// /// X coordinate. /// Y coordinate. /// Z coordinate. /// Vertex index. Indices start at zero and count up. public int AddVertex(float x, float y, float z) { mVerticesX.Add(x); mVerticesY.Add(y); mVerticesZ.Add(z); return mVerticesX.Count - 1; } /// /// Adds an edge to the list. The referenced vertices do not need to be defined /// before calling. /// /// Index of first vertex. /// Index of second vertex. /// Edge index. Indices start at zero and count up. public int AddEdge(int index0, int index1) { Debug.Assert(index0 >= 0); Debug.Assert(index1 >= 0); mEdges.Add(new IntPair(index0, index1)); return mEdges.Count - 1; } /// /// Adds the face normal to the list. /// /// X coordinate. /// Y coordinate. /// Z coordinate. /// Face index. Indices start at zero and count up. public int AddFaceNormal(float x, float y, float z) { Debug.Assert(x != 0.0f || y != 0.0f || z != 0.0f); // no zero-length normals mNormalsX.Add(x); mNormalsY.Add(y); mNormalsZ.Add(z); return mNormalsX.Count - 1; } /// /// Marks a vertex's visibility as being tied to the specified face. The vertices and /// faces being referenced do not need to exist yet. /// /// Index of vertex. /// Index of face. public void AddVertexFace(int vertexIndex, int faceIndex) { Debug.Assert(vertexIndex >= 0); Debug.Assert(faceIndex >= 0); mVertexFaces.Add(new IntPair(vertexIndex, faceIndex)); } /// /// Marks an edge's visibility as being tied to the specified face. The edges and /// faces being referenced do not need to exist yet. /// /// Index of edge. /// Index of face. public void AddEdgeFace(int edgeIndex, int faceIndex) { Debug.Assert(edgeIndex >= 0); Debug.Assert(faceIndex >= 0); mEdgeFaces.Add(new IntPair(edgeIndex, faceIndex)); } /// /// Verifies that the various references by index are valid. /// /// Failure detail. /// True if everything looks valid. public bool Validate(out string msg) { int vertexCount = mVerticesX.Count; int faceCount = mNormalsX.Count; int edgeCount = mEdges.Count; // check edges foreach (IntPair ip in mEdges) { if (ip.Val0 < 0 || ip.Val0 >= vertexCount || ip.Val1 < 0 || ip.Val1 >= vertexCount) { msg = "invalid edge"; return false; } } // check vertex-faces foreach (IntPair ip in mVertexFaces) { if (ip.Val0 < 0 || ip.Val0 >= vertexCount || ip.Val1 < 0 || ip.Val1 >= faceCount) { msg = "invalid vertex-face"; return false; } } // check edge-faces foreach (IntPair ip in mVertexFaces) { if (ip.Val0 < 0 || ip.Val0 >= edgeCount || ip.Val1 < 0 || ip.Val1 >= faceCount) { msg = "invalid edge-face"; return false; } } // check face normals for (int i = 0; i < mNormalsX.Count; i++) { if (mNormalsX[i] == 0.0f && mNormalsY[i] == 0.0f && mNormalsZ[i] == 0.0f) { msg = "zero-length normal"; return false; } } msg = string.Empty; return true; } // // IVisualizationWireframe implementation. // public float[] GetVerticesX() { return mVerticesX.ToArray(); } public float[] GetVerticesY() { return mVerticesY.ToArray(); } public float[] GetVerticesZ() { return mVerticesZ.ToArray(); } public IntPair[] GetEdges() { return mEdges.ToArray(); } public float[] GetNormalsX() { return mNormalsX.ToArray(); } public float[] GetNormalsY() { return mNormalsY.ToArray(); } public float[] GetNormalsZ() { return mNormalsZ.ToArray(); } public IntPair[] GetVertexFaces() { return mVertexFaces.ToArray(); } public IntPair[] GetEdgeFaces() { return mEdgeFaces.ToArray(); } public override string ToString() { return "[VisWireframe: " + mVerticesX.Count + " vertices, " + mEdges.Count + " edges, " + mNormalsX.Count + " faces, " + mVertexFaces.Count + " vfaces, " + mEdgeFaces.Count + " efaces]"; } } }