public static SurfaceComponentGeometry CreateExtrudedPolygonCapGeometry(
        float radius, float height, int segmentP, int segmentH, float topRatio = 1, int surfaceGroup = 0, RenderGeometry.FaceType faceType = RenderGeometry.FaceType.Smooth,
        bool splitBoundary = false)
    {
        if (topRatio == 0)
        {
            return(CreateConeCapGeometry(radius, height, segmentP, segmentH, 0, surfaceGroup, faceType, splitBoundary));
        }
        if (topRatio == 1 && height == 0)
        {
            return(CreateRegularPolygonGeometry(radius, segmentP, surfaceGroup, RenderGeometry.FaceType.Polygonal, true));
        }

        StructureGeometry structure = new StructureGeometry();

        SurfaceComponentGeometry upperCap = CreateRegularPolygonGeometry(radius * topRatio, segmentP, surfaceGroup + 1);
        SurfaceComponentGeometry side     = CreateConeSideGeometry(radius, radius * topRatio, height, segmentP, segmentH, 0, false, surfaceGroup, faceType);

        side.ApplyOffset(Vector3.up * (height / 2));

        Vertex cornerUp   = structure.CreateVertex(new Vector3(radius * topRatio, height, 0));
        Vertex cornerDown = structure.CreateVertex(new Vector3(radius, 0, 0));

        structure.CreateFace(side, false, cornerUp, cornerUp, cornerDown, cornerDown);
        structure.CreateFace(upperCap, true, cornerUp);

        SurfaceComponentGeometry geometry = new SurfaceComponentGeometry(structure.Build());

        geometry.DefineBoundaries(structure.GetBuiltVertex(cornerDown));
        if (splitBoundary)
        {
            geometry.SplitBoundaries();
        }
        return(geometry);
    }
    public static SurfaceComponentGeometry CreateStarConvexPolygonGeometry(List <Vector3> vertices, int surfaceGroup = 0, RenderGeometry.FaceType faceType = RenderGeometry.FaceType.Polygonal)
    {
        SurfaceComponentGeometry geometry = new SurfaceComponentGeometry();
        bool normalRequired = (faceType != RenderGeometry.FaceType.Polygonal && faceType != RenderGeometry.FaceType.Triangular);

        foreach (Vector3 vertex in vertices)
        {
            geometry.CreateVertex(vertex);
        }
        for (int i = 1; i < vertices.Count - 1; i++)
        {
            Face f = geometry.CreateFace(geometry.vertices[0], geometry.vertices[i], geometry.vertices[i + 1]);
            f.surfaceGroup = surfaceGroup;
            geometry.SetFaceType(f, faceType);
        }
        if (normalRequired)
        {
            Vector3 normal = Vector3.Cross(geometry.vertices[1].p - geometry.vertices[0].p, geometry.vertices[vertices.Count - 1].p - geometry.vertices[0].p).normalized;
            foreach (Halfedge e in geometry.halfedges)
            {
                geometry.SetNormal(e, normal);
            }
        }
        geometry.DefineBoundaries(geometry.vertices[0]);
        geometry.SplitBoundaries();
        return(geometry);
    }
    public static SurfaceComponentGeometry CreateRegularPolygonGeometry(
        float radius, int segmentP, int surfaceGroup = 0, RenderGeometry.FaceType faceType = RenderGeometry.FaceType.Polygonal, bool splitBoundary = false)
    {
        SurfaceComponentGeometry geometry = new SurfaceComponentGeometry();
        bool normalRequired = (faceType != RenderGeometry.FaceType.Polygonal && faceType != RenderGeometry.FaceType.Triangular);

        float dth = 2 * Mathf.PI / segmentP;

        for (int i = 0; i < segmentP; i++)
        {
            geometry.CreateVertex(new Vector3(radius * Mathf.Cos(dth * i), 0, -radius * Mathf.Sin(dth * i)));
        }

        Face f = geometry.CreateFace(geometry.vertices.ToArray());

        f.surfaceGroup = surfaceGroup;
        geometry.SetFaceType(f, faceType);

        if (normalRequired)
        {
            foreach (Halfedge e in geometry.halfedges)
            {
                geometry.SetNormal(e, Vector3.up);
            }
        }
        geometry.DefineBoundaries(geometry.vertices[0]);
        if (splitBoundary)
        {
            geometry.SplitBoundaries();
        }
        return(geometry);
    }
示例#4
0
    public static SurfaceComponentGeometry CreateTrianglesCombinedRegularPolygonGeometry(float radius, int segmentP, Func <SurfaceComponentGeometry> triangleSurfaceComponentProvider)
    {
        SurfaceComponentGeometry polygonGeometry = SurfaceComponentGeometries.CreateFanCapGeometry(radius, segmentP, 1);

        polygonGeometry.SplitBoundaries();
        List <Vertex> corners = polygonGeometry.corners;

        var structure = new StructureGeometry(polygonGeometry);

        structure.faces.ForEach(f => structure.SetFaceComponent(f, triangleSurfaceComponentProvider(), true));
        var geometry = new SurfaceComponentGeometry(structure.Build());

        geometry.DefineBoundaries(corners.Select(structure.GetBuiltVertex).ToArray());

        return(geometry);
    }
    public static SurfaceComponentGeometry CreateConeCapGeometry(
        float radius, float height, int segmentP, int segmentR, float cutAngle = 0, int surfaceGroup = 0, RenderGeometry.FaceType faceType = RenderGeometry.FaceType.Smooth,
        bool splitBoundary = false)
    {
        SurfaceComponentGeometry geometry = new SurfaceComponentGeometry();
        bool normalRequired  = (faceType != RenderGeometry.FaceType.Polygonal && faceType != RenderGeometry.FaceType.Triangular);
        bool tangentRequired = (faceType == RenderGeometry.FaceType.Directinal1 || faceType == RenderGeometry.FaceType.Directinal2);

        int   n          = cutAngle > 0 ? segmentP + 1 : segmentP;
        float deltaAngle = (2 * Mathf.PI - cutAngle) / segmentP;

        float Angle(float th) => cutAngle + deltaAngle * th;

        for (int rr = 0; rr < segmentR; rr++)
        {
            for (int th = 0; th < n; th++)
            {
                float r = radius * (segmentR - rr) / segmentR;
                float h = height * rr / segmentR;
                geometry.CreateVertex(new Vector3(r * Mathf.Cos(Angle(th)), h, -r * Mathf.Sin(Angle(th))));
            }
        }
        Vertex vertice(int rr, int th) => geometry.vertices[rr * n + th];

        Vertex center = geometry.CreateVertex(new Vector3(0, height, 0));

        for (int rr = 0; rr < segmentR - 1; rr++)
        {
            for (int th = 0; th < segmentP; th++)
            {
                int  th2 = (th + 1) % n;
                Face f   = geometry.CreateFace(vertice(rr, th), vertice(rr, th2), vertice(rr + 1, th2), vertice(rr + 1, th));
                if (tangentRequired)
                {
                    List <Halfedge> edges = f.edges;
                    geometry.SetTangent(edges[1], -edges[1].vector.normalized);
                    geometry.SetTangent(edges[3], -edges[3].vector.normalized);
                    geometry.SetTangent(edges[0], new Vector3(Mathf.Sin(Angle(th2)), 0, Mathf.Cos(Angle(th2))));
                    geometry.SetTangent(edges[2], new Vector3(-Mathf.Sin(Angle(th)), 0, -Mathf.Cos(Angle(th))));
                    if (rr == 0)
                    {
                        geometry.SetTangent(edges[0].opposite, new Vector3(-Mathf.Sin(Angle(th)), 0, -Mathf.Cos(Angle(th))));
                    }
                }
            }
        }
        for (int th = 0; th < segmentP; th++)
        {
            int  th2 = (th + 1) % n;
            Face f   = geometry.CreateFace(vertice(segmentR - 1, th), vertice(segmentR - 1, th2), center);
            if (tangentRequired)
            {
                List <Halfedge> edges = f.edges;
                geometry.SetTangent(edges[1], -edges[1].vector.normalized);
                geometry.SetTangent(edges[2], -edges[2].vector.normalized);
                geometry.SetTangent(edges[0], new Vector3(Mathf.Sin(Angle(th2)), 0, Mathf.Cos(Angle(th2))));
            }
        }
        foreach (Face f in geometry.faces)
        {
            f.surfaceGroup = surfaceGroup;
            geometry.SetFaceType(f, faceType);
        }

        if (normalRequired)
        {
            if (height == 0)
            {
                foreach (Halfedge e in geometry.halfedges)
                {
                    geometry.SetNormal(e, Vector3.up);
                }
            }
            else
            {
                for (int rr = 0; rr < segmentR; rr++)
                {
                    for (int th = 0; th < n; th++)
                    {
                        geometry.SetNormal(vertice(rr, th), new Vector3(Mathf.Cos(Angle(th)), radius / height, -Mathf.Sin(Angle(th))).normalized, surfaceGroup);
                    }
                }
                foreach (Halfedge e in center.edges)
                {
                    geometry.SetNormal(e, Vector3.Cross(e.vector, e.next.vector).normalized);
                }
            }
        }

        if (cutAngle == 0)
        {
            geometry.DefineBoundaries(vertice(0, 0));
        }
        else
        {
            geometry.DefineBoundaries(vertice(0, 0), vertice(0, n - 1), center);
        }
        if (splitBoundary)
        {
            geometry.SplitBoundaries();
        }
        return(geometry);
    }