Exemplo n.º 1
0
    public static Solid CreateSolidExtrusion(List <List <Entity> > entitiyLoops, float extrude, UnityEngine.Matrix4x4 tf, IdPath feature)
    {
        var  ids      = new List <List <Id> >();
        var  polygons = Sketch.GetPolygons(entitiyLoops, ref ids);
        bool inversed = extrude < 0f;

        var polys = new List <Polygon>();

        Func <Vector3, Vector3> TF = v => tf.MultiplyPoint(v);

        for (int pi = 0; pi < polygons.Count; pi++)
        {
            var p         = polygons[pi];
            var pid       = ids[pi];
            var pv        = new List <Vector3>(p);
            var triangles = Triangulation.Triangulate(pv);

            IdPath polyId        = feature.With(new Id(-1));
            bool   invComp       = true;
            var    shift         = Vector3.zero;
            var    extrudeVector = Vector3.forward * extrude;

            for (int side = 0; side < 2; side++)
            {
                for (int i = 0; i < triangles.Count / 3; i++)
                {
                    var polygonVertices = new List <Vertex>();
                    for (int j = 0; j < 3; j++)
                    {
                        polygonVertices.Add(TF(triangles[i * 3 + j] + shift).ToVertex());
                    }
                    if (inversed == invComp)
                    {
                        polygonVertices.Reverse();
                    }
                    polys.Add(new Polygon(polygonVertices, polyId));
                }
                polyId  = feature.With(new Id(-2));
                invComp = false;
                shift   = extrudeVector;
            }

            Dictionary <Id, IdPath> paths = new Dictionary <Id, IdPath>();
            for (int i = 0; i < p.Count; i++)
            {
                var polygonVertices = new List <Vertex>();
                polygonVertices.Add(TF(p[i]).ToVertex());
                polygonVertices.Add(TF(p[(i + 1) % p.Count]).ToVertex());
                polygonVertices.Add(TF((p[(i + 1) % p.Count] + extrudeVector)).ToVertex());
                polygonVertices.Add(TF((p[i] + extrudeVector)).ToVertex());
                if (!inversed)
                {
                    polygonVertices.Reverse();
                }
                IdPath curPath = null;
                if (!paths.ContainsKey(pid[i]))
                {
                    curPath = feature.With(pid[i]);
                    paths.Add(pid[i], curPath);
                }
                else
                {
                    curPath = paths[pid[i]];
                }
                polys.Add(new Polygon(polygonVertices, curPath));
            }
        }
        return(Solid.FromPolygons(polys));
    }
Exemplo n.º 2
0
    public static Solid CreateSolidRevolve(List <List <Entity> > entitiyLoops, float angle, float helixStep, Vector3 axis, Vector3 origin, float angleStep, UnityEngine.Matrix4x4 tf, IdPath feature)
    {
        var  ids      = new List <List <Id> >();
        var  polygons = Sketch.GetPolygons(entitiyLoops, ref ids);
        bool isHelix  = (Math.Abs(helixStep) > 1e-6);

        if (!isHelix && Mathf.Abs(angle) > 360f)
        {
            angle = Mathf.Sign(angle) * 360f;
        }
        bool inversed = angle < 0f;
        int  subdiv   = (int)Mathf.Ceil(Math.Abs(angle) / angleStep);
        var  drot     = UnityEngine.Matrix4x4.Translate(origin) * UnityEngine.Matrix4x4.Rotate(Quaternion.AngleAxis(angle / subdiv, axis)) * UnityEngine.Matrix4x4.Translate(-origin);

        Func <float, Vector3, Vector3> PointOn = (float a, Vector3 point) => {
            var ax  = axis;
            var axn = axis.normalized;
            var t   = a / 360.0f;
            var o   = origin;
            var prj = ExpVector.ProjectPointToLine(point, o, o + ax);
            var ra  = Mathf.Atan2(helixStep / 4.0f, (point - prj).magnitude);
            var res = ExpVector.RotateAround(point, point - prj, o, ra);
            res = ExpVector.RotateAround(res, ax, o, a * Mathf.PI / 180.0f);
            return(res + axn * t * helixStep);
        };

        var polys = new List <Polygon>();
        Func <Vector3, Vector3> TF = v => tf.MultiplyPoint(v);

        for (int pi = 0; pi < polygons.Count; pi++)
        {
            var p         = polygons[pi];
            var pid       = ids[pi];
            var pv        = new List <Vector3>(p);
            var triangles = Triangulation.Triangulate(pv);

            IdPath polyId  = feature.With(new Id(-1));
            bool   invComp = true;

            if (Math.Abs(Math.Abs(angle) - 360f) > 1e-6 || isHelix)
            {
                float a = 0f;
                for (int side = 0; side < 2; side++)
                {
                    for (int i = 0; i < triangles.Count / 3; i++)
                    {
                        var polygonVertices = new List <Vertex>();
                        for (int j = 0; j < 3; j++)
                        {
                            polygonVertices.Add(PointOn(a, TF(triangles[i * 3 + j])).ToVertex());
                        }
                        if (inversed == invComp)
                        {
                            polygonVertices.Reverse();
                        }
                        polys.Add(new Polygon(polygonVertices, polyId));
                    }
                    polyId  = feature.With(new Id(-2));
                    invComp = false;
                    a       = angle;
                }
            }

            Dictionary <Id, IdPath> paths = new Dictionary <Id, IdPath>();
            for (int i = 0; i < p.Count; i++)
            {
                float a  = 0f;
                float da = angle / subdiv;
                for (int j = 0; j < subdiv; j++)
                {
                    var polygonVertices = new List <Vertex>();
                    polygonVertices.Add(PointOn(a, TF(p[(i + 1) % p.Count])).ToVertex());
                    polygonVertices.Add(PointOn(a + da, TF(p[(i + 1) % p.Count])).ToVertex());
                    polygonVertices.Add(PointOn(a + da, TF(p[i])).ToVertex());
                    polygonVertices.Add(PointOn(a, TF(p[i])).ToVertex());
                    a += da;
                    if (!inversed)
                    {
                        polygonVertices.Reverse();
                    }
                    IdPath curPath = null;
                    if (!paths.ContainsKey(pid[i]))
                    {
                        curPath = feature.With(pid[i]);
                        paths.Add(pid[i], curPath);
                    }
                    else
                    {
                        curPath = paths[pid[i]];
                    }

                    if (isHelix)
                    {
                        var verts = new List <Vertex>();
                        verts.Add(polygonVertices[0]);
                        verts.Add(polygonVertices[1]);
                        verts.Add(polygonVertices[2]);
                        polys.Add(new Polygon(verts, curPath));

                        verts = new List <Vertex>();
                        verts.Add(polygonVertices[0]);
                        verts.Add(polygonVertices[2]);
                        verts.Add(polygonVertices[3]);
                        polys.Add(new Polygon(verts, curPath));
                    }
                    else
                    {
                        polys.Add(new Polygon(polygonVertices, curPath));
                    }
                }
            }
        }
        return(Solid.FromPolygons(polys));
    }