예제 #1
0
 public void ApplyOrthographicCentered()
 {
     ViewMatrix             = Matrix4.View(Position, LookAtPosition, UpPosition - Position);
     ProjectionMatrix       = Matrix4.OrthographicCentered(ViewPort.Size.Width, ViewPort.Size.Height, Near, Far);
     TransformMatrix        = ViewMatrix.Multiply(ProjectionMatrix);
     TransformInverseMatrix = TransformMatrix.Invert();
 }
예제 #2
0
 public void Apply()
 {
     ViewMatrix             = Matrix4.View(Position, LookAtPosition, UpPosition - Position);
     ProjectionMatrix       = Matrix4.Perspective(Fov, float.IsNaN(Aspect) ? ViewPort.AspectRatio : Aspect, Near, Far);
     TransformMatrix        = ViewMatrix.Multiply(ProjectionMatrix);
     TransformInverseMatrix = TransformMatrix.Invert();
 }
예제 #3
0
        public static AnalysisGrid AnalysisGrid(this Polyline externalBoundary, List <Polyline> innerBoundaries = null, int id = -1, string name = "", double gridSpacing = 0.2, double edgeOffset = 0.1, double pointOffset = 0.765)
        {
            innerBoundaries = innerBoundaries ?? new List <Polyline>();

            if (id == -1)
            {
                BH.Engine.Reflection.Compute.RecordWarning("ID has not been set to a valid ID, this may cause errors in processing results from this AnalysisGrid if it cannot be uniquely identified later");
            }
            if (name == "")
            {
                BH.Engine.Reflection.Compute.RecordWarning("Name has not been set to a valid Name, this may cause confusion in reading results from this AnalysisGrid if it cannot be attributed to the model later");
            }

            //Get the normal from the external boundary
            Vector surfaceNormal = externalBoundary.Normal().Normalise();

            //Offset the external boundary inwards by the edgeOffset amount
            Polyline offsetCurve = externalBoundary.Offset(-edgeOffset);

            //Offset the opening curves by the edgeOffset amount
            List <Polyline> offsetInner = new List <Polyline>();

            foreach (Polyline p in innerBoundaries)
            {
                offsetInner.Add(p.Offset(edgeOffset));
            }

            //Project all of the geometry to the XY plane
            Vector          zVector          = BH.Engine.Geometry.Create.Vector(0, 0, 1);
            Plane           curvePlane       = offsetCurve.IFitPlane();
            Vector          curvePlaneNormal = curvePlane.Normal;
            List <Point>    vertices         = offsetCurve.IDiscontinuityPoints();
            Point           referencePoint   = vertices.Min();
            Point           xyReferencePoint = BH.Engine.Geometry.Create.Point(referencePoint.X, referencePoint.Y, 0);
            Vector          translateVector  = xyReferencePoint - referencePoint;
            Vector          rotationVector   = curvePlaneNormal.CrossProduct(zVector).Normalise();
            double          rotationAngle    = curvePlaneNormal.Angle(zVector);
            TransformMatrix transformMatrix  = BH.Engine.Geometry.Create.RotationMatrix(vertices.Min(), rotationVector, rotationAngle);

            Polyline        transformedCurve = offsetCurve.Transform(transformMatrix).Translate(translateVector);
            List <Polyline> transformedHoles = new List <Polyline>();

            foreach (Polyline h in offsetInner)
            {
                transformedHoles.Add(h.Transform(transformMatrix).Translate(translateVector));
            }

            //Create a grid of points across the flattened curves
            List <Point> vs = transformedCurve.IDiscontinuityPoints();

            List <double> xValues = vs.Select(x => x.X).ToList();
            List <double> yValues = vs.Select(x => x.Y).ToList();

            double gridSizeX = Math.Round((xValues.Max() - xValues.Min()) / gridSpacing);
            double gridSizeY = Math.Round((yValues.Max() - yValues.Min()) / gridSpacing);

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

            for (int i = 0; i < gridSizeX; i++)
            {
                for (int j = 0; j < gridSizeY; j++)
                {
                    pts.Add(new Point
                    {
                        X = xValues.Min() + i * gridSpacing + 0.5 * gridSpacing,
                        Y = yValues.Min() + j * gridSpacing + 0.5 * gridSpacing
                    });
                }
            }

            //Remove points within hole curves
            List <Point> ptsCleaned = new List <Point>();

            foreach (Point pt in pts)
            {
                Polyline containedByHole = transformedHoles.Where(x => x.IsContaining(new List <Point> {
                    pt
                })).FirstOrDefault();

                if (containedByHole == null)
                {
                    //Point is not contained by any opening
                    if (transformedCurve.IsContaining(new List <Point> {
                        pt
                    }))
                    {
                        ptsCleaned.Add(pt); //Point is contained by the external boundary
                    }
                }
            }

            //Retransform the analsyis points back to their original plane
            List <Point> ptsCleanedRetransformed = new List <Point>();

            foreach (Point p in ptsCleaned)
            {
                ptsCleanedRetransformed.Add(p.Translate(translateVector.Reverse()).Transform(transformMatrix.Invert()).Translate(surfaceNormal * pointOffset));
            }

            //Create the nodes for the grid
            List <Node> nodes = new List <Node>();

            for (int x = 0; x < ptsCleanedRetransformed.Count; x++)
            {
                nodes.Add(new Node {
                    ID = (x + 1), Position = ptsCleanedRetransformed[x]
                });
            }

            AnalysisGrid grid = new AnalysisGrid(externalBoundary, new ReadOnlyCollection <Polyline>(innerBoundaries), new ReadOnlyCollection <Node>(nodes), id);

            grid.Name = name;

            return(grid);
        }
        public static List <Polyline> DelaunayTriangulation(this Polyline outerCurve, List <Polyline> innerCurves = null, double offsetDistance = -0.001, bool conformingDelaunay = true)
        {
            if (outerCurve == null)
            {
                BH.Engine.Base.Compute.RecordError("Cannot perform Delaunay Triangulation on an outer curve that is set to null.");
                return(new List <Polyline>());
            }

            // Create a zero length list if no holes input
            if (innerCurves == null)
            {
                innerCurves = new List <Polyline>();
            }

            double area = outerCurve.Area();

            for (int x = 0; x < innerCurves.Count; x++)
            {
                Polyline pLine = outerCurve.BooleanDifference(new List <Polyline> {
                    innerCurves[x]
                })[0];

                if (pLine.Area() != area)
                {
                    //The boolean difference returned a different polyline - offset this inner curve
                    innerCurves[x] = innerCurves[x].Offset(offsetDistance);
                }
            }

            // Get the transformation matrix
            Plane           plane           = outerCurve.IFitPlane();
            Vector          normal          = plane.Normal;
            List <Point>    vertices        = outerCurve.IDiscontinuityPoints();
            Point           refPoint        = vertices.Min();
            Point           refPointP       = BH.Engine.Geometry.Create.Point(refPoint.X, refPoint.Y, 0);
            Vector          zVector         = BH.Engine.Geometry.Create.Vector(0, 0, 1);
            Vector          rotationVector  = normal.CrossProduct(zVector).Normalise();
            double          rotationAngle   = normal.Angle(zVector);
            TransformMatrix transformMatrix = BH.Engine.Geometry.Create.RotationMatrix(vertices.Min(), rotationVector, rotationAngle);

            // Get the translation vector
            Vector translateVector = refPointP - refPoint;

            // Transform the original input curve/s
            Polyline        transformedCurve = Modify.Translate(outerCurve.Transform(transformMatrix), translateVector);
            List <Polyline> transformedHole  = new List <Polyline>();

            foreach (Polyline h in innerCurves)
            {
                if (h.IsCoplanar(outerCurve))
                {
                    transformedHole.Add(Modify.Translate(h.Transform(transformMatrix), translateVector));
                }
            }

            // Convert geometry to Triangle inputs
            TriangleNet.Geometry.Polygon       parentPolygon  = new TriangleNet.Geometry.Polygon();
            List <TriangleNet.Geometry.Vertex> parentVertices = new List <TriangleNet.Geometry.Vertex>();

            foreach (Point point in transformedCurve.IDiscontinuityPoints())
            {
                parentPolygon.Add(new TriangleNet.Geometry.Vertex(point.X, point.Y));
                parentVertices.Add(new TriangleNet.Geometry.Vertex(point.X, point.Y));
            }
            TriangleNet.Geometry.Contour parentContour = new TriangleNet.Geometry.Contour(parentVertices);
            parentPolygon.Add(parentContour);

            foreach (Polyline h in transformedHole)
            {
                List <TriangleNet.Geometry.Vertex> childVertices = new List <TriangleNet.Geometry.Vertex>();
                foreach (Point point in h.IDiscontinuityPoints())
                {
                    childVertices.Add(new TriangleNet.Geometry.Vertex(point.X, point.Y));
                }
                TriangleNet.Geometry.Contour childContour = new TriangleNet.Geometry.Contour(childVertices);
                Point childCentroid = h.PointInRegion();
                parentPolygon.Add(childContour, new TriangleNet.Geometry.Point(childCentroid.X, childCentroid.Y));
            }

            // Triangulate
            TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions()
            {
                ConformingDelaunay = conformingDelaunay,
            };
            TriangleNet.Meshing.QualityOptions quality = new TriangleNet.Meshing.QualityOptions()
            {
            };
            TriangleNet.Mesh mesh = (TriangleNet.Mesh)TriangleNet.Geometry.ExtensionMethods.Triangulate(parentPolygon, options, quality);

            // Convert triangulations back to BHoM geometry
            List <Polyline> translatedPolylines = new List <Polyline>();

            foreach (var face in mesh.Triangles)
            {
                // List points defining the triangle
                List <Point> pts = new List <Point>();
                pts.Add(BH.Engine.Geometry.Create.Point(face.GetVertex(0).X, face.GetVertex(0).Y));
                pts.Add(BH.Engine.Geometry.Create.Point(face.GetVertex(1).X, face.GetVertex(1).Y));
                pts.Add(BH.Engine.Geometry.Create.Point(face.GetVertex(2).X, face.GetVertex(2).Y));
                pts.Add(pts.First());
                translatedPolylines.Add(BH.Engine.Geometry.Create.Polyline(pts));
            }

            // Translate back to original plane
            List <Polyline> meshPolylines = new List <Polyline>();

            foreach (Polyline pl in translatedPolylines)
            {
                TransformMatrix matrixTransposed = transformMatrix.Invert();
                Polyline        meshPolyline     = pl.Translate(-translateVector).Transform(transformMatrix.Invert());
                meshPolylines.Add(meshPolyline);
            }

            return(meshPolylines);
        }
예제 #5
0
        public static Point BottomLeft(this Polyline polyline, List <Panel> panelsAsSpace)
        {
            if (polyline == null)
            {
                BH.Engine.Reflection.Compute.RecordError("Cannot query the bottom left corner of a null polyline.");
                return(null);
            }

            if (panelsAsSpace == null)
            {
                BH.Engine.Reflection.Compute.RecordError("Cannot query the bottom left corner of a polyline without knowing the space it belongs to.");
                return(null);
            }

            Vector normal = polyline.Normal();

            if (!polyline.NormalAwayFromSpace(panelsAsSpace))
            {
                normal = polyline.Flip().Normal();
            }
            if (normal == null)
            {
                return(null);
            }

            Point centre = polyline.Centroid();

            if (centre == null)
            {
                centre = polyline.ControlPoints.CullDuplicates().Average();
            }

            Line line = new Line
            {
                Start = centre,
                End   = centre.Translate(normal),
            };

            List <Point> pnts = polyline.DiscontinuityPoints();

            bool            wasFlat   = false;
            TransformMatrix transform = null;

            if (pnts.Min(x => Math.Round(x.Z, 6)) == pnts.Max(x => Math.Round(x.Z, 6)))
            {
                //All the points are on the same Z level - we're looking at a floor/roof
                transform = BH.Engine.Geometry.Create.RotationMatrix(polyline.Centroid(), new Vector {
                    X = 1, Y = 0, Z = 0
                }, 1.5708);
                polyline = polyline.Transform(transform);
                pnts     = polyline.ControlPoints;
                line.End = line.Start.Translate(polyline.Normal());
                wasFlat  = true;
            }

            Point leftMost = null;

            foreach (Point p in pnts)
            {
                if (IsLeft(line, p) && (leftMost == null || leftMost.Z > p.Z))
                {
                    leftMost = p;
                }
            }

            if (wasFlat && leftMost != null)
            {
                leftMost = leftMost.Transform(transform.Invert());
            }

            return(leftMost);
        }
예제 #6
0
        public static Point BottomRight(this Polyline polyline, List <Panel> panelsAsSpace)
        {
            Vector normal = polyline.Normal();

            if (!polyline.NormalAwayFromSpace(panelsAsSpace))
            {
                normal = polyline.Flip().Normal();
            }

            Point centre = polyline.Centroid();

            if (centre == null)
            {
                centre = polyline.Centre();
            }

            if (normal == null)
            {
                return(null);
            }

            Line line = new Line
            {
                Start = centre,
                End   = centre.Translate(normal),
            };

            List <Point> pnts = polyline.DiscontinuityPoints();

            bool            wasFlat   = false;
            TransformMatrix transform = null;

            if (pnts.Min(x => Math.Round(x.Z, 6)) == pnts.Max(x => Math.Round(x.Z, 6)))
            {
                //All the points are on the same Z level - we're looking at a floor/roof
                transform = BH.Engine.Geometry.Create.RotationMatrix(polyline.Centroid(), new Vector {
                    X = 1, Y = 0, Z = 0
                }, 1.5708);
                polyline = polyline.Transform(transform);
                pnts     = polyline.ControlPoints;
                line.End = line.Start.Translate(polyline.Normal());
                wasFlat  = true;
            }

            Point rightMost = null;

            foreach (Point p in pnts)
            {
                if (!IsLeft(line, p) && (rightMost == null || rightMost.Z > p.Z))
                {
                    rightMost = p;
                }
            }

            if (wasFlat && rightMost != null)
            {
                rightMost = rightMost.Transform(transform.Invert());
            }

            return(rightMost);
        }