public static RenderGeometry CreateCubeFrameGeometry(float size, float ratio)
    {
        RenderGeometry geometry = new RenderGeometry();

        var corners = new Dictionary <IntVector3, Vertex>();
        var lengths = new Dictionary <int, float> {
            [-2] = -size / 2, [-1] = -size / 2 * ratio, [1] = size / 2 * ratio, [2] = size / 2
        };

        foreach (int x in lengths.Keys)
        {
            foreach (int y in lengths.Keys)
            {
                foreach (int z in lengths.Keys)
                {
                    corners[Key(x, y, z)] = geometry.CreateVertex(new Vector3(lengths[x], lengths[y], lengths[z]));
                }
            }
        }

        foreach (IntVector3[] keys in Combine(
                     FaceSymmetryGroup("211", Key(2, 1, 1), Key(2, 2, 1), Key(2, 2, 2), Key(2, 1, 2)),
                     FaceSymmetryGroup("210", Key(2, 1, -1), Key(2, 2, -1), Key(2, 2, 1), Key(2, 1, 1)),
                     FaceSymmetryGroup("210", Key(1, 1, -1), Key(2, 1, -1), Key(2, 1, 1), Key(1, 1, 1))))
        {
            geometry.CreateFace(keys.Select(i => corners[i]).ToArray());
        }
        return(geometry);
    }
    private Vector3 CalculateVertexPosition(Halfedge edge1, Halfedge edge2, RenderGeometry geometry)
    {
        Vector3 origin1 = CalculateShiftedEdgeToPosition(edge1, geometry);
        Vector3 origin2 = CalculateShiftedEdgeFromPosition(edge2, geometry);

        return(CalculateApproximateIntersection(origin1, edge1.vector, origin2, edge2.vector));
    }
    public static RenderGeometry CreateCuboctahedronGeometry(float size, float ratio)
    {
        if (ratio <= 0)
        {
            return(CreateTetrahedronGeometry(size, 1));
        }
        if (ratio >= 1)
        {
            RenderGeometry result = CreateTetrahedronGeometry(size, 1);
            result.ApplyRotation(Quaternion.AngleAxis(90, Vector3.up));
            return(result);
        }

        RenderGeometry geometry = new RenderGeometry();

        var corners = new Dictionary <IntVector3, Vertex>();

        foreach (var symmetry in Symmetry.SymmetryGroup("110"))
        {
            IntVector3 key      = symmetry.Apply(Key(1, 1, 0));
            Vector3    position = symmetry.Apply(Vec(1, 1, (1 - ratio * 2) * (symmetry.isNegative ? -1 : 1)) * (size / 2));
            corners[key] = geometry.CreateVertex(position);
        }
        foreach (IntVector3[] keys in Combine(
                     FaceSymmetryGroup("100", Key(1, 0, -1), Key(1, 1, 0), Key(1, 0, 1), Key(1, -1, 0)),
                     FaceSymmetryGroup("111", Key(1, 1, 0), Key(0, 1, 1), Key(1, 0, 1))))
        {
            geometry.CreateFace(keys.Select(key => corners[key]).ToArray());
        }
        return(geometry);
    }
    public void Apply(RenderGeometry geometry)
    {
        if (curvature == 0)
        {
            return;
        }

        Vector3 dir1 = Vector3.Cross(direction, axis).normalized;
        Vector3 dir2 = Vector3.Cross(axis, dir1).normalized;
        Vector3 dir3 = axis.normalized;

        Vector3 transform(Vector3 pos, out Matrix4x4 localTransform)
        {
            Vector3 v  = pos - pivot;
            float   v1 = Vector3.Dot(v, dir1);
            float   v2 = Vector3.Dot(v, dir2);
            float   v3 = Vector3.Dot(v, dir3);

            float sin = Mathf.Sin(v1 * curvature);
            float cos = Mathf.Cos(v1 * curvature);
            float v1t = sin / curvature - v2 * sin;
            float v2t = (1 - cos) / curvature + v2 * cos;

            localTransform = Matrix4x4.Rotate(Quaternion.AngleAxis(v1 * curvature * Mathf.Rad2Deg, dir3));
            return(dir1 * v1t + dir2 * v2t + dir3 * v3);
        }

        geometry.ApplyPositionTransform(transform);
    }
示例#5
0
        private RenderGeometry ReplaceAllFace(RenderGeometry original, Func <Face, SurfaceComponentGeometry> surfaceProvider)
        {
            var structure = new StructureGeometry(original);

            structure.faces.ForEach(f => structure.SetFaceComponent(f, surfaceProvider(f), true));
            return(structure.Build());
        }
    // Should only build once!
    public RenderGeometry Build()
    {
        RenderGeometry g = new RenderGeometry();

        foreach (Face f in faces)
        {
            g.CombineGeometry(surfaceComponents[f]);
        }
        foreach (Halfedge e in halfedges)
        {
            if (connections.ContainsKey(e) && connections.ContainsKey(e.opposite))
            {
                List <Halfedge> list1 = connections[e];
                List <Halfedge> list2 = connections[e.opposite];
                if (list1.Count != list2.Count)
                {
                    throw new Exception("Cannot connect two surface blocks, segment count doesn't match.");
                }
                for (int i = 0; i < list1.Count; i++)
                {
                    g.ConnectEdges(list1[i], list2[list1.Count - 1 - i]);
                }
                connections.Remove(e);
                connections.Remove(e.opposite);
            }
        }
        return(g);
    }
    public static RenderGeometry CreateRhombicuboctahedronGeometry(float size, float ratio)
    {
        if (ratio <= 0)
        {
            return(CreateCubeGeometry(Vector3.one * size, new int[] { 1, 1, 1 }));
        }
        if (ratio >= 1)
        {
            return(CreateOctahedronGeometry(size, 1));
        }

        RenderGeometry geometry = new RenderGeometry();

        var corners = new Dictionary <IntVector3, Vertex>();

        foreach (var keyAndPosition in VertexSymmetryGroup("211", Key(2, 1, 1), Vec(1, 1 - ratio, 1 - ratio) * (size / 2)))
        {
            corners[keyAndPosition.Key] = geometry.CreateVertex(keyAndPosition.Value);
        }
        foreach (IntVector3[] keys in Combine(
                     FaceSymmetryGroup("100", Key(2, -1, -1), Key(2, 1, -1), Key(2, 1, 1), Key(2, -1, 1)),
                     FaceSymmetryGroup("110", Key(2, 1, -1), Key(1, 2, -1), Key(1, 2, 1), Key(2, 1, 1)),
                     FaceSymmetryGroup("111", Key(2, 1, 1), Key(1, 2, 1), Key(1, 1, 2))))
        {
            geometry.CreateFace(keys.Select(key => corners[key]).ToArray());
        }
        return(geometry);
    }
    public static RenderGeometry CreateIcosidodecahedronGeometry(float size)
    {
        RenderGeometry geometry = new RenderGeometry();

        float goldenRatio = (1 + Mathf.Sqrt(5)) / 2;
        float dL          = size / 2;
        float dM          = dL / 2;
        float dS          = dM / goldenRatio;
        float dL2         = Mathf.Lerp(dL, dS * 2, 0.5f);

        var corners = new Dictionary <IntVector3, Vertex>();

        foreach (var keyAndPosition in Combine(
                     VertexSymmetryGroup("100", Key(2, 0, 0), Vec(dL, 0, 0)),
                     VertexSymmetryGroup("211", Key(2, 1, 1), Vec(dL2, dS, dM))))
        {
            corners[keyAndPosition.Key] = geometry.CreateVertex(keyAndPosition.Value);
        }
        foreach (IntVector3[] keys in Combine(
                     FaceSymmetryGroup("101", Key(2, 0, 0), Key(2, 1, 1), Key(2, -1, 1)),
                     FaceSymmetryGroup("111", Key(2, 1, 1), Key(1, 2, 1), Key(1, 1, 2)),
                     FaceSymmetryGroup("110", Key(1, 2, 1), Key(2, 1, 1), Key(2, 0, 0), Key(2, 1, -1), Key(1, 2, -1))))
        {
            geometry.CreateFace(keys.Select(key => corners[key]).ToArray());
        }
        return(geometry);
    }
示例#9
0
        /***************************************************/

        public static object ToRhino(this RenderGeometry renderGeo)
        {
            if (renderGeo.Geometry == null)
            {
                return(null);
            }

            return(ToRhino(renderGeo.Geometry as dynamic));
        }
示例#10
0
        /***************************************************/
        /**** Private Method                            ****/
        /***************************************************/

        private bool SetGeometry()
        {
            ResetPreviewMeshes();   //Clears cashed preview meshes and resets preview flag.

            if (Value == null)
            {
                m_IsMeshPreviewable = false;
                return(true);
            }
            else if (Value is IRender)
            {
                m_RhinoGeometry = (Value as IRender).IToRhino();
                m_Color         = (Value as IRender).Colour;
                BH.oM.Graphics.Texture texture = null;

                if (Value is RenderGeometry)
                {
                    RenderGeometry renderGeom = Value as RenderGeometry;
                    m_Geometry  = renderGeom.Geometry;
                    m_thickness = renderGeom.EdgeThickness;
                    texture     = renderGeom.SurfaceColour;
                }
                else if (Value is RenderCurve)
                {
                    m_thickness = (Value as RenderCurve).Thickness;
                    m_Geometry  = (Value as RenderCurve).Curve;
                }

                if (texture != null)
                {
                    m_PreviewMaterial = texture.ToRhino();
                }
                else
                {
                    double transparency = (255 - m_Color.A) / (double)255;
                    m_PreviewMaterial = new Rhino.Display.DisplayMaterial(m_Color, transparency);
                }
                return(true);
            }
            else if (Value is BHoMObject)
            {
                m_Geometry      = (Value as BHoMObject).IGeometry();
                m_RhinoGeometry = m_Geometry.IToRhino();
                return(true);
            }
            else if (Value is IGeometry)
            {
                m_Geometry      = Value as IGeometry;
                m_RhinoGeometry = m_Geometry.IToRhino();
                return(true);
            }
            else
            {
                m_IsMeshPreviewable = false;
                return(false);
            }
        }
示例#11
0
 private bool IsValidEdge(Halfedge edge, RenderGeometry geometry)
 {
     if (edge.isBoundary || edge.opposite.isBoundary)
     {
         return(false);
     }
     return
         (CalculateEdgeAngleDegree(edge, geometry) >= angleThreshold ||
          CalculateEdgeAngleDegree(edge.opposite, geometry) >= angleThreshold);
 }
        private RenderGeometry BuildTileBaseGeometry()
        {
            var geometry = new RenderGeometry();

            parent.tile.face.edges.ForEach(e => geometry.CreateVertex(e.vertex.p - parent.faceCenter));
            geometry.CreateFace(geometry.vertices.ToArray());

            new FaceCurving(BASE_CURVATURE).Apply(geometry);
            return(geometry);
        }
        private RenderGeometry BuildTileBaseColliderGeometry()
        {
            RenderGeometry geometry1 = BuildTileBaseGeometry();
            RenderGeometry geometry2 = BuildTileBaseGeometry();

            geometry2.ApplyScale(0.5f * Vector3.one);
            geometry2.ApplyOffset(-0.01f * parent.faceNormal);
            geometry1.CombineGeometry(geometry2);

            return(geometry1);
        }
示例#14
0
 private Vector3 CalculateShiftedEdgeFromPosition(Halfedge edge, RenderGeometry geometry)
 {
     if (edge.isBoundary || edge.opposite.isBoundary)
     {
         return(edge.opposite.vertex.p);
     }
     else
     {
         float shiftedDistance = smoothRadius * Mathf.Tan(CalculateEdgeAngleDegree(edge.opposite, geometry) * Mathf.Deg2Rad / 2);
         return(edge.opposite.vertex.p + Vector3.Cross(geometry.GetEffectiveNormal(edge.prev), edge.vector).normalized *shiftedDistance);
     }
 }
示例#15
0
        public DumpRenderGeometryCommand(GameCache cache, RenderGeometry geometry, string title = "") :
            base(true,

                 $"Dump{title}RenderGeometry",
                 $"Dumps {title.ToLower()} render geometry in ascii format.",

                 $"Dump{title}RenderGeometry [raw] <Output File>",

                 $"Dumps {title.ToLower()} render geometry in ascii format.")
        {
            Cache    = cache;
            Geometry = geometry;
        }
        public DumpRenderGeometryCommand(HaloOnlineCacheContext cacheContext, RenderGeometry geometry, string title = "") :
            base(true,

                 $"Dump{title}RenderGeometry",
                 $"Dumps {title.ToLower()} render geometry in ascii format.",

                 $"Dump{title}RenderGeometry [raw] <Output File>",

                 $"Dumps {title.ToLower()} render geometry in ascii format.")
        {
            CacheContext = cacheContext;
            Geometry     = geometry;
        }
示例#17
0
    public void Apply(RenderGeometry geometry)
    {
        foreach (Face face in geometry.faces)
        {
            Vector3 faceCenter = face.CalculateCenter();

            foreach (Halfedge edge in face.edges)
            {
                geometry.SetNormal(edge, geometry.GetEffectiveNormal(edge) + (edge.vertex.p - faceCenter).normalized * curvature);
            }
            geometry.SetFaceType(face, RenderGeometry.FaceType.Smooth);
        }
    }
        public void InitField(RenderGeometry geometry, int numberOfMines)
        {
            ClearField();
            mineField = new MineFieldModel(geometry);
            mineField.onTileStateChanged += OnTileStateChanged;
            mineField.onWon   += OnWon;
            mineField.onLost  += OnLost;
            this.numberOfMines = numberOfMines;

            foreach (MineFieldModel.Tile tile in mineField.tiles.Values)
            {
                GameObject  obj       = Instantiate(tileBlockPrefab);
                TileControl tileBlock = obj.GetComponent <TileControl>();
                tileBlock.InitBlock(tile);
                tileBlocks[tile] = tileBlock;
            }
        }
 public static RenderGeometry CreateTetrahedronToTetrahedronTransitionGeometry(float size, float ratio, bool cutEdge)
 {
     if (cutEdge)
     {
         return(CreateCuboctahedronGeometry(size, ratio));
     }
     if (ratio <= 0.5f)
     {
         return(CreateTrunctedTetrahedronGeometry(size, ratio * 2));
     }
     else
     {
         RenderGeometry geometry = CreateTrunctedTetrahedronGeometry(size, (1 - ratio) * 2);
         geometry.ApplyRotation(Quaternion.AngleAxis(90, Vector3.up));
         return(geometry);
     }
 }
    public static RenderGeometry CreateConeGeometry(float radius, float height, int segmentP, int segmentH, bool smoothH, bool smoothV, float cutTop = 0, float cutAngle = 0)
    {
        if (cutTop == 0)
        {
            StructureGeometry       structure = new StructureGeometry();
            RenderGeometry.FaceType faceType  = GetFaceType(smoothH, smoothV);

            SurfaceComponentGeometry coneCap = SurfaceComponentGeometries.CreateConeCapGeometry(radius, height, segmentP, segmentH, cutAngle, 1, faceType);
            if (cutAngle == 0)
            {
                SurfaceComponentGeometry bottom = SurfaceComponentGeometries.CreateRegularPolygonGeometry(radius, segmentP, 2);
                bottom.ApplyRotation(Quaternion.AngleAxis(180, Vector3.right));

                Vertex corner = structure.CreateVertex();
                structure.CreateFace(coneCap, false, corner);
                structure.CreateFace(bottom, false, corner);
            }
            else
            {
                SurfaceComponentGeometry bottom = SurfaceComponentGeometries.CreateFanCapGeometry(radius, segmentP, 1, cutAngle, 2);
                SurfaceComponentGeometry wall1  = SurfaceComponentGeometries.CreateTriangleGeometry(1, 1, 0, segmentH, true, 3);
                SurfaceComponentGeometry wall2  = SurfaceComponentGeometries.CreateTriangleGeometry(1, 1, 0, segmentH, true, 4);

                Vertex cornerUp    = structure.CreateVertex(new Vector3(0, height, 0));
                Vertex cornerDownC = structure.CreateVertex(Vector3.zero);
                Vertex cornerDown1 = structure.CreateVertex(new Vector3(radius * Mathf.Cos(cutAngle), 0, -radius * Mathf.Sin(cutAngle)));
                Vertex cornerDown2 = structure.CreateVertex(new Vector3(radius, 0, 0));

                structure.CreateFace(coneCap, true, cornerDown1, cornerDown2, cornerUp);
                structure.CreateFace(bottom, true, cornerDown2, cornerDown1, cornerDownC);
                structure.CreateFace(wall1, true, cornerDown1, cornerUp, cornerDownC);
                structure.CreateFace(wall2, true, cornerDownC, cornerUp, cornerDown2);
            }
            return(structure.Build());
        }
        else
        {
            RenderGeometry geometry = CreateCylinderGeometry(radius, height, segmentP, segmentH, smoothH, smoothV, cutAngle);
            geometry.ApplyOffset(Vector3.up * (height / 2));

            float     shrinkCoeff = (1 - cutTop) / height;
            SpaceWarp warp        = new SpaceWarp($"x*(1-y*{shrinkCoeff})", "y", $"z*(1-y*{shrinkCoeff})");
            geometry.ApplySpaceWarp(warp);
            return(geometry);
        }
    }
示例#21
0
    public void Apply(RenderGeometry geometry)
    {
        if (angle == 0)
        {
            return;
        }

        Vector3 transform(Vector3 pos, out Matrix4x4 localTransform)
        {
            Vector3    v        = pos - pivot;
            Quaternion rotation = Quaternion.AngleAxis(Vector3.Dot(v, axis.normalized) * angle, axis);

            localTransform = Matrix4x4.Rotate(rotation);
            return(pivot + rotation * v);
        }

        geometry.ApplyPositionTransform(transform);
    }
    public static RenderGeometry CreateRhombicosidodecahedronGeometry(float size, float ratio)
    {
        if (ratio <= 0)
        {
            return(CreateIcosahedronGeometry(size, 1));
        }
        if (ratio >= 1)
        {
            return(CreateDodecahedronGeometry(size));
        }

        RenderGeometry geometry = new RenderGeometry();

        float goldenRatio = (1 + Mathf.Sqrt(5)) / 2;
        float dL          = size / 2;
        float dM          = dL / goldenRatio;
        float dS          = dM / goldenRatio;
        float dLtoM       = Mathf.Lerp(dL, dM, ratio);
        float dLtoS       = Mathf.Lerp(dL, dS, ratio);
        float dMtoL       = Mathf.Lerp(dM, dL, ratio);
        float dMto0       = Mathf.Lerp(dM, 0, ratio);
        float d0toM       = dM * ratio;
        float d0toS       = dS * ratio;

        var corners = new Dictionary <IntVector3, Vertex>();

        foreach (var keyAndPosition in Combine(
                     VertexSymmetryGroup("110", Key(3, 2, 0), Vec(dLtoS, dMtoL, 0)),
                     VertexSymmetryGroup("211", Key(3, 1, 1), Vec(dL, dMto0, d0toS)),
                     VertexSymmetryGroup("211", Key(3, 2, 1), Vec(dLtoM, dM, d0toM))))
        {
            corners[keyAndPosition.Key] = geometry.CreateVertex(keyAndPosition.Value);
        }
        foreach (IntVector3[] keys in Combine(
                     FaceSymmetryGroup("101", Key(3, -1, 1), Key(3, 1, 1), Key(2, 0, 3)),
                     FaceSymmetryGroup("111", Key(3, 2, 1), Key(1, 3, 2), Key(2, 1, 3)),
                     FaceSymmetryGroup("110", Key(3, 1, -1), Key(3, 2, -1), Key(3, 2, 0), Key(3, 2, 1), Key(3, 1, 1)),
                     FaceSymmetryGroup("211", Key(3, 1, 1), Key(3, 2, 1), Key(2, 1, 3), Key(2, 0, 3)),
                     FaceSymmetryGroup("100", Key(3, -1, -1), Key(3, 1, -1), Key(3, 1, 1), Key(3, -1, 1))))
        {
            geometry.CreateFace(keys.Select(key => corners[key]).ToArray());
        }
        return(geometry);
    }
示例#23
0
 /// <summary> Adds the other geometry to this geometry. The other geometry should not be used afterwards </summary>
 public void CombineGeometry(RenderGeometry other)
 {
     foreach (Face f in other.faceTypes.Keys)
     {
         faceTypes[f] = other.faceTypes[f];
     }
     foreach (Halfedge e in other.normals.Keys)
     {
         normals[e] = other.normals[e];
     }
     foreach (Halfedge e in other.tangents.Keys)
     {
         tangents[e] = other.tangents[e];
     }
     foreach (Halfedge e in other.uv.Keys)
     {
         uv[e] = other.uv[e];
     }
     base.CombineGeometry(other);
 }
        private RenderGeometry BuildTileBlockGeometry()
        {
            var geometry = new RenderGeometry();

            parent.tile.face.edges.ForEach(e => geometry.CreateVertex(e.vertex.p - parent.faceCenter));
            parent.tile.face.edges.ForEach(e => geometry.CreateVertex(CalculateTileTopVertexPosition(e)));

            int n = geometry.vertices.Count / 2;

            for (int i = 0; i < n; i++)
            {
                geometry.CreateFace(geometry.vertices[i], geometry.vertices[(i + 1) % n], geometry.vertices[(i + 1) % n + n], geometry.vertices[i + n]);
            }
            geometry.CreateFace(Enumerable.Range(n, n).Select(i => geometry.vertices[i]).ToArray());

            new FaceMerging(1f).Apply(geometry);
            new FaceCurving(BLOCK_CURVATURE).Apply(geometry);
            new EdgeSmoothing(BLOCK_SMOOTH_RADIUS, 10).Apply(geometry);
            return(geometry);
        }
示例#25
0
 public void Apply(RenderGeometry geometry)
 {
     if (type == HyperModifierType.CommonTransform)
     {
         new CommonTransform(translation, rotation, scale, pivot).Apply(geometry);
     }
     else if (type == HyperModifierType.MatrixTransform)
     {
         new MatrixTransform(new Matrix4x4(new Vector4(m00, m10, m20, m30), new Vector4(m01, m11, m21, m31), new Vector4(m02, m12, m22, m32), new Vector4(m03, m13, m23, m33))).Apply(geometry);
     }
     else if (type == HyperModifierType.BendTransform)
     {
         new BendTransform(curvature, axis1, direction, pivot).Apply(geometry);
     }
     else if (type == HyperModifierType.TwistTransform)
     {
         new TwistTransform(angle, axis2, pivot).Apply(geometry);
     }
     else if (type == HyperModifierType.CustomTransform)
     {
         try {
             new CustomTransform(exprX, exprY, exprZ).Apply(geometry);
         } catch (ExpressionParseException e) {
             message = e.Message;
         }
     }
     else if (type == HyperModifierType.FaceCurving)
     {
         new FaceCurving(curvature).Apply(geometry);
     }
     else if (type == HyperModifierType.FaceMerging)
     {
         new FaceMerging(angleThresholdSmall).Apply(geometry);
     }
     else if (type == HyperModifierType.EdgeSmoothing)
     {
         new EdgeSmoothing(smoothRadius, angleThreshold).Apply(geometry);
     }
 }
示例#26
0
    public void Apply(RenderGeometry geometry)
    {
        foreach (Halfedge edge in new List <Halfedge>(geometry.halfedges))
        {
            if (edge.index < 0 || edge.isBoundary || edge.opposite.isBoundary)
            {
                continue;
            }

            float angle1 = Vector3.Angle(geometry.GetEffectiveNormal(edge), geometry.GetEffectiveNormal(edge.opposite.prev));
            if (angle1 > angleThreshold)
            {
                continue;
            }
            float angle2 = Vector3.Angle(geometry.GetEffectiveNormal(edge.opposite), geometry.GetEffectiveNormal(edge.prev));
            if (angle2 > angleThreshold)
            {
                continue;
            }

            geometry.MergeFaces(edge);
        }

        foreach (Vertex vertex in new List <Vertex>(geometry.vertices))
        {
            List <Halfedge> edges = vertex.edges;
            if (edges.Count != 2)
            {
                continue;
            }

            if (Vector3.Angle(edges[0].vector, edges[1].opposite.vector) < angleThreshold)
            {
                geometry.MergeEdges(vertex);
            }
        }
    }
示例#27
0
 public SurfaceComponentGeometry(RenderGeometry geometry)
 {
     CombineGeometry(geometry);
 }
示例#28
0
    public void Apply(RenderGeometry geometry)
    {
        var splitHalfedges = new HashSet <Halfedge>(geometry.halfedges.Where(e => IsValidEdge(e, geometry)));
        var additionalBoundaryHalfedges = new HashSet <Halfedge>();
        var splitVertices = splitHalfedges.Select(e => e.vertex).Distinct().ToArray();

        var splitHalfedgeToNewVertexPosition       = new Dictionary <Halfedge, Vector3>();
        var splitHalfedgeToVertexNormal            = new Dictionary <Halfedge, Vector3>();
        var splitHalfedgeToPreviousOpposite        = new Dictionary <Halfedge, Halfedge>();
        var splitVertexToSurroundingSplitHalfedges = new Dictionary <Vertex, Halfedge[]>();

        // Precalculates new vertex positions. Memorize old normals and old opposites of split halfedges.
        foreach (Halfedge edge in splitHalfedges)
        {
            Halfedge nextSplitEdge = NextEdgeThat(edge, e => splitHalfedges.Contains(e) || e.isBoundary);
            if (nextSplitEdge != edge)
            {
                splitHalfedgeToNewVertexPosition[edge] = CalculateVertexPosition(edge, nextSplitEdge.opposite, geometry);
                if (nextSplitEdge.isBoundary)
                {
                    Halfedge otherEdge          = nextSplitEdge.next.opposite;
                    Halfedge otherNextSplitEdge = NextEdgeThat(edge, e => splitHalfedges.Contains(e));
                    splitHalfedgeToNewVertexPosition[otherEdge] = CalculateVertexPosition(otherEdge, otherNextSplitEdge.opposite, geometry);

                    additionalBoundaryHalfedges.Add(otherEdge);
                    splitHalfedgeToVertexNormal[otherEdge] = geometry.GetEffectiveNormal(otherEdge);
                }
            }
            else
            {
                splitHalfedgeToNewVertexPosition[edge] = edge.vertex.p;
            }
            splitHalfedgeToVertexNormal[edge]     = geometry.GetEffectiveNormal(edge);
            splitHalfedgeToPreviousOpposite[edge] = edge.opposite;
        }

        // Memorize the old connected split halfedges around any given split vertex.
        foreach (Vertex vertex in splitVertices)
        {
            splitVertexToSurroundingSplitHalfedges[vertex] = vertex.edges.Where(e => splitHalfedges.Contains(e) || additionalBoundaryHalfedges.Contains(e)).ToArray();
        }

        // Split the geometry. A pair of halfedges only needs to be split once.
        foreach (Halfedge edge in splitHalfedges)
        {
            if (!edge.opposite.isBoundary)
            {
                geometry.DisconnectEdge(edge);
            }
        }

        // Set new vertex positions
        foreach (Halfedge edge in splitHalfedges.Concat(additionalBoundaryHalfedges))
        {
            edge.vertex.p = splitHalfedgeToNewVertexPosition[edge];
        }

        var vertexNormals = splitHalfedgeToVertexNormal.ToDictionary(entry => entry.Key.vertex, entry => entry.Value);

        void AddFace(params Vertex[] faceVertices)
        {
            Face newFace = geometry.CreateFace(faceVertices.ToArray());

            geometry.SetFaceType(newFace, RenderGeometry.FaceType.Smooth);
            newFace.edges.ForEach(e => geometry.SetNormal(e, vertexNormals[e.vertex]));
        }

        // Create one edge face for each split edge.
        foreach (Halfedge edge in splitHalfedges)
        {
            if (!edge.opposite.isBoundary)
            {
                continue;
            }

            Halfedge otherEdge    = splitHalfedgeToPreviousOpposite[edge];
            var      faceVertices = new List <Vertex>();
            AddIfNotPresent(faceVertices, edge.vertex);
            AddIfNotPresent(faceVertices, edge.prev.vertex);
            AddIfNotPresent(faceVertices, otherEdge.vertex);
            AddIfNotPresent(faceVertices, otherEdge.prev.vertex);

            if (faceVertices.Count >= 3)
            {
                AddFace(faceVertices.ToArray());
            }
        }

        // Create one corner face for each split vertex.
        foreach (Vertex vertex in splitVertices)
        {
            Halfedge[] surroundingSplitHalfedges = splitVertexToSurroundingSplitHalfedges[vertex];
            int        n = surroundingSplitHalfedges.Length;
            if (n < 3)
            {
                continue;
            }

            Vertex[] faceVertices = surroundingSplitHalfedges.Select(e => e.vertex).Reverse().ToArray();
            if (n == 3)
            {
                AddFace(faceVertices.ToArray());
            }
            else
            {
                Vertex faceCenter = geometry.CreateVertex(faceVertices.Average(v => v.p));
                vertexNormals[faceCenter] = faceVertices.Average(v => vertexNormals[v]).normalized;
                for (int i = 0; i < n; i++)
                {
                    AddFace(faceVertices[i], faceVertices[(i + 1) % n], faceCenter);
                }
            }
        }
    }
示例#29
0
 private float CalculateEdgeAngleDegree(Halfedge edge, RenderGeometry geometry)
 {
     return(Vector3.Angle(geometry.GetEffectiveNormal(edge), geometry.GetEffectiveNormal(edge.opposite.prev)));
 }
示例#30
0
    public void UpdateMesh()
    {
        if (meshSaved)
        {
            return;
        }

        RenderGeometry g = null;

        if (type == HyperPrimitiveType.Plane)
        {
            g = SurfaceComponentGeometries.CreatePlaneGeometry(sizeX, sizeZ, segmentX, segmentZ);
        }
        else if (type == HyperPrimitiveType.Triangle)
        {
            g = SurfaceComponentGeometries.CreateTriangleGeometry(sizeX, sizeZ, offset, segmentX);
        }
        else if (type == HyperPrimitiveType.Polygon)
        {
            g = SurfaceComponentGeometries.CreateRegularPolygonGeometry(sizeR, segmentP);
        }
        else if (type == HyperPrimitiveType.PolygonFan)
        {
            g = SurfaceComponentGeometries.CreateFanCapGeometry(sizeR, segmentP, segmentY, Rad(cutAngle));
        }
        else if (type == HyperPrimitiveType.Sphere)
        {
            g = CircularGeometries.CreateSphereGeometry(sizeR, segmentP, segmentP2, smoothH, smoothV, cutTop, cutBottom);
        }
        else if (type == HyperPrimitiveType.Cylinder)
        {
            g = CircularGeometries.CreateCylinderGeometry(sizeR, sizeY, segmentP, segmentY, smoothH, smoothV, Rad(cutAngle), hollowRatio);
        }
        else if (type == HyperPrimitiveType.Capsule)
        {
            g = CircularGeometries.CreateCapsuleGeometry(sizeR, sizeY, segmentP, segmentY, segmentP2, smoothH, smoothV);
        }
        else if (type == HyperPrimitiveType.Cone)
        {
            g = CircularGeometries.CreateConeGeometry(sizeR, sizeY, segmentP, segmentP2, smoothH, smoothV, cutTop, Rad(cutAngle));
        }
        else if (type == HyperPrimitiveType.Torus)
        {
            g = CircularGeometries.CreateTorusGeometry(sizeR, sizeR2, segmentP, segmentP2, smoothH, smoothV, Rad(cutAngle), Rad(angleOffset));
        }
        else if (type == HyperPrimitiveType.Spring)
        {
            g = CircularGeometries.CreateSpringGeometry(sizeR, sizeR2, sizeY, segmentP, segmentP2, smoothH, smoothV, Rad(angle), Rad(angleOffset));
        }
        else if (type == HyperPrimitiveType.Cube)
        {
            g = PolyhedronGeometries.CreateCubeGeometry(new Vector3(sizeX, sizeY, sizeZ), new int[] { segmentX, segmentY, segmentZ });
        }
        else if (type == HyperPrimitiveType.CubeStar)
        {
            g = PolyhedronGeometries.CreateCubeStarGeometry(sizeX, extrusion, cutTop);
        }
        else if (type == HyperPrimitiveType.CubeFrame)
        {
            g = PolyhedronGeometries.CreateCubeFrameGeometry(sizeX, ratio);
        }
        else if (type == HyperPrimitiveType.BuildingBlock)
        {
            g = PolyhedronGeometries.CreateBuildingBlockGeometry(new Vector3(sizeX, sizeY, sizeZ), new bool[, , ] {
                { { xyz, xyZ }, { xYz, xYZ } }, { { Xyz, XyZ }, { XYz, XYZ } }
            });
        }
        else if (type == HyperPrimitiveType.Tetrahedron)
        {
            g = PolyhedronGeometries.CreateTetrahedronGeometry(sizeX, segmentX);
        }
        else if (type == HyperPrimitiveType.TetrahedronStar)
        {
            g = PolyhedronGeometries.CreateTetrahedronStarGeometry(sizeX, extrusion, cutTop);
        }
        else if (type == HyperPrimitiveType.Octahedron)
        {
            g = PolyhedronGeometries.CreateOctahedronGeometry(sizeX, segmentX);
        }
        else if (type == HyperPrimitiveType.OctahedronStar)
        {
            g = PolyhedronGeometries.CreateOctahedronStarGeometry(sizeX, extrusion, cutTop);
        }
        else if (type == HyperPrimitiveType.Dodecahedron)
        {
            g = PolyhedronGeometries.CreateDodecahedronGeometry(sizeX);
        }
        else if (type == HyperPrimitiveType.DodecahedronStar)
        {
            g = PolyhedronGeometries.CreateDodecahedronStarGeometry(sizeX, extrusion, cutTop);
        }
        else if (type == HyperPrimitiveType.Icosahedron)
        {
            g = PolyhedronGeometries.CreateIcosahedronGeometry(sizeX, segmentX);
        }
        else if (type == HyperPrimitiveType.IcosahedronStar)
        {
            g = PolyhedronGeometries.CreateIcosahedronStarGeometry(sizeX, extrusion, cutTop);
        }
        else if (type == HyperPrimitiveType.TrunctedTetrahedron)
        {
            g = PolyhedronGeometries.CreateTetrahedronToTetrahedronTransitionGeometry(sizeX, ratio, cutEdge);
        }
        else if (type == HyperPrimitiveType.TrunctedCubeOctahedron)
        {
            g = PolyhedronGeometries.CreateCubeToOctahedronTransitionGeometry(sizeX, ratio, cutEdge);
        }
        else if (type == HyperPrimitiveType.TrunctedIcosahedronDodecahedron)
        {
            g = PolyhedronGeometries.CreateIcosahedronToDodecahedronTransitionGeometry(sizeX, ratio, cutEdge);
        }
        else if (type == HyperPrimitiveType.Ramp)
        {
            g = RampGeometries.CreateStraightRampGeometry(sizeX, sizeY, sizeZ, segmentX, segmentZ, smoothX, smoothZ, rampType, curvature, extraSizeY, extraSizeX, extraSizeX2);
        }
        else if (type == HyperPrimitiveType.Test)
        {
            g = SpecialSurfaceComponentGeometries.CreateSplitTriangleGeometry(1, 1, 0, 3);
        }
        else
        {
            g = new RenderGeometry();
        }

        foreach (HyperModifier modifier in GetComponents <HyperModifier>())
        {
            modifier.Apply(g);
        }

        GetComponent <MeshFilter>().sharedMesh = g.ToMesh(surfaceFacing, globalSurfaceType);
        currentGeometry = g;
    }