Пример #1
0
    private static ComplexArea GetArea(EdgeSpan span)
    {
        var middle = span.GetMidPoint();

        var leftMost   = Math.Min(span.NotInSet.Real, span.InSet.Real);
        var rightMost  = Math.Max(span.NotInSet.Real, span.InSet.Real);
        var bottomMost = Math.Min(span.NotInSet.Imaginary, span.InSet.Imaginary);
        var topMost    = Math.Max(span.NotInSet.Imaginary, span.InSet.Imaginary);

        var horizontalDistance = rightMost - leftMost;
        var verticalDistance   = topMost - bottomMost;

        var horizontalLongest = horizontalDistance > verticalDistance;

        var paddingPercentage = 0.1;

        var sideLength    = horizontalLongest ? horizontalDistance : verticalDistance;
        var paddingLength = paddingPercentage * sideLength;
        var paddedLength  = sideLength + 2 * paddingLength;

        var halfPaddedLength = paddedLength / 2;

        return(new ComplexArea(
                   realRange: new DoubleRange(middle.Real - halfPaddedLength, middle.Real + halfPaddedLength),
                   imagRange: new DoubleRange(middle.Imaginary - halfPaddedLength, middle.Imaginary + halfPaddedLength)));
    }
Пример #2
0
        public static EdgeSpan find_edge_path(DMesh3 mesh, int v0, int v1)
        {
            if (v0 == v1)
            {
                throw new Exception("same vertices!");
            }

            int eid = mesh.FindEdge(v0, v1);

            if (eid >= 0)
            {
                return(EdgeSpan.FromEdges(mesh, new List <int>()
                {
                    eid
                }));
            }

            DijkstraGraphDistance dist = DijkstraGraphDistance.MeshVertices(mesh);

            //DijkstraGraphDistance dist = DijkstraGraphDistance.MeshVerticesSparse(mesh);
            dist.AddSeed(v0, 0);
            dist.ComputeToNode(v1);
            List <int> vpath = new List <int>();
            bool       bOK   = dist.GetPathToSeed(v1, vpath);

            Util.gDevAssert(bOK);
            vpath.Reverse();
            return(EdgeSpan.FromVertices(mesh, vpath));
        }
Пример #3
0
    public void ShouldFindMiddle(double aR, double aI, double bR, double bI, double expectedR, double expectedI)
    {
        var span = new EdgeSpan(new Complex(aR, aI), new Complex(bR, bI));

        var middle = span.GetMidPoint();

        Assert.That(middle.Real, Is.EqualTo(expectedR).Within(0.00000001f), "Incorrect real component.");
        Assert.That(middle.Imaginary, Is.EqualTo(expectedI).Within(0.00000001f), "Incorrect imaginary component.");
    }
Пример #4
0
        Polygon2d to_polygon(EdgeSpan span, Frame3f polyFrame)
        {
            int       NV   = span.VertexCount;
            Polygon2d poly = new Polygon2d();

            for (int k = 0; k < NV; ++k)
            {
                poly.AppendVertex(polyFrame.ToPlaneUV((Vector3f)span.GetVertex(k), 2));
            }
            return(poly);
        }
        public VehicleRegionLink LinkFrom(EdgeSpan span)
        {
            ulong key = span.UniqueHashCode();

            if (!links.TryGetValue(key, out VehicleRegionLink regionLink))
            {
                regionLink      = new VehicleRegionLink();
                regionLink.span = span;
                links.Add(key, regionLink);
            }
            return(regionLink);
        }
Пример #6
0
        public WaterRegionLink LinkFrom(EdgeSpan span)
        {
            ulong           key = span.UniqueHashCode();
            WaterRegionLink regionLink;

            if (!this.links.TryGetValue(key, out regionLink))
            {
                regionLink      = new WaterRegionLink();
                regionLink.span = span;
                this.links.Add(key, regionLink);
            }
            return(regionLink);
        }
Пример #7
0
        private static IntVec3 LinkClosestCell(IntVec3 cell, RegionLink link)
        {
            EdgeSpan span = link.span;
            int      num  = 0;
            int      num2 = 0;

            if (span.dir == SpanDirection.North)
            {
                num2 = span.length - 1;
            }
            else
            {
                num = span.length - 1;
            }
            IntVec3 root = span.root;

            return(new IntVec3(Mathf.Clamp(cell.x, root.x, root.x + num), 0, Mathf.Clamp(cell.z, root.z, root.z + num2)));
        }
    static Complex FindBorderPointMagnitudeSquared(EdgeSpan span, int iterationLimit)
    {
//            var initialLength2 = span.LengthSquared();
        int maxSubdivisions = 38;
        //double oldLength = 0;
        //while (oldLength != initialLength2)
        //{
        //    maxSubdivisions++;
        //    oldLength = initialLength2;
        //    initialLength2 /= 2;
        //}

        //Console.WriteLine(maxSubdivisions);

        double lastLength = 0;

        for (int i = 0; i < maxSubdivisions; i++)
        {
            //var length = span.LengthSquared();
            //if (length == lastLength)
            //{
            //    return span.NotInSet;
            //}
            //lastLength = length;
            var middle = span.GetMidPoint();

            var escapeTime = ScalarDoubleKernel.FindEscapeTime(middle, iterationLimit);

            span = escapeTime.IsInfinite
                ? new EdgeSpan(middle, span.NotInSet)
                : new EdgeSpan(span.InSet, middle);

            //if (i % 10 == 0)
            //{
            //    Console.WriteLine(i);
            //}
        }

        return(span.NotInSet);
    }
Пример #9
0
        // NO DOES NOT WORK. DOES NOT FIND EDGE SPANS THAT ARE IN PLANE BUT HAVE DIFFERENT NORMAL!
        // NEED TO COLLECT UP SPANS USING NORMAL HISTOGRAM NORMALS!
        // ALSO NEED TO ACTUALLY CHECK FOR COPLANARITY, NOT JUST SAME NORMAL!!

        Dictionary <Vector3d, List <EdgeSpan> > find_coplanar_span_sets(DMesh3 mesh, EdgeLoop loop)
        {
            double dot_thresh = 0.999;

            var span_sets = new Dictionary <Vector3d, List <EdgeSpan> >();

            int NV = loop.Vertices.Length;
            int NE = loop.Edges.Length;

            var edge_normals = new Vector3d[NE];

            for (int k = 0; k < NE; ++k)
            {
                edge_normals[k] = mesh.GetTriNormal(mesh.GetEdgeT(loop.Edges[k]).a);
            }

            // find coplanar verts
            // [RMS] this is wrong, if normals vary smoothly enough we will mark non-coplanar spans as coplanar
            bool[] vert_coplanar = new bool[NV];
            int    nc            = 0;

            for (int k = 0; k < NV; ++k)
            {
                int prev = (k == 0) ? NV - 1 : k - 1;
                if (edge_normals[k].Dot(ref edge_normals[prev]) > dot_thresh)
                {
                    vert_coplanar[k] = true;
                    nc++;
                }
            }
            if (nc < 2)
            {
                return(null);
            }

            int iStart = 0;

            while (vert_coplanar[iStart])
            {
                iStart++;
            }

            int iPrev = iStart;
            int iCur  = iStart + 1;

            while (iCur != iStart)
            {
                if (vert_coplanar[iCur] == false)
                {
                    iPrev = iCur;
                    iCur  = (iCur + 1) % NV;
                    continue;
                }

                var edges = new List <int>()
                {
                    loop.Edges[iPrev]
                };
                int span_start_idx = iCur;
                while (vert_coplanar[iCur])
                {
                    edges.Add(loop.Edges[iCur]);
                    iCur = (iCur + 1) % NV;
                }

                if (edges.Count > 1)
                {
                    Vector3d span_n = edge_normals[span_start_idx];
                    var      span   = EdgeSpan.FromEdges(mesh, edges);
                    span.CheckValidity();
                    foreach (var pair in span_sets)
                    {
                        if (pair.Key.Dot(ref span_n) > dot_thresh)
                        {
                            span_n = pair.Key;
                            break;
                        }
                    }
                    List <EdgeSpan> found;
                    if (span_sets.TryGetValue(span_n, out found) == false)
                    {
                        span_sets[span_n] = new List <EdgeSpan>()
                        {
                            span
                        };
                    }
                    else
                    {
                        found.Add(span);
                    }
                }
            }



            return(span_sets);
        }
Пример #10
0
        private void SweepInTwoDirectionsAndTryToCreateLink(Rot4 potentialOtherRegionDir, IntVec3 c)
        {
            if (!potentialOtherRegionDir.IsValid)
            {
                return;
            }
            HashSet <IntVec3> hashSet = this.linksProcessedAt[potentialOtherRegionDir.AsInt];

            if (hashSet.Contains(c))
            {
                return;
            }
            IntVec3 c2 = c + potentialOtherRegionDir.FacingCell;

            if (c2.InBoundsShip(this.map) && this.regionGrid.GetRegionAt_NoRebuild_InvalidAllowed(c2) == this.newReg)
            {
                return;
            }
            RegionType expectedRegionType = WaterRegionTypeUtility.GetExpectedRegionType(c2, this.map);

            if (expectedRegionType == RegionType.None)
            {
                return;
            }
            Rot4 rot = potentialOtherRegionDir;

            rot.Rotate(RotationDirection.Clockwise);
            int num  = 0;
            int num2 = 0;

            hashSet.Add(c);
            if (!WaterRegionTypeUtility.IsOneCellRegion(expectedRegionType))
            {
                for (;;)
                {
                    IntVec3 intVec = c + rot.FacingCell * (num + 1);
                    if (!intVec.InBoundsShip(this.map) || this.regionGrid.GetRegionAt_NoRebuild_InvalidAllowed(intVec) != this.newReg ||
                        WaterRegionTypeUtility.GetExpectedRegionType(intVec + potentialOtherRegionDir.FacingCell, this.map) != expectedRegionType)
                    {
                        break;
                    }
                    if (!hashSet.Add(intVec))
                    {
                        Log.Error("We've processed the same cell twice.", false);
                    }
                    num++;
                }
                for (; ;)
                {
                    IntVec3 intVec2 = c - rot.FacingCell * (num2 + 1);
                    if (!intVec2.InBoundsShip(this.map) || this.regionGrid.GetRegionAt_NoRebuild_InvalidAllowed(intVec2) != this.newReg ||
                        WaterRegionTypeUtility.GetExpectedRegionType(intVec2 + potentialOtherRegionDir.FacingCell, this.map) != expectedRegionType)
                    {
                        break;
                    }
                    if (!hashSet.Add(intVec2))
                    {
                        Log.Error("We've processed the same cell twice.", false);
                    }
                    num2++;
                }
            }
            int           length = num + num2 + 1;
            SpanDirection dir;
            IntVec3       root;

            if (potentialOtherRegionDir == Rot4.North)
            {
                dir  = SpanDirection.East;
                root = c - rot.FacingCell * num2;
                root.z++;
            }
            else if (potentialOtherRegionDir == Rot4.South)
            {
                dir  = SpanDirection.East;
                root = c + rot.FacingCell * num;
            }
            else if (potentialOtherRegionDir == Rot4.East)
            {
                dir  = SpanDirection.North;
                root = c + rot.FacingCell * num;
                root.x++;
            }
            else
            {
                dir  = SpanDirection.North;
                root = c - rot.FacingCell * num2;
            }
            EdgeSpan        span       = new EdgeSpan(root, dir, length);
            WaterRegionLink regionLink = MapExtensionUtility.GetExtensionToMap(this.map).getWaterRegionLinkDatabase.LinkFrom(span);

            regionLink.Register(this.newReg);
            this.newReg.links.Add(regionLink);
        }
 private static int SpanEndZ(EdgeSpan e) => e.root.z + (e.dir == SpanDirection.North ? e.length : 0);
 private static int SpanEndX(EdgeSpan e) => e.root.x + (e.dir == SpanDirection.East ? e.length : 0);
 private static int SpanCenterZ(EdgeSpan e) => e.root.z + (e.dir == SpanDirection.North ? e.length / 2 : 0);
 private static int SpanCenterX(EdgeSpan e) => e.root.x + (e.dir == SpanDirection.East ? e.length / 2 : 0);
Пример #15
0
 public static int SpanCenterX2(EdgeSpan e)
 {
     return(e.root.x + ((e.dir == SpanDirection.East) ? (e.length / 2) : 0));
 }
Пример #16
0
 private static int SpanCenterX(EdgeSpan e)
 {
     return(e.root.x + ((e.dir != SpanDirection.East) ? 0 : (e.length / 2)));
 }
Пример #17
0
        public static void quick_test_2()
        {
            DMesh3         target        = TestUtil.LoadTestInputMesh("cylinder_orig.obj");
            DMeshAABBTree3 targetSpatial = new DMeshAABBTree3(target, true);

            DMesh3         mesh        = TestUtil.LoadTestInputMesh("cylinder_approx.obj");
            DMeshAABBTree3 meshSpatial = new DMeshAABBTree3(mesh, true);

            double search_dist = 10.0;

            MeshTopology topo = new MeshTopology(target);

            topo.Compute();

            RemesherPro r = new RemesherPro(mesh);

            r.SetTargetEdgeLength(2.0);
            r.SmoothSpeedT = 0.5;
            r.SetProjectionTarget(MeshProjectionTarget.Auto(target));
            MeshConstraints cons = new MeshConstraints();

            r.SetExternalConstraints(cons);


            int set_id = 1;

            foreach (var loop in topo.Loops)
            {
                DCurveProjectionTarget curveTarget = new DCurveProjectionTarget(loop.ToCurve(target));
                set_id++;

                // pick a set of points we will find paths between. We will chain
                // up those paths and constrain them to target loops.
                // (this part is the hack!)
                List <int> target_verts = new List <int>();
                List <int> mesh_verts   = new List <int>();
                for (int k = 0; k < loop.VertexCount; k += 5)
                {
                    target_verts.Add(loop.Vertices[k]);

                    Vector3d vCurve   = target.GetVertex(loop.Vertices[k]);
                    int      mesh_vid = meshSpatial.FindNearestVertex(vCurve, search_dist);
                    mesh_verts.Add(mesh_vid);
                }
                int NT = target_verts.Count;

                // find the paths to assemble the edge chain
                // [TODO] need to filter out junction vertices? or will they just handle themselves
                //   because they can be collapsed away?
                List <int> vert_seq = new List <int>();
                for (int k = 0; k < NT; k++)
                {
                    EdgeSpan e = find_edge_path(mesh, mesh_verts[k], mesh_verts[(k + 1) % NT]);
                    int      n = e.Vertices.Length;
                    for (int i = 0; i < n - 1; ++i)
                    {
                        vert_seq.Add(e.Vertices[i]);
                    }
                }

                // now it's easy, just add the loop constraint
                EdgeLoop full_loop = EdgeLoop.FromVertices(mesh, vert_seq);
                MeshConstraintUtil.ConstrainVtxLoopTo(cons, mesh, full_loop.Vertices, curveTarget, set_id);
            }


            r.FastestRemesh();

            TestUtil.WriteTestOutputMesh(mesh, "curves_test_out.obj");
        }
Пример #18
0
 public static int SpanCenterZ2(EdgeSpan e)
 {
     return(e.root.z + ((e.dir == SpanDirection.North) ? (e.length / 2) : 0));
 }
Пример #19
0
 private static int SpanCenterZ(EdgeSpan e)
 {
     return(e.root.z + ((e.dir != SpanDirection.North) ? 0 : (e.length / 2)));
 }
Пример #20
0
        void extract_topology()
        {
            var graph = new DGraph3();

            // add vertices to graph, and store mappings
            int[] mapV     = new int[Mesh.MaxVertexID];
            int[] mapVFrom = new int[AllVertices.Count];
            foreach (int vid in AllVertices)
            {
                int new_vid = graph.AppendVertex(Mesh.GetVertex(vid));
                mapV[vid]         = new_vid;
                mapVFrom[new_vid] = vid;
            }

            // add edges to graph. graph-to-mesh eid mapping is stored via graph edge-group-id
            int[] mapE = new int[Mesh.MaxEdgeID];
            foreach (int eid in AllEdges)
            {
                Index2i ev      = Mesh.GetEdgeV(eid);
                int     new_a   = mapV[ev.a];
                int     new_b   = mapV[ev.b];
                int     new_eid = graph.AppendEdge(new_a, new_b, eid);
                mapE[eid] = new_eid;
            }

            // extract the graph topology
            DGraph3Util.Curves curves = DGraph3Util.ExtractCurves(graph, true);

            // reconstruct mesh spans / curves / junctions from graph topology

            int NP = curves.PathEdges.Count;

            Spans = new EdgeSpan[NP];
            for (int pi = 0; pi < NP; ++pi)
            {
                List <int> pathE = curves.PathEdges[pi];
                for (int k = 0; k < pathE.Count; ++k)
                {
                    pathE[k] = graph.GetEdgeGroup(pathE[k]);
                }
                Spans[pi] = EdgeSpan.FromEdges(Mesh, pathE);
            }

            int NL = curves.LoopEdges.Count;

            Loops = new EdgeLoop[NL];
            for (int li = 0; li < NL; ++li)
            {
                List <int> loopE = curves.LoopEdges[li];
                for (int k = 0; k < loopE.Count; ++k)
                {
                    loopE[k] = graph.GetEdgeGroup(loopE[k]);
                }
                Loops[li] = EdgeLoop.FromEdges(Mesh, loopE);
            }

            JunctionVertices = new HashSet <int>();
            foreach (int gvid in curves.JunctionV)
            {
                JunctionVertices.Add(mapVFrom[gvid]);
            }
        }