public void SubtractIcosahedronsWorks() { Vector3 centering = new Vector3(100, 100, 20); Mesh meshA = PlatonicSolids.CreateIcosahedron(35); meshA.Translate(centering); Mesh meshB = PlatonicSolids.CreateIcosahedron(35); Vector3 finalTransform = new Vector3(105.240172225344, 92.9716306394062, 18.4619570261172); Vector3 rotCurrent = new Vector3(4.56890223673623, -2.67874102322035, 1.02768848238523); Vector3 scaleCurrent = new Vector3(1.07853517569753, 0.964980885267323, 1.09290934544604); Matrix4X4 transformB = Matrix4X4.CreateScale(scaleCurrent) * Matrix4X4.CreateRotation(rotCurrent) * Matrix4X4.CreateTranslation(finalTransform); meshB.Transform(transformB); Mesh result = CsgOperations.Subtract(meshA, meshB); AxisAlignedBoundingBox a_aabb = meshA.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox b_aabb = meshB.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox intersect_aabb = result.GetAxisAlignedBoundingBox(); Assert.IsTrue(a_aabb.XSize == 40 && a_aabb.YSize == 40 && a_aabb.ZSize == 40); Assert.IsTrue(intersect_aabb.XSize == 40 && intersect_aabb.YSize == 40 && intersect_aabb.ZSize == 40); // Todo: turn this on //Assert.IsTrue(result.IsManifold()); }
public void UnionExactlyOnWorks() { Mesh meshA = PlatonicSolids.CreateCube(40, 40, 40); Mesh meshB = PlatonicSolids.CreateCube(40, 40, 40); Mesh meshToAdd = CsgOperations.Union(meshA, meshB); AxisAlignedBoundingBox a_aabb = meshA.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox b_aabb = meshB.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox intersect_aabb = meshToAdd.GetAxisAlignedBoundingBox(); Assert.IsTrue(a_aabb.XSize == 40 && a_aabb.YSize == 40 && a_aabb.ZSize == 40); Assert.IsTrue(intersect_aabb.XSize == 40 && intersect_aabb.YSize == 40 && intersect_aabb.ZSize == 40); }
public void UnionExactlyOnWorks() { Mesh meshA = PlatonicSolids.CreateCube(40, 40, 40); Mesh meshB = PlatonicSolids.CreateCube(40, 40, 40); Mesh result = CsgOperations.Union(meshA, meshB); AxisAlignedBoundingBox a_aabb = meshA.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox b_aabb = meshB.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox intersect_aabb = result.GetAxisAlignedBoundingBox(); Assert.IsTrue(a_aabb.XSize == 40 && a_aabb.YSize == 40 && a_aabb.ZSize == 40); Assert.IsTrue(intersect_aabb.XSize == 40 && intersect_aabb.YSize == 40 && intersect_aabb.ZSize == 40); // Todo: turn this on //Assert.IsTrue(result.IsManifold()); }
public static Mesh DoMerge(List <MeshGroup> meshGroupsToMerge, MeshOutputSettings outputInfo) { Mesh allPolygons = new Mesh(); if (outputInfo.CsgOptionState == MeshOutputSettings.CsgOption.DoCsgMerge) { foreach (MeshGroup meshGroup in meshGroupsToMerge) { foreach (Mesh mesh in meshGroup.Meshes) { allPolygons = CsgOperations.Union(allPolygons, mesh); } } } else { foreach (MeshGroup meshGroup in meshGroupsToMerge) { foreach (Mesh mesh in meshGroup.Meshes) { int currentMeshMaterialIntdex = MeshMaterialData.Get(mesh).MaterialIndex; if (outputInfo.MaterialIndexsToSave == null || outputInfo.MaterialIndexsToSave.Contains(currentMeshMaterialIntdex)) { foreach (Face face in mesh.Faces) { List <Vertex> faceVertices = new List <Vertex>(); foreach (FaceEdge faceEdgeToAdd in face.FaceEdges()) { // we allow duplicates (the true) to make sure we are not changing the loaded models acuracy. Vertex newVertex = allPolygons.CreateVertex(faceEdgeToAdd.firstVertex.Position, CreateOption.CreateNew, SortOption.WillSortLater); faceVertices.Add(newVertex); } // we allow duplicates (the true) to make sure we are not changing the loaded models acuracy. allPolygons.CreateFace(faceVertices.ToArray(), CreateOption.CreateNew); } } } } allPolygons.CleanAndMergMesh(); } return(allPolygons); }
private void mergeAndSavePartsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; BackgroundWorker backgroundWorker = (BackgroundWorker)sender; try { // push all the transforms into the meshes for (int i = 0; i < asynchMeshGroups.Count; i++) { asynchMeshGroups[i].Transform(MeshGroupTransforms[i].TotalTransform); int nextPercent = (i + 1) * 40 / asynchMeshGroups.Count; backgroundWorker.ReportProgress(nextPercent); } string fileName = "TextCreator_{0}".FormatWith(Path.ChangeExtension(Path.GetRandomFileName(), ".amf")); string filePath = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, fileName); List <MeshGroup> mergResults = new List <MeshGroup>(); mergResults.Add(new MeshGroup()); mergResults[0].Meshes.Add(new Mesh()); foreach (MeshGroup meshGroup in asynchMeshGroups) { foreach (Mesh mesh in meshGroup.Meshes) { mergResults[0].Meshes[0] = CsgOperations.Union(mergResults[0].Meshes[0], mesh); } } MeshFileIo.Save(mergResults, filePath); e.Result = filePath; } catch (System.UnauthorizedAccessException) { //Do something special when unauthorized? StyledMessageBox.ShowMessageBox(null, "Oops! Unable to save changes.".Localize(), "Unable to save".Localize()); } catch { StyledMessageBox.ShowMessageBox(null, "Oops! Unable to save changes.".Localize(), "Unable to save".Localize()); } }
public void EnsureSimpleCubeIntersection() { // the intersection of 2 cubes { Mesh meshA = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshA.Translate(new Vector3(-2, -2, -2)); Mesh meshB = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshB.Translate(new Vector3(2, 2, 2)); Mesh result = CsgOperations.Intersect(meshA, meshB); AxisAlignedBoundingBox a_aabb = meshA.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox b_aabb = meshB.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox intersect_aabb = result.GetAxisAlignedBoundingBox(); Assert.IsTrue(a_aabb.XSize == 10 && a_aabb.YSize == 10 && a_aabb.ZSize == 10); Assert.IsTrue(intersect_aabb.XSize == 6 && intersect_aabb.YSize == 6 && intersect_aabb.ZSize == 6); // Todo: turn this on //Assert.IsTrue(result.IsManifold()); } // the intersection of 2 cubes that miss eachother { Mesh meshA = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshA.Translate(new Vector3(-5, -5, -5)); Mesh meshB = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshB.Translate(new Vector3(5, 5, 5)); Mesh result = CsgOperations.Intersect(meshA, meshB); AxisAlignedBoundingBox a_aabb = meshA.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox b_aabb = meshB.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox intersect_aabb = result.GetAxisAlignedBoundingBox(); Assert.IsTrue(a_aabb.XSize == 10 && a_aabb.YSize == 10 && a_aabb.ZSize == 10); Assert.IsTrue(intersect_aabb.XSize == 0 && intersect_aabb.YSize == 0 && intersect_aabb.ZSize == 0); // Todo: turn this on //Assert.IsTrue(result.IsManifold()); } }
public static Mesh DoMerge(List <Mesh> meshesToMerge, BackgroundWorker backgroundWorker, int startPercent, int endPercent, bool doCSGMerge = false) { int lengthPercent = endPercent - startPercent; Mesh allPolygons = new Mesh(); if (doCSGMerge) { for (int i = 0; i < meshesToMerge.Count; i++) { Mesh mesh = meshesToMerge[i]; allPolygons = CsgOperations.PerformOperation(allPolygons, mesh, CsgNode.Union); } } else { for (int i = 0; i < meshesToMerge.Count; i++) { Mesh mesh = meshesToMerge[i]; foreach (Face face in mesh.Faces) { List <Vertex> faceVertices = new List <Vertex>(); foreach (FaceEdge faceEdgeToAdd in face.FaceEdges()) { // we allow duplicates (the true) to make sure we are not changing the loaded models acuracy. Vertex newVertex = allPolygons.CreateVertex(faceEdgeToAdd.firstVertex.Position, true, true); faceVertices.Add(newVertex); } // we allow duplicates (the true) to make sure we are not changing the loaded models acuracy. allPolygons.CreateFace(faceVertices.ToArray(), true); } int nextPercent = startPercent + (i + 1) * lengthPercent / meshesToMerge.Count; backgroundWorker.ReportProgress(nextPercent); } allPolygons.CleanAndMergMesh(); } return(allPolygons); }
public void EnsureSimpleCubeSubtraction() { // the subtraction of 2 cubes { Mesh meshA = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshA.Translate(new Vector3(-2, 0, 0)); Mesh meshB = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshB.Translate(new Vector3(2, 0, 0)); Mesh meshIntersect = CsgOperations.Subtract(meshA, meshB); AxisAlignedBoundingBox a_aabb = meshA.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox b_aabb = meshB.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox intersect_aabb = meshIntersect.GetAxisAlignedBoundingBox(); Assert.IsTrue(a_aabb.XSize == 10 && a_aabb.YSize == 10 && a_aabb.ZSize == 10); Assert.IsTrue(intersect_aabb.XSize == 4 && intersect_aabb.YSize == 10 && intersect_aabb.ZSize == 10); } }
public void SubtractWorks() { Vector3 centering = new Vector3(100, 100, 20); Mesh meshA = PlatonicSolids.CreateCube(40, 40, 40); meshA.Translate(centering); Mesh meshB = PlatonicSolids.CreateCube(40, 40, 40); Vector3 finalTransform = new Vector3(99.999927784394, 102.400700290798, 16.3588316937214); meshB.Translate(finalTransform); Mesh meshToAdd = CsgOperations.Subtract(meshA, meshB); AxisAlignedBoundingBox a_aabb = meshA.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox b_aabb = meshB.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox intersect_aabb = meshToAdd.GetAxisAlignedBoundingBox(); Assert.IsTrue(a_aabb.XSize == 40 && a_aabb.YSize == 40 && a_aabb.ZSize == 40); Assert.IsTrue(intersect_aabb.XSize == 40 && intersect_aabb.YSize == 40 && intersect_aabb.ZSize == 40); }
private void mergeAndSavePartsBackgroundWorker_DoWork(string filePath) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; try { // push all the transforms into the meshes for (int i = 0; i < asynchMeshGroups.Count; i++) { asynchMeshGroups[i].Transform(MeshGroupTransforms[i].TotalTransform); processingProgressControl.RatioComplete = (double)i / asynchMeshGroups.Count * .1; } List <MeshGroup> mergResults = new List <MeshGroup>(); mergResults.Add(new MeshGroup()); mergResults[0].Meshes.Add(new Mesh()); double meshGroupIndex = 0; foreach (MeshGroup meshGroup in asynchMeshGroups) { foreach (Mesh mesh in meshGroup.Meshes) { processingProgressControl.RatioComplete = .1 + (double)meshGroupIndex / asynchMeshGroups.Count; mergResults[0].Meshes[0] = CsgOperations.Union(mergResults[0].Meshes[0], mesh); } meshGroupIndex++; } MeshFileIo.Save(mergResults, filePath); } catch (System.UnauthorizedAccessException) { //Do something special when unauthorized? StyledMessageBox.ShowMessageBox(null, "Oops! Unable to save changes.".Localize(), "Unable to save".Localize()); } catch { StyledMessageBox.ShowMessageBox(null, "Oops! Unable to save changes.".Localize(), "Unable to save".Localize()); } }
public void EnsureSimpleCubeIntersection() { // the intersection of 2 cubes { Mesh meshA = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); List <CsgPolygon> polygonsA = CsgOperations.PolygonsFromMesh(meshA); Assert.IsTrue(polygonsA.Count == 6); meshA.Translate(new Vector3(-2, -2, -2)); Mesh meshB = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshB.Translate(new Vector3(2, 2, 2)); Mesh meshIntersect = CsgOperations.Intersect(meshA, meshB); Assert.IsTrue(meshIntersect.Faces.Count == 6); Assert.IsTrue(meshIntersect.Vertices.Count == 8); foreach (Face face in meshIntersect.Faces) { Assert.IsTrue(Math.Abs(face.firstFaceEdge.meshEdge.VertexOnEnd[0].Position.x) == 3); Assert.IsTrue(Math.Abs(face.firstFaceEdge.meshEdge.VertexOnEnd[0].Position.y) == 3); Assert.IsTrue(Math.Abs(face.firstFaceEdge.meshEdge.VertexOnEnd[0].Position.z) == 3); } } // the intersection of 2 cubes that miss eachother { Mesh meshA = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); List <CsgPolygon> polygonsA = CsgOperations.PolygonsFromMesh(meshA); Assert.IsTrue(polygonsA.Count == 6); meshA.Translate(new Vector3(-5, -5, -5)); Mesh meshB = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshB.Translate(new Vector3(5, 5, 5)); Mesh meshIntersect = CsgOperations.Intersect(meshA, meshB); Assert.IsTrue(meshIntersect.Faces.Count == 0); } }
public void EnsureSimpleCubeUnion() { // the union of 2 cubes { Mesh meshA = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshA.Translate(new Vector3(-2, 0, 0)); Mesh meshB = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshB.Translate(new Vector3(2, 0, 0)); Mesh result = CsgOperations.Union(meshA, meshB); AxisAlignedBoundingBox a_aabb = meshA.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox b_aabb = meshB.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox intersect_aabb = result.GetAxisAlignedBoundingBox(); Assert.IsTrue(a_aabb.XSize == 10 && a_aabb.YSize == 10 && a_aabb.ZSize == 10); Assert.IsTrue(intersect_aabb.XSize == 14 && intersect_aabb.YSize == 10 && intersect_aabb.ZSize == 10); // Todo: turn this on //Assert.IsTrue(result.IsManifold()); } }
public void EnsureSimpleCubeUnion() { // the union of 2 cubes { Mesh meshA = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); List <CsgPolygon> polygonsA = CsgOperations.PolygonsFromMesh(meshA); Assert.IsTrue(polygonsA.Count == 6); meshA.Translate(new Vector3(-2, 0, 0)); Mesh meshB = PlatonicSolids.CreateCube(new Vector3(10, 10, 10)); meshB.Translate(new Vector3(2, 0, 0)); Mesh meshIntersect = CsgOperations.Union(meshA, meshB); Assert.IsTrue(meshIntersect.Faces.Count == 13); Assert.IsTrue(meshIntersect.Vertices.Count == 16); foreach (Face face in meshIntersect.Faces) { Assert.IsTrue(Math.Abs(face.firstFaceEdge.meshEdge.VertexOnEnd[0].Position.x) == 7 || Math.Abs(face.firstFaceEdge.meshEdge.VertexOnEnd[0].Position.x) == 3); Assert.IsTrue(Math.Abs(face.firstFaceEdge.meshEdge.VertexOnEnd[0].Position.y) == 5); Assert.IsTrue(Math.Abs(face.firstFaceEdge.meshEdge.VertexOnEnd[0].Position.z) == 5); } } }