/// <summary> /// Creates a new object from a wireframe visualization. /// </summary> /// <param name="visWire">Visualization object.</param> /// <returns>New object, or null if visualization data fails validation.</returns> public static WireframeObject Create(IVisualizationWireframe visWire) { if (!visWire.Validate(out string msg)) { // Should not be here -- visualizer should have checked validation and // reported an error. Debug.WriteLine("Wireframe validation failed: " + msg); return(null); } WireframeObject wireObj = new WireframeObject(); wireObj.mIs2d = visWire.Is2d; // // Start by extracting data from the visualization object. Everything stored // there is loaded into this object. The VisWireframe validator will have // ensured that all the indices are in range. // // IMPORTANT: do not retain "visWire", as it may be a proxy for an object with a // limited lifespan. // float[] normalsX = visWire.GetNormalsX(); if (normalsX.Length > 0) { float[] normalsY = visWire.GetNormalsY(); float[] normalsZ = visWire.GetNormalsZ(); for (int i = 0; i < normalsX.Length; i++) { wireObj.mFaces.Add(new Face(normalsX[i], normalsY[i], normalsZ[i])); } } float[] verticesX = visWire.GetVerticesX(); float[] verticesY = visWire.GetVerticesY(); float[] verticesZ = visWire.GetVerticesZ(); int[] excludedVertices = visWire.GetExcludedVertices(); // Compute min/max for X/Y for 2d re-centering. The trick is that we only want // to use vertices that are visible. If the shape starts with a huge move off to // the left, we don't want to include (0,0). double xmin, xmax, ymin, ymax; xmin = ymin = 10e9; xmax = ymax = -10e9; for (int i = 0; i < verticesX.Length; i++) { wireObj.mVertices.Add(new Vertex(verticesX[i], verticesY[i], verticesZ[i], HasIndex(excludedVertices, i))); } int[] points = visWire.GetPoints(); for (int i = 0; i < points.Length; i++) { Vertex vert = wireObj.mVertices[points[i]]; wireObj.mPoints.Add(vert); UpdateMinMax(vert, ref xmin, ref xmax, ref ymin, ref ymax); } IntPair[] edges = visWire.GetEdges(); int[] excludedEdges = visWire.GetExcludedEdges(); for (int i = 0; i < edges.Length; i++) { int v0index = edges[i].Val0; int v1index = edges[i].Val1; //if (v0index < 0 || v0index >= wireObj.mVertices.Count || // v1index < 0 || v1index >= wireObj.mVertices.Count) { // Debug.Assert(false); // return null; //} Vertex vert0 = wireObj.mVertices[v0index]; Vertex vert1 = wireObj.mVertices[v1index]; wireObj.mEdges.Add(new Edge(vert0, vert1, HasIndex(excludedEdges, i))); UpdateMinMax(vert0, ref xmin, ref xmax, ref ymin, ref ymax); UpdateMinMax(vert1, ref xmin, ref xmax, ref ymin, ref ymax); } IntPair[] vfaces = visWire.GetVertexFaces(); for (int i = 0; i < vfaces.Length; i++) { int vindex = vfaces[i].Val0; int findex = vfaces[i].Val1; //if (vindex < 0 || vindex >= wireObj.mVertices.Count || // findex < 0 || findex >= wireObj.mFaces.Count) { // Debug.Assert(false); // return null; //} Face face = wireObj.mFaces[findex]; wireObj.mVertices[vindex].Faces.Add(face); if (face.Vert == null) { face.Vert = wireObj.mVertices[vindex]; } } IntPair[] efaces = visWire.GetEdgeFaces(); for (int i = 0; i < efaces.Length; i++) { int eindex = efaces[i].Val0; int findex = efaces[i].Val1; //if (eindex < 0 || eindex >= wireObj.mEdges.Count || // findex < 0 || findex >= wireObj.mFaces.Count) { // Debug.Assert(false); // return null; //} Face face = wireObj.mFaces[findex]; wireObj.mEdges[eindex].Faces.Add(face); if (face.Vert == null) { face.Vert = wireObj.mEdges[eindex].Vertex0; } } // // All data has been loaded into friendly classes. // // Compute center of visible vertices. wireObj.mCenterAdjX = -(xmin + xmax) / 2; wireObj.mCenterAdjY = -(ymin + ymax / 2); // Compute the magnitude of the largest vertex, for scaling. double bigMag = -1.0; double bigMagRc = -1.0; for (int i = 0; i < wireObj.mVertices.Count; i++) { Vector3 vec = wireObj.mVertices[i].Vec; double mag = vec.Magnitude(); if (bigMag < mag) { bigMag = mag; } // Repeat the operation with recentering. This isn't quite right as we're // including all vertices, not just the visible ones. mag = new Vector3(vec.X + wireObj.mCenterAdjX, vec.Y + wireObj.mCenterAdjY, vec.Z).Magnitude(); if (bigMagRc < mag) { bigMagRc = mag; } } // Avoid divide-by-zero. if (bigMag == 0) { Debug.WriteLine("NOTE: wireframe magnitude was zero"); bigMag = 1; } if (bigMagRc == 0) { bigMagRc = 1; } wireObj.mBigMag = bigMag; wireObj.mBigMagRc = bigMagRc; return(wireObj); }
/// <summary> /// Creates a new object from a wireframe visualization. /// </summary> /// <param name="visWire">Visualization object.</param> /// <returns>New object.</returns> public static WireframeObject Create(IVisualizationWireframe visWire) { WireframeObject wireObj = new WireframeObject(); // // Start by extracting data from the visualization object. Everything stored // there is loaded into this object. // float[] normalsX = visWire.GetNormalsX(); if (normalsX.Length > 0) { float[] normalsY = visWire.GetNormalsY(); float[] normalsZ = visWire.GetNormalsZ(); if (normalsX.Length != normalsY.Length || normalsX.Length != normalsZ.Length) { Debug.Assert(false); return(null); } for (int i = 0; i < normalsX.Length; i++) { wireObj.mFaces.Add(new Face(normalsX[i], normalsY[i], normalsZ[i])); } } float[] verticesX = visWire.GetVerticesX(); float[] verticesY = visWire.GetVerticesY(); float[] verticesZ = visWire.GetVerticesZ(); int[] excludedVertices = visWire.GetExcludedVertices(); if (verticesX.Length == 0) { Debug.Assert(false); return(null); } if (verticesX.Length != verticesY.Length || verticesX.Length != verticesZ.Length) { Debug.Assert(false); return(null); } for (int i = 0; i < verticesX.Length; i++) { wireObj.mVertices.Add(new Vertex(verticesX[i], verticesY[i], verticesZ[i], HasIndex(excludedVertices, i))); } IntPair[] edges = visWire.GetEdges(); int[] excludedEdges = visWire.GetExcludedEdges(); for (int i = 0; i < edges.Length; i++) { int v0index = edges[i].Val0; int v1index = edges[i].Val1; if (v0index < 0 || v0index >= wireObj.mVertices.Count || v1index < 0 || v1index >= wireObj.mVertices.Count) { Debug.Assert(false); return(null); } wireObj.mEdges.Add(new Edge(wireObj.mVertices[v0index], wireObj.mVertices[v1index], HasIndex(excludedEdges, i))); } IntPair[] vfaces = visWire.GetVertexFaces(); for (int i = 0; i < vfaces.Length; i++) { int vindex = vfaces[i].Val0; int findex = vfaces[i].Val1; if (vindex < 0 || vindex >= wireObj.mVertices.Count || findex < 0 || findex >= wireObj.mFaces.Count) { Debug.Assert(false); return(null); } Face face = wireObj.mFaces[findex]; wireObj.mVertices[vindex].Faces.Add(face); if (face.Vert == null) { face.Vert = wireObj.mVertices[vindex]; } } IntPair[] efaces = visWire.GetEdgeFaces(); for (int i = 0; i < efaces.Length; i++) { int eindex = efaces[i].Val0; int findex = efaces[i].Val1; if (eindex < 0 || eindex >= wireObj.mEdges.Count || findex < 0 || findex >= wireObj.mFaces.Count) { Debug.Assert(false); return(null); } Face face = wireObj.mFaces[findex]; wireObj.mEdges[eindex].Faces.Add(face); if (face.Vert == null) { face.Vert = wireObj.mEdges[eindex].Vertex0; } } // // All data has been loaded into friendly classes. // // Compute the magnitude of the largest vertex, for scaling. double bigMag = -1.0; for (int i = 0; i < wireObj.mVertices.Count; i++) { double mag = wireObj.mVertices[i].Vec.Magnitude(); if (bigMag < mag) { bigMag = mag; } } wireObj.mBigMag = bigMag; return(wireObj); }