예제 #1
0
        public static AxisAlignedBox2d ToAABox2d(this BoundingBoxXYZ _bb, Frame3f _frame)
        {
            var min = _frame.ToPlaneUV((Vector3f)_bb.Min.ToVector3d(), 2);
            var max = _frame.ToPlaneUV((Vector3f)_bb.Max.ToVector3d(), 2);

            return(new AxisAlignedBox2d(min, max));
        }
예제 #2
0
        /// <summary>
        /// Builds the UV values for thw mesh represented by the vertices
        /// </summary>
        /// <param name="vertices"></param>
        /// <returns></returns>
        protected Vector2[] BuildUVs(Vector3[] vertices)
        {
            List <Vector2>  ret        = new List <Vector2>();
            List <Vector3d> vertices3d = vertices.ToList <Vector3>().ConvertAll(item => (Vector3d)item);

            //
            // create a UV mapping plane
            // to make image planes work  - we assume that the origin of UV plane is the last vertex
            //
            OrthogonalPlaneFit3 orth  = new OrthogonalPlaneFit3(vertices3d);
            Frame3f             frame = new Frame3f(vertices[vertices.Length - 1], -1 * orth.Normal);

            //
            // check the orientation of the plane in UV space.
            // for image planes  - we assume that the x direction from the first point to the second point should always be positive
            // if not - reverse the frame
            //
            if (Math.Sign(
                    frame.ToPlaneUV((Vector3f)vertices3d[0], 2).x -
                    frame.ToPlaneUV((Vector3f)vertices3d[1], 2).x
                    ) > -1)
            {
                frame = new Frame3f(vertices[vertices.Length - 1], orth.Normal);
            }

            //
            // map all of the points to UV space
            //
            foreach (Vector3d v in vertices3d)
            {
                ret.Add(frame.ToPlaneUV((Vector3f)v, 2));
            }

            //
            // normalize UVs to [0..1, 0..1]
            //
            float maxX = float.NegativeInfinity;
            float maxY = float.NegativeInfinity;
            float minX = float.PositiveInfinity;
            float minY = float.PositiveInfinity;

            for (int i = 0; i < ret.Count; i++)
            {
                Vector2 v = ret[i];
                maxX = maxX > v.x ? maxX : v.x;
                minX = minX < v.x ? minX : v.x;
                maxY = maxY > v.y ? maxY : v.y;
                minY = minY < v.y ? minY : v.y;
            }

            scaleX = maxX - minX;
            scaleY = maxY - minY;


            for (int i = 0; i < ret.Count; i++)
            {
                ret[i] = new Vector2((ret[i].x - minX) / scaleX, (ret[i].y - minY) / scaleY);
            }
            return(ret.ToArray());
        }
예제 #3
0
        public static Segment2d IntoFrame(this Segment3d _seg3d, Frame3f _frame)
        {
            var seg2f = new Segment2f
                            (_frame.ToPlaneUV((Vector3f)_seg3d.P0, 2),
                            _frame.ToPlaneUV((Vector3f)_seg3d.P1, 2));

            return(new Segment2d(seg2f.P0, seg2f.P1));
        }
예제 #4
0
        public List <GeneralPolygon2d> GetSolids()
        {
            Frame3f f = frameL;

            if (OutputSpace != CoordSpace.ObjectCoords)
            {
                f = SceneTransforms.TransformTo(f, SO, CoordSpace.ObjectCoords, OutputSpace);
            }

            PlanarComplex complex = new PlanarComplex();

            foreach (DCurve3 c in localCurves.Loops)
            {
                Polygon2d poly = new Polygon2d();
                for (int i = 0; i < c.VertexCount; ++i)
                {
                    Vector2f uv = f.ToPlaneUV((Vector3f)c[i], 2);
                    poly.AppendVertex(uv);
                }
                complex.Add(poly);
            }
            PlanarComplex.FindSolidsOptions options = PlanarComplex.FindSolidsOptions.SortPolygons;
            var info = complex.FindSolidRegions(options);

            return(info.Polygons);
        }
예제 #5
0
        Polygon2d to_polygon(EdgeSpan span, Frame3f polyFrame)
        {
            int       NV   = span.VertexCount;
            Polygon2d poly = new Polygon2d();

            for (int k = 0; k < NV; ++k)
            {
                poly.AppendVertex(polyFrame.ToPlaneUV((Vector3f)span.GetVertex(k), 2));
            }
            return(poly);
        }
예제 #6
0
        public static GeneralPolygon2d ToPolygon(this List <Dataline> list, ref Frame3f frame)
        {
            List <VertexLookup> VertexTable = list[0].VertexTable;

            Vector3d[] vertices = new Vector3d[VertexTable.Count];
            for (int j = 0; j < VertexTable.Count; j++)
            {
                vertices[j] = VertexTable.Find(item => item.Vertex == j).Com.transform.position;
            }
            OrthogonalPlaneFit3 orth = new OrthogonalPlaneFit3(vertices);

            frame = new Frame3f(orth.Origin, orth.Normal);
            GeneralPolygon2d poly = new GeneralPolygon2d(new Polygon2d());

            for (int i = 0; i < list.Count; i++)
            {
                VertexTable = list[i].VertexTable;
                vertices    = new Vector3d[VertexTable.Count];
                for (int j = 0; j < VertexTable.Count; j++)
                {
                    vertices[j] = VertexTable.Find(item => item.Vertex == j).Com.transform.position;
                }
                List <Vector2d> vertices2d = new List <Vector2d>();
                foreach (Vector3d v in vertices)
                {
                    Vector2f vertex = frame.ToPlaneUV((Vector3f)v, 3);
                    if (i != 0 && !poly.Outer.Contains(vertex))
                    {
                        break;
                    }
                    vertices2d.Add(vertex);
                }
                Polygon2d p2d = new Polygon2d(vertices2d);
                if (i == 0)
                {
                    p2d = new Polygon2d(vertices2d);
                    p2d.Reverse();
                    poly.Outer = p2d;
                }
                else
                {
                    try {
                        poly.AddHole(p2d, true, true);
                    } catch {
                        p2d.Reverse();
                        poly.AddHole(p2d, true, true);
                    }
                }
            }
            return(poly);
        }
예제 #7
0
        public static void CalculateUVs(this DMesh3 dMesh)
        {
            dMesh.EnableVertexUVs(Vector2f.Zero);
            OrthogonalPlaneFit3 orth          = new OrthogonalPlaneFit3(dMesh.Vertices());
            Frame3f             frame         = new Frame3f(orth.Origin, orth.Normal);
            AxisAlignedBox3d    bounds        = dMesh.CachedBounds;
            AxisAlignedBox2d    boundsInFrame = new AxisAlignedBox2d();

            for (int i = 0; i < 8; i++)
            {
                boundsInFrame.Contain(frame.ToPlaneUV((Vector3f)bounds.Corner(i), 3));
            }
            Vector2f min    = (Vector2f)boundsInFrame.Min;
            float    width  = (float)boundsInFrame.Width;
            float    height = (float)boundsInFrame.Height;

            for (int i = 0; i < dMesh.VertexCount; i++)
            {
                Vector2f UV = frame.ToPlaneUV((Vector3f)dMesh.GetVertex(i), 3);
                UV.x = (UV.x - min.x) / width;
                UV.y = (UV.y - min.y) / height;
                dMesh.SetVertexUV(i, UV);
            }
        }
예제 #8
0
        /// <summary>
        /// create Polygon by projecting polygon3 into frame
        /// </summary>
        public MeshInsertProjectedPolygon(DMesh3 mesh, DCurve3 polygon3, Frame3f frame, int seedTri)
        {
            if (polygon3.Closed == false)
            {
                throw new Exception("MeshInsertPolyCurve(): only closed polygon3 supported for now");
            }

            Mesh         = mesh;
            ProjectFrame = frame;
            SeedTriangle = seedTri;

            Polygon = new Polygon2d();
            foreach (Vector3d v3 in polygon3.Vertices)
            {
                Vector2f uv = frame.ToPlaneUV((Vector3f)v3, 2);
                Polygon.AppendVertex(uv);
            }
        }
예제 #9
0
        public static GeneralPolygon2d ToPolygon(this List <DCurve3> list, ref Frame3f frame)
        {
            OrthogonalPlaneFit3 orth = new OrthogonalPlaneFit3(list[0].Vertices);

            frame = new Frame3f(orth.Origin, orth.Normal);
            GeneralPolygon2d poly = new GeneralPolygon2d(new Polygon2d());

            for (int i = 0; i < list.Count; i++)
            {
                List <Vector3d> vertices   = list[i].Vertices.ToList();
                List <Vector2d> vertices2d = new List <Vector2d>();
                foreach (Vector3d v in vertices)
                {
                    Vector2f vertex = frame.ToPlaneUV((Vector3f)v, 3);
                    if (i != 0 && !poly.Outer.Contains(vertex))
                    {
                        break;
                    }
                    vertices2d.Add(vertex);
                }
                Polygon2d p2d = new Polygon2d(vertices2d);
                if (i == 0)
                {
                    p2d = new Polygon2d(vertices2d);
                    p2d.Reverse();
                    poly.Outer = p2d;
                }
                else
                {
                    try {
                        poly.AddHole(p2d, true, true);
                    } catch {
                        p2d.Reverse();
                        poly.AddHole(p2d, true, true);
                    }
                }
            }
            return(poly);
        }
예제 #10
0
        public List <Polygon2d> GetPolygons()
        {
            Frame3f f = frameL;

            if (OutputSpace != CoordSpace.ObjectCoords)
            {
                f = SceneTransforms.TransformTo(f, SO, CoordSpace.ObjectCoords, OutputSpace);
            }

            List <Polygon2d> polygons = new List <Polygon2d>();

            foreach (DCurve3 c in localCurves.Loops)
            {
                Polygon2d poly = new Polygon2d();
                for (int i = 0; i < c.VertexCount; ++i)
                {
                    Vector2f uv = f.ToPlaneUV((Vector3f)c[i], 2);
                    poly.AppendVertex(uv);
                }
                polygons.Add(poly);
            }
            return(polygons);
        }
예제 #11
0
        public bool Insert()
        {
            Func <int, bool> is_contained_v = (vid) => {
                Vector3d v   = Mesh.GetVertex(vid);
                Vector2f vf2 = ProjectFrame.ToPlaneUV((Vector3f)v, 2);
                return(Polygon.Contains(vf2));
            };

            MeshVertexSelection vertexROI = new MeshVertexSelection(Mesh);
            Index3i             seedT     = Mesh.GetTriangle(SeedTriangle);

            // if a seed vert of seed triangle is containd in polygon, we will
            // flood-fill out from there, this gives a better ROI.
            // If not, we will try flood-fill from the seed triangles.
            List <int> seed_verts = new List <int>();

            for (int j = 0; j < 3; ++j)
            {
                if (is_contained_v(seedT[j]))
                {
                    seed_verts.Add(seedT[j]);
                }
            }
            if (seed_verts.Count == 0)
            {
                seed_verts.Add(seedT.a);
                seed_verts.Add(seedT.b);
                seed_verts.Add(seedT.c);
            }

            // flood-fill out from seed vertices until we have found all vertices
            // contained in polygon
            vertexROI.FloodFill(seed_verts.ToArray(), is_contained_v);

            // convert vertex ROI to face ROI
            MeshFaceSelection faceROI = new MeshFaceSelection(Mesh, vertexROI, 1);

            faceROI.ExpandToOneRingNeighbours();
            faceROI.FillEars(true);    // this might be a good idea...

            // construct submesh
            RegionOperator regionOp   = new RegionOperator(Mesh, faceROI);
            DSubmesh3      roiSubmesh = regionOp.Region;
            DMesh3         roiMesh    = roiSubmesh.SubMesh;

            // save 3D positions of unmodified mesh
            Vector3d[] initialPositions = new Vector3d[roiMesh.MaxVertexID];

            // map roi mesh to plane
            MeshTransforms.PerVertexTransform(roiMesh, roiMesh.VertexIndices(), (v, vid) => {
                Vector2f uv           = ProjectFrame.ToPlaneUV((Vector3f)v, 2);
                initialPositions[vid] = v;
                return(new Vector3d(uv.x, uv.y, 0));
            });

            // save a copy of 2D mesh and construct bvtree. we will use
            // this later to project back to 3d
            // [TODO] can we use a better spatial DS here, that takes advantage of 2D?
            DMesh3         projectMesh = new DMesh3(roiMesh);
            DMeshAABBTree3 projecter   = new DMeshAABBTree3(projectMesh, true);

            MeshInsertUVPolyCurve insertUV = new MeshInsertUVPolyCurve(roiMesh, Polygon);
            //insertUV.Validate()
            bool bOK = insertUV.Apply();

            if (!bOK)
            {
                throw new Exception("insertUV.Apply() failed");
            }

            if (SimplifyInsertion)
            {
                insertUV.Simplify();
            }

            int[] insertedPolyVerts = insertUV.CurveVertices;

            // grab inserted loop, assuming it worked
            EdgeLoop insertedLoop = null;

            if (insertUV.Loops.Count == 1)
            {
                insertedLoop = insertUV.Loops[0];
            }

            // find interior triangles
            List <int> interiorT = new List <int>();

            foreach (int tid in roiMesh.TriangleIndices())
            {
                Vector3d centroid = roiMesh.GetTriCentroid(tid);
                if (Polygon.Contains(centroid.xy))
                {
                    interiorT.Add(tid);
                }
            }
            if (RemovePolygonInterior)
            {
                MeshEditor editor = new MeshEditor(roiMesh);
                editor.RemoveTriangles(interiorT, true);
                InteriorTriangles = null;
            }
            else
            {
                InteriorTriangles = interiorT.ToArray();
            }


            // map back to 3d
            Vector3d a = Vector3d.Zero, b = Vector3d.Zero, c = Vector3d.Zero;

            foreach (int vid in roiMesh.VertexIndices())
            {
                // [TODO] somehow re-use exact positions from regionOp maps?

                // construct new 3D pos w/ barycentric interpolation
                Vector3d v   = roiMesh.GetVertex(vid);
                int      tid = projecter.FindNearestTriangle(v);
                Index3i  tri = projectMesh.GetTriangle(tid);
                projectMesh.GetTriVertices(tid, ref a, ref b, ref c);
                Vector3d bary = MathUtil.BarycentricCoords(ref v, ref a, ref b, ref c);
                Vector3d pos  = bary.x * initialPositions[tri.a] + bary.y * initialPositions[tri.b] + bary.z * initialPositions[tri.c];

                roiMesh.SetVertex(vid, pos);
            }

            bOK = BackPropagate(regionOp, insertedPolyVerts, insertedLoop);

            return(bOK);
        }
예제 #12
0
        /// <summary>
        /// Makes the actual mesh
        /// </summary>
        protected void _redraw()
        {
            if (lines.Count > 0)
            {
                Polygon = new List <DCurve3>();
                foreach (Dataline ring in lines)
                {
                    foreach (VertexLookup v in ring.VertexTable)
                    {
                        VertexTable.Add(v);
                    }
                    DCurve3 curve = new DCurve3();
                    curve.Vector3(ring.GetVertexPositions(), true);
                    Polygon.Add(curve);
                }
            }

            MeshFilter mf = Shape.GetComponent <MeshFilter>();

            MeshCollider[] mc = Shape.GetComponents <MeshCollider>();
            mf.mesh = null;
            Mesh mesh  = new Mesh();
            Mesh imesh = new Mesh();

            mesh.indexFormat  = UnityEngine.Rendering.IndexFormat.UInt32;
            imesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            Frame3f frame = new Frame3f();

            Vector3[]        vertices;
            GeneralPolygon2d polygon2d;
            Delaunator       delaunator;
            List <int>       triangles = new List <int>();

            try {
                //
                // Map 3d Polygon to the bext fit 2d polygon and also return the frame used for the mapping
                //
                polygon2d = Polygon.ToPolygon(ref frame);

                //
                // calculate the dalaunay triangulation of the 2d polygon
                //
                delaunator = new Delaunator(polygon2d.AllVerticesItr().ToPoints());

                IEnumerable <Vector2d> vlist = delaunator.Points.ToVectors2d();
                vertices = new Vector3[vlist.Count()];

                //
                // for each vertex in the dalaunay triangulatin - map back to a 3d point and also populate the vertex table
                //
                for (int i = 0; i < vlist.Count(); i++)
                {
                    Vector2d v = vlist.ElementAt(i);
                    try {
                        Vector3d v1 = Polygon.AllVertexItr().Find(item => v.Distance(frame.ToPlaneUV((Vector3f)item, 2)) < 0.001);
                        vertices[i] = Shape.transform.InverseTransformPoint((Vector3)v1);
                        VertexLookup vl = VertexTable.Find(item => v1.Distance(item.Com.transform.position) < 0.001);
                        if (vl != null)
                        {
                            vl.pVertex = i;
                        }
                    } catch {
                        Debug.Log("Mesh Error");
                    }
                }

                //
                // eaxtract the triangles from the delaunay triangulation
                //
                IEnumerable <ITriangle> tris = delaunator.GetTriangles();
                for (int i = 0; i < tris.Count(); i++)
                {
                    ITriangle tri = tris.ElementAt(i);

                    if (polygon2d.Contains(tri.CetIncenter()))
                    {
                        int index = 3 * i;
                        triangles.Add(delaunator.Triangles[index]);
                        triangles.Add(delaunator.Triangles[index + 1]);
                        triangles.Add(delaunator.Triangles[index + 2]);
                    }
                }
            } catch (Exception e) {
                throw new Exception("feature is not a valid Polygon : " + e.ToString());
            }

            //
            // build the mesh entity
            //
            mesh.vertices  = vertices;
            mesh.triangles = triangles.ToArray();
            mesh.uv        = BuildUVs(vertices);

            mesh.RecalculateBounds();
            mesh.RecalculateNormals();

            imesh.vertices  = mesh.vertices;
            imesh.triangles = triangles.Reverse <int>().ToArray();
            imesh.uv        = mesh.uv;

            imesh.RecalculateBounds();
            imesh.RecalculateNormals();

            mf.mesh = mesh;
            try {
                mc[0].sharedMesh = mesh;
                mc[1].sharedMesh = imesh;
            } catch (Exception e) {
                Debug.Log(e.ToString());
            }
        }
예제 #13
0
        /// <summary>
        /// Generates the actual mesh for the polyhedron
        /// </summary>
        private void MakeMesh()
        {
            MeshFilter mf;

            mf = Shape.GetComponent <MeshFilter>();
            if (mf == null)
            {
                mf = Shape.AddComponent <MeshFilter>();
            }
            mf.mesh = null;
            Mesh mesh = new Mesh();
            TriangulatedPolygonGenerator tpg = new TriangulatedPolygonGenerator();
            Frame3f frame = new Frame3f();

            tpg.Polygon = Polygon.ToPolygon(ref frame);
            tpg.Generate();
            int nv = tpg.vertices.Count;

            VertexTable.Clear();

            foreach (Dataline ring in Polygon)
            {
                foreach (VertexLookup v in ring.VertexTable)
                {
                    VertexTable.Add(v);
                }
            }
            IEnumerable <Vector3d> vlist = tpg.vertices.AsVector3d();

            Vector3[] vertices = new Vector3[vlist.Count()];

            for (int i = 0; i < vlist.Count(); i++)
            {
                Vector3d v = vlist.ElementAt(i);
                try {
                    VertexLookup vl = VertexTable.Find(item => v.xy.Distance(frame.ToPlaneUV(item.Com.transform.position, 3)) < 0.001);
                    vertices[i] = Shape.transform.InverseTransformPoint(vl.Com.transform.position);
                    vl.pVertex  = i;
                } catch {
                    VertexTable.Add(new VertexLookup()
                    {
                        pVertex = i, Com = VertexTable[0].Com
                    });
                    vertices[i] = Shape.transform.InverseTransformPoint((Vector3)frame.FromFrameV(v));
                }
            }

            List <Vector2>         uvs  = new List <Vector2>();
            IEnumerable <Vector2d> uv2d = tpg.uv.AsVector2f();

            foreach (Vector2d uv in uv2d)
            {
                uvs.Add((Vector2)uv);
            }
            mesh.vertices  = vertices.ToArray();
            mesh.triangles = tpg.triangles.ToArray <int>();
            mesh.uv        = uvs.ToArray <Vector2>();

            mesh.RecalculateBounds();
            mesh.RecalculateNormals();

            mf.mesh = mesh;
        }