From 9372e736911ed5ea43ea6061a86a747bc46b6fbc Mon Sep 17 00:00:00 2001 From: coder Date: Wed, 16 Oct 2019 22:04:08 -0600 Subject: [PATCH 1/4] Expose edgeloops to the caller. --- EzySlice/Framework/IntersectionResult.cs | 0 EzySlice/Framework/Intersector.cs | 0 EzySlice/Framework/Line.cs | 0 EzySlice/Framework/Plane.cs | 0 EzySlice/Framework/TextureRegion.cs | 0 EzySlice/Framework/Triangle.cs | 0 EzySlice/Framework/Triangulator.cs | 0 EzySlice/SlicedHull.cs | 0 EzySlice/Slicer.cs | 191 +++++++++++++++++------ EzySlice/SlicerExtensions.cs | 8 +- 10 files changed, 150 insertions(+), 49 deletions(-) mode change 100644 => 100755 EzySlice/Framework/IntersectionResult.cs mode change 100644 => 100755 EzySlice/Framework/Intersector.cs mode change 100644 => 100755 EzySlice/Framework/Line.cs mode change 100644 => 100755 EzySlice/Framework/Plane.cs mode change 100644 => 100755 EzySlice/Framework/TextureRegion.cs mode change 100644 => 100755 EzySlice/Framework/Triangle.cs mode change 100644 => 100755 EzySlice/Framework/Triangulator.cs mode change 100644 => 100755 EzySlice/SlicedHull.cs mode change 100644 => 100755 EzySlice/Slicer.cs mode change 100644 => 100755 EzySlice/SlicerExtensions.cs diff --git a/EzySlice/Framework/IntersectionResult.cs b/EzySlice/Framework/IntersectionResult.cs old mode 100644 new mode 100755 diff --git a/EzySlice/Framework/Intersector.cs b/EzySlice/Framework/Intersector.cs old mode 100644 new mode 100755 diff --git a/EzySlice/Framework/Line.cs b/EzySlice/Framework/Line.cs old mode 100644 new mode 100755 diff --git a/EzySlice/Framework/Plane.cs b/EzySlice/Framework/Plane.cs old mode 100644 new mode 100755 diff --git a/EzySlice/Framework/TextureRegion.cs b/EzySlice/Framework/TextureRegion.cs old mode 100644 new mode 100755 diff --git a/EzySlice/Framework/Triangle.cs b/EzySlice/Framework/Triangle.cs old mode 100644 new mode 100755 diff --git a/EzySlice/Framework/Triangulator.cs b/EzySlice/Framework/Triangulator.cs old mode 100644 new mode 100755 diff --git a/EzySlice/SlicedHull.cs b/EzySlice/SlicedHull.cs old mode 100644 new mode 100755 diff --git a/EzySlice/Slicer.cs b/EzySlice/Slicer.cs old mode 100644 new mode 100755 index 73b841f..666108d --- a/EzySlice/Slicer.cs +++ b/EzySlice/Slicer.cs @@ -9,6 +9,23 @@ namespace EzySlice { */ public sealed class Slicer { + internal struct SlicedMeshDetails + { + public List crossHull; + public SlicedSubmesh[] slices; + }; + + internal struct MeshDetails + { + public bool valid; + public MeshFilter filter; + public MeshRenderer renderer; + public Material[] materials; + public Mesh mesh; + public int submeshCount; + public int crossIndex; + }; + /** * An internal class for storing internal submesh values */ @@ -66,62 +83,63 @@ public bool isValid { * See -> Slice(Mesh, Plane) for more info */ public static SlicedHull Slice(GameObject obj, Plane pl, TextureRegion crossRegion, Material crossMaterial) { - MeshFilter filter = obj.GetComponent(); - // cannot continue without a proper filter - if (filter == null) { - Debug.LogWarning("EzySlice::Slice -> Provided GameObject must have a MeshFilter Component."); + MeshDetails md = GetMeshDetails(obj); + if (!md.valid) + { return null; } - - MeshRenderer renderer = obj.GetComponent(); - - // cannot continue without a proper renderer - if (renderer == null) { - Debug.LogWarning("EzySlice::Slice -> Provided GameObject must have a MeshRenderer Component."); - - return null; + + // crossIndex - we need to find the index of the material for the cross section. + // default to the end of the array + // for cases where the sliced material is null, we will append the cross section to the end + // of the submesh array, this is because the application may want to set/change the material + // after slicing has occured, so we don't assume anything + if (crossMaterial != null) { + for (int i = 0; i < md.crossIndex; i++) { + if (md.materials[i] == crossMaterial) { + md.crossIndex = i; + break; + } + } } - Material[] materials = renderer.sharedMaterials; + return Slice(md.mesh, pl, crossRegion, md.crossIndex); + } - Mesh mesh = filter.sharedMesh; - // cannot slice a mesh that doesn't exist - if (mesh == null) { - Debug.LogWarning("EzySlice::Slice -> Provided GameObject must have a Mesh that is not NULL."); + // Helper function for edgeloop functionality + public static List EdgeLoop(GameObject obj, Plane pl) { + + MeshDetails md = GetMeshDetails(obj); + if (!md.valid) + { return null; } - int submeshCount = mesh.subMeshCount; - - // to make things straightforward, exit without slicing if the materials and mesh - // array don't match. This shouldn't happen anyway - if (materials.Length != submeshCount) { - Debug.LogWarning("EzySlice::Slice -> Provided Material array must match the length of submeshes."); + return EdgeLoop(md.mesh, pl, md.crossIndex); + } + private static List EdgeLoop(Mesh sharedMesh, Plane pl, int crossIndex) { + if (sharedMesh == null) { return null; } - // we need to find the index of the material for the cross section. - // default to the end of the array - int crossIndex = materials.Length; - - // for cases where the sliced material is null, we will append the cross section to the end - // of the submesh array, this is because the application may want to set/change the material - // after slicing has occured, so we don't assume anything - if (crossMaterial != null) { - for (int i = 0; i < crossIndex; i++) { - if (materials[i] == crossMaterial) { - crossIndex = i; - break; - } + SlicedMeshDetails sliceDetails = SliceMesh(sharedMesh, pl); + + // check if slicing actually occured + for (int i = 0; i < sliceDetails.slices.Length; i++) { + // check if at least one of the submeshes was sliced. If so, stop checking + // because we need to go through the generation step + if (sliceDetails.slices[i] != null && sliceDetails.slices[i].isValid) { + return sliceDetails.crossHull; } } - return Slice(mesh, pl, crossRegion, crossIndex); + // no slicing occured, just return null to signify + return null; } /** @@ -137,6 +155,27 @@ public static SlicedHull Slice(Mesh sharedMesh, Plane pl, TextureRegion region, return null; } + SlicedMeshDetails sliceDetails = SliceMesh(sharedMesh, pl); + + // check if slicing actually occured + for (int i = 0; i < sliceDetails.slices.Length; i++) { + // check if at least one of the submeshes was sliced. If so, stop checking + // because we need to go through the generation step + if (sliceDetails.slices[i] != null && sliceDetails.slices[i].isValid) { + return CreateFrom(sliceDetails.slices, CreateFrom(sliceDetails.crossHull, pl.normal, region), crossIndex); + } + } + + // no slicing occured, just return null to signify + return null; + } + + /** + * Slice the mesh, and return sliced mesh details + **/ + private static SlicedMeshDetails SliceMesh(Mesh sharedMesh, Plane pl) { + + SlicedMeshDetails details = new SlicedMeshDetails(); Vector3[] verts = sharedMesh.vertices; Vector2[] uv = sharedMesh.uv; Vector3[] norm = sharedMesh.normals; @@ -222,17 +261,77 @@ public static SlicedHull Slice(Mesh sharedMesh, Plane pl, TextureRegion region, slices[submesh] = mesh; } - // check if slicing actually occured - for (int i = 0; i < slices.Length; i++) { - // check if at least one of the submeshes was sliced. If so, stop checking - // because we need to go through the generation step - if (slices[i] != null && slices[i].isValid) { - return CreateFrom(slices, CreateFrom(crossHull, pl.normal, region), crossIndex); - } + details.slices = slices; + details.crossHull = crossHull; + return details; + } + + private static bool IsGameObjectOk(GameObject obj) + { + MeshFilter filter = obj.GetComponent(); + + // cannot continue without a proper filter + if (filter == null) { + Debug.LogWarning("EzySlice::Slice -> Provided GameObject must have a MeshFilter Component."); + + return false; } - // no slicing occured, just return null to signify - return null; + MeshRenderer renderer = obj.GetComponent(); + + // cannot continue without a proper renderer + if (renderer == null) { + Debug.LogWarning("EzySlice::Slice -> Provided GameObject must have a MeshRenderer Component."); + + return false; + } + + Material[] materials = renderer.sharedMaterials; + + Mesh mesh = filter.sharedMesh; + + // cannot slice a mesh that doesn't exist + if (mesh == null) { + Debug.LogWarning("EzySlice::Slice -> Provided GameObject must have a Mesh that is not NULL."); + + return false; + } + + int submeshCount = mesh.subMeshCount; + + // to make things straightforward, exit without slicing if the materials and mesh + // array don't match. This shouldn't happen anyway + if (materials.Length != submeshCount) { + Debug.LogWarning("EzySlice::Slice -> Provided Material array must match the length of submeshes."); + + return false; + } + + return true; + } + + /** + * Return mesh details or null if the supplied gameobject cannot be processed. + */ + private static MeshDetails GetMeshDetails(GameObject obj) + { + MeshDetails md = new MeshDetails(); + + if (!IsGameObjectOk(obj)) + { + md.valid = false; + return md; + } + + md.filter = obj.GetComponent(); + md.renderer = obj.GetComponent(); + md.materials = md.renderer.sharedMaterials; + md.mesh = md.filter.sharedMesh; + md.submeshCount = md.mesh.subMeshCount; + md.crossIndex = md.materials.Length; + md.valid = true; + + return md; } /** diff --git a/EzySlice/SlicerExtensions.cs b/EzySlice/SlicerExtensions.cs old mode 100644 new mode 100755 index 3793dc5..8c26cee --- a/EzySlice/SlicerExtensions.cs +++ b/EzySlice/SlicerExtensions.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Collections.Generic; using UnityEngine; namespace EzySlice { @@ -6,7 +7,6 @@ namespace EzySlice { * Define Extension methods for easy access to slicer functionality */ public static class SlicerExtensions { - /** * SlicedHull Return functions and appropriate overrides! */ @@ -44,11 +44,12 @@ public static GameObject[] SliceInstantiate(this GameObject obj, Vector3 positio return SliceInstantiate(obj, position, direction, null); } - public static GameObject[] SliceInstantiate(this GameObject obj, Vector3 position, Vector3 direction, Material crossSectionMat) { + public static GameObject[] SliceInstantiate(this GameObject obj, Vector3 position, Vector3 direction, Material crossSectionMat) { return SliceInstantiate(obj, position, direction, new TextureRegion(0.0f, 0.0f, 1.0f, 1.0f), crossSectionMat); } public static GameObject[] SliceInstantiate(this GameObject obj, Vector3 position, Vector3 direction, TextureRegion cuttingRegion, Material crossSectionMaterial = null) { + EzySlice.Plane cuttingPlane = new EzySlice.Plane(); Vector3 refUp = obj.transform.InverseTransformDirection(direction); @@ -82,9 +83,10 @@ public static GameObject[] SliceInstantiate(this GameObject obj, Plane pl, Textu if (lowerHull != null) { return new GameObject[] { lowerHull }; } - + // nothing to return, so return nothing! return null; + } } } \ No newline at end of file From 611b7e11c6ec61e970ad666fabf3644ed6b4bed2 Mon Sep 17 00:00:00 2001 From: coder Date: Wed, 16 Oct 2019 22:07:51 -0600 Subject: [PATCH 2/4] Revert bad file permission changes. --- EzySlice/Framework/IntersectionResult.cs | 0 EzySlice/Framework/Intersector.cs | 0 EzySlice/Framework/Line.cs | 0 EzySlice/Framework/Plane.cs | 0 EzySlice/Framework/TextureRegion.cs | 0 EzySlice/Framework/Triangle.cs | 0 EzySlice/Framework/Triangulator.cs | 0 7 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 EzySlice/Framework/IntersectionResult.cs mode change 100755 => 100644 EzySlice/Framework/Intersector.cs mode change 100755 => 100644 EzySlice/Framework/Line.cs mode change 100755 => 100644 EzySlice/Framework/Plane.cs mode change 100755 => 100644 EzySlice/Framework/TextureRegion.cs mode change 100755 => 100644 EzySlice/Framework/Triangle.cs mode change 100755 => 100644 EzySlice/Framework/Triangulator.cs diff --git a/EzySlice/Framework/IntersectionResult.cs b/EzySlice/Framework/IntersectionResult.cs old mode 100755 new mode 100644 diff --git a/EzySlice/Framework/Intersector.cs b/EzySlice/Framework/Intersector.cs old mode 100755 new mode 100644 diff --git a/EzySlice/Framework/Line.cs b/EzySlice/Framework/Line.cs old mode 100755 new mode 100644 diff --git a/EzySlice/Framework/Plane.cs b/EzySlice/Framework/Plane.cs old mode 100755 new mode 100644 diff --git a/EzySlice/Framework/TextureRegion.cs b/EzySlice/Framework/TextureRegion.cs old mode 100755 new mode 100644 diff --git a/EzySlice/Framework/Triangle.cs b/EzySlice/Framework/Triangle.cs old mode 100755 new mode 100644 diff --git a/EzySlice/Framework/Triangulator.cs b/EzySlice/Framework/Triangulator.cs old mode 100755 new mode 100644 From 46e8a316a4271bb048ea195f1156a779497029c9 Mon Sep 17 00:00:00 2001 From: coder Date: Wed, 16 Oct 2019 22:08:30 -0600 Subject: [PATCH 3/4] Revert bad file permission change. --- EzySlice/SlicedHull.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 EzySlice/SlicedHull.cs diff --git a/EzySlice/SlicedHull.cs b/EzySlice/SlicedHull.cs old mode 100755 new mode 100644 From 4e848b1e642da38681f6c915a7c47507bb26caf0 Mon Sep 17 00:00:00 2001 From: coder Date: Thu, 17 Oct 2019 19:08:03 -0600 Subject: [PATCH 4/4] Fix issues reported in PR. --- EzySlice/Slicer.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/EzySlice/Slicer.cs b/EzySlice/Slicer.cs index 666108d..1b28201 100755 --- a/EzySlice/Slicer.cs +++ b/EzySlice/Slicer.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -9,13 +10,18 @@ namespace EzySlice { */ public sealed class Slicer { - internal struct SlicedMeshDetails + internal struct SlicedMeshDetails : IEquatable { public List crossHull; public SlicedSubmesh[] slices; + + public bool Equals(SlicedMeshDetails other) + { + throw new NotImplementedException(); + } }; - internal struct MeshDetails + internal struct MeshDetails : IEquatable { public bool valid; public MeshFilter filter; @@ -24,6 +30,11 @@ internal struct MeshDetails public Mesh mesh; public int submeshCount; public int crossIndex; + + public bool Equals(MeshDetails other) + { + throw new NotImplementedException(); + } }; /** @@ -119,10 +130,10 @@ public static List EdgeLoop(GameObject obj, Plane pl) { return null; } - return EdgeLoop(md.mesh, pl, md.crossIndex); + return EdgeLoop(md.mesh, pl); } - private static List EdgeLoop(Mesh sharedMesh, Plane pl, int crossIndex) { + private static List EdgeLoop(Mesh sharedMesh, Plane pl) { if (sharedMesh == null) { return null; }