Example #1
0
    private Plane checkForSimilarPlanes(Plane current, IEnumerable <Plane> usedPlanes)
    {
        var similarPlanes = usedPlanes.Where(plane => RansacPlaneFinder.Similar(plane, current, this.PointCloud.GroundPoint));

        if (similarPlanes.Any())
        {
            return(similarPlanes.First());
        }
        else
        {
            return(current);
        }
    }
Example #2
0
    public void Classify(IEnumerable <int> indicesParam)
    {
        if (this.PointCloud.Normals == null || this.PointCloud.Normals.Length == 0)
        {
            this.PointCloud.EstimateNormals();
        }

        List <int> indices;

        if (indicesParam == null)
        {
            indices = Enumerable.Range(0, this.PointCloud.Points.Length).ToList();
        }
        else
        {
            indices = indicesParam.ToList();
        }

        while (indices.Count() > RansacPlaneFinder.randomSampleCount)
        {
            indices.RemoveAt(Random.Range(0, indices.Count));
        }

        var planes = indices.Select(i => new Plane(this.PointCloud.Normals[i], this.PointCloud.Points[i])).ToList();

        this.PlanesWithScore = planes.Select(plane => new Tuple <Plane, float>(plane, this.PointCloud.GetScore(plane)))
                               .OrderByDescending(tuple => tuple.Value2).ToList();

        for (int i = 0; i < this.PlanesWithScore.Count; i++)
        {
            var plane = this.PlanesWithScore.ElementAt(i).Value1;
            for (int j = i + 1; j < this.PlanesWithScore.Count; j++)
            {
                if (RansacPlaneFinder.Similar(plane, this.PlanesWithScore[j].Value1, this.PointCloud.GroundPoint))
                {
                    this.PlanesWithScore.RemoveAt(j);
                    j--;
                }
            }
        }
    }
Example #3
0
    public void CreateMeshCutoff(bool createAttachments)
    {
        this.CheckForPlanes();
        Timekeeping.CompleteTask("Find planes");

        float bestScore = -1.0f;
        IEnumerable <Triangle> bestMesh   = null;
        IEnumerable <Plane>    bestPlanes = null;

        foreach (var selectedPlanes in this.Planes.Take(5).Subsets())
        {
            var currentMesh  = this.createFromPlanes(selectedPlanes);
            var currentScore = this.GetScore(currentMesh);

            if (currentScore > bestScore)
            {
                bestScore  = currentScore;
                bestMesh   = currentMesh;
                bestPlanes = selectedPlanes;
            }
        }

        var resultMesh = bestMesh.ToList();
        var usedPlanes = bestPlanes.ToList();

        Timekeeping.CompleteTask("Convex roof");

        if (!createAttachments)
        {
            this.Triangles = resultMesh;
            this.CleanMesh = false;
            return;
        }

        var planeFinder = new RansacPlaneFinder(this.PointCloud);

        int attachmentCount = 0;

        foreach (var plane in bestPlanes)
        {
            var indices = new List <int>();
            for (int i = 0; i < this.PointCloud.Points.Length; i++)
            {
                if (plane.GetDistanceToPoint(this.PointCloud.Points[i]) > HoughPlaneFinder.MaxDistance * 0.5f)
                {
                    indices.Add(i);
                }
            }

            while (true)
            {
                planeFinder.Classify(indices);
                planeFinder.RemoveGroundPlanesAndVerticalPlanes();
                var outsidePlanes = planeFinder.PlanesWithScore.Where(tuple => tuple.Value2 > 2.0f).Select(tuple => tuple.Value1).Where(newPlane => !RansacPlaneFinder.Similar(plane, newPlane, this.PointCloud.GroundPoint));
                outsidePlanes = outsidePlanes.Select(p => this.checkForSimilarPlanes(p, usedPlanes));

                if (outsidePlanes.Count() == 0)
                {
                    break;
                }

                bestScore = 0.0f;
                IEnumerable <Plane> planesInAttachment = null;
                foreach (var selectedPlanes in outsidePlanes.Take(5).Subsets())
                {
                    var currentMesh = this.createFromPlanes(selectedPlanes);
                    currentMesh = Triangle.CutMesh(currentMesh, plane, true);
                    float pointDensity = currentMesh.Sum(t => t.GetPointCount(this.PointCloud, indices)) / currentMesh.Sum(t => t.GetArea());
                    if (pointDensity < 3.0f)
                    {
                        continue;
                    }
                    var currentScore = currentMesh.Sum(triangle => triangle.GetScore(this.PointCloud, indices));

                    if (currentScore > bestScore)
                    {
                        bestScore          = currentScore;
                        bestMesh           = currentMesh;
                        planesInAttachment = selectedPlanes;
                    }
                }

                if (bestScore > 2.0f)
                {
                    resultMesh.AddRange(bestMesh);
                    attachmentCount++;
                    usedPlanes = usedPlanes.Union(planesInAttachment).ToList();
                }
                else
                {
                    break;
                }

                indices = indices.Where(i => !bestMesh.Any(triangle => triangle.Contains(this.PointCloud.Points[i]))).ToList();
            }
        }

        Timekeeping.CompleteTask("Find attachments");

        if (attachmentCount == 0)
        {
            this.CleanMesh = false;
        }
        this.Triangles = resultMesh;
    }