Пример #1
0
        public static void print_compare(string prefix, Frame3f v1, g3.Frame3f v2)
        {
            double dErr =
                (v1.Origin - v2.Origin).Length +
                ((g3.Quaternionf)v1.Rotation - (v2.Rotation)).Length;

            DebugUtil.Log(2, "{0} {1} {2} err {3}", prefix, v1.ToString("F8"), v2.ToString(), dErr);
        }
Пример #2
0
 internal MeshNode(int i, int fi, g3.Frame3f f, g3.Index3i neighbors_index, g3.Index3i vertex_index)
 {
     frame = f;
     this.neighbors_index = neighbors_index;
     this.vertex_index    = vertex_index;
     meshIndex            = fi;
     index = i;
 }
Пример #3
0
        /// <summary> Map mesh *from* local frame coordinates into "world" coordinates </summary>
        public static void FromFrame(IDeformableMesh mesh, Frame3f f)
        {
            int  NV          = mesh.MaxVertexID;
            bool bHasNormals = mesh.HasVertexNormals;

            for (int vid = 0; vid < NV; ++vid)
            {
                if (mesh.IsVertex(vid))
                {
                    Vector3d vf = mesh.GetVertex(vid);
                    Vector3d v  = f.FromFrameP((Vector3f)vf);
                    mesh.SetVertex(vid, v);
                    if (bHasNormals)
                    {
                        Vector3f n  = mesh.GetVertexNormal(vid);
                        Vector3f nf = f.FromFrameV(n);
                        mesh.SetVertexNormal(vid, nf);
                    }
                }
            }
        }
        // returns max edge length of moved vertices, after deformation
        public override DeformInfo Apply(Frame3f vNextPos)
        {
            // if we did not move brush far enough, don't do anything
            Vector3d vDelta = (vNextPos.Origin - vPreviousPos.Origin);

            if (vDelta.Length < 0.0001f)
            {
                return(new DeformInfo()
                {
                    bNoChange = true, maxEdgeLenSqr = 0, minEdgeLenSqr = double.MaxValue
                });
            }

            // otherwise apply base deformation
            DeformF = (idx, t) =>
            {
                Vector3d v    = vPreviousPos.ToFrameP(Curve[idx]);
                Vector3d vNew = vNextPos.FromFrameP(v);
                return(Vector3d.Lerp(Curve[idx], vNew, t));
            };
            return(base.Apply(vNextPos));
        }
        /// <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);
        }
Пример #6
0
        public virtual int[] AddTriangleStrip(IList <Frame3f> frames, IList <Interval1d> spans, int group_id = -1)
        {
            int N = frames.Count;

            if (N != spans.Count)
            {
                throw new Exception("MeshEditor.AddTriangleStrip: spans list is not the same size!");
            }

            int[] new_tris = new int[2 * (N - 1)];

            int prev_a = -1, prev_b = -1;
            int i = 0, ti = 0;

            for (i = 0; i < N; ++i)
            {
                Frame3f    f    = frames[i];
                Interval1d span = spans[i];

                Vector3d va = f.Origin + (float)span.a * f.Y;
                Vector3d vb = f.Origin + (float)span.b * f.Y;

                // [TODO] could compute normals here...

                int a = Mesh.AppendVertex(va);
                int b = Mesh.AppendVertex(vb);

                if (prev_a != -1)
                {
                    new_tris[ti++] = Mesh.AppendTriangle(prev_a, b, prev_b);
                    new_tris[ti++] = Mesh.AppendTriangle(prev_a, a, b);
                }
                prev_a = a; prev_b = b;
            }

            return(new_tris);
        }
Пример #7
0
        public static void AppendBox(DMesh3 mesh, Frame3f frame, Vector3f size, Colorf color)
        {
            var editor = new MeshEditor(mesh);

            editor.AppendBox(frame, size, color);
        }
Пример #8
0
 public FrameGridIndexer3(Frame3f frame, Vector3f cellSize)
 {
     GridFrame = frame;
     CellSize  = cellSize;
 }
Пример #9
0
 public static void Store(Frame3f vFrame, BinaryWriter writer)
 {
     Store(vFrame.Origin, writer);
     Store(vFrame.Rotation, writer);
 }
Пример #10
0
        override public MeshGenerator Generate()
        {
            if (Polygon == null)
            {
                Polygon = Polygon2d.MakeCircle(1.0f, 8);
            }

            int NV           = Vertices.Count;
            int Slices       = Polygon.VertexCount;
            int nRings       = (ClosedLoop && NoSharedVertices) ? NV + 1 : NV;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false || ClosedLoop == true)
            {
                nCapVertices = 0;
            }

            vertices = new VectorArray3d(nRings * nRingSize + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int quad_strips = (ClosedLoop) ? NV : NV - 1;
            int nSpanTris   = quad_strips * (2 * Slices);
            int nCapTris    = (Capped && ClosedLoop == false) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            Frame3f  fCur = new Frame3f(Frame);
            Vector3d dv   = CurveUtils.GetTangent(Vertices, 0, ClosedLoop);

            fCur.Origin = (Vector3f)Vertices[0];
            fCur.AlignAxis(2, (Vector3f)dv);
            Frame3f fStart = new Frame3f(fCur);

            double circumference = Polygon.ArcLength;
            double pathLength    = CurveUtils.ArcLength(Vertices, ClosedLoop);
            double accum_path_u  = 0;

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                int vi = ri % NV;

                // propagate frame
                Vector3d tangent = CurveUtils.GetTangent(Vertices, vi, ClosedLoop);
                fCur.Origin = (Vector3f)Vertices[vi];
                fCur.AlignAxis(2, (Vector3f)tangent);

                // generate vertices
                int nStartR = ri * nRingSize;

                double accum_ring_v = 0;
                for (int j = 0; j < nRingSize; ++j)
                {
                    int      k      = nStartR + j;
                    Vector2d pv     = Polygon.Vertices[j % Slices];
                    Vector2d pvNext = Polygon.Vertices[(j + 1) % Slices];
                    Vector3d v      = fCur.FromPlaneUV((Vector2f)pv, 2);
                    vertices[k] = v;

                    uv[k]         = new Vector2f(accum_path_u, accum_ring_v);
                    accum_ring_v += (pv.Distance(pvNext) / circumference);

                    Vector3f n = (Vector3f)(v - fCur.Origin).Normalized;
                    normals[k] = n;
                }

                int    viNext = (ri + 1) % NV;
                double d      = Vertices[vi].Distance(Vertices[viNext]);
                accum_path_u += d / pathLength;
            }


            // generate triangles
            int ti    = 0;
            int nStop = (ClosedLoop && NoSharedVertices == false) ? nRings : (nRings - 1);

            for (int ri = 0; ri < nStop; ++ri)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                if (ClosedLoop && ri == nStop - 1 && NoSharedVertices == false)
                {
                    r1 = 0;
                }
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // last quad if we aren't sharing vertices
                {
                    int M = nRingSize - 1;
                    triangles.Set(ti++, r0 + M, r0, r1, Clockwise);
                    triangles.Set(ti++, r0 + M, r1, r1 + M, Clockwise);
                }
            }

            if (Capped && ClosedLoop == false)
            {
                Vector2d c = (OverrideCapCenter) ? CapCenter : Polygon.Bounds.Center;

                // add endcap verts
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = fStart.FromPlaneUV((Vector2f)c, 2);
                uv[nBottomC]        = new Vector2f(0.5f, 0.5f);
                normals[nBottomC]   = -fStart.Z;
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = fCur.FromPlaneUV((Vector2f)c, 2);
                uv[nTopC]         = new Vector2f(0.5f, 0.5f);
                normals[nTopC]    = fCur.Z;
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    // duplicate first loop and make a fan w/ bottom-center
                    int nExistingB = 0;
                    int nStartB    = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartB + k] = vertices[nExistingB + k];
                        Vector2d vuv = ((Polygon[k] - c).Normalized + Vector2d.One) * 0.5;
                        uv[nStartB + k]      = (Vector2f)vuv;
                        normals[nStartB + k] = normals[nBottomC];
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    // duplicate second loop and make fan
                    int nExistingT = nRingSize * (nRings - 1);
                    int nStartT    = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartT + k] = vertices[nExistingT + k];
                        uv[nStartT + k]       = uv[nStartB + k];
                        normals[nStartT + k]  = normals[nTopC];
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti);
                }
            }

            return(this);
        }
Пример #11
0
        /// <summary>
        /// Find point-normal frame at ray-intersection point on mesh, or return false if no hit.
        /// Returns interpolated vertex-normal frame if available, otherwise tri-normal frame.
        /// </summary>
        public static bool RayHitPointFrame(DMesh3 mesh, ISpatial spatial, Ray3d ray, out Frame3f hitPosFrame, bool bForceFaceNormal = false)
        {
            hitPosFrame = new Frame3f();
            int tid = spatial.FindNearestHitTriangle(ray);

            if (tid == DMesh3.InvalidID)
            {
                return(false);
            }

            var isect = TriangleIntersection(mesh, tid, ray);

            if (isect.Result != IntersectionResult.Intersects)
            {
                return(false);
            }

            Vector3d surfPt = ray.PointAt(isect.RayParameter);

            if (mesh.HasVertexNormals && bForceFaceNormal == false)
            {
                hitPosFrame = SurfaceFrame(mesh, tid, surfPt);                      // TODO isect has bary-coords already!!
            }
            else
            {
                hitPosFrame = new Frame3f(surfPt, mesh.GetTriNormal(tid));
            }

            return(true);
        }
Пример #12
0
 /// <summary>
 /// Interpolate between two frames - Lerp for origin, Slerp for rotation
 /// </summary>
 public static Frame3f Interpolate(Frame3f f1, Frame3f f2, float t)
 {
     return(new Frame3f(
                Vector3.Lerp(f1.origin, f2.origin, t),
                Quaternion.Slerp(f1.rotation, f2.rotation, t)));
 }
Пример #13
0
 public void AppendBox(Frame3f frame, float size)
 {
     AppendBox(frame, size * Vector3f.One);
 }
Пример #14
0
 ///<summary> Map frame *into* local coordinates of Frame </summary>
 public Frame3f ToFrame(Frame3f f)
 {
     return(new Frame3f(ToFrameP(f.origin), ToFrame(f.rotation)));
 }
Пример #15
0
 public static Frame3f Interpolate(Frame3f f1, Frame3f f2, float alpha)
 {
     return(new Frame3f(
                Vector3f.Lerp(f1.origin, f2.origin, alpha),
                Quaternionf.Slerp(f1.rotation, f2.rotation, alpha)));
 }
Пример #16
0
 public static Frame3f Rotate(Frame3f f, Vector3d origin, Quaternionf rotation)
 {
     f.Rotate(rotation);
     f.Origin = (Vector3f)Rotate(f.Origin, origin, rotation);
     return(f);
 }
Пример #17
0
        public override void Generate()
        {
            int nRings       = Curve.Length;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false)
            {
                nCapVertices = 0;
            }

            vertices = new VectorArray3d(nRingSize * nRings + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nSpanTris = (nRings - 1) * (2 * Slices);
            int nCapTris  = (Capped) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            float fDelta = (float)((Math.PI * 2.0) / Slices);

            Frame3f f = Axis;

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                Vector3d v_along  = Curve[ri];
                Vector3f v_frame  = f.ToFrameP((Vector3f)v_along);
                float    uv_along = (float)ri / (float)(nRings - 1);

                // generate vertices
                int nStartR = ri * nRingSize;
                for (int j = 0; j < nRingSize; ++j)
                {
                    float angle = (float)j * fDelta;

                    // [TODO] this is not efficient...use Matrix3f?
                    Vector3f v_rot = Quaternionf.AxisAngleR(Vector3f.AxisY, angle) * v_frame;
                    Vector3d v_new = f.FromFrameP(v_rot);
                    int      k     = nStartR + j;
                    vertices[k] = v_new;

                    float uv_around = (float)j / (float)(nRingSize);
                    uv[k] = new Vector2f(uv_along, uv_around);

                    // [TODO] proper normal
                    Vector3f n = (Vector3f)(v_new - f.Origin).Normalized;
                    normals[k] = n;
                }
            }


            // generate triangles
            int ti = 0;

            for (int ri = 0; ri < nRings - 1; ++ri)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // close disc if we went all the way
                {
                    triangles.Set(ti++, r1 - 1, r0, r1, Clockwise);
                    triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise);
                }
            }



            if (Capped)
            {
                // find avg start loop size
                Vector3d vAvgStart = Vector3d.Zero, vAvgEnd = Vector3d.Zero;
                for (int k = 0; k < Slices; ++k)
                {
                    vAvgStart += vertices[k];
                    vAvgEnd   += vertices[(nRings - 1) * nRingSize + k];
                }
                vAvgStart /= (double)Slices;
                vAvgEnd   /= (double)Slices;

                Frame3f fStart = f;
                fStart.Origin = (Vector3f)vAvgStart;
                Frame3f fEnd = f;
                fEnd.Origin = (Vector3f)vAvgEnd;



                // add endcap verts
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = fStart.Origin;
                uv[nBottomC]        = new Vector2f(0.5f, 0.5f);
                normals[nBottomC]   = -fStart.Z;
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = fEnd.Origin;
                uv[nTopC]         = new Vector2f(0.5f, 0.5f);
                normals[nTopC]    = fEnd.Z;
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    // duplicate first loop and make a fan w/ bottom-center
                    int nExistingB = 0;
                    int nStartB    = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartB + k] = vertices[nExistingB + k];
                        //uv[nStartB + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartB + k] = new Vector2f(0.5f * (1.0f + cosa), 0.5f * (1 + sina));

                        normals[nStartB + k] = normals[nBottomC];
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    // duplicate second loop and make fan
                    int nExistingT = nRingSize * (nRings - 1);
                    int nStartT    = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartT + k] = vertices[nExistingT + k];
                        //uv[nStartT + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartT + k] = new Vector2f(0.5f * (1.0f + cosa), 0.5f * (1 + sina));


                        normals[nStartT + k] = normals[nTopC];
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti);
                }
            }
        }
Пример #18
0
 public void AppendBox(Frame3f frame, Vector3f size)
 {
     AppendBox(frame, size, Colorf.White);
 }
Пример #19
0
        public override DeformInfo Apply(Frame3f vNextPos)
        {
            Interval1d edgeRangeSqr = Interval1d.Empty;

            int N = Curve.VertexCount;

            if (N > NewV.size)
            {
                NewV.resize(N);
            }
            if (N > ModifiedV.Length)
            {
                ModifiedV = new BitArray(2 * N);
            }

            // clear modified
            ModifiedV.SetAll(false);

            bool   bSmooth = (SmoothAlpha > 0 && SmoothIterations > 0);
            double r2      = Radius * Radius;

            // deform pass
            if (DeformF != null)
            {
                for (int i = 0; i < N; ++i)
                {
                    Vector3d v  = Curve[i];
                    double   d2 = (v - vPreviousPos.Origin).LengthSquared;
                    if (d2 < r2)
                    {
                        double t = WeightFunc(Math.Sqrt(d2), Radius);

                        Vector3d vNew = DeformF(i, t);

                        if (bSmooth == false)
                        {
                            if (i > 0)
                            {
                                edgeRangeSqr.Contain(vNew.DistanceSquared(Curve[i - 1]));
                            }
                            if (i < N - 1)
                            {
                                edgeRangeSqr.Contain(vNew.DistanceSquared(Curve[i + 1]));
                            }
                        }

                        NewV[i]      = vNew;
                        ModifiedV[i] = true;
                    }
                }
            }
            else
            {
                // anything?
            }

            // smooth pass
            if (bSmooth)
            {
                for (int j = 0; j < SmoothIterations; ++j)
                {
                    int iStart = (Curve.Closed) ? 0 : 1;
                    int iEnd   = (Curve.Closed) ? N : N - 1;
                    for (int i = iStart; i < iEnd; ++i)
                    {
                        Vector3d v  = (ModifiedV[i]) ? NewV[i] : Curve[i];
                        double   d2 = (v - vPreviousPos.Origin).LengthSquared;
                        if (ModifiedV[i] || d2 < r2)            // always smooth any modified verts
                        {
                            double a = SmoothAlpha * WeightFunc(Math.Sqrt(d2), Radius);

                            int      iPrev = (i == 0) ? N - 1 : i - 1;
                            int      iNext = (i + 1) % N;
                            Vector3d vPrev = (ModifiedV[iPrev]) ? NewV[iPrev] : Curve[iPrev];
                            Vector3d vNext = (ModifiedV[iNext]) ? NewV[iNext] : Curve[iNext];
                            Vector3d c     = (vPrev + vNext) * 0.5f;
                            NewV[i]      = (1 - a) * v + (a) * c;
                            ModifiedV[i] = true;

                            if (i > 0)
                            {
                                edgeRangeSqr.Contain(NewV[i].DistanceSquared(Curve[i - 1]));
                            }
                            if (i < N - 1)
                            {
                                edgeRangeSqr.Contain(NewV[i].DistanceSquared(Curve[i + 1]));
                            }
                        }
                    }
                }
            }

            // bake
            for (int i = 0; i < N; ++i)
            {
                if (ModifiedV[i])
                {
                    Curve[i] = NewV[i];
                }
            }

            return(new DeformInfo()
            {
                minEdgeLenSqr = edgeRangeSqr.a, maxEdgeLenSqr = edgeRangeSqr.b
            });
        }
Пример #20
0
 public Cylinder3d(Frame3f frame, double radius, double height, int nNormalAxis = 1)
 {
     Axis   = new Line3d(frame.Origin, frame.GetAxis(nNormalAxis));
     Radius = radius;
     Height = height;
 }
Пример #21
0
 public abstract DeformInfo Apply(Frame3f vNextPos);
Пример #22
0
 public virtual void BeginDeformation(Frame3f vStartPos)
 {
     vPreviousPos = vStartPos;
 }
Пример #23
0
        override public void Generate()
        {
            if (Polygon == null)
            {
                Polygon = Polygon2d.MakeCircle(1.0f, 8);
            }

            int Slices       = Polygon.VertexCount;
            int nRings       = Vertices.Count;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false)
            {
                nCapVertices = 0;
            }

            vertices = new VectorArray3d(nRings * nRingSize + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nSpanTris = (Vertices.Count - 1) * (2 * Slices);
            int nCapTris  = (Capped) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            Frame3f  fCur = new Frame3f(Frame);
            Vector3d dv   = CurveUtils.GetTangent(Vertices, 0);;

            fCur.Origin = (Vector3f)Vertices[0];
            fCur.AlignAxis(2, (Vector3f)dv);
            Frame3f fStart = new Frame3f(fCur);

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                // propagate frame
                if (ri != 0)
                {
                    Vector3d tan = CurveUtils.GetTangent(Vertices, ri);
                    fCur.Origin = (Vector3f)Vertices[ri];
                    if (ri == 11)
                    {
                        dv = tan;
                    }
                    fCur.AlignAxis(2, (Vector3f)tan);
                }

                float uv_along = (float)ri / (float)(nRings - 1);

                // generate vertices
                int nStartR = ri * nRingSize;
                for (int j = 0; j < nRingSize; ++j)
                {
                    float uv_around = (float)j / (float)(nRings);

                    int      k  = nStartR + j;
                    Vector2d pv = Polygon.Vertices[j % Slices];
                    Vector3d v  = fCur.FromFrameP((Vector2f)pv, 2);
                    vertices[k] = v;
                    uv[k]       = new Vector2f(uv_along, uv_around);
                    Vector3f n = (Vector3f)(v - fCur.Origin).Normalized;
                    normals[k] = n;
                }
            }


            // generate triangles
            int ti = 0;

            for (int ri = 0; ri < nRings - 1; ++ri)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // close disc if we went all the way
                {
                    triangles.Set(ti++, r1 - 1, r0, r1, Clockwise);
                    triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise);
                }
            }

            if (Capped)
            {
                // add endcap verts
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = fStart.Origin;
                uv[nBottomC]        = new Vector2f(0.5f, 0.5f);
                normals[nBottomC]   = -fStart.Z;
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = fCur.Origin;
                uv[nTopC]         = new Vector2f(0.5f, 0.5f);
                normals[nTopC]    = fCur.Z;
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    // duplicate first loop and make a fan w/ bottom-center
                    int nExistingB = 0;
                    int nStartB    = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartB + k] = vertices[nExistingB + k];
                        uv[nStartB + k]       = (Vector2f)Polygon.Vertices[k].Normalized;
                        normals[nStartB + k]  = normals[nBottomC];
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    // duplicate second loop and make fan
                    int nExistingT = nRingSize * (nRings - 1);
                    int nStartT    = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartT + k] = vertices[nExistingT + k];
                        uv[nStartT + k]       = (Vector2f)Polygon.Vertices[k].Normalized;
                        normals[nStartT + k]  = normals[nTopC];
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti);
                }
            }
        }
Пример #24
0
		///<summary> Map frame *into* local coordinates of Frame </summary>
		public Frame3f ToFrame(ref Frame3f f)
		{
			return new Frame3f(ToFrameP(ref f.origin), ToFrame(ref f.rotation));
		}
Пример #25
0
 public Frame3f(Frame3f copy)
 {
     this.rotation = copy.rotation;
     this.origin   = copy.origin;
 }
Пример #26
0
		/// <summary> Map frame *from* local frame coordinates into "world" coordinates </summary>
		public Frame3f FromFrame(ref Frame3f f)
		{
			return new Frame3f(FromFrameP(ref f.origin), FromFrame(ref f.rotation));
		}
Пример #27
0
 /// <summary> Map frame *from* local frame coordinates into "world" coordinates </summary>
 public Frame3f FromFrame(Frame3f f)
 {
     return(new Frame3f(FromFrameP(f.origin), FromFrame(f.rotation)));
 }
Пример #28
0
 public bool PrecisionEqual(Frame3f f2, int nDigits)
 {
     return(origin.PrecisionEqual(f2.origin, nDigits) &&
            rotation.PrecisionEqual(f2.rotation, nDigits));
 }
Пример #29
0
 public bool EpsilonEqual(Frame3f f2, float epsilon)
 {
     return(origin.EpsilonEqual(f2.origin, epsilon) &&
            rotation.EpsilonEqual(f2.rotation, epsilon));
 }
        void constrained_smooth(DGraph3 graph, double surfDist, double dotThresh, double alpha, int rounds)
        {
            int NV = graph.MaxVertexID;
            Vector3d[] pos = new Vector3d[NV];

            for (int ri = 0; ri < rounds; ++ri) {

                gParallel.ForEach(graph.VertexIndices(), (vid) => {
                    Vector3d v = graph.GetVertex(vid);

                    if ( GroundVertices.Contains(vid) || TipVertices.Contains(vid) ) {
                        pos[vid] = v;
                        return;
                    }

                    // for tip base vertices, we could allow them to move down and away within angle cone...
                    if (TipBaseVertices.Contains(vid)) {
                        pos[vid] = v;
                        return;
                    }

                    // compute smoothed position of vtx
                    Vector3d centroid = Vector3d.Zero; int nbr_count = 0;
                    foreach (int nbr_vid in graph.VtxVerticesItr(vid)) {
                        centroid += graph.GetVertex(nbr_vid);
                        nbr_count++;
                    }
                    if (nbr_count == 1) {
                        pos[vid] = v;
                        return;
                    }
                    centroid /= nbr_count;
                    Vector3d vnew = (1 - alpha) * v + (alpha) * centroid;

                    // make sure we don't violate angle constraint to any nbrs
                    int attempt = 0;
                    try_again:
                    foreach ( int nbr_vid in graph.VtxVerticesItr(vid)) {
                        Vector3d dv = graph.GetVertex(nbr_vid) - vnew;
                        dv.Normalize();
                        double dot = dv.Dot(Vector3d.AxisY);
                        if ( Math.Abs(dot) < dotThresh ) {
                            if (attempt++ < 3) {
                                vnew = Vector3d.Lerp(v, vnew, 0.66);
                                goto try_again;
                            } else {
                                pos[vid] = v;
                                return;
                            }
                        }
                    }

                    // offset from nearest point on surface
                    Frame3f fNearest = MeshQueries.NearestPointFrame(Mesh, MeshSpatial, vnew, true);
                    Vector3d vNearest = fNearest.Origin;
                    double dist = vnew.Distance(vNearest);
                    bool inside = MeshSpatial.IsInside(vnew);

                    if (inside || dist < surfDist) {
                        Vector3d normal = fNearest.Z;
                        // don't push down?
                        if (normal.Dot(Vector3d.AxisY) < 0) {
                            normal.y = 0; normal.Normalize();
                        }
                        vnew = fNearest.Origin + surfDist * normal;
                    }

                    pos[vid] = vnew;
                });

                foreach (int vid in graph.VertexIndices())
                    graph.SetVertex(vid, pos[vid]);
            }
        }