예제 #1
0
    internal void MoveAllPointsDepthDependant(CuttingInfo info, DMesh3 newMesh, Dictionary <int, BacksideAlgorithm.PeprStatusVert> stati)
    {
        var tree = new DMeshAABBTree3(info.oldMesh, true);

        tree.TriangleFilterF = i => tree.Mesh.GetTriangleGroup(i) != info.data.ColorNum;
        foreach (var status in stati)
        {
            var   shellPoint = newMesh.GetVertex(status.Value.idNewMeshOuter.Value);
            var   normal     = info.oldMesh.CalcVertexNormal(status.Value.idOldMeshOuter);
            var   position   = shellPoint + info.data.minDepth * normal;
            Ray3d ray        = new Ray3d(shellPoint - normal * info.data.minDepth, -normal); //tiny shift to make sure it's not hitting itself
            int   hit_tid    = tree.FindNearestHitTriangle(ray);
            Debug.Log("Hit " + hit_tid);
            if (hit_tid != DMesh3.InvalidID)
            {
                IntrRay3Triangle3 intr     = MeshQueries.TriangleIntersection(info.oldMesh, hit_tid, ray);
                double            hit_dist = shellPoint.Distance(ray.PointAt(intr.RayParameter));
                position = shellPoint - normal * hit_dist * (info.data.depth / 100);
                Debug.Log($"Hit Dist: {hit_dist}");
            }
            else
            {
                StaticFunctions.ErrorMessage("Depth Dependant Calculation has encountered an error");
            }
            info.mesh.SetVertex(status.Value.idOldMeshInner.Value, position);
            newMesh.SetVertex(status.Value.idNewMeshInner.Value, position);
        }
    }
예제 #2
0
 private void MoveVerticesToValidPositions(CuttingInfo info, DMesh3 newMesh, Dictionary <int, PeprStatusVert> stati)
 {
     foreach (var status in stati)
     {
         var point    = info.mesh.GetVertex(status.Value.idOldMeshInner.Value);
         var newPoint = MovePointInsideAndAwayFromShell(info, point, 1);
         info.mesh.SetVertex(status.Value.idOldMeshInner.Value, newPoint);
         newMesh.SetVertex(status.Value.idNewMeshInner.Value, newPoint);
     }
 }
예제 #3
0
    //If the position is too close to shell, returns the direction to move away from it to try again. Returns null if not too close
    internal Vector3d?GetAwayFromShellDirection(CuttingInfo info, DMeshAABBTree3 tree, Vector3d position)
    {
        tree.TriangleFilterF = i => tree.Mesh.GetTriangleGroup(i) != info.data.ColorNum;

        int near_tid = tree.FindNearestTriangle(position, info.data.minDepth); //TODO scale the max dist by SDF or so

        if (near_tid != DMesh3.InvalidID)
        {
            return(-tree.Mesh.GetTriNormal(near_tid));
        }

        return(null);
    }
예제 #4
0
    private IEnumerator CutCoroutine(CutSettingData cutSettings)
    {
        var algorithm = Algorithm.BuildAlgo(cutSettings.algo);
        var info      = new CuttingInfo()
        {
            mesh    = mesh,
            oldMesh = originalMesh,
            data    = cutSettings
        };
        var newMesh = algorithm.Cut(info);

        mesh = g3UnityUtils.SetGOMesh(gameObject, newMesh);
        yield return(null);
    }
예제 #5
0
 public static void InstantiateNewObjects(CuttingInfo info, List <DMesh3> subMeshes)
 {
     if (info.data.Multipiece || subMeshes.Count <= 1)
     {
         foreach (var subMesh in subMeshes)
         {
             subMesh.EnableTriangleGroups(info.data.ColorNum);
             var newObj = StaticFunctions.SpawnNewObject(subMesh);
             newObj.GetComponent <Generate>().cuttingInfo = info;
         }
     }
     else
     {
         var totalNewMesh = MeshEditor.Combine(subMeshes.ToArray());
         totalNewMesh.EnableTriangleGroups(info.data.ColorNum);
         var newObj = StaticFunctions.SpawnNewObject(totalNewMesh);
         newObj.GetComponent <Generate>().cuttingInfo = info; //todo we need to fix PointToPoint for Point algo if we combine
     }
 }
예제 #6
0
    public static MeshConnectedComponents FindConnectedComponents(CuttingInfo info, List <int> painted)
    {
        var components = new MeshConnectedComponents(info.mesh);

        if (info.data.Multipiece)
        {
            components.FilterF = i => info.mesh.GetTriangleGroup(i) == info.data.ColorNum;
            components.FindConnectedT();
        }
        else
        {
            var newC = new MeshConnectedComponents.Component
            {
                Indices = painted.ToArray()
            };
            components.Components.Add(newC);
        }

        return(components);
    }
예제 #7
0
    internal Vector3d MovePointInsideAndAwayFromShell(CuttingInfo info, Vector3d position, int maxCount = 5)
    {
        var tree = new DMeshAABBTree3(info.mesh, true);

        if (!tree.IsInside(position))
        {
            Debug.Log("Point outside of mesh");
            var getInside = GetInsideShell(tree, position, info.data.ColorNum);
            if (getInside != null)
            {
                position += getInside.Value;
                Debug.Log($"GetInside. New Pos: {position} ");
            }
            else
            {
                Debug.Log("Point too far away from shell");
            }
        }
        var getAway = this.GetAwayFromShellDirection(info, tree, position);
        int count   = 0;

        while (getAway != null)
        {
            position += getAway.Value.Normalized * info.data.minDepth;
            Debug.Log($"Getaway. New Pos: {position} ");

            count++;

            if (count >= maxCount)
            {
                Debug.Log("MoveAway could not find a suitable position, count exceeded");
                StaticFunctions.ErrorMessage("The object is too thin to find a suitable position. Might cause intersections.");
                break;
            }
            getAway = GetAwayFromShellDirection(info, tree, position);
        }
        return(position);
    }
예제 #8
0
    internal Vector3d MovePointDepthDependant(CuttingInfo info, Vector3d shellPoint, Vector3d normal)
    {
        normal = normal.Normalized;
        var   position = shellPoint + info.data.minDepth * normal;;
        var   tree     = new DMeshAABBTree3(info.oldMesh, true);
        Ray3d ray      = new Ray3d(shellPoint, -normal);
        int   hit_tid  = tree.FindNearestHitTriangle(ray);

        Debug.Log("Hit " + hit_tid);
        if (hit_tid != DMesh3.InvalidID)
        {
            IntrRay3Triangle3 intr     = MeshQueries.TriangleIntersection(info.oldMesh, hit_tid, ray);
            double            hit_dist = shellPoint.Distance(ray.PointAt(intr.RayParameter));
            position = shellPoint - normal * hit_dist * (info.data.depth / 100);
            Debug.Log($"Hit Dist: {hit_dist}");
        }
        else
        {
            StaticFunctions.ErrorMessage("Depth Dependant Calculation failed");
        }

        return(position);
    }
예제 #9
0
    public override DMesh3 Cut(CuttingInfo info)
    {
        var painted = FindPaintedTriangles(info.mesh, info.data.ColorNum);

        if (painted.Count <= 0)
        {
            return(info.mesh);
        }

        var components = new MeshConnectedComponents(info.mesh);

        components.FilterF = i => info.mesh.GetTriangleGroup(i) == info.data.ColorNum;
        components.FindConnectedT();
        var subMeshes = new List <DMesh3>();

        foreach (var component in components)
        {
            DSubmesh3 subMesh = new DSubmesh3(info.mesh, component.Indices);
            var       newMesh = subMesh.SubMesh;
            newMesh.EnableTriangleGroups();

            var normals  = new List <Vector3d>();
            var vertices = new List <Vector3d>();

            foreach (var componentTriIndex in component.Indices)
            {
                var tri    = info.mesh.GetTriangle(componentTriIndex);
                var normal = info.mesh.GetTriNormal(componentTriIndex);
                normals.Add(normal);
                var orgA = info.mesh.GetVertex(tri.a);
                vertices.Add(orgA);
                var orgB = info.mesh.GetVertex(tri.b);
                vertices.Add(orgB);
                var orgC = info.mesh.GetVertex(tri.c);
                vertices.Add(orgC);
            }

            var avgNormal   = normals.Average();
            var avgVertices = vertices.Average();
            var newPoint    = avgVertices - avgNormal * info.data.depth;

            if (info.data.modifier == CutSettingData.Modifier.Compute)
            {
                newPoint = MovePointInsideAndAwayFromShell(info, newPoint);
            }
            if (info.data.modifier == CutSettingData.Modifier.DepthDependant)
            {
                newPoint = MovePointDepthDependant(info, avgVertices, avgNormal);
            }
            component.Indices.ToList().ForEach(index => info.mesh.RemoveTriangle(index));


            var newPointId          = newMesh.AppendVertex(newPoint);
            var newPointIdInOldMesh = info.mesh.AppendVertex(newPoint);
            info.PointToPoint.Add(newPointId, newPointIdInOldMesh);

            var eidsNewMesh = newMesh.BoundaryEdgeIndices().ToList();
            foreach (var openEdge in eidsNewMesh)
            {
                var edge = newMesh.GetOrientedBoundaryEdgeV(openEdge);
                newMesh.AppendTriangle(edge.b, edge.a, newPointId, info.data.ColorNum);
                info.mesh.AppendTriangle(subMesh.MapVertexToBaseMesh(edge.a), subMesh.MapVertexToBaseMesh(edge.b),
                                         newPointIdInOldMesh, ColorManager.Instance.MainColorId);
            }

            subMeshes.Add(newMesh);
        }

        InstantiateNewObjects(info, subMeshes);


        return(info.mesh);
    }
예제 #10
0
 public virtual DMesh3 Cut(CuttingInfo info)
 {
     return(info.mesh);
 }
예제 #11
0
    public override DMesh3 Cut(CuttingInfo info)
    {
        var painted = FindPaintedTriangles(info.mesh, info.data.ColorNum);

        if (painted.Count <= 0)
        {
            return(info.mesh);
        }
        var components = FindConnectedComponents(info, painted);

        var subMeshes = new List <DMesh3>();

        foreach (var component in components.Components)
        {
            DSubmesh3 subMesh = new DSubmesh3(info.mesh, new List <int>()); //component.Indices
            var       newMesh = subMesh.SubMesh;
            newMesh.EnableTriangleGroups();
            newMesh.EnableVertexColors(ColorManager.Instance.GetColorForId(info.data.ColorNum).toVector3f());

            var stati = new Dictionary <int, PeprStatusVert>();
            foreach (var triIndex in component.Indices)
            {
                var triangle = info.mesh.GetTriangle(triIndex);
                var vertex1  = info.mesh.GetVertex(triangle.a);
                var vertex2  = info.mesh.GetVertex(triangle.b);
                var vertex3  = info.mesh.GetVertex(triangle.c);
                stati.AppendIfNotExists(triangle.a);
                stati.AppendIfNotExists(triangle.b);
                stati.AppendIfNotExists(triangle.c);

                if (stati[triangle.a].idNewMeshOuter == null)
                {
                    stati[triangle.a].idNewMeshOuter = newMesh.AppendVertex(vertex1);
                }
                if (stati[triangle.b].idNewMeshOuter == null)
                {
                    stati[triangle.b].idNewMeshOuter = newMesh.AppendVertex(vertex2);
                }
                if (stati[triangle.c].idNewMeshOuter == null)
                {
                    stati[triangle.c].idNewMeshOuter = newMesh.AppendVertex(vertex3);
                }

                var newTriOuter = newMesh.AppendTriangle(stati[triangle.a].idNewMeshOuter.Value,
                                                         stati[triangle.b].idNewMeshOuter.Value, stati[triangle.c].idNewMeshOuter.Value, info.data.ColorNum);

                //normals TriAvgNormal
                var normal1 = info.mesh.GetVertexNormal(triangle.a).toVector3d();
                var normal2 = info.mesh.GetVertexNormal(triangle.b).toVector3d();
                var normal3 = info.mesh.GetVertexNormal(triangle.c).toVector3d();

                if (info.data.modifier == CutSettingData.Modifier.StraightNormals)
                {
                    if (info.mesh.IsGroupBoundaryVertex(triangle.a))
                    {
                        normal1 = info.mesh.GetTriNormal(triIndex);
                    }
                    if (info.mesh.IsGroupBoundaryVertex(triangle.b))
                    {
                        normal2 = info.mesh.GetTriNormal(triIndex);
                    }
                    if (info.mesh.IsGroupBoundaryVertex(triangle.c))
                    {
                        normal3 = info.mesh.GetTriNormal(triIndex);
                    }
                }

                if (info.data.modifier == CutSettingData.Modifier.AveragedNormals)
                {
                    normal1 = GetAveragedNormal(info.mesh, triangle.a);
                    normal2 = GetAveragedNormal(info.mesh, triangle.b);
                    normal3 = GetAveragedNormal(info.mesh, triangle.c);
                }


                var pos1 = vertex1 - normal1 * info.data.depth;
                var pos2 = vertex2 - normal2 * info.data.depth;
                var pos3 = vertex3 - normal3 * info.data.depth;

                if (stati[triangle.a].idNewMeshInner == null)
                {
                    stati[triangle.a].idNewMeshInner = newMesh.AppendVertex(pos1);
                }
                if (stati[triangle.b].idNewMeshInner == null)
                {
                    stati[triangle.b].idNewMeshInner = newMesh.AppendVertex(pos2);
                }
                if (stati[triangle.c].idNewMeshInner == null)
                {
                    stati[triangle.c].idNewMeshInner =
                        newMesh.AppendVertex(
                            pos3); //TODO it was flipped from here before, but we have to flip when making the triangles
                }
                if (stati[triangle.a].idOldMeshInner == null)
                {
                    stati[triangle.a].idOldMeshInner = info.mesh.AppendVertex(pos1);
                }
                if (stati[triangle.b].idOldMeshInner == null)
                {
                    stati[triangle.b].idOldMeshInner = info.mesh.AppendVertex(pos2);
                }
                if (stati[triangle.c].idOldMeshInner == null)
                {
                    stati[triangle.c].idOldMeshInner = info.mesh.AppendVertex(pos3);
                }


                var color = ColorManager.Instance.GetColorForId(info.data.ColorNum).toVector3f();
                newMesh.SetVertexColor(stati[triangle.a].idNewMeshInner.Value, color);
                newMesh.SetVertexColor(stati[triangle.b].idNewMeshInner.Value, color);
                newMesh.SetVertexColor(stati[triangle.c].idNewMeshInner.Value, color);
                info.mesh.SetVertexColor(stati[triangle.a].idOldMeshInner.Value, color);
                info.mesh.SetVertexColor(stati[triangle.b].idOldMeshInner.Value, color);
                info.mesh.SetVertexColor(stati[triangle.c].idOldMeshInner.Value, color);
                var newTriInner = newMesh.AppendTriangle(stati[triangle.a].idNewMeshInner.Value,
                                                         stati[triangle.c].idNewMeshInner.Value, stati[triangle.b].idNewMeshInner.Value, info.data.ColorNum);
                var newTriInnerOldMesh = info.mesh.AppendTriangle(stati[triangle.a].idOldMeshInner.Value,
                                                                  stati[triangle.b].idOldMeshInner.Value, stati[triangle.c].idOldMeshInner.Value,
                                                                  info.data.mainColorId);
            }

            if (info.data.modifier == CutSettingData.Modifier.DepthDependant)
            {
                MoveAllPointsDepthDependant(info, newMesh, stati);
            }
            if (info.data.modifier == CutSettingData.Modifier.Compute)
            {
                MoveVerticesToValidPositions(info, newMesh, stati);
            }

            component.Indices.ToList().ForEach(index => info.mesh.RemoveTriangle(index));

            var openEdges = newMesh.BoundaryEdgeIndices();
            foreach (var openEdge in openEdges)
            {
                var edgeOriented = newMesh.GetOrientedBoundaryEdgeV(openEdge);
                int thirdPoint   = Corresponding(stati, edgeOriented.a, true);
                var newTriSide   = newMesh.AppendTriangle(edgeOriented.b, edgeOriented.a, thirdPoint, info.data.ColorNum);
            }

            var openEdgesOldMesh = info.mesh.BoundaryEdgeIndices();
            foreach (var openEdge in openEdgesOldMesh)
            {
                var edgeOriented = info.mesh.GetOrientedBoundaryEdgeV(openEdge);
                int thirdPoint   = Corresponding(stati, edgeOriented.a, false);
                var newTriSide   = info.mesh.AppendTriangle(edgeOriented.b, edgeOriented.a, thirdPoint,
                                                            info.data.mainColorId);
            }


            foreach (var peprStatusVert in stati)
            {
                if (info.PointToPoint.ContainsKey(peprStatusVert.Value.idNewMeshInner.Value))
                {
                    Debug.Log(
                        $"Double insertion from BS: {peprStatusVert.Value.idNewMeshInner.Value}, {peprStatusVert.Value.idOldMeshInner.Value}");
                }
                else
                {
                    info.PointToPoint.Add(peprStatusVert.Value.idNewMeshInner.Value,
                                          peprStatusVert.Value.idOldMeshInner.Value);
                }
            }
            subMeshes.Add(newMesh);
        }

        InstantiateNewObjects(info, subMeshes);
        return(info.mesh);
    }