示例#1
0
        // A helper function, analogous to ProcessFaces.
        private void ProcessEdges(RenderingPassBufferStorage bufferStorage)
        {
            List <IList <XYZ> > edges = bufferStorage.EdgeXYZs;

            if (edges.Count == 0)
            {
                return;
            }

            // Edges are encoded as line segment primitives whose vertices contain only position information.
            bufferStorage.FormatBits = VertexFormatBits.Position;

            int        edgeVertexBufferSizeInFloats = VertexPosition.GetSizeInFloats() * bufferStorage.VertexBufferCount;
            List <int> numVerticesInEdgesBefore     = new List <int>();

            numVerticesInEdgesBefore.Add(0);

            bufferStorage.VertexBuffer = new VertexBuffer(edgeVertexBufferSizeInFloats);
            bufferStorage.VertexBuffer.Map(edgeVertexBufferSizeInFloats);
            {
                VertexStreamPosition vertexStream = bufferStorage.VertexBuffer.GetVertexStreamPosition();
                foreach (IList <XYZ> xyzs in edges)
                {
                    foreach (XYZ vertex in xyzs)
                    {
                        vertexStream.AddVertex(new VertexPosition(vertex + m_offset));
                    }

                    numVerticesInEdgesBefore.Add(numVerticesInEdgesBefore.Last() + xyzs.Count);
                }
            }
            bufferStorage.VertexBuffer.Unmap();

            int edgeNumber = 0;

            bufferStorage.IndexBufferCount = bufferStorage.PrimitiveCount * IndexLine.GetSizeInShortInts();
            int indexBufferSizeInShortInts = 1 * bufferStorage.IndexBufferCount;

            bufferStorage.IndexBuffer = new IndexBuffer(indexBufferSizeInShortInts);
            bufferStorage.IndexBuffer.Map(indexBufferSizeInShortInts);
            {
                IndexStreamLine indexStream = bufferStorage.IndexBuffer.GetIndexStreamLine();
                foreach (IList <XYZ> xyzs in edges)
                {
                    int startIndex = numVerticesInEdgesBefore[edgeNumber];
                    for (int i = 1; i < xyzs.Count; i++)
                    {
                        // Add two indices that define a line segment.
                        indexStream.AddLine(new IndexLine((int)(startIndex + i - 1),
                                                          (int)(startIndex + i)));
                    }
                    edgeNumber++;
                }
            }
            bufferStorage.IndexBuffer.Unmap();


            bufferStorage.VertexFormat   = new VertexFormat(bufferStorage.FormatBits);
            bufferStorage.EffectInstance = new EffectInstance(bufferStorage.FormatBits);
        }
        // Submits the geometry for rendering.
        public void RenderScene(Autodesk.Revit.DB.View view, DisplayStyle displayStyle)
        {
            try
            {
                // Populate geometry buffers if they are not initialized or need updating.
                if (UpdateAll ||
                    m_nonTransparentFaceBufferStorage == null || m_nonTransparentFaceBufferStorage.needsUpdate(displayStyle) ||
                    m_transparentFaceBufferStorage == null || m_transparentFaceBufferStorage.needsUpdate(displayStyle) ||
                    m_edgeBufferStorage == null || m_edgeBufferStorage.needsUpdate(displayStyle))
                {
                    Options         options  = new Options();
                    GeometryElement geomElem = m_element.get_Geometry(options);

                    CreateBufferStorageForElement(geomElem, displayStyle);
                }

                // Submit a subset of the geometry for drawing. Determine what geometry should be submitted based on
                // the type of the rendering pass (opaque or transparent) and DisplayStyle (wireframe or shaded).

                // If the server is requested to submit transparent geometry, DrawContext().IsTransparentPass()
                // will indicate that the current rendering pass is for transparent objects.
                RenderingPassBufferStorage faceBufferStorage = DrawContext.IsTransparentPass() ? m_transparentFaceBufferStorage : m_nonTransparentFaceBufferStorage;

                // Conditionally submit triangle primitives (for non-wireframe views).
                if (displayStyle != DisplayStyle.Wireframe &&
                    faceBufferStorage.PrimitiveCount > 0)
                {
                    DrawContext.FlushBuffer(faceBufferStorage.VertexBuffer,
                                            faceBufferStorage.VertexBufferCount,
                                            faceBufferStorage.IndexBuffer,
                                            faceBufferStorage.IndexBufferCount,
                                            faceBufferStorage.VertexFormat,
                                            faceBufferStorage.EffectInstance, PrimitiveType.TriangleList, 0,
                                            faceBufferStorage.PrimitiveCount);
                }

                // Conditionally submit line segment primitives.
                if (displayStyle != DisplayStyle.Shading &&
                    m_edgeBufferStorage.PrimitiveCount > 0)
                {
                    DrawContext.FlushBuffer(m_edgeBufferStorage.VertexBuffer,
                                            m_edgeBufferStorage.VertexBufferCount,
                                            m_edgeBufferStorage.IndexBuffer,
                                            m_edgeBufferStorage.IndexBufferCount,
                                            m_edgeBufferStorage.VertexFormat,
                                            m_edgeBufferStorage.EffectInstance, PrimitiveType.LineList, 0,
                                            m_edgeBufferStorage.PrimitiveCount);
                }

                UpdateAll = false;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }
示例#3
0
        // Create and populate a pair of vertex and index buffers. Also update parameters associated with the format of the vertices.
        private void ProcessFaces(RenderingPassBufferStorage bufferStorage)
        {
            List <MeshInfo> meshes = bufferStorage.Meshes;
            List <int>      numVerticesInMeshesBefore = new List <int>();

            if (meshes.Count == 0)
            {
                return;
            }

            bool useNormals = bufferStorage.DisplayStyle == DisplayStyle.Shading ||
                              bufferStorage.DisplayStyle == DisplayStyle.ShadingWithEdges;

            // Vertex attributes are stored sequentially in vertex buffers. The attributes can include position, normal vector, and color.
            // All vertices within a vertex buffer must have the same format. Possible formats are enumerated by VertexFormatBits.
            // Vertex format also determines the type of rendering effect that can be used with the vertex buffer. In this sample,
            // the color is always encoded in the vertex attributes.

            bufferStorage.FormatBits = useNormals ? VertexFormatBits.PositionNormalColored : VertexFormatBits.PositionColored;

            // The format of the vertices determines the size of the vertex buffer.
            int vertexBufferSizeInFloats = (useNormals ? VertexPositionNormalColored.GetSizeInFloats() : VertexPositionColored.GetSizeInFloats()) *
                                           bufferStorage.VertexBufferCount;

            numVerticesInMeshesBefore.Add(0);

            bufferStorage.VertexBuffer = new VertexBuffer(vertexBufferSizeInFloats);
            bufferStorage.VertexBuffer.Map(vertexBufferSizeInFloats);

            if (useNormals)
            {
                // A VertexStream is used to write data into a VertexBuffer.
                VertexStreamPositionNormalColored vertexStream = bufferStorage.VertexBuffer.GetVertexStreamPositionNormalColored();
                foreach (MeshInfo meshInfo in meshes)
                {
                    Mesh mesh = meshInfo.Mesh;
                    foreach (XYZ vertex in mesh.Vertices)
                    {
                        vertexStream.AddVertex(new VertexPositionNormalColored(vertex + m_offset, meshInfo.Normal, meshInfo.ColorWithTransparency));
                    }

                    numVerticesInMeshesBefore.Add(numVerticesInMeshesBefore.Last() + mesh.Vertices.Count);
                }
            }
            else
            {
                // A VertexStream is used to write data into a VertexBuffer.
                VertexStreamPositionColored vertexStream = bufferStorage.VertexBuffer.GetVertexStreamPositionColored();
                foreach (MeshInfo meshInfo in meshes)
                {
                    Mesh mesh = meshInfo.Mesh;
                    // make the color of all faces white in HLR
                    ColorWithTransparency color = (bufferStorage.DisplayStyle == DisplayStyle.HLR) ?
                                                  new ColorWithTransparency(255, 255, 255, meshInfo.ColorWithTransparency.GetTransparency()) :
                                                  meshInfo.ColorWithTransparency;
                    foreach (XYZ vertex in mesh.Vertices)
                    {
                        vertexStream.AddVertex(new VertexPositionColored(vertex + m_offset, color));
                    }

                    numVerticesInMeshesBefore.Add(numVerticesInMeshesBefore.Last() + mesh.Vertices.Count);
                }
            }

            bufferStorage.VertexBuffer.Unmap();

            // Primitives are specified using a pair of vertex and index buffers. An index buffer contains a sequence of indices into
            // the associated vertex buffer, each index referencing a particular vertex.

            int meshNumber = 0;

            bufferStorage.IndexBufferCount = bufferStorage.PrimitiveCount * IndexTriangle.GetSizeInShortInts();
            int indexBufferSizeInShortInts = 1 * bufferStorage.IndexBufferCount;

            bufferStorage.IndexBuffer = new IndexBuffer(indexBufferSizeInShortInts);
            bufferStorage.IndexBuffer.Map(indexBufferSizeInShortInts);
            {
                // An IndexStream is used to write data into an IndexBuffer.
                IndexStreamTriangle indexStream = bufferStorage.IndexBuffer.GetIndexStreamTriangle();
                foreach (MeshInfo meshInfo in meshes)
                {
                    Mesh mesh       = meshInfo.Mesh;
                    int  startIndex = numVerticesInMeshesBefore[meshNumber];
                    for (int i = 0; i < mesh.NumTriangles; i++)
                    {
                        MeshTriangle mt = mesh.get_Triangle(i);
                        // Add three indices that define a triangle.
                        indexStream.AddTriangle(new IndexTriangle((int)(startIndex + mt.get_Index(0)),
                                                                  (int)(startIndex + mt.get_Index(1)),
                                                                  (int)(startIndex + mt.get_Index(2))));
                    }
                    meshNumber++;
                }
            }
            bufferStorage.IndexBuffer.Unmap();


            // VertexFormat is a specification of the data that is associated with a vertex (e.g., position).
            bufferStorage.VertexFormat = new VertexFormat(bufferStorage.FormatBits);
            // Effect instance is a specification of the appearance of geometry. For example, it may be used to specify color, if there is no color information provided with the vertices.
            bufferStorage.EffectInstance = new EffectInstance(bufferStorage.FormatBits);
        }
示例#4
0
        // Initialize and populate buffers that hold graphics primitives, set up related parameters that are needed for drawing.
        private void CreateBufferStorageForElement(GeometryElement geomElem, DisplayStyle displayStyle)
        {
            List <Solid> allSolids = new List <Solid>();

            foreach (GeometryObject geomObj in geomElem)
            {
                if (geomObj is Solid)
                {
                    Solid solid = (Solid)geomObj;
                    if (solid.Volume > 1e-06)
                    {
                        allSolids.Add(solid);
                    }
                }
            }

            m_nonTransparentFaceBufferStorage = new RenderingPassBufferStorage(displayStyle);
            m_transparentFaceBufferStorage    = new RenderingPassBufferStorage(displayStyle);
            m_edgeBufferStorage = new RenderingPassBufferStorage(displayStyle);

            // Collect primitives (and associated rendering parameters, such as colors) from faces and edges.
            foreach (Solid solid in allSolids)
            {
                foreach (Face face in solid.Faces)
                {
                    if (face.Area > 1e-06)
                    {
                        Mesh mesh = face.Triangulate();

                        ElementId             materialId    = face.MaterialElementId;
                        bool                  isTransparent = false;
                        ColorWithTransparency cwt           = new ColorWithTransparency(127, 127, 127, 0);
                        if (materialId != ElementId.InvalidElementId)
                        {
                            Material material = m_element.Document.GetElement(materialId) as Material;

                            Color color = material.Color;
                            int   transparency0To100 = material.Transparency;
                            uint  transparency0To255 = (uint)((float)transparency0To100 / 100f * 255f);

                            cwt = new ColorWithTransparency(color.Red, color.Green, color.Blue, transparency0To255);
                            if (transparency0To255 > 0)
                            {
                                isTransparent = true;
                            }
                        }

                        BoundingBoxUV env    = face.GetBoundingBox();
                        UV            center = 0.5 * (env.Min + env.Max);
                        XYZ           normal = face.ComputeNormal(center);

                        MeshInfo meshInfo = new MeshInfo(mesh, normal, cwt);

                        if (isTransparent)
                        {
                            m_transparentFaceBufferStorage.Meshes.Add(meshInfo);
                            m_transparentFaceBufferStorage.VertexBufferCount += mesh.Vertices.Count;
                            m_transparentFaceBufferStorage.PrimitiveCount    += mesh.NumTriangles;
                        }
                        else
                        {
                            m_nonTransparentFaceBufferStorage.Meshes.Add(meshInfo);
                            m_nonTransparentFaceBufferStorage.VertexBufferCount += mesh.Vertices.Count;
                            m_nonTransparentFaceBufferStorage.PrimitiveCount    += mesh.NumTriangles;
                        }
                    }
                }

                foreach (Edge edge in solid.Edges)
                {
                    // if (edge.Length > 1e-06)
                    {
                        IList <XYZ> xyzs = edge.Tessellate();

                        m_edgeBufferStorage.VertexBufferCount += xyzs.Count;
                        m_edgeBufferStorage.PrimitiveCount    += xyzs.Count - 1;
                        m_edgeBufferStorage.EdgeXYZs.Add(xyzs);
                    }
                }
            }

            // Fill out buffers with primitives based on the intermediate information about faces and edges.
            ProcessFaces(m_nonTransparentFaceBufferStorage);
            ProcessFaces(m_transparentFaceBufferStorage);
            ProcessEdges(m_edgeBufferStorage);
        }