public DCurve3 ToCurve()
        {
            DCurve3 curve = MeshUtil.ExtractLoopV(Mesh, Vertices);

            curve.Closed = true;
            return(curve);
        }
        /// <summary>
        /// Resample curve so that:
        ///   - if opening angle at vertex is > sharp_thresh, we emit two more vertices at +/- corner_t, where the t is used in prev/next lerps
        ///   - if opening angle is > flat_thresh, we skip the vertex entirely (simplification)
        /// This is mainly useful to get nicer polylines to use as the basis for (eg) creating 3D tubes, rendering, etc
        ///
        /// [TODO] skip tiny segments?
        /// </summary>
        public DCurve3 ResampleSharpTurns(double sharp_thresh = 90, double flat_thresh = 189, double corner_t = 0.01)
        {
            int     NV        = vertices.Count;
            DCurve3 resampled = new DCurve3()
            {
                Closed = this.Closed
            };
            double prev_t = 1.0 - corner_t;

            for (int k = 0; k < NV; ++k)
            {
                double open_angle = Math.Abs(OpeningAngleDeg(k));
                if (open_angle > flat_thresh && k > 0)
                {
                    // ignore skip this vertex
                }
                else if (open_angle > sharp_thresh)
                {
                    resampled.AppendVertex(vertices[k]);
                }
                else
                {
                    Vector3d n = vertices[(k + 1) % NV];
                    Vector3d p = vertices[k == 0 ? NV - 1 : k - 1];
                    resampled.AppendVertex(Vector3d.Lerp(p, vertices[k], prev_t));
                    resampled.AppendVertex(vertices[k]);
                    resampled.AppendVertex(Vector3d.Lerp(vertices[k], n, corner_t));
                }
            }
            return(resampled);
        }
Beispiel #3
0
 public TubeGenerator(DCurve3 tubePath, Polygon2d tubeShape)
 {
     Vertices   = new List <Vector3d>(tubePath.Vertices);
     Polygon    = new Polygon2d(tubeShape);
     ClosedLoop = tubePath.Closed;
     Capped     = !ClosedLoop;
 }
Beispiel #4
0
 public InPlaceIterativeCurveSmooth(DCurve3 curve, float alpha = 0.25f)
 {
     Curve = curve;
     Start = 0;
     End   = Curve.VertexCount;
     Alpha = alpha;
 }
 public ImplicitCurve3d(DCurve3 curve, double radius)
 {
     Curve = curve;
     Radius = radius;
     Box = curve.GetBoundingBox();
     Box.Expand(Radius);
     spatial = new DCurve3BoxTree(curve);
 }
Beispiel #6
0
 /// <summary>
 /// Creates g3.DCurve from Vector3[]
 /// </summary>
 /// <param name="curve">DCurve</param>
 /// <param name="verteces">Vextor3[]</param>
 /// <param name="bClosed">whether the line is closed</param>
 public static void Vector3(this g3.DCurve3 curve, Vector3[] verteces, bool bClosed)
 {
     curve.ClearVertices();
     curve.Closed = bClosed;
     foreach (Vector3 vertex in verteces)
     {
         curve.AppendVertex(vertex);
     }
 }
Beispiel #7
0
        public DCurve3BoxTree(DCurve3 curve)
        {
            if (curve.Closed == false)
            {
                throw new NotImplementedException("not done yet");
            }

            Curve = curve;
            build_sequential(curve);
        }
        public void Make(DCurve3 c)
        {
            int nV = vertices.Count;

            for (int i = 0; i < nV; ++i)
            {
                c.AppendVertex(vertices[i]);
            }
            c.Closed = closed;
        }
        public static DCurve3 ExtractLoopV(IMesh mesh, IEnumerable <int> vertices)
        {
            DCurve3 curve = new DCurve3();

            foreach (int vid in vertices)
            {
                curve.AppendVertex(mesh.GetVertex(vid));
            }
            curve.Closed = true;
            return(curve);
        }
Beispiel #10
0
 public static void Store(DCurve3 curve, BinaryWriter writer)
 {
     writer.Write(curve.Closed);
     writer.Write(curve.VertexCount);
     for (int i = 0; i < curve.VertexCount; ++i)
     {
         writer.Write(curve[i].x);
         writer.Write(curve[i].y);
         writer.Write(curve[i].z);
     }
 }
Beispiel #11
0
        public static void PreserveBoundaryLoops(MeshConstraints cons, DMesh3 mesh)
        {
            MeshBoundaryLoops loops = new MeshBoundaryLoops(mesh);

            foreach (EdgeLoop loop in loops)
            {
                DCurve3 loopC = MeshUtil.ExtractLoopV(mesh, loop.Vertices);
                DCurveProjectionTarget target = new DCurveProjectionTarget(loopC);
                ConstrainVtxLoopTo(cons, mesh, loop.Vertices, target);
            }
        }
        public DCurve3 ToCurve(DMesh3 sourceMesh = null)
        {
            if (sourceMesh == null)
            {
                sourceMesh = Mesh;
            }
            DCurve3 curve = MeshUtil.ExtractLoopV(sourceMesh, Vertices);

            curve.Closed = false;
            return(curve);
        }
        public static DCurve3 ExtractLoopV(IMesh mesh, int[] vertices)
        {
            DCurve3 curve = new DCurve3();

            for (int i = 0; i < vertices.Length; ++i)
            {
                curve.AppendVertex(mesh.GetVertex(vertices[i]));
            }
            curve.Closed = true;
            return(curve);
        }
Beispiel #14
0
        public static void Restore(DCurve3 curve, BinaryReader reader)
        {
            curve.Closed = reader.ReadBoolean();
            int count = reader.ReadInt32();

            for (int i = 0; i < count; ++i)
            {
                double x = reader.ReadDouble();
                double y = reader.ReadDouble();
                double z = reader.ReadDouble();
                curve.AppendVertex(new Vector3d(x, y, z));
            }
        }
Beispiel #15
0
 public MeshTrimLoop(DMesh3 mesh, DCurve3 trimline, Vector3d vSeedPt, DMeshAABBTree3 spatial = null)
 {
     if (spatial != null && spatial.Mesh == mesh)
     {
         throw new ArgumentException("MeshTrimLoop: input spatial DS must have its own copy of mesh");
     }
     Mesh     = mesh;
     TrimLine = new DCurve3(trimline);
     if (spatial != null)
     {
         Spatial = spatial;
     }
     seed_pt = vSeedPt;
 }
        public MeshFacesFromLoop(DMesh3 Mesh, DCurve3 SpaceCurve, ISpatial Spatial, int tSeed)
        {
            this.Mesh = Mesh;

            int N = SpaceCurve.VertexCount;

            InitialLoopT = new int[N];
            for (int i = 0; i < N; ++i)
            {
                InitialLoopT[i] = Spatial.FindNearestTriangle(SpaceCurve[i]);
            }

            find_path();
            find_interior_from_seed(tSeed);
        }
Beispiel #17
0
        /// <summary>
        /// Decompose graph into simple polylines and polygons.
        /// </summary>
        public static Curves ExtractCurves(DGraph3 graph)
        {
            Curves c = new Curves();

            c.Loops = new List <DCurve3>();
            c.Paths = new List <DCurve3>();

            HashSet <int> used = new HashSet <int>();

            // find boundary and junction vertices
            HashSet <int> boundaries = new HashSet <int>();
            HashSet <int> junctions  = new HashSet <int>();

            foreach (int vid in graph.VertexIndices())
            {
                if (graph.IsBoundaryVertex(vid))
                {
                    boundaries.Add(vid);
                }
                if (graph.IsJunctionVertex(vid))
                {
                    junctions.Add(vid);
                }
            }

            // walk paths from boundary vertices
            foreach (int start_vid in boundaries)
            {
                int vid = start_vid;
                int eid = graph.GetVtxEdges(vid)[0];
                if (used.Contains(eid))
                {
                    continue;
                }

                DCurve3 path = new DCurve3()
                {
                    Closed = false
                };
                path.AppendVertex(graph.GetVertex(vid));
                while (true)
                {
                    used.Add(eid);
                    Index2i next = NextEdgeAndVtx(eid, vid, graph);
                    eid = next.a;
                    vid = next.b;
                    path.AppendVertex(graph.GetVertex(vid));
                    if (boundaries.Contains(vid) || junctions.Contains(vid))
                    {
                        break;  // done!
                    }
                }
                c.Paths.Add(path);
            }

            // ok we should be done w/ boundary verts now...
            boundaries.Clear();


            foreach (int start_vid in junctions)
            {
                foreach (int outgoing_eid in graph.VtxEdgesItr(start_vid))
                {
                    if (used.Contains(outgoing_eid))
                    {
                        continue;
                    }
                    int vid = start_vid;
                    int eid = outgoing_eid;

                    DCurve3 path = new DCurve3()
                    {
                        Closed = false
                    };
                    path.AppendVertex(graph.GetVertex(vid));
                    while (true)
                    {
                        used.Add(eid);
                        Index2i next = NextEdgeAndVtx(eid, vid, graph);
                        eid = next.a;
                        vid = next.b;
                        path.AppendVertex(graph.GetVertex(vid));
                        if (eid == int.MaxValue || junctions.Contains(vid))
                        {
                            break;  // done!
                        }
                    }

                    // we could end up back at our start junction vertex!
                    if (vid == start_vid)
                    {
                        path.RemoveVertex(path.VertexCount - 1);
                        path.Closed = true;
                        c.Loops.Add(path);
                        // need to mark incoming edge as used...but is it valid now?
                        //Util.gDevAssert(eid != int.MaxValue);
                        if (eid != int.MaxValue)
                        {
                            used.Add(eid);
                        }
                    }
                    else
                    {
                        c.Paths.Add(path);
                    }
                }
            }


            // all that should be left are continuous loops...
            foreach (int start_eid in graph.EdgeIndices())
            {
                if (used.Contains(start_eid))
                {
                    continue;
                }

                int     eid = start_eid;
                Index2i ev  = graph.GetEdgeV(eid);
                int     vid = ev.a;

                DCurve3 poly = new DCurve3()
                {
                    Closed = true
                };
                poly.AppendVertex(graph.GetVertex(vid));
                while (true)
                {
                    used.Add(eid);
                    Index2i next = NextEdgeAndVtx(eid, vid, graph);
                    eid = next.a;
                    vid = next.b;
                    poly.AppendVertex(graph.GetVertex(vid));
                    if (eid == int.MaxValue || junctions.Contains(vid))
                    {
                        throw new Exception("how did this happen??");
                    }
                    if (used.Contains(eid))
                    {
                        break;
                    }
                }
                poly.RemoveVertex(poly.VertexCount - 1);
                c.Loops.Add(poly);
            }


            return(c);
        }
Beispiel #18
0
        /// <summary>
        /// Decompose graph into simple polylines and polygons.
        /// </summary>
        public static Curves ExtractCurves(DGraph3 graph,
                                           bool bWantLoopIndices = false,
                                           Func <int, bool> CurveOrientationF = null)
        {
            var c = new Curves();

            c.Loops = new List <DCurve3>();
            c.Paths = new List <DCurve3>();
            if (bWantLoopIndices)
            {
                c.LoopEdges = new List <List <int> >();
                c.PathEdges = new List <List <int> >();
            }

            var used = new HashSet <int>();

            // find boundary and junction vertices
            var boundaries = new HashSet <int>();
            var junctions  = new HashSet <int>();

            foreach (int vid in graph.VertexIndices())
            {
                if (graph.IsBoundaryVertex(vid))
                {
                    boundaries.Add(vid);
                }

                if (graph.IsJunctionVertex(vid))
                {
                    junctions.Add(vid);
                }
            }

            // walk paths from boundary vertices
            foreach (int start_vid in boundaries)
            {
                int vid = start_vid;
                int eid = graph.GetVtxEdges(vid)[0];
                if (used.Contains(eid))
                {
                    continue;
                }

                bool reverse = (CurveOrientationF != null) ? CurveOrientationF(eid) : false;

                var path = new DCurve3()
                {
                    Closed = false
                };
                List <int> pathE = (bWantLoopIndices) ? new List <int>() : null;
                path.AppendVertex(graph.GetVertex(vid));
                if (pathE != null)
                {
                    pathE.Add(eid);
                }

                while (true)
                {
                    used.Add(eid);
                    Index2i next = NextEdgeAndVtx(eid, vid, graph);
                    eid = next.a;
                    vid = next.b;
                    path.AppendVertex(graph.GetVertex(vid));
                    if (boundaries.Contains(vid) || junctions.Contains(vid))
                    {
                        break;                          // done!
                    }

                    if (pathE != null)
                    {
                        pathE.Add(eid);
                    }
                }
                if (reverse)
                {
                    path.Reverse();
                }

                c.Paths.Add(path);

                if (pathE != null)
                {
                    Util.gDevAssert(pathE.Count == path.VertexCount - 1);
                    if (reverse)
                    {
                        pathE.Reverse();
                    }

                    c.PathEdges.Add(pathE);
                }
            }

            // ok we should be done w/ boundary verts now...
            //boundaries.Clear();
            c.BoundaryV = boundaries;


            foreach (int start_vid in junctions)
            {
                foreach (int outgoing_eid in graph.VtxEdgesItr(start_vid))
                {
                    if (used.Contains(outgoing_eid))
                    {
                        continue;
                    }

                    int vid = start_vid;
                    int eid = outgoing_eid;

                    bool reverse = (CurveOrientationF != null) ? CurveOrientationF(eid) : false;

                    var path = new DCurve3()
                    {
                        Closed = false
                    };
                    List <int> pathE = (bWantLoopIndices) ? new List <int>() : null;
                    path.AppendVertex(graph.GetVertex(vid));
                    if (pathE != null)
                    {
                        pathE.Add(eid);
                    }

                    while (true)
                    {
                        used.Add(eid);
                        Index2i next = NextEdgeAndVtx(eid, vid, graph);
                        eid = next.a;
                        vid = next.b;
                        path.AppendVertex(graph.GetVertex(vid));
                        if (eid == int.MaxValue || junctions.Contains(vid))
                        {
                            break;                              // done!
                        }

                        if (pathE != null)
                        {
                            pathE.Add(eid);
                        }
                    }

                    // we could end up back at our start junction vertex!
                    if (vid == start_vid)
                    {
                        path.RemoveVertex(path.VertexCount - 1);
                        path.Closed = true;
                        if (reverse)
                        {
                            path.Reverse();
                        }

                        c.Loops.Add(path);

                        if (pathE != null)
                        {
                            Util.gDevAssert(pathE.Count == path.VertexCount);
                            if (reverse)
                            {
                                pathE.Reverse();
                            }

                            c.LoopEdges.Add(pathE);
                        }

                        // need to mark incoming edge as used...but is it valid now?
                        //Util.gDevAssert(eid != int.MaxValue);
                        if (eid != int.MaxValue)
                        {
                            used.Add(eid);
                        }
                    }
                    else
                    {
                        if (reverse)
                        {
                            path.Reverse();
                        }

                        c.Paths.Add(path);

                        if (pathE != null)
                        {
                            Util.gDevAssert(pathE.Count == path.VertexCount - 1);
                            if (reverse)
                            {
                                pathE.Reverse();
                            }

                            c.PathEdges.Add(pathE);
                        }
                    }
                }
            }
            c.JunctionV = junctions;


            // all that should be left are continuous loops...
            foreach (int start_eid in graph.EdgeIndices())
            {
                if (used.Contains(start_eid))
                {
                    continue;
                }

                int     eid = start_eid;
                Index2i ev  = graph.GetEdgeV(eid);
                int     vid = ev.a;

                bool reverse = (CurveOrientationF != null) ? CurveOrientationF(eid) : false;

                var poly = new DCurve3()
                {
                    Closed = true
                };
                List <int> polyE = (bWantLoopIndices) ? new List <int>() : null;
                poly.AppendVertex(graph.GetVertex(vid));
                if (polyE != null)
                {
                    polyE.Add(eid);
                }

                while (true)
                {
                    used.Add(eid);
                    Index2i next = NextEdgeAndVtx(eid, vid, graph);
                    eid = next.a;
                    vid = next.b;
                    poly.AppendVertex(graph.GetVertex(vid));
                    if (polyE != null)
                    {
                        polyE.Add(eid);
                    }

                    if (eid == int.MaxValue || junctions.Contains(vid))
                    {
                        throw new Exception("how did this happen??");
                    }

                    if (used.Contains(eid))
                    {
                        break;
                    }
                }
                poly.RemoveVertex(poly.VertexCount - 1);
                if (reverse)
                {
                    poly.Reverse();
                }

                c.Loops.Add(poly);

                if (polyE != null)
                {
                    polyE.RemoveAt(polyE.Count - 1);
                    Util.gDevAssert(polyE.Count == poly.VertexCount);
                    if (reverse)
                    {
                        polyE.Reverse();
                    }

                    c.LoopEdges.Add(polyE);
                }
            }

            return(c);
        }
Beispiel #19
0
        // build tree of boxes as sequential array
        void build_sequential(DCurve3 curve)
        {
            int NV       = curve.VertexCount;
            int N        = NV;
            int boxCount = 0;

            layers       = 0;
            layer_counts = new List <int>();

            // count how many boxes in each layer, building up from initial segments
            int bi = 0;

            while (N > 1)
            {
                int layer_boxes = (N / 2) + (N % 2 == 0 ? 0 : 1);
                boxCount += layer_boxes;
                N         = layer_boxes;

                layer_counts.Add(layer_boxes);
                bi += layer_boxes;
                layers++;
            }


            boxes = new Box3d[boxCount];
            bi    = 0;

            // make first layer
            for (int si = 0; si < NV; si += 2)
            {
                Vector3d  v1   = curve[(si + 1) % NV];
                Segment3d seg1 = new Segment3d(curve[si], v1);
                Box3d     box  = new Box3d(seg1);
                if (si < NV - 1)
                {
                    Segment3d seg2 = new Segment3d(v1, curve[(si + 2) % NV]);
                    Box3d     box2 = new Box3d(seg2);
                    box = Box3d.Merge(ref box, ref box2);
                }
                boxes[bi++] = box;
            }

            // repeatedly build layers until we hit a single box
            N = bi;
            int  prev_layer_start = 0;
            bool done             = false;

            while (done == false)
            {
                int layer_start = bi;

                for (int k = 0; k < N; k += 2)
                {
                    Box3d mbox = Box3d.Merge(ref boxes[prev_layer_start + k], ref boxes[prev_layer_start + k + 1]);
                    boxes[bi++] = mbox;
                }

                N = (N / 2) + (N % 2 == 0 ? 0 : 1);
                prev_layer_start = layer_start;
                if (N == 1)
                {
                    done = true;
                }
            }
        }
Beispiel #20
0
 public DCurveProjectionTarget(DCurve3 curve)
 {
     this.Curve = curve;
 }
Beispiel #21
0
        public void Close_Flat()
        {
            double minlen, maxlen, avglen;

            MeshQueries.EdgeLengthStats(Mesh, out minlen, out maxlen, out avglen, 1000);
            double target_edge_len = (TargetEdgeLen <= 0) ? avglen : TargetEdgeLen;

            // massage around boundary loop
            List <int> refinedBorderEdges;

            cleanup_boundary(Mesh, InitialBorderLoop, avglen, out refinedBorderEdges, 3);

            // find new border loop. try to find new loop containing edges from loop we refined in cleanup_boundary,
            // if that fails just use largest loop.
            MeshBoundaryLoops loops = new MeshBoundaryLoops(Mesh);
            int iloop = loops.FindLoopContainingEdge(refinedBorderEdges[0]);

            if (iloop == -1)
            {
                iloop = loops.MaxVerticesLoopIndex;
            }
            EdgeLoop fill_loop = loops.Loops[iloop];

            int extrude_group = (ExtrudeGroup == -1) ? Mesh.AllocateTriangleGroup() : ExtrudeGroup;
            int fill_group    = (FillGroup == -1) ? Mesh.AllocateTriangleGroup() : FillGroup;

            // decide on projection plane
            //AxisAlignedBox3d loopbox = fill_loop.GetBounds();
            //Vector3d topPt = loopbox.Center;
            //if ( bIsUpper ) {
            //    topPt.y = loopbox.Max.y + 0.25 * dims.y;
            //} else {
            //    topPt.y = loopbox.Min.y - 0.25 * dims.y;
            //}
            //Frame3f plane = new Frame3f((Vector3f)topPt);

            // extrude loop to this plane
            MeshExtrudeLoop extrude = new MeshExtrudeLoop(Mesh, fill_loop);

            extrude.PositionF = (v, n, i) => {
                return(FlatClosePlane.ProjectToPlane((Vector3f)v, 1));
            };
            extrude.Extrude(extrude_group);
            MeshValidation.IsBoundaryLoop(Mesh, extrude.NewLoop);

            Debug.Assert(Mesh.CheckValidity());

            // smooth the extrude loop
            MeshLoopSmooth loop_smooth = new MeshLoopSmooth(Mesh, extrude.NewLoop);

            loop_smooth.ProjectF = (v, i) => {
                return(FlatClosePlane.ProjectToPlane((Vector3f)v, 1));
            };
            loop_smooth.Alpha  = 0.5f;
            loop_smooth.Rounds = 100;
            loop_smooth.Smooth();

            Debug.Assert(Mesh.CheckValidity());

            // fill result
            SimpleHoleFiller filler = new SimpleHoleFiller(Mesh, extrude.NewLoop);

            filler.Fill(fill_group);

            Debug.Assert(Mesh.CheckValidity());

            // make selection for remesh region
            MeshFaceSelection remesh_roi = new MeshFaceSelection(Mesh);

            remesh_roi.Select(extrude.NewTriangles);
            remesh_roi.Select(filler.NewTriangles);
            remesh_roi.ExpandToOneRingNeighbours();
            remesh_roi.ExpandToOneRingNeighbours();
            remesh_roi.LocalOptimize(true, true);
            int[] new_roi = remesh_roi.ToArray();

            // get rid of extrude group
            FaceGroupUtil.SetGroupToGroup(Mesh, extrude_group, 0);

            /*  clean up via remesh
             *     - constrain loop we filled to itself
             */

            RegionRemesher r = new RegionRemesher(Mesh, new_roi);

            DCurve3 top_curve = MeshUtil.ExtractLoopV(Mesh, extrude.NewLoop.Vertices);
            DCurveProjectionTarget curve_target = new DCurveProjectionTarget(top_curve);

            int[] top_loop = (int[])extrude.NewLoop.Vertices.Clone();
            r.Region.MapVerticesToSubmesh(top_loop);
            MeshConstraintUtil.ConstrainVtxLoopTo(r.Constraints, r.Mesh, top_loop, curve_target);

            DMeshAABBTree3 spatial = new DMeshAABBTree3(Mesh);

            spatial.Build();
            MeshProjectionTarget target = new MeshProjectionTarget(Mesh, spatial);

            r.SetProjectionTarget(target);

            bool bRemesh = true;

            if (bRemesh)
            {
                r.Precompute();
                r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
                r.MinEdgeLength   = target_edge_len;
                r.MaxEdgeLength   = 2 * target_edge_len;
                r.EnableSmoothing = true;
                r.SmoothSpeedT    = 1.0f;
                for (int k = 0; k < 40; ++k)
                {
                    r.BasicRemeshPass();
                }
                r.SetProjectionTarget(null);
                r.SmoothSpeedT = 0.25f;
                for (int k = 0; k < 10; ++k)
                {
                    r.BasicRemeshPass();
                }
                Debug.Assert(Mesh.CheckValidity());

                r.BackPropropagate();
            }

            // smooth around the join region to clean up ugliness
            smooth_region(Mesh, r.Region.BaseBorderV, 3);
        }
Beispiel #22
0
 public DCurveProjection(DCurve3 curve)
 {
     this.Curve = curve;
 }
Beispiel #23
0
 public DCurve3BoxTree(DCurve3 curve)
 {
     Curve = curve;
     build_sequential(curve);
 }
Beispiel #24
0
        // build tree of boxes as sequential array
        void build_sequential(DCurve3 curve)
        {
            int NV       = curve.VertexCount;
            int N        = (curve.Closed) ? NV : NV - 1;
            int boxCount = 0;

            layers       = 0;
            layer_counts = new List <int>();

            // count how many boxes in each layer, building up from initial segments
            int bi = 0;

            while (N > 1)
            {
                int layer_boxes = (N / 2) + (N % 2 == 0 ? 0 : 1);
                boxCount += layer_boxes;
                N         = layer_boxes;

                layer_counts.Add(layer_boxes);
                bi += layer_boxes;
                layers++;
            }
            // [RMS] this case happens if N = 1, previous loop is skipped and we have to
            // hardcode initialization to this redundant box
            if (layers == 0)
            {
                layers       = 1;
                boxCount     = 1;
                layer_counts = new List <int>()
                {
                    1
                };
            }

            boxes = new Box3d[boxCount];
            bi    = 0;

            // make first layer
            int NStop = (curve.Closed) ? NV : NV - 1;

            for (int si = 0; si < NStop; si += 2)
            {
                Vector3d v1   = curve[(si + 1) % NV];
                var      seg1 = new Segment3d(curve[si], v1);
                var      box  = new Box3d(seg1);
                if (si < NV - 1)
                {
                    var seg2 = new Segment3d(v1, curve[(si + 2) % NV]);
                    var box2 = new Box3d(seg2);
                    box = Box3d.Merge(ref box, ref box2);
                }
                boxes[bi++] = box;
            }

            // repeatedly build layers until we hit a single box
            N = bi;
            if (N == 1)
            {
                return;
            }

            int  prev_layer_start = 0;
            bool done             = false;

            while (done == false)
            {
                int layer_start = bi;

                for (int k = 0; k < N; k += 2)
                {
                    var mbox = Box3d.Merge(ref boxes[prev_layer_start + k], ref boxes[prev_layer_start + k + 1]);
                    boxes[bi++] = mbox;
                }

                N = (N / 2) + (N % 2 == 0 ? 0 : 1);
                prev_layer_start = layer_start;
                if (N == 1)
                {
                    done = true;
                }
            }
        }
Beispiel #25
0
 public DCurve3(DCurve3 copy)
 {
     vertices  = new List <Vector3d>(copy.vertices);
     Closed    = copy.Closed;
     Timestamp = 0;
 }
Beispiel #26
0
 public LaplacianCurveDeformer(DCurve3 curve)
 {
     Curve = curve;
 }