Пример #1
0
        public MeshResult RemoveEdge(int eID, bool bRemoveIsolatedVertices)
        {
            if (!edges_refcount.isValid(eID))
            {
                Util.gDevAssert(false);
                return(MeshResult.Failed_NotAnEdge);
            }

            int i  = 3 * eID;
            var ev = new Index2i(edges[i], edges[i + 1]);

            vertex_edges[ev.a].Remove(eID);
            vertex_edges[ev.b].Remove(eID);

            edges_refcount.decrement(eID);

            // Decrement vertex refcounts. If any hit 1 and we got remove-isolated flag,
            // we need to remove that vertex
            for (int j = 0; j < 2; ++j)
            {
                int vid = ev[j];
                vertices_refcount.decrement(vid);
                if (bRemoveIsolatedVertices && vertices_refcount.refCount(vid) == 1)
                {
                    vertices_refcount.decrement(vid);
                    Util.gDevAssert(vertices_refcount.isValid(vid) == false);
                    vertex_edges[vid] = null;
                }
            }

            updateTimeStamp(true);
            return(MeshResult.Ok);
        }
Пример #2
0
        public virtual void MakeMesh(NTMesh3 m)
        {
            int nV = vertices.Count;

            for (int i = 0; i < nV; ++i)
            {
                int vID = m.AppendVertex(vertices[i]);
                Util.gDevAssert(vID == i);
            }
            int nT = triangles.Count;

            if (WantGroups && groups != null && groups.Length == nT)
            {
                m.EnableTriangleGroups();
                for (int i = 0; i < nT; ++i)
                {
                    m.AppendTriangle(triangles[i], groups[i]);
                }
            }
            else
            {
                for (int i = 0; i < nT; ++i)
                {
                    m.AppendTriangle(triangles[i]);
                }
            }
        }
Пример #3
0
        public int AppendEdge(Index2i ev, int gid = -1)
        {
            if (IsVertex(ev[0]) == false || IsVertex(ev[1]) == false)
            {
                Util.gDevAssert(false);
                return(InvalidID);
            }
            if (ev[0] == ev[1])
            {
                Util.gDevAssert(false);
                return(InvalidID);
            }
            int e0 = FindEdge(ev[0], ev[1]);

            if (e0 != InvalidID)
            {
                return(DuplicateEdgeID);
            }

            // increment ref counts and update/create edges
            vertices_refcount.increment(ev[0]);
            vertices_refcount.increment(ev[1]);
            max_group_id = Math.Max(max_group_id, gid + 1);

            // now safe to insert edge
            int eid = add_edge(ev[0], ev[1], gid);

            updateTimeStamp(true);
            return(eid);
        }
Пример #4
0
        public void InitializeFromExisting(DMesh3 mesh, IEnumerable <int> added_v, IEnumerable <int> added_t)
        {
            initialize_buffers(mesh);
            bool has_groups = mesh.HasTriangleGroups;

            if (added_v != null)
            {
                foreach (int vid in added_v)
                {
                    Util.gDevAssert(mesh.IsVertex(vid));
                    append_vertex(mesh, vid);
                }
            }

            foreach (int tid in added_t)
            {
                Util.gDevAssert(mesh.IsTriangle(tid));

                Index3i tv  = mesh.GetTriangle(tid);
                Index4i tri = new Index4i(tv.a, tv.b, tv.c,
                                          has_groups ? mesh.GetTriangleGroup(tid) : DMesh3.InvalidID);
                AddedT.Add(tid);
                Triangles.Add(tri);
            }
        }
Пример #5
0
        void update_uv_upwind_expmap(GraphNode node)
        {
            int      vid = node.id;
            Vector3f pos = PositionF(vid);

            Vector2f avg_uv     = Vector2f.Zero;
            float    fWeightSum = 0;
            int      nbr_count  = 0;

            foreach (var nbr_id in NeighboursF(node.id))
            {
                GraphNode nbr_node = get_node(nbr_id, false);
                if (nbr_node.frozen)
                {
                    Vector3f nbr_pos   = PositionF(nbr_id);
                    Frame3f  nbr_frame = new Frame3f(nbr_pos, NormalF(nbr_id));
                    Vector2f nbr_uv    = propagate_uv(pos, nbr_node.uv, ref nbr_frame, ref SeedFrame);
                    float    fWeight   = 1.0f / (pos.DistanceSquared(nbr_pos) + MathUtil.ZeroTolerancef);
                    avg_uv     += fWeight * nbr_uv;
                    fWeightSum += fWeight;
                    nbr_count++;
                }
            }
            Util.gDevAssert(nbr_count > 0);

            //avg_uv /= (float)nbr_count;
            avg_uv /= fWeightSum;
            node.uv = avg_uv;
        }
Пример #6
0
        public static Polygon2d SplitToTargetLength(Polygon2d poly, double length)
        {
            Polygon2d result = new Polygon2d();

            result.AppendVertex(poly[0]);
            for (int j = 0; j < poly.VertexCount; ++j)
            {
                int    next = (j + 1) % poly.VertexCount;
                double len  = poly[j].Distance(poly[next]);
                if (len < length)
                {
                    result.AppendVertex(poly[next]);
                    continue;
                }

                int steps = (int)Math.Ceiling(len / length);
                for (int k = 1; k < steps; ++k)
                {
                    double   t = (double)(k) / (double)steps;
                    Vector2d v = (1.0 - t) * poly[j] + (t) * poly[next];
                    result.AppendVertex(v);
                }

                if (j < poly.VertexCount - 1)
                {
                    Util.gDevAssert(poly[j].Distance(result.Vertices[result.VertexCount - 1]) > 0.0001);
                    result.AppendVertex(poly[next]);
                }
            }

            return(result);
        }
Пример #7
0
 public void MakeMesh(DMesh3 m)
 {
     int nV = vertices.Count;
     for (int i = 0; i < nV; ++i) {
         NewVertexInfo ni = new NewVertexInfo() { v = vertices[i] };
         if ( WantNormals ) {
             ni.bHaveN = true;
             ni.n = normals[i];
         }
         if ( WantUVs ) {
             ni.bHaveUV = true;
             ni.uv = uv[i];
         }
         int vID = m.AppendVertex(ni);
         Util.gDevAssert(vID == i);
     }
     int nT = triangles.Count;
     if (WantGroups && groups != null && groups.Length == nT) {
         for (int i = 0; i < nT; ++i)
             m.AppendTriangle(triangles[i], groups[i]);
     } else {
         for (int i = 0; i < nT; ++i)
             m.AppendTriangle(triangles[i]);
     }
 }
        public void Initialize(DMesh3 mesh, IEnumerable <int> triangles)
        {
            initialize_buffers(mesh);
            bool has_groups = mesh.HasTriangleGroups;


            foreach (int tid in triangles)
            {
                if (!mesh.IsTriangle(tid))
                {
                    continue;
                }

                Index3i tv = mesh.GetTriangle(tid);
                bool    va = save_vertex(mesh, tv.a);
                bool    vb = save_vertex(mesh, tv.b);
                bool    vc = save_vertex(mesh, tv.c);

                Index4i tri = new Index4i(tv.a, tv.b, tv.c,
                                          has_groups ? mesh.GetTriangleGroup(tid) : DMesh3.InvalidID);
                RemovedT.Add(tid);
                Triangles.Add(tri);

                MeshResult result = mesh.RemoveTriangle(tid, true, false);
                if (result != MeshResult.Ok)
                {
                    throw new Exception("RemoveTrianglesMeshChange.Initialize: exception in RemoveTriangle(" + tid.ToString() + "): " + result.ToString());
                }
                Util.gDevAssert(mesh.IsVertex(tv.a) == va && mesh.IsVertex(tv.b) == vb && mesh.IsVertex(tv.c) == vc);
            }
        }
Пример #9
0
        /// <summary>
        /// if before a flip we have normals (n1,n2) and after we have (m1,m2), check if
        /// the dot between any of the 4 pairs changes sign after the flip, or is
        /// less than the dot-product tolerance (ie angle tolerance)
        /// </summary>
        public static bool CheckIfEdgeFlipCreatesFlip(DMesh3 mesh, int eID, double flip_dot_tol = 0.0)
        {
            Util.gDevAssert(mesh.IsBoundaryEdge(eID) == false);
            Index4i einfo = mesh.GetEdge(eID);
            Index2i ov    = mesh.GetEdgeOpposingV(eID);

            int a = einfo.a, b = einfo.b, c = ov.a, d = ov.b;
            int t0 = einfo.c;

            Vector3d vC = mesh.GetVertex(c), vD = mesh.GetVertex(d);
            Index3i  tri_v = mesh.GetTriangle(t0);
            int      oa = a, ob = b;

            IndexUtil.orient_tri_edge(ref oa, ref ob, ref tri_v);
            Vector3d vOA = mesh.GetVertex(oa), vOB = mesh.GetVertex(ob);
            Vector3d n0 = MathUtil.FastNormalDirection(ref vOA, ref vOB, ref vC);
            Vector3d n1 = MathUtil.FastNormalDirection(ref vOB, ref vOA, ref vD);
            Vector3d f0 = MathUtil.FastNormalDirection(ref vC, ref vD, ref vOB);

            if (edge_flip_metric(ref n0, ref f0, flip_dot_tol) <= flip_dot_tol ||
                edge_flip_metric(ref n1, ref f0, flip_dot_tol) <= flip_dot_tol)
            {
                return(true);
            }
            Vector3d f1 = MathUtil.FastNormalDirection(ref vD, ref vC, ref vOA);

            if (edge_flip_metric(ref n0, ref f1, flip_dot_tol) <= flip_dot_tol ||
                edge_flip_metric(ref n1, ref f1, flip_dot_tol) <= flip_dot_tol)
            {
                return(true);
            }
            return(false);
        }
Пример #10
0
        public void swap(DenseGrid3f g2)
        {
            Util.gDevAssert(ni == g2.ni && nj == g2.nj && nk == g2.nk);
            var tmp = g2.Buffer;

            g2.Buffer   = this.Buffer;
            this.Buffer = tmp;
        }
Пример #11
0
 public int increment(int index, short increment = 1)
 {
     Util.gDevAssert(isValid(index));
     // debug check for overflow...
     Util.gDevAssert((short)(ref_counts[index] + increment) > 0);
     ref_counts[index] += increment;
     return(ref_counts[index]);
 }
Пример #12
0
        public virtual void MakeMesh(DMesh3 m)
        {
            int  nV           = vertices.Count;
            bool bWantNormals = WantNormals && normals != null && normals.Count == vertices.Count;

            if (bWantNormals)
            {
                m.EnableVertexNormals(Vector3f.AxisY);
            }

            bool bWantUVs = WantUVs && uv != null && uv.Count == vertices.Count;

            if (bWantUVs)
            {
                m.EnableVertexUVs(Vector2f.Zero);
            }

            for (int i = 0; i < nV; ++i)
            {
                var ni = new NewVertexInfo()
                {
                    v = vertices[i]
                };
                if (bWantNormals)
                {
                    ni.bHaveN = true;
                    ni.n      = normals[i];
                }
                if (bWantUVs)
                {
                    ni.bHaveUV = true;
                    ni.uv      = uv[i];
                }
                int vID = m.AppendVertex(ni);
                Util.gDevAssert(vID == i);
            }
            int nT = triangles.Count;

            if (WantGroups && groups != null && groups.Length == nT)
            {
                m.EnableTriangleGroups();
                for (int i = 0; i < nT; ++i)
                {
                    m.AppendTriangle(triangles[i], groups[i]);
                }
            }
            else
            {
                for (int i = 0; i < nT; ++i)
                {
                    m.AppendTriangle(triangles[i]);
                }
            }
        }
Пример #13
0
        void find_cut_paths(HashSet <int> CutEdges)
        {
            Spans = new List <EdgeSpan>();
            Loops = new List <EdgeLoop>();

            // [TODO] what about if vert appears more than twice in list? we should check for that!

            var Remaining = new HashSet <int>(CutEdges);

            while (Remaining.Count > 0)
            {
                int start_edge = Remaining.First();
                Remaining.Remove(start_edge);
                Index2i start_edge_v = Mesh.GetEdgeV(start_edge);

                bool       isLoop;
                List <int> forwardSpan = walk_edge_span_forward(Mesh, start_edge, start_edge_v.a, Remaining, out isLoop);
                if (isLoop == false)
                {
                    List <int> backwardSpan = walk_edge_span_forward(Mesh, start_edge, start_edge_v.b, Remaining, out isLoop);
                    if (isLoop)
                    {
                        throw new Exception("find_cut_paths: how did this possibly happen?!?");
                    }

                    if (backwardSpan.Count > 1)
                    {
                        backwardSpan.Reverse();
                        backwardSpan.RemoveAt(backwardSpan.Count - 1);
                        backwardSpan.AddRange(forwardSpan);
                        Index2i start_ev = Mesh.GetEdgeV(backwardSpan[0]);
                        Index2i end_ev   = Mesh.GetEdgeV(backwardSpan[backwardSpan.Count - 1]);
                        // [RMS] >2 check here catches two-edge span case, where we do have shared vert but
                        //   can never be loop unless we have duplicate edge (!)
                        isLoop      = backwardSpan.Count > 2 && IndexUtil.find_shared_edge_v(ref start_ev, ref end_ev) != DMesh3.InvalidID;
                        forwardSpan = backwardSpan;
                    }
                }

                if (isLoop)
                {
                    var loop = EdgeLoop.FromEdges(Mesh, forwardSpan);
                    Util.gDevAssert(loop.CheckValidity());
                    Loops.Add(loop);
                }
                else
                {
                    var span = EdgeSpan.FromEdges(Mesh, forwardSpan);
                    Util.gDevAssert(span.CheckValidity());
                    Spans.Add(span);
                }
            }
        }
Пример #14
0
        // compute FWN cache for all points underneath this box
        protected void make_box_fast_winding_cache(int iBox, IEnumerable <int> pointIndices)
        {
            Util.gDevAssert(FastWindingCache.ContainsKey(iBox) == false);

            // construct cache
            var cacheInfo = new FWNInfo();

            FastPointWinding.ComputeCoeffs(points, pointIndices, FastWindingAreaCache,
                                           ref cacheInfo.Center, ref cacheInfo.R, ref cacheInfo.Order1Vec, ref cacheInfo.Order2Mat);

            FastWindingCache[iBox] = cacheInfo;
        }
Пример #15
0
 public void decrement(int index, short decrement = 1)
 {
     Util.gDevAssert(isValid(index));
     ref_counts[index] -= decrement;
     Util.gDevAssert(ref_counts[index] >= 0);
     if (ref_counts[index] == 0)
     {
         free_indices.push_back(index);
         ref_counts[index] = invalid;
         used_count--;
     }
 }
Пример #16
0
        /// <summary>
        /// Exhaustively check that verts and edges of this EdgeSpan are consistent. Not for production use.
        /// </summary>
        public bool CheckValidity(FailMode eFailMode = FailMode.Throw)
        {
            bool          is_ok        = true;
            Action <bool> CheckOrFailF = (b) => { is_ok = is_ok && b; };

            if (eFailMode == FailMode.DebugAssert)
            {
                CheckOrFailF = (b) => { Debug.Assert(b); is_ok = is_ok && b; };
            }
            else if (eFailMode == FailMode.gDevAssert)
            {
                CheckOrFailF = (b) => { Util.gDevAssert(b); is_ok = is_ok && b; };
            }
            else if (eFailMode == FailMode.Throw)
            {
                CheckOrFailF = (b) => { if (b == false)
                                        {
                                            throw new Exception("EdgeSpan.CheckValidity: check failed");
                                        }
                };
            }

            CheckOrFailF(Vertices.Length == Edges.Length + 1);
            for (int ei = 0; ei < Edges.Length; ++ei)
            {
                Index2i ev = Mesh.GetEdgeV(Edges[ei]);
                CheckOrFailF(Mesh.IsVertex(ev.a));
                CheckOrFailF(Mesh.IsVertex(ev.b));
                CheckOrFailF(Mesh.FindEdge(ev.a, ev.b) != DMesh3.InvalidID);
                CheckOrFailF(Vertices[ei] == ev.a || Vertices[ei] == ev.b);
                CheckOrFailF(Vertices[ei + 1] == ev.a || Vertices[ei + 1] == ev.b);
            }
            for (int vi = 0; vi < Vertices.Length - 1; ++vi)
            {
                int a = Vertices[vi], b = Vertices[vi + 1];
                CheckOrFailF(Mesh.IsVertex(a));
                CheckOrFailF(Mesh.IsVertex(b));
                CheckOrFailF(Mesh.FindEdge(a, b) != DMesh3.InvalidID);
                if (vi < Vertices.Length - 2)
                {
                    int n = 0, edge_before_b = Edges[vi], edge_after_b = Edges[vi + 1];
                    foreach (int nbr_e in Mesh.VtxEdgesItr(b))
                    {
                        if (nbr_e == edge_before_b || nbr_e == edge_after_b)
                        {
                            n++;
                        }
                    }
                    CheckOrFailF(n == 2);
                }
            }
            return(true);
        }
Пример #17
0
        void update_uv_expmap(GraphNode node)
        {
            int vid = node.id;

            Util.gDevAssert(node.parent != null && node.parent.frozen == true);
            int parent_id = node.parent.id;

            Vector3f parentPos   = PositionF(parent_id);
            Frame3f  parentFrame = new Frame3f(parentPos, NormalF(parent_id));

            node.uv = propagate_uv(PositionF(vid), node.parent.uv, ref parentFrame, ref SeedFrame);
        }
Пример #18
0
        /// <summary>
        /// Compute i'th spherical point
        /// </summary>
        public Vector3d Point(int i)
        {
            Util.gDevAssert(i < N);
            double div = (double)i / PHI;
            double phi = MathUtil.TwoPI * (div - Math.Floor(div));
            double cos_phi = Math.Cos(phi), sin_phi = Math.Sin(phi);

            double z         = 1.0 - (2.0 * (double)i + 1.0) / (double)N;
            double theta     = Math.Acos(z);
            double sin_theta = Math.Sin(theta);

            return(new Vector3d(cos_phi * sin_theta, sin_phi * sin_theta, z));
        }
Пример #19
0
        public int AppendTriangle(Index3i tv, int gid = -1)
        {
            if (IsVertex(tv[0]) == false || IsVertex(tv[1]) == false || IsVertex(tv[2]) == false)
            {
                Util.gDevAssert(false);
                return(InvalidID);
            }
            if (tv[0] == tv[1] || tv[0] == tv[2] || tv[1] == tv[2])
            {
                Util.gDevAssert(false);
                return(InvalidID);
            }

            // look up edges. if any already have two triangles, this would
            // create non-manifold geometry and so we do not allow it
            int e0 = find_edge(tv[0], tv[1]);
            int e1 = find_edge(tv[1], tv[2]);
            int e2 = find_edge(tv[2], tv[0]);

            if ((e0 != InvalidID && edge_is_boundary(e0) == false) ||
                (e1 != InvalidID && edge_is_boundary(e1) == false) ||
                (e2 != InvalidID && edge_is_boundary(e2) == false))
            {
                return(NonManifoldID);
            }

            // now safe to insert triangle
            int tid = triangles_refcount.allocate();
            int i   = 3 * tid;

            triangles.insert(tv[2], i + 2);
            triangles.insert(tv[1], i + 1);
            triangles.insert(tv[0], i);
            if (triangle_groups != null)
            {
                triangle_groups.insert(gid, tid);
            }

            // increment ref counts and update/create edges
            vertices_refcount.increment(tv[0]);
            vertices_refcount.increment(tv[1]);
            vertices_refcount.increment(tv[2]);

            add_tri_edge(tid, tv[0], tv[1], 0, e0);
            add_tri_edge(tid, tv[1], tv[2], 1, e1);
            add_tri_edge(tid, tv[2], tv[0], 2, e2);

            updateTimeStamp();
            return(tid);
        }
Пример #20
0
        void resolve_vtx_pairs()
        {
            //HashSet<int> targetVerts = new HashSet<int>(cutTargetOp.CutVertices);
            //HashSet<int> toolVerts = new HashSet<int>(cutToolOp.CutVertices);

            // tracking on-cut vertices is not working yet...
            Util.gDevAssert(Target.IsClosed() && Tool.IsClosed());

            HashSet <int> targetVerts = new HashSet <int>(MeshIterators.BoundaryVertices(cutTargetMesh));
            HashSet <int> toolVerts   = new HashSet <int>(MeshIterators.BoundaryVertices(cutToolMesh));

            split_missing(cutTargetOp, cutToolOp, cutTargetMesh, cutToolMesh, targetVerts, toolVerts);
            split_missing(cutToolOp, cutTargetOp, cutToolMesh, cutTargetMesh, toolVerts, targetVerts);
        }
Пример #21
0
        /// <summary>
        /// Move point from old to new position. This function is thread-safe, uses a SpinLock internally
        /// </summary>
        public void UpdatePoint(T value, Vector3d old_pos, Vector3d new_pos)
        {
            Vector3i old_idx = Indexer.ToGrid(old_pos);
            Vector3i new_idx = Indexer.ToGrid(new_pos);

            if (old_idx == new_idx)
            {
                return;
            }
            bool ok = remove_point(value, old_idx);

            Util.gDevAssert(ok);
            insert_point(value, new_idx);
            return;
        }
Пример #22
0
        protected int on_edge_eid(int tid, Vector3d v)
        {
            Index3i    tv  = Target.GetTriangle(tid);
            Triangle3d tri = new Triangle3d();

            Target.GetTriVertices(tid, ref tri.V0, ref tri.V1, ref tri.V2);
            int eidx = on_edge(ref tri, ref v);

            if (eidx < 0)
            {
                return(DMesh3.InvalidID);
            }
            int eid = Target.FindEdge(tv[eidx], tv[(eidx + 1) % 3]);

            Util.gDevAssert(eid != DMesh3.InvalidID);
            return(eid);
        }
Пример #23
0
        /// <summary>
        /// DGraph3 edges are not oriented, which means they cannot inherit orientation from mesh.
        /// This function returns true if, for a given graph_eid, the vertex pair returned by
        /// Graph.GetEdgeV(graph_eid) should be reversed to be consistent with mesh orientation.
        /// Mainly inteded to be passed to DGraph3Util.ExtractCurves
        /// </summary>
        public bool ShouldReverseGraphEdge(int graph_eid)
        {
            if (GraphEdges == null)
            {
                throw new Exception("MeshIsoCurves.OrientEdge: must track edge graph info to orient edge");
            }

            Index2i       graph_ev = Graph.GetEdgeV(graph_eid);
            GraphEdgeInfo einfo    = GraphEdges[graph_eid];

            if (graph_ev.b == einfo.order.a && graph_ev.a == einfo.order.b)
            {
                return(true);
            }
            Util.gDevAssert(graph_ev.a == einfo.order.a && graph_ev.b == einfo.order.b);
            return(false);
        }
Пример #24
0
        public void InitializeFromExisting(DMesh3 mesh, IEnumerable <int> remove_t)
        {
            initialize_buffers(mesh);
            bool has_groups = mesh.HasTriangleGroups;

            HashSet <int> triangles = new HashSet <int>(remove_t);
            HashSet <int> vertices  = new HashSet <int>();

            IndexUtil.TrianglesToVertices(mesh, remove_t, vertices);
            List <int> save_v = new List <int>();

            foreach (int vid in vertices)
            {
                bool all_contained = true;
                foreach (int tid in mesh.VtxTrianglesItr(vid))
                {
                    if (triangles.Contains(tid) == false)
                    {
                        all_contained = false;
                        break;
                    }
                }
                if (all_contained)
                {
                    save_v.Add(vid);
                }
            }

            foreach (int vid in save_v)
            {
                save_vertex(mesh, vid, true);
            }

            foreach (int tid in remove_t)
            {
                Util.gDevAssert(mesh.IsTriangle(tid));
                Index3i tv  = mesh.GetTriangle(tid);
                Index4i tri = new Index4i(tv.a, tv.b, tv.c,
                                          has_groups ? mesh.GetTriangleGroup(tid) : DMesh3.InvalidID);
                RemovedT.Add(tid);
                Triangles.Add(tri);
            }
        }
Пример #25
0
        /// <summary>
        /// Move segment from old to new position. This function is thread-safe, uses a SpinLock internally
        /// </summary>
        public void UpdateSegment(T value, Vector2d old_center, Vector2d new_center, double new_extent)
        {
            if (new_extent > MaxExtent)
            {
                MaxExtent = new_extent;
            }
            Vector2i old_idx = Indexer.ToGrid(old_center);
            Vector2i new_idx = Indexer.ToGrid(new_center);

            if (old_idx == new_idx)
            {
                return;
            }
            bool ok = remove_segment(value, old_idx);

            Util.gDevAssert(ok);
            insert_segment(value, new_idx);
            return;
        }
Пример #26
0
        /// <summary>
        /// Apply transforms to normalized vector
        /// </summary>
        public Vector2d TransformN(Vector2d n)
        {
            int N = Operations.Count;

            for (int i = 0; i < N; ++i)
            {
                switch (Operations[i].type)
                {
                case XFormType.Translation:
                    break;

                case XFormType.Rotation:
                    n = Operations[i].Rotation * n;
                    break;

                case XFormType.RotateAroundPoint:
                    n = Operations[i].Rotation * n;
                    break;

                case XFormType.Scale:
                    Util.gDevAssert(Operations[i].ScaleIsUniform);
                    n *= Operations[i].Scale;
                    break;

                case XFormType.ScaleAroundPoint:
                    Util.gDevAssert(Operations[i].ScaleIsUniform);
                    n *= Operations[i].Scale;
                    break;

                case XFormType.NestedITransform2:
                    n = Operations[i].NestedITransform2.TransformN(n);
                    break;

                default:
                    throw new NotImplementedException("TransformSequence.TransformN: unhandled type!");
                }
            }

            return(n);
        }
Пример #27
0
 void sanity_check()
 {
     if (Quantity == 0)
     {
         Util.gDevAssert(Type == IntersectionType.Empty);
         Util.gDevAssert(Result == IntersectionResult.NoIntersection);
     }
     else if (Quantity == 1)
     {
         Util.gDevAssert(Type == IntersectionType.Point);
         Util.gDevAssert(segment1.DistanceSquared(Point0) < MathUtil.ZeroTolerance);
         Util.gDevAssert(segment2.DistanceSquared(Point0) < MathUtil.ZeroTolerance);
     }
     else if (Quantity == 2)
     {
         Util.gDevAssert(Type == IntersectionType.Segment);
         Util.gDevAssert(segment1.DistanceSquared(Point0) < MathUtil.ZeroTolerance);
         Util.gDevAssert(segment1.DistanceSquared(Point1) < MathUtil.ZeroTolerance);
         Util.gDevAssert(segment2.DistanceSquared(Point0) < MathUtil.ZeroTolerance);
         Util.gDevAssert(segment2.DistanceSquared(Point1) < MathUtil.ZeroTolerance);
     }
 }
Пример #28
0
        /// <summary>
        /// Apply transforms to scalar dimension
        /// </summary>
        public double TransformScalar(double s)
        {
            int N = Operations.Count;

            for (int i = 0; i < N; ++i)
            {
                switch (Operations[i].type)
                {
                case XFormType.Translation:
                    break;

                case XFormType.Rotation:
                    break;

                case XFormType.RotateAroundPoint:
                    break;

                case XFormType.Scale:
                    Util.gDevAssert(Operations[i].ScaleIsUniform);
                    s *= Operations[i].Scale.x;
                    break;

                case XFormType.ScaleAroundPoint:
                    Util.gDevAssert(Operations[i].ScaleIsUniform);
                    s *= Operations[i].Scale.x;
                    break;

                case XFormType.NestedITransform2:
                    s = Operations[i].NestedITransform2.TransformScalar(s);
                    break;

                default:
                    throw new NotImplementedException("TransformSequence.TransformScalar: unhandled type!");
                }
            }

            return(s);
        }
Пример #29
0
        /// <summary>
        /// 1) Find intersection segments
        /// 2) sort onto existing input mesh vtx/edge/face
        /// </summary>
        void find_segments()
        {
            Dictionary <Vector3d, SegmentVtx> SegVtxMap = new Dictionary <Vector3d, SegmentVtx>();

            // find intersection segments
            // TODO: intersection polygons
            // TODO: do we need to care about intersection vertices?
            DMeshAABBTree3 targetSpatial = new DMeshAABBTree3(Target, true);
            DMeshAABBTree3 cutSpatial    = new DMeshAABBTree3(CutMesh, true);
            var            intersections = targetSpatial.FindAllIntersections(cutSpatial);

            // for each segment, for each vtx, determine if it is
            // at an existing vertex, on-edge, or in-face
            Segments = new IntersectSegment[intersections.Segments.Count];
            for (int i = 0; i < Segments.Length; ++i)
            {
                var              isect  = intersections.Segments[i];
                Vector3dTuple2   points = new Vector3dTuple2(isect.point0, isect.point1);
                IntersectSegment iseg   = new IntersectSegment()
                {
                    base_tid = isect.t0
                };
                Segments[i] = iseg;
                for (int j = 0; j < 2; ++j)
                {
                    Vector3d v = points[j];

                    // if this exact vtx coord has been seen, use same vtx
                    SegmentVtx sv;
                    if (SegVtxMap.TryGetValue(v, out sv))
                    {
                        iseg[j] = sv;
                        continue;
                    }
                    sv = new SegmentVtx()
                    {
                        v = v
                    };
                    SegVertices.Add(sv);
                    SegVtxMap[v] = sv;
                    iseg[j]      = sv;

                    // this vtx is tol-equal to input mesh vtx
                    int existing_v = find_existing_vertex(isect.point0);
                    if (existing_v >= 0)
                    {
                        sv.initial_type           = sv.type = 0;
                        sv.elem_id                = existing_v;
                        sv.vtx_id                 = existing_v;
                        VIDToSegVtxMap[sv.vtx_id] = sv;
                        continue;
                    }

                    Triangle3d tri = new Triangle3d();
                    Target.GetTriVertices(isect.t0, ref tri.V0, ref tri.V1, ref tri.V2);
                    Index3i tv = Target.GetTriangle(isect.t0);

                    // this vtx is tol-on input mesh edge
                    int on_edge_i = on_edge(ref tri, ref v);
                    if (on_edge_i >= 0)
                    {
                        sv.initial_type = sv.type = 1;
                        sv.elem_id      = Target.FindEdge(tv[on_edge_i], tv[(on_edge_i + 1) % 3]);
                        Util.gDevAssert(sv.elem_id != DMesh3.InvalidID);
                        add_edge_vtx(sv.elem_id, sv);
                        continue;
                    }

                    // otherwise contained in input mesh face
                    sv.initial_type = sv.type = 2;
                    sv.elem_id      = isect.t0;
                    add_face_vtx(sv.elem_id, sv);
                }
            }
        }
Пример #30
0
 public LaplacianMeshSmoother(DMesh3 mesh)
 {
     Mesh = mesh;
     Util.gDevAssert(mesh.IsCompact);
 }