コード例 #1
0
        // (sequentially) find each triangle that path point lies in, and insert a vertex for
        // that point into mesh.
        void insert_corners(HashSet <int> MeshVertsOnCurve)
        {
            PrimalQuery2d query = new PrimalQuery2d(PointF);

            if (UseTriSpatial)
            {
                int count = Mesh.TriangleCount + Curve.VertexCount;
                int bins  = 32;
                if (count < 25)
                {
                    bins = 8;
                }
                else if (count < 100)
                {
                    bins = 16;
                }
                AxisAlignedBox3d bounds3 = Mesh.CachedBounds;
                AxisAlignedBox2d bounds2 = new AxisAlignedBox2d(bounds3.Min.xy, bounds3.Max.xy);
                triSpatial = new TriangleBinsGrid2d(bounds2, bins);
                foreach (int tid in Mesh.TriangleIndices())
                {
                    spatial_add_triangle(tid);
                }
            }

            Func <int, Vector2d, bool> inTriangleF = (tid, pos) => {
                Index3i tv           = Mesh.GetTriangle(tid);
                int     query_result = query.ToTriangleUnsigned(pos, tv.a, tv.b, tv.c);
                return(query_result == -1 || query_result == 0);
            };

            CurveVertices = new int[Curve.VertexCount];
            for (int i = 0; i < Curve.VertexCount; ++i)
            {
                Vector2d vInsert  = Curve[i];
                bool     inserted = false;

                int contain_tid = DMesh3.InvalidID;
                if (triSpatial != null)
                {
                    contain_tid = triSpatial.FindContainingTriangle(vInsert, inTriangleF);
                }
                else
                {
                    foreach (int tid in Mesh.TriangleIndices())
                    {
                        Index3i tv = Mesh.GetTriangle(tid);
                        // [RMS] using unsigned query here because we do not need to care about tri CW/CCW orientation
                        //   (right? otherwise we have to explicitly invert mesh. Nothing else we do depends on tri orientation)
                        //int query_result = query.ToTriangle(vInsert, tv.a, tv.b, tv.c);
                        int query_result = query.ToTriangleUnsigned(vInsert, tv.a, tv.b, tv.c);
                        if (query_result == -1 || query_result == 0)
                        {
                            contain_tid = tid;
                            break;
                        }
                    }
                }

                if (contain_tid != DMesh3.InvalidID)
                {
                    Index3i  tv   = Mesh.GetTriangle(contain_tid);
                    Vector3d bary = MathUtil.BarycentricCoords(vInsert, PointF(tv.a), PointF(tv.b), PointF(tv.c));
                    // SpatialEpsilon is our zero-tolerance, so merge if we are closer than that
                    bool is_existing_v;
                    int  vid = insert_corner_from_bary(i, contain_tid, bary, 0.01, 100 * SpatialEpsilon, out is_existing_v);
                    if (vid > 0)      // this should be always happening..
                    {
                        CurveVertices[i] = vid;
                        if (is_existing_v)
                        {
                            MeshVertsOnCurve.Add(vid);
                        }
                        inserted = true;
                    }
                    else
                    {
                        throw new Exception("MeshInsertUVPolyCurve.insert_corners: failed to insert vertex " + i.ToString());
                    }
                }

                if (inserted == false)
                {
                    throw new Exception("MeshInsertUVPolyCurve.insert_corners: curve vertex "
                                        + i.ToString() + " is not inside or on any mesh triangle!");
                }
            }
        }
コード例 #2
0
        // (sequentially) find each triangle that path point lies in, and insert a vertex for
        // that point into mesh.
        void insert_corners(HashSet <int> MeshVertsOnCurve)
        {
            PrimalQuery2d query = new PrimalQuery2d(PointF);

            if (UseTriSpatial)
            {
                int count = Mesh.TriangleCount + Curve.VertexCount;
                int bins  = 32;
                if (count < 25)
                {
                    bins = 8;
                }
                else if (count < 100)
                {
                    bins = 16;
                }
                AxisAlignedBox3d bounds3 = Mesh.CachedBounds;
                AxisAlignedBox2d bounds2 = new AxisAlignedBox2d(bounds3.Min.xy, bounds3.Max.xy);
                triSpatial = new TriangleBinsGrid2d(bounds2, bins);
                foreach (int tid in Mesh.TriangleIndices())
                {
                    spatial_add_triangle(tid);
                }
            }

            Func <int, Vector2d, bool> inTriangleF = (tid, pos) => {
                Index3i tv           = Mesh.GetTriangle(tid);
                int     query_result = query.ToTriangleUnsigned(pos, tv.a, tv.b, tv.c);
                return(query_result == -1 || query_result == 0);
            };

            CurveVertices = new int[Curve.VertexCount];
            for (int i = 0; i < Curve.VertexCount; ++i)
            {
                Vector2d vInsert  = Curve[i];
                bool     inserted = false;

                // find the triangle that contains this curve point
                int contain_tid = DMesh3.InvalidID;
                if (triSpatial != null)
                {
                    contain_tid = triSpatial.FindContainingTriangle(vInsert, inTriangleF);
                }
                else
                {
                    foreach (int tid in Mesh.TriangleIndices())
                    {
                        Index3i tv = Mesh.GetTriangle(tid);
                        // [RMS] using unsigned query here because we do not need to care about tri CW/CCW orientation
                        //   (right? otherwise we have to explicitly invert mesh. Nothing else we do depends on tri orientation)
                        //int query_result = query.ToTriangle(vInsert, tv.a, tv.b, tv.c);
                        int query_result = query.ToTriangleUnsigned(vInsert, tv.a, tv.b, tv.c);
                        if (query_result == -1 || query_result == 0)
                        {
                            contain_tid = tid;
                            break;
                        }
                    }
                }

                // if we found one, insert the point via face-poke or edge-split,
                // unless it is exactly at existing vertex, in which case we can re-use it
                if (contain_tid != DMesh3.InvalidID)
                {
                    Index3i  tv   = Mesh.GetTriangle(contain_tid);
                    Vector3d bary = MathUtil.BarycentricCoords(vInsert, PointF(tv.a), PointF(tv.b), PointF(tv.c));
                    // SpatialEpsilon is our zero-tolerance, so merge if we are closer than that
                    bool is_existing_v;
                    int  vid = insert_corner_from_bary(i, contain_tid, bary, 0.01, 100 * SpatialEpsilon, out is_existing_v);
                    if (vid > 0)
                    {
                        CurveVertices[i] = vid;
                        if (is_existing_v)
                        {
                            MeshVertsOnCurve.Add(vid);
                        }
                        inserted = true;
                    }
                }

                // if we did not find containing triangle,
                // try matching with any existing vertices.
                // This can happen if curve point is right on mesh border...
                if (inserted == false)
                {
                    foreach (int vid in Mesh.VertexIndices())
                    {
                        Vector2d v = PointF(vid);
                        if (vInsert.Distance(v) < SpatialEpsilon)
                        {
                            CurveVertices[i] = vid;
                            MeshVertsOnCurve.Add(vid);
                            inserted = true;
                        }
                    }
                }

                // TODO: also case where curve point is right on mesh border edge,
                // and so it ends up being outside all triangles?


                if (inserted == false)
                {
                    throw new Exception("MeshInsertUVPolyCurve.insert_corners: curve vertex "
                                        + i.ToString() + " is not inside or on any mesh triangle!");
                }
            }
        }