Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }