Example #1
0
        public static Polyline Rationalise(this Circle circle, RenderMeshOptions renderMeshOptions = null, int minSubdivisions = 3)
        {
            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            Polyline polyline = new Polyline();

            List <Point> controlPoints = new List <Point> {
                circle.IStartPoint()
            };

            // Subdivide the circle.
            // Empyrical formula to extract a reasonable amount of segments
            int numSubdvision = (int)(Math.Ceiling(circle.Radius * 10) * renderMeshOptions.Element1DRefinement);

            // Scale the number of subdivisions based on the Options
            numSubdvision = (int)Math.Ceiling(numSubdvision * renderMeshOptions.Element1DRefinement);

            // Check the number of subdivisions is over the minimum acceptable
            numSubdvision = numSubdvision < minSubdivisions ? minSubdivisions : numSubdvision;

            if (renderMeshOptions.RepresentationOptions.Detailed1DElements)
            {
                numSubdvision = (int)(Math.Ceiling(numSubdvision * 2f));
            }

            List <double> pointParams = Enumerable.Range(0, numSubdvision).Select(i => (double)((double)i / (double)numSubdvision)).ToList();

            pointParams.Add(1);

            controlPoints.AddRange(pointParams.Select(par => circle.IPointAtParameter(par)));

            polyline.ControlPoints = controlPoints;

            return(polyline);
        }
Example #2
0
        public static BH.oM.Graphics.RenderMesh RenderMesh(this Cone cone, RenderMeshOptions renderMeshOptions = null)
        {
            if (cone == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot compute the mesh of a null cone.");
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            int           coneFaces   = 4; // by default this creates a pyramid
            List <double> pointParams = new List <double>();

            if (coneFaces == 4)
            {
                pointParams = new List <double>()
                {
                    0.125, 0.375, 0.625, 0.875, 0.125
                }
            }
            ;                                                                           // for 4 corners, make sure the pyramid is oriented like global axes
            else
            {
                pointParams = Enumerable.Range(0, coneFaces + 1).Select(i => (double)((double)i / (double)coneFaces)).ToList();
            }

            Circle       baseCircle       = BH.Engine.Geometry.Create.Circle(cone.Centre, cone.Axis, cone.Radius);
            List <Point> pointsOnBase     = pointParams.Select(par => baseCircle.IPointAtParameter(par)).ToList();
            Vector       coneHeightVector = Compute.Scale(cone.Axis, cone.Height);

            Point topPoint = new Point()
            {
                X = cone.Centre.X + BHEG.Modify.Project(coneHeightVector, BHOG.Plane.XY).X,
                Y = cone.Centre.Y + BHEG.Modify.Project(coneHeightVector, BHOG.Plane.XY).Y,// Math.Sin(BHEG.Query.Angle(BHEG.Modify.Project(cone.Axis, BHOG.Plane.XY), BHOG.Vector.XAxis)),
                Z = cone.Centre.Z + coneHeightVector.Z
            };

            List <Face>  faces    = new List <Face>();
            List <Point> vertices = new List <Point>();

            vertices.AddRange(pointsOnBase);
            vertices.Add(topPoint);

            for (int i = 0; i < pointsOnBase.Count - 1; i++)
            {
                faces.Add(new Face()
                {
                    A = i, B = i + 1, C = vertices.Count - 1
                });
            }

            return(new RenderMesh()
            {
                Vertices = vertices.Select(pt => (RenderPoint)pt).ToList(), Faces = faces
            });
        }
Example #3
0
        public static BH.oM.Graphics.RenderMesh RenderMesh(this Cuboid cuboid, RenderMeshOptions renderMeshOptions = null)
        {
            if (cuboid == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot compute the mesh of a null cuboid.");
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            return(BoxRenderMesh(cuboid.CoordinateSystem.Origin, cuboid.Length, cuboid.Depth, cuboid.Height, renderMeshOptions));
        }
Example #4
0
        public static BH.oM.Graphics.RenderMesh RenderMesh(this ICurve curve, RenderMeshOptions renderMeshOptions = null)
        {
            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            Polyline polyline = curve.IRationalise(renderMeshOptions);

            if (polyline != null)
            {
                return(polyline.GeometricalRepresentation(renderMeshOptions.RepresentationOptions).IRenderMesh(renderMeshOptions));
            }

            return(null);
        }
Example #5
0
        public static Polyline Rationalise(this Arc arc, RenderMeshOptions renderMeshOptions = null, int minSubdivisions = 3)
        {
            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            Polyline polyline = new Polyline();

            List <Point> controlPoints = new List <Point> {
                arc.IStartPoint()
            };

            double arcAngle = Math.Round(Math.Abs(Math.Abs(arc.StartAngle - arc.EndAngle)), 4);

            double minRadiusForSubdivision = 0.02;
            double minAngleForSubdivision  = 0.1;

            if (renderMeshOptions.RepresentationOptions.Detailed1DElements)
            {
                minRadiusForSubdivision = minRadiusForSubdivision / renderMeshOptions.Element1DRefinement;
                minAngleForSubdivision  = minAngleForSubdivision / renderMeshOptions.Element1DRefinement;
            }

            double length = arc.Length();

            if (arc.Radius < minRadiusForSubdivision || arcAngle < minAngleForSubdivision) // a very small arc should not be subdivided.
            {
                controlPoints.Add(arc.IEndPoint());
            }
            else
            {
                // If not, subdivide the arc.
                int numSubdvision = (int)Math.Abs(Math.Ceiling(1.5708 / (arcAngle) * renderMeshOptions.Element1DRefinement * length / 2) - 1);

                // Scale the number of subdivisions based on the Options
                numSubdvision = (int)Math.Ceiling(numSubdvision * renderMeshOptions.Element1DRefinement);

                // Check the number of subdivisions is over the minimum acceptable
                numSubdvision = numSubdvision < minSubdivisions ? minSubdivisions : numSubdvision;

                List <double> pointParams = Enumerable.Range(0, numSubdvision).Select(i => (double)((double)i / (double)numSubdvision)).ToList();

                controlPoints.AddRange(pointParams.Select(par => arc.IPointAtParameter(par)));

                controlPoints.Add(arc.IEndPoint());
            }

            polyline.ControlPoints = controlPoints;

            return(polyline);
        }
Example #6
0
        public static BH.oM.Graphics.RenderMesh IRenderMesh(this IObject obj, RenderMeshOptions renderMeshOptions = null)
        {
            if (obj == null)
            {
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            RenderMesh renderMesh = null;

            // See if there is a custom BHoM mesh representation for this BHoMObject, before attempting the RenderMesh computation.
            if (obj is IBHoMObject)
            {
                if (Query.TryGetRendermesh(obj as IBHoMObject, out renderMesh))
                {
                    return(renderMesh);
                }
            }

            if (obj is BH.oM.Graphics.RenderMesh)
            {
                return(obj as BH.oM.Graphics.RenderMesh);
            }

            BH.oM.Geometry.Mesh mesh = obj as BH.oM.Geometry.Mesh;
            if (mesh != null)
            {
                return(mesh.ToRenderMesh());
            }

            // If obj is of type IGeometry, we still need to compute its geometrical representation.
            // E.g. A BH.oM.Geometry.Point can only be represented with a Sphere, a Pixel, a Voxel, etc.
            IGeometry geomRepr = IGeometricalRepresentation(obj, renderMeshOptions.RepresentationOptions);

            if (geomRepr != null)
            {
                renderMesh = RenderMesh(geomRepr as dynamic, renderMeshOptions);
            }

            if (renderMesh == null)
            {
                throw new Exception($"Could not compute the {nameof(BH.oM.Graphics.RenderMesh)} of {obj.GetType().Name}.");
            }

            return(renderMesh);
        }
Example #7
0
        public static Polyline IRationalise(this ICurve curve, RenderMeshOptions renderMeshOptions = null)
        {
            if (curve is Polyline) // no need to rationalise
            {
                return(curve as Polyline);
            }

            if (curve is Line) // no need to rationalise
            {
                return new Polyline()
                       {
                           ControlPoints = (curve as Line).ControlPoints()
                       }
            }
            ;

            return(Rationalise(curve as dynamic, renderMeshOptions));
        }
Example #8
0
        public static Polyline Rationalise(this PolyCurve curve, RenderMeshOptions renderMeshOptions = null, int minSubdivisions = 3)
        {
            if (curve == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot rationalise a null polycurve.");
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            if (curve.Curves.Count == 0)
            {
                return(new Polyline());
            }

            Polyline polyline = new Polyline();

            polyline.ControlPoints.Add(curve.SubParts()[0].IStartPoint());

            foreach (ICurve c in curve.SubParts())
            {
                Line line = c as Line;
                if (line != null)
                {
                    polyline.ControlPoints.Add(line.End);
                    continue;
                }

                Polyline rationalised = Rationalise(c as dynamic, renderMeshOptions, minSubdivisions);

                List <Point> points = rationalised.ControlPoints.Skip(1).ToList();

                polyline.ControlPoints.AddRange(points);
            }

            if (polyline == null || polyline.ControlPoints.Count < 2)
            {
                BH.Engine.Base.Compute.RecordError("Rationalisation of curves currently only supports Arcs.");
            }

            return(polyline);
        }
Example #9
0
        /***************************************************/
        /**** Public Methods - Graphics                 ****/
        /***************************************************/

        public static BH.oM.Graphics.RenderMesh RenderMesh(this BoundingBox bbox, RenderMeshOptions renderMeshOptions = null)
        {
            if (bbox == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot compute the mesh of a null bounding box.");
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            double length = bbox.Max.X - bbox.Min.X;
            double depth  = bbox.Max.Y - bbox.Min.Y;
            double height = bbox.Max.Z - bbox.Min.Z;

            Point centrePoint = new Point()
            {
                X = bbox.Min.X + length / 2, Y = bbox.Min.Y + depth / 2, Z = bbox.Min.Z + height / 2
            };

            return(BoxRenderMesh(centrePoint, length, depth, height));
        }
Example #10
0
        public static IBHoMObject ISetRendermesh(this IBHoMObject bHoMObject, object meshRepresentation = null, RenderMeshOptions renderMeshOptions = null)
        {
            if (bHoMObject == null)
            {
                return(null);
            }

            if (meshRepresentation == null)
            {
                // Try computing a RenderMesh from the specified representation Geometry
                RenderMesh rm = Compute.IRenderMesh(bHoMObject, renderMeshOptions);

                if (rm == null)
                {
                    BH.Engine.Base.Compute.RecordError($"The input {nameof(meshRepresentation)} was null. The method attempted to compute a RenderMesh for the object, but this failed.");
                    return(null);
                }

                return(SetRendermesh(bHoMObject, rm));
            }

            return(SetRendermesh(bHoMObject, meshRepresentation as dynamic));
        }
Example #11
0
        public static BH.oM.Graphics.RenderMesh RenderMesh(this Pipe pipe, RenderMeshOptions renderMeshOptions = null)
        {
            if (pipe == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot compute the mesh of a null pipe.");
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            double radius = pipe.Radius;
            bool   capped = renderMeshOptions.RepresentationOptions.Cap1DElements;

            Line     centreLine     = pipe.Centreline as Line;
            Polyline centrePolyline = pipe.Centreline as Polyline;

            if (centreLine != null)
            {
                int           pipeFaces   = (int)Math.Ceiling(3 * renderMeshOptions.Element1DRefinement);
                List <double> pointParams = Enumerable.Range(0, pipeFaces + 1).Select(i => (double)((double)i / (double)pipeFaces)).ToList();

                Circle c = BH.Engine.Geometry.Create.Circle(centreLine.Start, centreLine.Direction(), radius * renderMeshOptions.RepresentationOptions.Element1DScale);

                var      gna      = BH.Engine.Geometry.Create.Polyline(pointParams.Select(par => c.IPointAtParameter(par)));
                Polyline polyline = Rationalise(c, renderMeshOptions);

                Vector lengthVector = new Vector()
                {
                    X = centreLine.End.X - centreLine.Start.X,
                    Y = centreLine.End.Y - centreLine.Start.Y,
                    Z = centreLine.End.Z - centreLine.Start.Z
                };

                Extrusion extr = BH.Engine.Geometry.Create.Extrusion(polyline, lengthVector);
                extr.Capped = capped;

                return(RenderMesh(extr, renderMeshOptions));
            }

            if (centrePolyline == null)
            {
                centrePolyline = pipe.Centreline.IRationalise(renderMeshOptions); // Try rationalising the Curve
            }
            if (centrePolyline != null)
            {
                RenderMesh unifiedMesh = new RenderMesh();

                List <RenderMesh> allMeshes = new List <RenderMesh>();

                for (int i = 0; i < centrePolyline.ControlPoints.Count - 1; i++)
                {
                    Line line = BH.Engine.Geometry.Create.Line(centrePolyline.ControlPoints[i], centrePolyline.ControlPoints[i + 1]);

                    Pipe subPipe = BH.Engine.Geometry.Create.Pipe(line, radius, capped);

                    RenderMesh m = RenderMesh(subPipe, renderMeshOptions);

                    allMeshes.Add(m);

                    // Join the meshes
                    m.Faces.ForEach(f => unifiedMesh.Faces.Add(new Face()
                    {
                        A = f.A + unifiedMesh.Faces.Count,
                        B = f.B + unifiedMesh.Faces.Count,
                        C = f.C + unifiedMesh.Faces.Count,
                        D = f.D + unifiedMesh.Faces.Count
                    }));

                    unifiedMesh.Vertices.AddRange(m.Vertices);
                }

                return(allMeshes.JoinRenderMeshes());
            }

            BH.Engine.Base.Compute.RecordError("RenderMesh for Pipe currently only works with pipes made of linear segments (not curved ICurves).");
            return(null);
        }
Example #12
0
        /***************************************************/
        /**** Private methods                           ****/
        /***************************************************/

        private static string WriteBIMFile(List <IObject> objectsToWrite, string directory = null, string fileName = null, RenderMeshOptions renderMeshOptions = null)
        {
            // --------------------------------------------- //
            //                    Set-up                     //
            // --------------------------------------------- //

            directory = directory ?? Path.Combine("C:\\temp", "BIMFileFormat");

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            fileName = fileName ?? Guid.NewGuid().ToString();
            string bimFilePath = Path.Combine(directory, fileName + ".bim");

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            // --------------------------------------------- //
            //             Compute representation            //
            // --------------------------------------------- //

            List <Mesh> representationMeshes = new List <Mesh>();
            List <Tuple <IObject, Mesh> > objsAndRepresentations = new List <Tuple <IObject, Mesh> >();

            IBHoMObject bHoMObject = null;

            for (int i = 0; i < objectsToWrite.Count; i++)
            {
                IObject obj = objectsToWrite[i];

                Mesh meshRepresentation = null;

                // See if there is a custom BHoM mesh representation for that BHoMObject.
                bHoMObject = obj as IBHoMObject;
                RenderMesh renderMesh = null;

                if (bHoMObject != null)
                {
                    bHoMObject.TryGetRendermesh(out renderMesh);
                }

                if (renderMesh == null && meshRepresentation == null)
                {
                    renderMesh = BH.Engine.Representation.Compute.IRenderMesh(obj, renderMeshOptions);
                }

                if (renderMesh != null) //convert to Mesh
                {
                    meshRepresentation = new Mesh()
                    {
                        Faces = renderMesh.Faces, Vertices = renderMesh.Vertices.Select(v => new oM.Geometry.Point()
                        {
                            X = v.Point.X, Y = v.Point.Y, Z = v.Point.Z
                        }).ToList()
                    }
                }
                ;

                representationMeshes.Add(meshRepresentation);

                if (bHoMObject != null)
                {
                    // Add/update the RenderMesh in the BHoMObject
                    bHoMObject.ISetRendermesh(meshRepresentation);
                    obj = bHoMObject;
                }

                objsAndRepresentations.Add(new Tuple <IObject, Mesh>(obj, meshRepresentation));
            }


            // --------------------------------------------- //
            //                File preparation               //
            // --------------------------------------------- //

            BIMDataExporter exporter = new BIMDataExporter();

            // Prepare default material
            TDR_Material defaultMat = new TDR_Material()
            {
                MaterialArray = new List <float> {
                    1f, 1f, 1f, 1f
                }
            };
            int defaultMatIdx = exporter.AddMaterial(defaultMat.MaterialArray);

            // Prepare transformation matrix
            List <float> transfMatrix = new List <float>
            {
                1, 0, 0, 2,
                0, 1, 0, 2,
                0, 0, 1, 2,
                0, 0, 0, 1
            };

            // Prepare root node
            int rootNodeIdx = exporter.AddNode("root", -1, null);

            // Process the meshes
            for (int i = 0; i < objsAndRepresentations.Count; i++)
            {
                BH.oM.Geometry.Mesh m = representationMeshes[i];
                Tuple <IObject, BH.oM.Geometry.Mesh> objAndRepr = objsAndRepresentations[i];

                // Check if a colour has been specified in the BHoMObject's Fragment
                bHoMObject = objAndRepr.Item1 as IBHoMObject;
                int customMatIdx = defaultMatIdx;
                if (bHoMObject != null)
                {
                    Color?colour = bHoMObject.FindFragment <ColourFragment>()?.Colour;

                    if (colour != null)
                    {
                        Color col = (Color)colour;

                        float r = (float)col.R / 255;
                        float g = (float)col.G / 255;
                        float b = (float)col.B / 255;
                        float a = (float)col.A / 255;

                        TDR_Material customMat = new TDR_Material()
                        {
                            MaterialArray = new List <float> {
                                r, g, b, a
                            }
                        };
                        customMatIdx = exporter.AddMaterial(customMat.MaterialArray);
                    }
                }

                // Convert object representation mesh to a
                Geometry geometry = BH.Adapter.TDrepo.Convert.MeshToGeometry(objAndRepr.Item2, customMatIdx);

                // Add metadata
                Dictionary <string, RepoVariant> metadata = new Dictionary <string, RepoVariant>();

                // Serialize the object
                string serialisedBHoMData = BH.Engine.Serialiser.Convert.ToJson(objAndRepr.Item1);

                // Flatten the JSON in a Dictionary. Nested properties names are concatenated with fullstops.
                Dictionary <string, object> flattenedObj = BH.Engine.Adapters.TDRepo.Compute.FlattenJsonToDictionary(serialisedBHoMData);

                // For each entry in the flattened object, add a metadata with the value.
                flattenedObj.ToList().ForEach(
                    kv =>
                {
                    if (kv.Value is int)
                    {
                        metadata.Add(kv.Key, RepoVariant.Int((int)kv.Value));
                    }
                    else if (kv.Value is double)
                    {
                        metadata.Add(kv.Key, RepoVariant.Double((double)kv.Value));
                    }
                    else if (kv.Value is bool)
                    {
                        metadata.Add(kv.Key, RepoVariant.Boolean((bool)kv.Value));
                    }
                    else
                    {
                        metadata.Add(kv.Key, RepoVariant.String(kv.Value?.ToString()));
                    }
                }
                    );

                metadata.Add("ZippedBHoM", RepoVariant.String(BH.Engine.Serialiser.Convert.ToZip(serialisedBHoMData)));

                //metadata.Add("Area", RepoVariant.Int(1));
                //metadata.Add("Boolean Test", RepoVariant.Boolean(true));
                //metadata.Add("Double", RepoVariant.Double(1.3242524));

                // Add node to exporter.
                exporter.AddNode("mesh" + i, rootNodeIdx, transfMatrix, geometry, metadata);
            }

            exporter.ExportToFile(bimFilePath);

            return(bimFilePath);
        }
Example #13
0
 // Fallback
 private static Polyline Rationalise(this ICurve curve, RenderMeshOptions renderMeshOptions = null)
 {
     BH.Engine.Base.Compute.RecordError($"Could not find a method to rationalise the curve {curve.GetType().Name}. Currently support only Arc and Circle.");
     return(null);
 }
        /***************************************************/
        /**** Public Methods - Graphics                 ****/
        /***************************************************/

        public static BH.oM.Graphics.RenderMesh RenderMesh(this CompositeGeometry compositeGeometry, RenderMeshOptions renderMeshOptions = null)
        {
            if (compositeGeometry == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot compute the mesh of a null composite geometry object.");
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            List <RenderMesh> renderMeshes = new List <RenderMesh>();

            for (int i = 0; i < compositeGeometry.Elements.Count; i++)
            {
                renderMeshes.Add(IRenderMesh(compositeGeometry.Elements[i]));
            }

            return(BH.Engine.Representation.Compute.JoinRenderMeshes(renderMeshes));
        }
Example #15
0
        private static BH.oM.Graphics.RenderMesh BoxRenderMesh(Point centrePoint, double length, double depth, double height, RenderMeshOptions renderMeshOptions = null)
        {
            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            List <RenderPoint> vertices = new List <RenderPoint>();

            // Top face (normal to global z, +)
            //0
            vertices.Add((RenderPoint) new Point()
            {
                X = centrePoint.X + (length / 2.0),
                Y = centrePoint.Y + (depth / 2.0),
                Z = centrePoint.Z + (height / 2.0)
            });

            //1
            vertices.Add((RenderPoint) new Point()
            {
                X = centrePoint.X + (length / -2.0),
                Y = centrePoint.Y + (depth / 2.0),
                Z = centrePoint.Z + (height / 2.0)
            });

            //2
            vertices.Add((RenderPoint) new Point()
            {
                X = centrePoint.X + (length / -2.0),
                Y = centrePoint.Y + (depth / -2.0),
                Z = centrePoint.Z + (height / 2.0)
            });

            //3
            vertices.Add((RenderPoint) new Point()
            {
                X = centrePoint.X + (length / 2.0),
                Y = centrePoint.Y + (depth / -2.0),
                Z = centrePoint.Z + (height / 2.0)
            });

            // Bottom face (normal to global z, -)
            //4
            vertices.Add((RenderPoint) new Point()
            {
                X = centrePoint.X + (length / 2.0),
                Y = centrePoint.Y + (depth / 2.0),
                Z = centrePoint.Z + (height / -2.0)
            });

            //5
            vertices.Add((RenderPoint) new Point()
            {
                X = centrePoint.X + (length / 2.0),
                Y = centrePoint.Y + (depth / -2.0),
                Z = centrePoint.Z + (height / -2.0)
            });

            //6
            vertices.Add((RenderPoint) new Point()
            {
                X = centrePoint.X + (length / -2.0),
                Y = centrePoint.Y + (depth / -2.0),
                Z = centrePoint.Z + (height / -2.0)
            });

            //7
            vertices.Add((RenderPoint) new Point()
            {
                X = centrePoint.X + (length / -2.0),
                Y = centrePoint.Y + (depth / 2.0),
                Z = centrePoint.Z + (height / -2.0)
            });

            List <Face> faces = new List <Face>();

            // Top face (normal to global z, +): 0, 1, 2, 3
            faces.Add(new Face()
            {
                A = 0, B = 1, C = 2, D = 3
            });

            // Bottom face (normal to global z, -): 4, 5, 6, 7
            faces.Add(new Face()
            {
                A = 4, B = 5, C = 6, D = 7
            });

            // Right face (normal to global x, +): 0, 3, 5, 4
            faces.Add(new Face()
            {
                A = 0, B = 3, C = 5, D = 4
            });

            // Left face (normal to global x, -): 2, 1, 7, 6
            faces.Add(new Face()
            {
                A = 2, B = 1, C = 7, D = 6
            });

            // Front face (normal to global y, +): 1, 0, 4, 7
            faces.Add(new Face()
            {
                A = 1, B = 0, C = 4, D = 7
            });

            // Rear face (normal to global y, -): 3, 2, 6, 5
            faces.Add(new Face()
            {
                A = 3, B = 2, C = 6, D = 5
            });

            return(new RenderMesh()
            {
                Faces = faces, Vertices = vertices
            });
        }
Example #16
0
        public static BH.oM.Graphics.RenderMesh RenderMesh(this Sphere sphere, RenderMeshOptions renderMeshOptions = null)
        {
            if (sphere == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot compute the mesh of a null sphere.");
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            BH.Engine.Base.Compute.RecordNote("RenderMesh for sphere still doesn't work properly and needs to be finished. A cube is output instead of a sphere.");

            double radius = sphere.Radius;

            // // - Sphere still doesn't work properly, for now just return a little cube instead of a sphere.
            Cuboid cuboid = BH.Engine.Geometry.Create.Cuboid(BH.Engine.Geometry.Create.CartesianCoordinateSystem(sphere.Centre, BH.Engine.Geometry.Create.Vector(1, 0, 0), BH.Engine.Geometry.Create.Vector(0, 1, 0)), radius, radius, radius);

            return(cuboid.RenderMesh(renderMeshOptions));

            // // - WIP Code for sphere mesh.

            int nLongitude = 6;                  // Number of vertical lines.
            int nLatitude  = nLongitude / 2;     // Number of horizontal lines. A good sphere mesh has about half the number of longitude lines than latitude.

            double DEGS_TO_RAD = Math.PI / 180;
            int    numVertices = 0;

            int    p, s;
            double x, y, z;
            int    nPitch = nLongitude + 1;

            double interLatitudeAngle = (180 / (nLatitude + 1));

            interLatitudeAngle = interLatitudeAngle * DEGS_TO_RAD;
            double interLongitudeAngle = (360 / nLongitude);

            interLongitudeAngle = interLongitudeAngle * DEGS_TO_RAD;
            Point centrePoint = sphere.Centre;

            // ------- Generate all points -------- //

            List <Point> allPoints = new List <Point>();

            Point top = new Point()
            {
                X = sphere.Centre.X, Y = sphere.Centre.Y, Z = sphere.Centre.Z + radius
            };

            allPoints.Add(top);

            for (p = 1; p < nLatitude + 1; p++)     // Generate all "intermediate vertices"
            {
                double pitchAngleFromZ = interLatitudeAngle * p;
                z = centrePoint.Z + radius * Math.Cos(pitchAngleFromZ);

                for (s = 0; s < nLongitude + 1; s++)
                {
                    x = centrePoint.X + radius * Math.Cos(s * interLongitudeAngle);
                    y = centrePoint.Y + radius * Math.Sin(s * interLongitudeAngle);

                    allPoints.Add(new Point()
                    {
                        X = x, Y = y, Z = z
                    });
                }
            }

            Point bottom = new Point()
            {
                X = sphere.Centre.X, Y = sphere.Centre.Y, Z = sphere.Centre.Z - radius
            };

            allPoints.Add(bottom);

            // ------- Generate all faces -------- //

            List <Face> allFaces = new List <Face>();

            // Square faces between intermediate points
            for (int lat = 1; lat < nLatitude; lat++)
            {
                for (int lon = 1; lon < nLongitude + 1; lon++)
                {
                    Face face = new Face()
                    {
                        A = lon * lat + nLongitude * (lat - 1),
                        B = lon * lat + 1 + nLongitude * (lat - 1),
                        C = lon * lat + nLongitude + nLongitude * (lat - 1) + 2,
                        D = lon * lat + nLongitude + nLongitude * (lat - 1) + 1,
                    };
                    allFaces.Add(face);
                }
            }

            //// Triangle faces between top/bottom points and the intermediate points
            //int offLastVerts = 2 + (nLatitude * (nLongitude - 1));
            //for (s = 0; s < nLatitude; s++)
            //{
            //    j = (s == nLatitude - 1) ? -1 : s;
            //    allFaces.Add(new Face() { A = 0, B = (j + 2) + 2, C = (s + 1) + 2 });
            //    allFaces.Add(new Face() { A = 1, B = (s + 1) + offLastVerts, C = (j + 2) + offLastVerts });
            //}
            //return null;

            return(new RenderMesh()
            {
                Faces = allFaces, Vertices = allPoints.Select(pt => (RenderPoint)pt).ToList()
            });
        }
Example #17
0
        public static BH.oM.Graphics.RenderMesh RenderMesh(this Extrusion extrusion, RenderMeshOptions renderMeshOptions = null)
        {
            if (extrusion == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot compute the mesh of a null extrusion.");
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            Line     line     = extrusion.Curve as Line;
            Polyline polyline = extrusion.Curve as Polyline;

            if (line == null && polyline == null)
            {
                polyline = Compute.IRationalise(extrusion.Curve, renderMeshOptions); // try to rationalise the extrusion profile
            }
            if (line == null && polyline == null)
            {
                BH.Engine.Base.Compute.RecordError($"Calling RenderMesh for {nameof(Extrusion)} currently works only if the {nameof(Extrusion.Curve)} is composed of linear segments.");
                return(null);
            }

            List <Face>  faces  = new List <Face>();
            List <Point> points = new List <Point>();

            if (line != null)
            {
                points.Add(new Point()
                {
                    X = line.Start.X, Y = line.Start.Y, Z = line.Start.Z
                });
                points.Add(new Point()
                {
                    X = line.End.X, Y = line.End.Y, Z = line.End.Z
                });
                points.Add(new Point()
                {
                    X = line.End.X + extrusion.Direction.X, Y = line.End.Y + extrusion.Direction.Y, Z = line.End.Z + extrusion.Direction.Z
                });
                points.Add(new Point()
                {
                    X = line.Start.X + extrusion.Direction.X, Y = line.Start.Y + extrusion.Direction.Y, Z = line.Start.Z + extrusion.Direction.Z
                });

                faces.Add(new Face()
                {
                    A = 0, B = 1, C = 2, D = 3
                });

                return(new RenderMesh()
                {
                    Faces = faces, Vertices = points.Cast <RenderPoint>().ToList()
                });
            }

            RenderMesh bottomCap = null;
            RenderMesh topCap    = null;

            if (polyline != null)
            {
                points.AddRange(polyline.ControlPoints);
                points.AddRange(polyline.ControlPoints.Select(p => new Point()
                {
                    X = p.X + extrusion.Direction.X, Y = p.Y + extrusion.Direction.Y, Z = p.Z + extrusion.Direction.Z
                }));

                int faceNo = polyline.ControlPoints.Count() - 1;

                for (int i = 0; i < faceNo; i++)
                {
                    int add = 0;//extrusion.Curve.IIsClosed() ? 1 : 0;

                    faces.Add(new Face()
                    {
                        A = i, B = i + 1, C = polyline.ControlPoints.Count() + (i + 1) + add, D = polyline.ControlPoints.Count() + i + add
                    });
                }

                if (extrusion.Curve.IIsClosed() && extrusion.Capped)
                {
                    Polyline bottomBoundary = extrusion.Curve.IRationalise(renderMeshOptions);

                    if (bottomBoundary == null)
                    {
                        Base.Compute.RecordNote("Mesh of Extrusion caps still not implemented for extrusion defined with a curve of this type.");
                    }
                    else
                    {
                        bottomCap = Create.PlanarSurface(bottomBoundary).RenderMesh(renderMeshOptions);

                        Polyline topBoundary = bottomBoundary.Translate(extrusion.Direction);
                        topCap = Create.PlanarSurface(topBoundary).RenderMesh(renderMeshOptions);
                    }
                }

                RenderMesh renderMesh = new RenderMesh()
                {
                    Vertices = points.Select(pt => (RenderPoint)pt).ToList(), Faces = faces
                };

                if (bottomCap != null)
                {
                    renderMesh = renderMesh.JoinRenderMeshes(bottomCap);
                }

                if (topCap != null)
                {
                    renderMesh = renderMesh.JoinRenderMeshes(topCap);
                }

                return(renderMesh);
            }

            BH.Engine.Base.Compute.RecordError($"Calling RenderMesh for {nameof(Extrusion)} currently works only if the {nameof(Extrusion.Curve)} is composed of linear segments.");
            return(null);
        }
Example #18
0
        public static SpeckleObject SpeckleRepresentation(IBHoMObject bhomObject, RenderMeshOptions renderMeshOptions = null)
        {
            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            SpeckleObject speckleRepresentation = null;

            if (bhomObject is CustomObject)
            {
                return(null);
            }

            // See if the object contains a custom Mesh Representation in its Fragments.
            Mesh       meshRepresentation = null;
            RenderMesh renderMesh         = null;

            if (bhomObject != null)
            {
                RenderMesh renderMeshObj = null;
                bhomObject.TryGetRendermesh(out renderMeshObj);

                if (renderMeshObj != null)
                {
                    meshRepresentation = new Mesh()
                    {
                        Faces = renderMeshObj.Faces, Vertices = renderMeshObj.Vertices.Select(v => v.Point).ToList()
                    }
                }
                ;
            }

            if (renderMesh != null)
            {
                meshRepresentation = new Mesh()
                {
                    Faces = renderMesh.Faces, Vertices = renderMesh.Vertices.Select(v => new oM.Geometry.Point()
                    {
                        X = v.Point.X, Y = v.Point.Y, Z = v.Point.Z
                    }).ToList()
                };
                return(meshRepresentation.ToSpeckle());
            }

            if (meshRepresentation != null)
            {
                return(meshRepresentation.ToSpeckle());
            }

            // See if there is a custom BHoM Geometry representation for that BHoMObject.
            // If so, attempt to convert it to Speckle.
            IGeometry geometricalRepresentation = null;

            try
            {
                geometricalRepresentation = BH.Engine.Representation.Compute.IGeometricalRepresentation(bhomObject, renderMeshOptions.RepresentationOptions);
            }
            catch { }

            // If found, attempt to convert the BHoM Geometrical representation of the object to Speckle geometry.
            if (geometricalRepresentation != null)
            {
                speckleRepresentation = geometricalRepresentation.IToSpeckle();
            }

            // If the convert of the base geometry to Speckle Geometry didn't work,
            // try to obtain a BHoM RenderMesh of the geometrical representation, then convert it to a Speckle mesh.
            if (speckleRepresentation == null)
            {
                try
                {
                    // Do not use the interface method IRenderMesh here. That one re-computes the geometrical representation.
                    renderMesh = BH.Engine.Representation.Compute.RenderMesh(geometricalRepresentation as dynamic);
                }
                catch { }

                if (renderMesh != null)
                {
                    speckleRepresentation = Speckle.Convert.ToSpeckle(renderMesh);
                }
            }

            return(speckleRepresentation);
        }
    }
Example #19
0
        public static BH.oM.Graphics.RenderMesh RenderMesh(this PlanarSurface planarSurface, RenderMeshOptions renderMeshOptions = null)
        {
            if (planarSurface == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot compute the mesh of a null planar surface.");
                return(null);
            }

            renderMeshOptions = renderMeshOptions ?? new RenderMeshOptions();

            Polyline externalBoundary = planarSurface.ExternalBoundary.IRationalise(renderMeshOptions);

            if (externalBoundary == null)
            {
                BH.Engine.Base.Compute.RecordError($"Meshing for {nameof(PlanarSurface)} works only if the {nameof(planarSurface.ExternalBoundary)} is of type {nameof(Polyline)}");
                return(null);
            }

            List <Polyline> internalBoundaries = planarSurface.InternalBoundaries.Select(c => c.IRationalise(renderMeshOptions)).ToList();

            if (internalBoundaries.Count != internalBoundaries.Count)
            {
                BH.Engine.Base.Compute.RecordError($"Meshing for {nameof(PlanarSurface)} works only if all of the {nameof(planarSurface.InternalBoundaries)} are of type {nameof(Polyline)}");
                return(null);
            }

            List <Polyline>   polylines         = BH.Engine.Geometry.Triangulation.Compute.DelaunayTriangulation(externalBoundary, internalBoundaries);
            List <RenderMesh> singleFacesMeshes = new List <RenderMesh>();

            foreach (Polyline poly in polylines)
            {
                RenderMesh singleFaceMesh = new RenderMesh();

                singleFaceMesh.Vertices.AddRange(poly.ControlPoints.Select(p => (RenderPoint)p));
                singleFaceMesh.Faces.Add(new Face()
                {
                    A = 0, B = 1, C = 2
                });

                singleFacesMeshes.Add(singleFaceMesh);
            }

            return(singleFacesMeshes.JoinRenderMeshes());
        }
Example #20
0
 // Fallback
 private static BH.oM.Graphics.RenderMesh RenderMesh(this IGeometry geom, RenderMeshOptions renderMeshOptions = null)
 {
     throw new MissingMethodException($"Could not find a method to compute the {nameof(BH.oM.Graphics.RenderMesh)} of {geom.GetType().Name}.");
 }