public static AxisAlignedBox3d BoundsT(IMesh mesh, IEnumerable <int> triangleIndices, Func <Vector3d, Vector3d> TransformF = null)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (int tid in triangleIndices)
                {
                    Index3i tri = mesh.GetTriangle(tid);
                    for (int j = 0; j < 3; ++j)
                    {
                        bounds.Contain(mesh.GetVertex(tri[j]));
                    }
                }
            }
            else
            {
                foreach (int tid in triangleIndices)
                {
                    Index3i tri = mesh.GetTriangle(tid);
                    for (int j = 0; j < 3; ++j)
                    {
                        bounds.Contain(TransformF(mesh.GetVertex(tri[j])));
                    }
                }
            }
            return(bounds);
        }
Ejemplo n.º 2
0
        public AxisAlignedBox3d Bounds()
        {
            Vector3d         o = Radius * Vector3d.One, p0 = Segment.P0, p1 = Segment.P1;
            AxisAlignedBox3d box = new AxisAlignedBox3d(p0 - o, p0 + o);

            box.Contain(p1 - o);
            box.Contain(p1 + o);
            return(box);
        }
Ejemplo n.º 3
0
        int split_point_set_sorted(int[] pt_indices, Vector3d[] positions,
                                   int iStart, int iCount, int depth, int minIndexCount,
                                   boxes_set leafs, boxes_set nodes, out AxisAlignedBox3d box)
        {
            box = AxisAlignedBox3d.Empty;
            int iBox = -1;

            if (iCount < minIndexCount)
            {
                // append new points box
                iBox = leafs.iBoxCur++;
                leafs.box_to_index.insert(leafs.iIndicesCur, iBox);

                leafs.index_list.insert(iCount, leafs.iIndicesCur++);
                for (int i = 0; i < iCount; ++i)
                {
                    leafs.index_list.insert(pt_indices[iStart + i], leafs.iIndicesCur++);
                    box.Contain(points.GetVertex(pt_indices[iStart + i]));
                }

                leafs.box_centers.insert(box.Center, iBox);
                leafs.box_extents.insert(box.Extents, iBox);

                return(-(iBox + 1));
            }

            AxisComp c = new AxisComp()
            {
                Axis = depth % 3
            };

            Array.Sort(positions, pt_indices, iStart, iCount, c);
            int mid = iCount / 2;
            int n0  = mid;
            int n1  = iCount - mid;

            // create child boxes
            AxisAlignedBox3d box1;
            int child0 = split_point_set_sorted(pt_indices, positions, iStart, n0, depth + 1, minIndexCount, leafs, nodes, out box);
            int child1 = split_point_set_sorted(pt_indices, positions, iStart + mid, n1, depth + 1, minIndexCount, leafs, nodes, out box1);

            box.Contain(box1);

            // append new box
            iBox = nodes.iBoxCur++;
            nodes.box_to_index.insert(nodes.iIndicesCur, iBox);

            nodes.index_list.insert(child0, nodes.iIndicesCur++);
            nodes.index_list.insert(child1, nodes.iIndicesCur++);

            nodes.box_centers.insert(box.Center, iBox);
            nodes.box_extents.insert(box.Extents, iBox);

            return(iBox);
        }
Ejemplo n.º 4
0
 public AxisAlignedBox3d GetBounds()
 {
     AxisAlignedBox3d box = AxisAlignedBox3d.Empty;
     for (int i = 0; i < Vertices.Length; ++i)
         box.Contain(Mesh.GetVertex(Vertices[i]));
     return box;
 }
Ejemplo n.º 5
0
        public AxisAlignedBox3d Bounds()
        {
            AxisAlignedBox3d box = A.Bounds();

            box.Contain(B.Bounds());
            box.Expand(0.25 * box.MaxDim);
            return(box);
        }
Ejemplo n.º 6
0
        public static AxisAlignedBox3d Bounds(IEnumerable <DMesh3> meshes)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            foreach (DMesh3 mesh in meshes)
            {
                bounds.Contain(mesh.CachedBounds);
            }
            return(bounds);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// compute axis-aligned bounds of set of points after transforming into frame f
        /// </summary>
        public static AxisAlignedBox3d BoundsInFrame(IEnumerable <Vector3d> values, Frame3f f)
        {
            AxisAlignedBox3d box = AxisAlignedBox3d.Empty;

            foreach (Vector3d v in values)
            {
                box.Contain(f.ToFrameP(v));
            }
            return(box);
        }
Ejemplo n.º 8
0
        public static AxisAlignedBox3d Bounds <T>(IEnumerable <T> values, Func <T, Vector3d> PositionF)
        {
            AxisAlignedBox3d box = AxisAlignedBox3d.Empty;

            foreach (T t in values)
            {
                box.Contain(PositionF(t));
            }
            return(box);
        }
Ejemplo n.º 9
0
        public static AxisAlignedBox3d Bounds(IEnumerable <Vector3d> positions)
        {
            AxisAlignedBox3d box = AxisAlignedBox3d.Empty;

            foreach (Vector3d v in positions)
            {
                box.Contain(v);
            }
            return(box);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// compute axis-aligned bounds of set of points after transforming
        /// </summary>
        public static AxisAlignedBox3d Bounds(IEnumerable <Vector3d> values, TransformSequence xform)
        {
            AxisAlignedBox3d box = AxisAlignedBox3d.Empty;

            foreach (Vector3d v in values)
            {
                box.Contain(xform.TransformP(v));
            }
            return(box);
        }
Ejemplo n.º 11
0
        public AxisAlignedBox3d GetBoundingBox()
        {
            AxisAlignedBox3d box = AxisAlignedBox3d.Empty;

            foreach (Vector3d v in vertices)
            {
                box.Contain(v);
            }
            return(box);
        }
Ejemplo n.º 12
0
        public static AxisAlignedBox3d Bounds(IPointSet source)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            foreach (int vid in source.VertexIndices())
            {
                bounds.Contain(source.GetVertex(vid));
            }
            return(bounds);
        }
Ejemplo n.º 13
0
        public static AxisAlignedBox3d BoundsV(IMesh mesh, IEnumerable <int> vertexIndices, Func <Vector3d, Vector3d> TransformF = null)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (int vid in vertexIndices)
                {
                    bounds.Contain(mesh.GetVertex(vid));
                }
            }
            else
            {
                foreach (int vid in vertexIndices)
                {
                    bounds.Contain(TransformF(mesh.GetVertex(vid)));
                }
            }
            return(bounds);
        }
Ejemplo n.º 14
0
        public static AxisAlignedBox3d Bounds(DMesh3 mesh, Func <Vector3d, Vector3d> TransformF)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (Vector3d v in mesh.Vertices())
                {
                    bounds.Contain(v);
                }
            }
            else
            {
                foreach (Vector3d v in mesh.Vertices())
                {
                    Vector3d vT = TransformF(v);
                    bounds.Contain(ref vT);
                }
            }
            return(bounds);
        }
Ejemplo n.º 15
0
        public static AxisAlignedBox3d Bounds(IMesh mesh, Func <Vector3d, Vector3d> TransformF)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (int vID in mesh.VertexIndices())
                {
                    bounds.Contain(mesh.GetVertex(vID));
                }
            }
            else
            {
                foreach (int vID in mesh.VertexIndices())
                {
                    Vector3d vT = TransformF(mesh.GetVertex(vID));
                    bounds.Contain(ref vT);
                }
            }
            return(bounds);
        }
Ejemplo n.º 16
0
        public AxisAlignedBox3d GetBoundingBox()
        {
            // [RMS] problem w/ readonly because vector is a class...
            //AxisAlignedBox3d box = AxisAlignedBox3d.Empty;
            AxisAlignedBox3d box = new AxisAlignedBox3d(false);

            foreach (Vector3d v in vertices)
            {
                box.Contain(v);
            }
            return(box);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// calculate extents of mesh along axes of frame, with optional transform
        /// </summary>
        public static AxisAlignedBox3d BoundsInFrame(DMesh3 mesh, Frame3f frame, Func <Vector3d, Vector3d> TransformF = null)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (Vector3d v in mesh.Vertices())
                {
                    Vector3d fv = frame.ToFrameP(v);
                    bounds.Contain(ref fv);
                }
            }
            else
            {
                foreach (Vector3d v in mesh.Vertices())
                {
                    Vector3d vT = TransformF(v);
                    Vector3d fv = frame.ToFrameP(ref vT);
                    bounds.Contain(ref fv);
                }
            }
            return(bounds);
        }
Ejemplo n.º 18
0
        public AxisAlignedBox3d GetBounds()
        {
            if (vertices.Count == 0)
            {
                return(AxisAlignedBox3d.Empty);
            }
            AxisAlignedBox3d box = new AxisAlignedBox3d(vertices[0]);

            for (int i = 1; i < vertices.Count; ++i)
            {
                box.Contain(vertices[i]);
            }
            return(box);
        }
Ejemplo n.º 19
0
        // AABB of transformed AABB (corners)
        public static AxisAlignedBox3d Bounds(ref AxisAlignedBox3d boxIn, Func <Vector3d, Vector3d> TransformF)
        {
            if (TransformF == null)
            {
                return(boxIn);
            }

            AxisAlignedBox3d box = new AxisAlignedBox3d(TransformF(boxIn.Corner(0)));

            for (int i = 1; i < 8; ++i)
            {
                box.Contain(TransformF(boxIn.Corner(i)));
            }
            return(box);
        }
Ejemplo n.º 20
0
        public AxisAlignedBox3d ToAABB()
        {
            // [TODO] probably more efficient way to do this...at minimum can move center-shift
            // to after the containments...
            Vector3d         extAxis0 = Extent.x * AxisX;
            Vector3d         extAxis1 = Extent.y * AxisY;
            Vector3d         extAxis2 = Extent.z * AxisZ;
            AxisAlignedBox3d result   = new AxisAlignedBox3d(Center - extAxis0 - extAxis1 - extAxis2);

            result.Contain(Center + extAxis0 - extAxis1 - extAxis2);
            result.Contain(Center + extAxis0 + extAxis1 - extAxis2);
            result.Contain(Center - extAxis0 + extAxis1 - extAxis2);
            result.Contain(Center - extAxis0 - extAxis1 + extAxis2);
            result.Contain(Center + extAxis0 - extAxis1 + extAxis2);
            result.Contain(Center + extAxis0 + extAxis1 + extAxis2);
            result.Contain(Center - extAxis0 + extAxis1 + extAxis2);
            return(result);
        }
Ejemplo n.º 21
0
        protected virtual DMesh3 BuildMesh_TolerantWeld(STLSolid solid, double weld_tolerance)
        {
            var builder = new DMesh3Builder();

            builder.AppendNewMesh(false, false, false, false);

            DVectorArray3f vertices = solid.Vertices;
            int            N        = vertices.Count;

            int[] mapV = new int[N];


            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            for (int i = 0; i < N; ++i)
            {
                bounds.Contain(vertices[i]);
            }

            // [RMS] because we are only searching within tiny radius, there is really no downside to
            // using lots of bins here, except memory usage. If we don't, and the mesh has a ton of triangles
            // very close together (happens all the time on big meshes!), then this step can start
            // to take an *extremely* long time!
            int num_bins = 256;

            if (N > 100000)
            {
                num_bins = 512;
            }

            if (N > 1000000)
            {
                num_bins = 1024;
            }

            if (N > 2000000)
            {
                num_bins = 2048;
            }

            if (N > 5000000)
            {
                num_bins = 4096;
            }

            var uniqueV = new PointHashGrid3d <int>(bounds.MaxDim / (float)num_bins, -1);
            var pos     = new Vector3f[N];

            for (int vi = 0; vi < N; ++vi)
            {
                Vector3f v = vertices[vi];

                var pair = uniqueV.FindNearestInRadius(v, weld_tolerance, (vid) =>
                {
                    return(v.Distance(pos[vid]));
                });
                if (pair.Key == -1)
                {
                    int vid = builder.AppendVertex(v.x, v.y, v.z);
                    uniqueV.InsertPoint(vid, v);
                    mapV[vi] = vid;
                    pos[vid] = v;
                }
                else
                {
                    mapV[vi] = pair.Key;
                }
            }

            append_mapped_triangles(solid, builder, mapV);
            return(builder.Meshes[0]);
        }
Ejemplo n.º 22
0
        int split_point_set_midpoint(int[] pt_indices, Vector3d[] positions,
                                     int iStart, int iCount, int depth, int minIndexCount,
                                     boxes_set leafs, boxes_set nodes, out AxisAlignedBox3d box)
        {
            box = AxisAlignedBox3d.Empty;
            int iBox = -1;

            if (iCount < minIndexCount)
            {
                // append new points box
                iBox = leafs.iBoxCur++;
                leafs.box_to_index.insert(leafs.iIndicesCur, iBox);

                leafs.index_list.insert(iCount, leafs.iIndicesCur++);
                for (int i = 0; i < iCount; ++i)
                {
                    leafs.index_list.insert(pt_indices[iStart + i], leafs.iIndicesCur++);
                    box.Contain(points.GetVertex(pt_indices[iStart + i]));
                }

                leafs.box_centers.insert(box.Center, iBox);
                leafs.box_extents.insert(box.Extents, iBox);

                return(-(iBox + 1));
            }

            //compute interval along an axis and find midpoint
            int        axis     = depth % 3;
            Interval1d interval = Interval1d.Empty;

            for (int i = 0; i < iCount; ++i)
            {
                interval.Contain(positions[iStart + i][axis]);
            }
            double midpoint = interval.Center;

            int n0, n1;

            if (Math.Abs(interval.a - interval.b) > MathUtil.ZeroTolerance)
            {
                // we have to re-sort the centers & indices lists so that centers < midpoint
                // are first, so that we can recurse on the two subsets. We walk in from each side,
                // until we find two out-of-order locations, then we swap them.
                int l = 0;
                int r = iCount - 1;
                while (l < r)
                {
                    // [RMS] is <= right here? if v.axis == midpoint, then this loop
                    //   can get stuck unless one of these has an equality test. But
                    //   I did not think enough about if this is the right thing to do...
                    while (positions[iStart + l][axis] <= midpoint)
                    {
                        l++;
                    }
                    while (positions[iStart + r][axis] > midpoint)
                    {
                        r--;
                    }
                    if (l >= r)
                    {
                        break;      //done!
                    }
                    //swap
                    Vector3d tmpc = positions[iStart + l]; positions[iStart + l] = positions[iStart + r];  positions[iStart + r] = tmpc;
                    int      tmpt = pt_indices[iStart + l]; pt_indices[iStart + l] = pt_indices[iStart + r]; pt_indices[iStart + r] = tmpt;
                }

                n0 = l;
                n1 = iCount - n0;
                Debug.Assert(n0 >= 1 && n1 >= 1);
            }
            else
            {
                // interval is near-empty, so no point trying to do sorting, just split half and half
                n0 = iCount / 2;
                n1 = iCount - n0;
            }

            // create child boxes
            AxisAlignedBox3d box1;
            int child0 = split_point_set_midpoint(pt_indices, positions, iStart, n0, depth + 1, minIndexCount, leafs, nodes, out box);
            int child1 = split_point_set_midpoint(pt_indices, positions, iStart + n0, n1, depth + 1, minIndexCount, leafs, nodes, out box1);

            box.Contain(box1);

            // append new box
            iBox = nodes.iBoxCur++;
            nodes.box_to_index.insert(nodes.iIndicesCur, iBox);

            nodes.index_list.insert(child0, nodes.iIndicesCur++);
            nodes.index_list.insert(child1, nodes.iIndicesCur++);

            nodes.box_centers.insert(box.Center, iBox);
            nodes.box_extents.insert(box.Extents, iBox);

            return(iBox);
        }