示例#1
0
        /// <summary>
        /// Create a ruled loft between sections.
        /// </summary>
        /// <param name="sections"></param>
        public static Mesh Loft(IList <Polygon> sections)
        {
            var mesh = new Elements.Geometry.Mesh();

            for (var i = 0; i < sections.Count; i++)
            {
                var p1 = sections[i];
                var p2 = i == sections.Count - 1 ? sections[0] : sections[i + 1];

                for (var j = 0; j < p1.Vertices.Length; j++)
                {
                    var j1 = j == p1.Vertices.Length - 1 ? 0 : j + 1;
                    var v1 = p1.Vertices[j];
                    var v2 = p1.Vertices[j1];
                    var v3 = p2.Vertices[j1];
                    var v4 = p2.Vertices[j];
                    mesh.AddQuad(new [] { v1, v2, v3, v4 });
                }
            }

            return(mesh);
        }
        public static RenderData DrawMesh(Elements.Geometry.Mesh mesh, ref Outline outline, DisplayStyle displayStyle)
        {
            var min = new XYZ(double.MaxValue, double.MaxValue, double.MaxValue);
            var max = new XYZ(double.MinValue, double.MinValue, double.MinValue);

            var numVertices   = mesh.Triangles.Count * 3;
            var numPrimitives = mesh.Triangles.Count;
            var pType         = PrimitiveType.TriangleList;
            var numIndices    = GetPrimitiveSize(pType) * numPrimitives;
            VertexFormatBits vertexFormatBits;

            switch (displayStyle)
            {
            case DisplayStyle.HLR:
            case DisplayStyle.FlatColors:
                vertexFormatBits = VertexFormatBits.PositionColored;
                break;

            default:
                vertexFormatBits = VertexFormatBits.PositionNormalColored;
                break;
            }
            var vertexFormat = new VertexFormat(vertexFormatBits);

            var vBuffer = new VertexBuffer(GetVertexSize(vertexFormatBits) * numVertices);
            var iBuffer = new IndexBuffer(numIndices);

            vBuffer.Map(GetVertexSize(vertexFormatBits) * numVertices);
            iBuffer.Map(numIndices);

            var verticesFlat = new List <VertexPositionColored>();
            var vertices     = new List <VertexPositionNormalColored>();
            var triangles    = new List <IndexTriangle>();

            // We duplicate the vertices on each triangle so that
            // we can get the correct number of face normals.
            foreach (var t in mesh.Triangles)
            {
                foreach (var v in t.Vertices)
                {
                    var pos = v.Position.ToXYZFeet();

                    outline.AddPoint(pos);

                    switch (vertexFormatBits)
                    {
                    case VertexFormatBits.PositionColored:
                        var color = displayStyle == DisplayStyle.HLR ? new ColorWithTransparency(255, 255, 255, 0) : v.Color.ToColorWithTransparency();
                        verticesFlat.Add(new VertexPositionColored(pos, color));
                        break;

                    default:
                        vertices.Add(new VertexPositionNormalColored(pos, t.Normal.ToXYZ(), v.Color.ToColorWithTransparency()));
                        break;
                    }

                    if (pos.X < min.X && pos.Y < min.Y && pos.Z < min.Z)
                    {
                        min = pos;
                    }
                    if (pos.X > min.X && pos.Y > min.Y && pos.Z > min.Z)
                    {
                        max = pos;
                    }
                }

                triangles.Add(new IndexTriangle(t.Vertices[0].Index, t.Vertices[1].Index, t.Vertices[2].Index));
            }

            switch (displayStyle)
            {
            case DisplayStyle.HLR:
            case DisplayStyle.FlatColors:
                var pc = vBuffer.GetVertexStreamPositionColored();
                pc.AddVertices(verticesFlat);
                break;

            default:
                var pnc = vBuffer.GetVertexStreamPositionNormalColored();
                pnc.AddVertices(vertices);
                break;
            }

            var iPos = iBuffer.GetIndexStreamTriangle();

            iPos.AddTriangles(triangles);

            vBuffer.Unmap();
            iBuffer.Unmap();

            var effect = new EffectInstance(vertexFormatBits);
            // There is no reason why this should work.
            // In other situations, 255 is the 'full' component.
            // In the case of hidden line rendering, 0, 0, 0 makes white.
            // if (displayStyle == DisplayStyle.HLR)
            // {
            //     var color = new ColorWithTransparency(0, 0, 0, 0);
            //     effect.SetColor(color.GetColor());
            //     effect.SetAmbientColor(color.GetColor());
            //     effect.SetDiffuseColor(color.GetColor());
            // }

            // Create a render data for reuse
            // on non-update calls.
            var renderData = new RenderData()
            {
                VertexBuffer   = vBuffer,
                VertexCount    = numVertices,
                IndexBuffer    = iBuffer,
                IndexCount     = numIndices,
                VertexFormat   = vertexFormat,
                Effect         = effect,
                PrimitiveType  = pType,
                PrimitiveCount = numPrimitives
            };

            if (displayStyle != DisplayStyle.Wireframe && numPrimitives > 0)
            {
                DrawContext.FlushBuffer(vBuffer, numVertices, iBuffer, numIndices, vertexFormat, effect, pType, 0, numPrimitives);
            }

            return(renderData);
        }
        private static List <RenderData> DrawExecution(ILogger logger,
                                                       string workflowId,
                                                       string executionId,
                                                       Outline outline,
                                                       DisplayStyle displayStyle)
        {
            // Read the workflow from disk
            var execPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), $".hypar/workflows/{workflowId}/{executionId}/model.json");

            if (!File.Exists(execPath))
            {
                logger.Debug("The execution path {Path} could not be found. Perhaps the workflow was deleted from the cache.", execPath);
                return(null);
            }

            var errors = new List <string>();
            var model  = Elements.Model.FromJson(File.ReadAllText(execPath), errors);

            foreach (var error in errors)
            {
                logger.Debug("{Error}", error);
            }

            var geoms = model.AllElementsOfType <Elements.GeometricElement>();

            var instances = model.AllElementsOfType <Elements.ElementInstance>();

            logger.Debug("Found {ElementCount} elements.", geoms.Count());
            if (geoms.Count() == 0)
            {
                return(null);
            }

            var meshes  = new List <Elements.Geometry.Mesh>();
            var edgeSet = new List <List <Elements.Geometry.Line> >();
            var edges   = new List <Elements.Geometry.Line>();

            edgeSet.Add(edges);

            // Draw the meshes and edges in batches. Arbitrarily large meshes
            // will overun the max value of ushorts causing data
            // not to show up.
            var meshBatchSize = 500;
            var edgeBatchSize = 1000;
            var mesh          = new Elements.Geometry.Mesh();

            var count = 0;

            foreach (var geom in geoms)
            {
                if (geom.Representation == null || geom.Representation.SolidOperations.Count() == 0)
                {
                    continue;
                }

                foreach (var solidOp in geom.Representation.SolidOperations)
                {
                    solidOp.Solid.Tessellate(ref mesh, geom.Transform, geom.Material.Color);
                    foreach (var e in solidOp.Solid.Edges.Values)
                    {
                        edges.Add(new Elements.Geometry.Line(geom.Transform.OfPoint(e.Left.Vertex.Point), geom.Transform.OfPoint(e.Right.Vertex.Point)));
                        if (edges.Count >= edgeBatchSize)
                        {
                            edgeSet.Add(edges);
                            edges = new List <Elements.Geometry.Line>();
                        }
                    }
                }

                count++;

                if (count > meshBatchSize)
                {
                    meshes.Add(mesh);
                    mesh  = new Elements.Geometry.Mesh();
                    count = 0;
                }
            }

            foreach (var instance in instances)
            {
                if (instance.BaseDefinition.Representation == null || instance.BaseDefinition.Representation.SolidOperations.Count() == 0)
                {
                    continue;
                }

                foreach (var solidOp in instance.BaseDefinition.Representation.SolidOperations)
                {
                    solidOp.Solid.Tessellate(ref mesh, instance.Transform, instance.BaseDefinition.Material.Color);
                    foreach (var e in solidOp.Solid.Edges.Values)
                    {
                        edges.Add(new Elements.Geometry.Line(instance.Transform.OfPoint(e.Left.Vertex.Point), instance.Transform.OfPoint(e.Right.Vertex.Point)));
                        if (edges.Count >= edgeBatchSize)
                        {
                            edgeSet.Add(edges);
                            edges = new List <Elements.Geometry.Line>();
                        }
                    }
                }

                count++;

                if (count > meshBatchSize)
                {
                    meshes.Add(mesh);
                    mesh  = new Elements.Geometry.Mesh();
                    count = 0;
                }
            }
            meshes.Add(mesh);
            edgeSet.Add(edges);

            var renderDatas = new List <RenderData>();

            logger.Debug("There are {MeshCount} meshes to be drawn.", meshes.Count);
            foreach (var subMesh in meshes)
            {
                try
                {
                    if (displayStyle != DisplayStyle.Wireframe)
                    {
                        renderDatas.Add(DrawMesh(subMesh, ref outline, displayStyle));
                    }
                }
                catch (Exception ex)
                {
                    logger.Debug(ex.Message);
                }
            }

            if (displayStyle != DisplayStyle.Shading)
            {
                foreach (var e in edgeSet)
                {
                    renderDatas.Add(DrawEdges(e));
                }
            }

            return(renderDatas);
        }