public void ScaleAndRotateMantainsCorrectAabb()
        {
            {
                // create a simple cube with translation
                var root = new Object3D();
                var cube = CubeObject3D.Create(20, 20, 20);
                cube.Matrix = Matrix4X4.CreateTranslation(50, 60, 10);
                root.Children.Add(cube);
                Assert.AreEqual(2, root.DescendantsAndSelf().Count());
                var preScaleAabb = root.GetAxisAlignedBoundingBox();

                // add a scale to it (that is not scaled)
                var scaleObject = new ScaleObject3D(cube);

                // ensure that the object did not move
                Assert.IsTrue(scaleObject.ScaleAbout.Equals(Vector3.Zero), "The objects have been moved to be scalling about 0.");
                Assert.AreEqual(4, root.DescendantsAndSelf().Count());
                var postScaleAabb = root.GetAxisAlignedBoundingBox();

                Assert.IsTrue(preScaleAabb.Equals(postScaleAabb, .001));

                Assert.AreEqual(cube, scaleObject.UntransformedChildren.First(), "There is no undo buffer, there should not have been a clone");

                var rotateScaleObject = new RotateObject3D_2(cube);
                // ensure that the object did not move
                Assert.AreEqual(6, root.DescendantsAndSelf().Count());
                var postRotateScaleAabb = root.GetAxisAlignedBoundingBox();

                Assert.IsTrue(preScaleAabb.Equals(postRotateScaleAabb, .001));

                Assert.AreEqual(cube, rotateScaleObject.UntransformedChildren.First(), "There is no undo buffer, there should not have been a clone");
            }
        }
        public async Task AabbCalculatedCorrectlyForCurvedFitObjects()
        {
            AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
            MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));

            // Automation runner must do as much as program.cs to spin up platform
            string platformFeaturesProvider = "MatterHackers.MatterControl.WindowsPlatformsFeatures, MatterControl.Winforms";

            AppContext.Platform = AggContext.CreateInstanceFrom <INativePlatformFeatures>(platformFeaturesProvider);
            AppContext.Platform.ProcessCommandline();

            var root = new Object3D();
            var cube = await CubeObject3D.Create(20, 20, 20);

            var fit = await FitToBoundsObject3D_2.Create(cube);

            fit.SizeX = 50;
            fit.SizeY = 20;
            fit.SizeZ = 20;

            Assert.IsTrue(fit.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-25, -10, -10), new Vector3(25, 10, 10)), 1.0));

            var curve = new CurveObject3D_2();

            curve.Children.Add(fit);
            await curve.Rebuild();

            var curveAabb = curve.GetAxisAlignedBoundingBox();

            root.Children.Add(curve);
            var rootAabb = root.GetAxisAlignedBoundingBox();

            Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-17.5, -9.9, -10), new Vector3(17.5, 11.97, 10)), 1.0));
        }
        public async Task RotateMaintainsCorrectAabb()
        {
            {
                // create a simple cube with translation
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                cube.Matrix = Matrix4X4.CreateTranslation(50, 60, 10);
                root.Children.Add(cube);
                Assert.AreEqual(2, root.DescendantsAndSelf().Count());
                var preRotateAabb = root.GetAxisAlignedBoundingBox();

                // add a rotate to it (that is not rotated)
                var rotateObject = new RotateObject3D_2(cube);

                // ensure that the object did not move
                Assert.IsTrue(rotateObject.RotateAbout.Origin.Equals(new Vector3(50, 60, 10)));
                Assert.AreEqual(4, root.DescendantsAndSelf().Count());
                var postRotateAabb = root.GetAxisAlignedBoundingBox();

                Assert.IsTrue(preRotateAabb.Equals(postRotateAabb, .001));

                Assert.AreEqual(cube, rotateObject.UntransformedChildren.First(), "There is no undo buffer, there should not have been a clone");
            }
        }
        public async Task AabbCalculatedCorrectlyForCurvedFitObjects()
        {
            StartupMC();

            var root = new Object3D();
            var cube = await CubeObject3D.Create(20, 20, 20);

            var fit = await FitToBoundsObject3D_3.Create(cube);

            fit.Width  = 50;
            fit.Depth  = 20;
            fit.Height = 20;
            fit.Invalidate(InvalidateType.Properties);

            Assert.IsTrue(fit.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-25, -10, -10), new Vector3(25, 10, 10)), 1.0));

            var curve = new CurveObject3D_3()
            {
                BendType = CurveObject3D_3.BendTypes.Diameter,
                Diameter = 50
            };

            curve.Children.Add(fit);
            await curve.Rebuild();

            var curveAabb = curve.GetAxisAlignedBoundingBox();

            root.Children.Add(curve);
            var rootAabb = root.GetAxisAlignedBoundingBox();

            Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-17.5, -9.9, -10), new Vector3(17.5, 11.97, 10)), 1.0));
        }
        public async Task ScaleObjectMaintainsCorrectAabb()
        {
            // build cube with scale and undo
            {
                // create a simple cube with translation
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                cube.Matrix = Matrix4X4.CreateTranslation(50, 60, 10);
                root.Children.Add(cube);
                Assert.AreEqual(2, root.DescendantsAndSelf().Count());
                var preScaleAabb = root.GetAxisAlignedBoundingBox();

                var undoBuffer = new UndoBuffer();

                // add a scale to it (that is not scaled)
                var scaleObject = new ScaleObject3D();
                scaleObject.WrapItems(new IObject3D[] { cube }, undoBuffer);

                // ensure that the object did not move
                Assert.IsTrue(scaleObject.ScaleAbout.Equals(Vector3.Zero), "The objects have been moved to be scalling about 0.");
                Assert.AreEqual(4, root.DescendantsAndSelf().Count());
                var postScaleAabb = root.GetAxisAlignedBoundingBox();

                Assert.IsTrue(preScaleAabb.Equals(postScaleAabb, .001));

                Assert.AreNotEqual(cube, scaleObject.UntransformedChildren.First(), "There is an undo buffer, there should have been a clone");
            }

            // build cube with scale
            {
                // create a simple cube with translation
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                cube.Matrix = Matrix4X4.CreateTranslation(50, 60, 10);
                root.Children.Add(cube);
                Assert.AreEqual(2, root.DescendantsAndSelf().Count());
                var preScaleAabb = root.GetAxisAlignedBoundingBox();

                // add a scale to it (that is not scaled)
                var scaleObject = new ScaleObject3D(cube);

                // ensure that the object did not move
                Assert.IsTrue(scaleObject.ScaleAbout.Equals(Vector3.Zero), "The objects have been moved to be scalling about 0.");
                Assert.AreEqual(4, root.DescendantsAndSelf().Count());
                var postScaleAabb = root.GetAxisAlignedBoundingBox();

                Assert.IsTrue(preScaleAabb.Equals(postScaleAabb, .001));

                Assert.AreEqual(cube, scaleObject.UntransformedChildren.First(), "There is no undo buffer, there should not have been a clone");
            }
        }
        public async Task AabbCalculatedCorrectlyForAlignedFitObject()
        {
            AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
            MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));

            // Automation runner must do as much as program.cs to spin up platform
            string platformFeaturesProvider = "MatterHackers.MatterControl.WindowsPlatformsFeatures, MatterControl.Winforms";

            AppContext.Platform = AggContext.CreateInstanceFrom <INativePlatformFeatures>(platformFeaturesProvider);
            AppContext.Platform.ProcessCommandline();

            var root = new Object3D();
            var cube = await CubeObject3D.Create(20, 20, 20);

            var fit = await FitToBoundsObject3D_2.Create(cube);

            fit.SizeX = 10;
            fit.SizeY = 10;
            fit.SizeZ = 6;

            Assert.IsTrue(fit.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-5, -5, -10), new Vector3(5, 5, -4)), .01));

            var bigCube = await CubeObject3D.Create(20, 20, 20);

            Assert.IsTrue(bigCube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)), .01));

            var align = new AlignObject3D();

            align.Children.Add(bigCube);
            align.Children.Add(fit);

            await align.Rebuild();

            align.XAlign   = Align.Center;
            align.YAlign   = Align.Center;
            align.ZAlign   = Align.Max;
            align.Advanced = true;
            align.ZOffset  = 1;

            await align.Rebuild();

            var alignAabb = align.GetAxisAlignedBoundingBox();

            Assert.IsTrue(alignAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 11)), .01));

            alignAabb = align.GetAxisAlignedBoundingBox();
            root.Children.Add(align);
            var rootAabb = root.GetAxisAlignedBoundingBox();

            Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 11)), .01));
        }
        public async Task AabbCalculatedCorrectlyForAlignedFitObject()
        {
            StartupMC();

            var root = new Object3D();
            var cube = await CubeObject3D.Create(20, 20, 20);

            var fit = await FitToBoundsObject3D_3.Create(cube);

            fit.Width  = 10;
            fit.Depth  = 10;
            fit.Height = 6;
            fit.Invalidate(InvalidateType.Properties);

            Assert.IsTrue(fit.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-5, -5, -10), new Vector3(5, 5, -4)), .01));

            var bigCube = await CubeObject3D.Create(20, 20, 20);

            Assert.IsTrue(bigCube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)), .01));

            var align = new AlignObject3D();

            align.Children.Add(bigCube);
            align.Children.Add(fit);

            await align.Rebuild();

            align.XAlign   = Align.Center;
            align.YAlign   = Align.Center;
            align.ZAlign   = Align.Max;
            align.Advanced = true;
            align.ZOffset  = 1;

            await align.Rebuild();

            var alignAabb = align.GetAxisAlignedBoundingBox();

            Assert.IsTrue(alignAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 11)), .01));

            alignAabb = align.GetAxisAlignedBoundingBox();
            root.Children.Add(align);
            var rootAabb = root.GetAxisAlignedBoundingBox();

            Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 11)), .01));
        }
        public async Task SubtractTests()
        {
            // Subtract has correct number of results
            {
                var root  = new Object3D();
                var cubeA = await CubeObject3D.Create(20, 20, 20);

                var cubeB = await CubeObject3D.Create(20, 20, 20);

                var offsetCubeB = new TranslateObject3D(cubeB, 10);

                var subtract = new SubtractObject3D();
                subtract.Children.Add(cubeA);
                subtract.Children.Add(offsetCubeB);
                subtract.SelectedChildren.Add(offsetCubeB.ID);
                root.Children.Add(subtract);

                subtract.Subtract();
                subtract.Flatten(null);

                Assert.AreEqual(1, root.Children.Count());
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  0, 10, 10).Equals(rootAabb, .001));
            }

            // make sure the MatterCAD subtract function is working
            {
                var cubeA = await CubeObject3D.Create(20, 20, 20);

                var cubeB = await CubeObject3D.Create(20, 20, 20);

                var offsetCubeB = new TranslateObject3D(cubeB, 10);

                var subtract = cubeA.Minus(offsetCubeB);

                Assert.AreEqual(0, subtract.Children.Count());
                Assert.IsTrue(subtract.Mesh != null);
                var aabb = subtract.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  0, 10, 10).Equals(aabb, .001));
            }
        }
        public async void DoAabbCalculatedCorrectlyForCurvedFitObjects()
        {
            var root = new Object3D();
            var cube = CubeObject3D.Create(20, 20, 20);
            var fit  = FitToBoundsObject3D_2.Create(cube).Result;

            fit.SizeX = 50;
            fit.SizeY = 20;
            fit.SizeZ = 20;

            Assert.IsTrue(fit.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-25, -10, -10), new Vector3(25, 10, 10)), 1.0));

            var curve = new CurveObject3D_2();

            curve.Children.Add(fit);
            await curve.Rebuild();

            var curveAabb = curve.GetAxisAlignedBoundingBox();

            root.Children.Add(curve);
            var rootAabb = root.GetAxisAlignedBoundingBox();

            Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-17.5, -9.2, -10), new Vector3(17.5, 9.2, 10)), 1.0));
        }
        public async Task AlignObjectHasCorrectPositionsOnXAxis()
        {
            StartupMC();

            var scene = new InteractiveScene();

            var cube = await CubeObject3D.Create(20, 20, 20);

            cube.Matrix = Matrix4X4.CreateTranslation(50, 60, 10);
            Assert.IsTrue(cube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 50, 0), new Vector3(60, 70, 20)), .01));
            scene.Children.Add(cube);

            var bigCube = await CubeObject3D.Create(40, 40, 40);

            bigCube.Matrix = Matrix4X4.CreateTranslation(20, 20, 20);
            Assert.IsTrue(bigCube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(0, 0, 0), new Vector3(40, 40, 40)), .01));
            scene.Children.Add(bigCube);

            // select them
            scene.SelectedItem = cube;
            scene.AddToSelection(bigCube);

            // create an align of them
            var align = new AlignObject3D();

            align.AddSelectionAsChildren(scene, scene.SelectedItem);

            var unalignedBounds = align.GetAxisAlignedBoundingBox();

            // assert the align in built correctly
            Assert.AreEqual(1, scene.Children.Count);
            Assert.AreEqual(2, align.Children.Count);
            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(0, 0, 0), new Vector3(60, 70, 40)), 1.0));

            align.SelectedChild = new SelectedChildren()
            {
                cube.ID.ToString()
            };

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(unalignedBounds, 1.0));

            // turn align on
            align.XAlign = Align.Min;
            await align.Rebuild();

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 0, 0), new Vector3(80, 70, 40)), 1.0));

            // turn it off
            align.XAlign = Align.None;
            await align.Rebuild();

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(unalignedBounds, 1.0));

            // turn it back on
            align.XAlign = Align.Min;
            await align.Rebuild();

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 0, 0), new Vector3(80, 70, 40)), 1.0));

            // remove the align and assert stuff moved back to where it started
            align.Remove(null);
            Assert.IsTrue(cube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 50, 0), new Vector3(60, 70, 20)), .01));
            Assert.IsTrue(bigCube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(0, 0, 0), new Vector3(40, 40, 40)), .01));
        }
        public async Task AabbCalculatedCorrectlyForPinchedFitObjects()
        {
            StartupMC();

            // build without pinch
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                root.Children.Add(cube);
                Assert.IsTrue(root.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)), .001));
                root.Children.Remove(cube);
                var fit = await FitToBoundsObject3D_3.Create(cube);

                fit.Width  = 50;
                fit.Depth  = 20;
                fit.Height = 20;
                fit.Invalidate(InvalidateType.Properties);
                root.Children.Add(fit);
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-25, -10, -10), new Vector3(25, 10, 10)), .001));
            }

            // build with pinch
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                var fit = await FitToBoundsObject3D_3.Create(cube);

                fit.Width  = 50;
                fit.Depth  = 20;
                fit.Height = 20;

                var pinch = new PinchObject3D_3();
                pinch.Children.Add(fit);
                await pinch.Rebuild();

                root.Children.Add(pinch);
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)), .001));
            }

            // build with translate
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                var translate = new TranslateObject3D(cube, 11, 0, 0);

                root.Children.Add(translate);
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(1, -10, -10), new Vector3(21, 10, 10)), .001));
            }

            // build with pinch and translate
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                var translate = new TranslateObject3D(cube, 11, 0, 0);

                var pinch = new PinchObject3D_3();
                pinch.Children.Add(translate);
                root.Children.Add(pinch);
                await pinch.Rebuild();

                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(1, -10, -10), new Vector3(21, 10, 10)), .001));
            }

            // build with pinch and translate
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                var fit = await FitToBoundsObject3D_3.Create(cube);

                fit.Width  = 50;
                fit.Depth  = 20;
                fit.Height = 20;

                var translate = new TranslateObject3D(fit, 11, 0, 0);

                var pinch = new PinchObject3D_3();
                pinch.Children.Add(translate);
                await pinch.Rebuild();

                root.Children.Add(pinch);
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(1, -10, -10), new Vector3(21, 10, 10)), .001));
            }
        }
        public async Task SupportsFromBedTests()
        {
            var minimumSupportHeight = .05;

            // Set the static data to point to the directory of MatterControl
            AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
            MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));

            // make a single cube in the air and ensure that support is generated
            //   _________
            //   |       |
            //   |       |
            //   |_______|
            //
            //______________
            {
                InteractiveScene scene = new InteractiveScene();

                var cube = await CubeObject3D.Create(20, 20, 20);

                var aabb = cube.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cube.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabb.MinXYZ.Z + 15);
                scene.Children.Add(cube);

                var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
                supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
                await supportGenerator.Create(null, CancellationToken.None);

                Assert.Greater(scene.Children.Count, 1, "We should have added some support");
                foreach (var support in scene.Children.Where(i => i.OutputType == PrintOutputTypes.Support))
                {
                    Assert.AreEqual(0, support.GetAxisAlignedBoundingBox().MinXYZ.Z, .001, "Support columns are all on the bed");
                    Assert.AreEqual(15, support.GetAxisAlignedBoundingBox().ZSize, .02, "Support columns should be the right height from the bed");
                }
            }

            // make a single cube in the bed and ensure that no support is generated
            //   _________
            //   |       |
            // __|       |__
            //   |_______|
            //
            {
                InteractiveScene scene = new InteractiveScene();

                var cube = await CubeObject3D.Create(20, 20, 20);

                var aabb = cube.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cube.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabb.MinXYZ.Z - 5);
                scene.Children.Add(cube);

                var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
                supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
                await supportGenerator.Create(null, CancellationToken.None);

                Assert.AreEqual(1, scene.Children.Count, "We should not have added any support");
            }

            // make a cube on the bed and single cube in the air and ensure that support is not generated
            //   _________
            //   |       |
            //   |       |
            //   |_______|
            //   _________
            //   |       |
            //   |       |
            //___|_______|___
            {
                InteractiveScene scene = new InteractiveScene();

                var cubeOnBed = await CubeObject3D.Create(20, 20, 20);

                var aabbBed = cubeOnBed.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z - 5);
                scene.Children.Add(cubeOnBed);

                var cubeInAir = await CubeObject3D.Create(20, 20, 20);

                var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 25);
                scene.Children.Add(cubeInAir);

                var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
                supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
                await supportGenerator.Create(null, CancellationToken.None);

                Assert.AreEqual(2, scene.Children.Count, "We should not have added support");
            }

            // make a single cube in the bed and another cube on top, ensure that no support is generated
            //   _________
            //   |       |
            //   |       |
            //   |_______|
            //   _________
            //   |       |
            // __|       |__
            //   |_______|
            //
            {
                InteractiveScene scene = new InteractiveScene();

                var cubeOnBed = await CubeObject3D.Create(20, 20, 20);

                var aabbBed = cubeOnBed.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
                scene.Children.Add(cubeOnBed);

                var cubeInAir = await CubeObject3D.Create(20, 20, 20);

                var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 25);
                scene.Children.Add(cubeInAir);

                var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
                supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
                await supportGenerator.Create(null, CancellationToken.None);

                Assert.AreEqual(2, scene.Children.Count, "We should not have added support");
            }

            // make a cube on the bed and another cube exactly on top of it and ensure that support is not generated
            //   _________
            //   |       |
            //   |       |
            //   |_______|
            //   |       |
            //   |       |
            //___|_______|___
            {
                InteractiveScene scene = new InteractiveScene();

                var cubeOnBed = await CubeObject3D.Create(20, 20, 20);

                var aabbBed = cubeOnBed.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
                scene.Children.Add(cubeOnBed);

                var cubeInAir = await CubeObject3D.Create(20, 20, 20);

                var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 20);
                scene.Children.Add(cubeInAir);

                var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
                supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
                await supportGenerator.Create(null, CancellationToken.None);

                Assert.AreEqual(2, scene.Children.Count, "We should not have added support");
            }

            // make a cube on the bed and single cube in the air that intersects it and ensure that support is not generated
            //    _________
            //    |       |
            //    |______ |  // top cube actually exactly on top of bottom cube
            //   ||______||
            //   |       |
            //___|_______|___
            {
                InteractiveScene scene = new InteractiveScene();

                var cubeOnBed = await CubeObject3D.Create(20, 20, 20);

                var aabbBed = cubeOnBed.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
                scene.Children.Add(cubeOnBed);

                var cubeInAir = await CubeObject3D.Create(20, 20, 20);

                var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 15);
                scene.Children.Add(cubeInAir);

                var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
                supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
                await supportGenerator.Create(null, CancellationToken.None);

                Assert.AreEqual(2, scene.Children.Count, "We should not have added support");
            }

            // Make a cube on the bed and single cube in the air that intersects it.
            // SELECT the cube on top
            // Ensure that support is not generated.
            //    _________
            //    |       |
            //    |______ |  // top cube actually exactly on top of bottom cube
            //   ||______||
            //   |       |
            //___|_______|___
            {
                InteractiveScene scene = new InteractiveScene();

                var cubeOnBed = await CubeObject3D.Create(20, 20, 20);

                var aabbBed = cubeOnBed.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
                scene.Children.Add(cubeOnBed);

                var cubeInAir = await CubeObject3D.Create(20, 20, 20);

                var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 15);
                scene.Children.Add(cubeInAir);

                scene.SelectedItem = cubeInAir;

                var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
                supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
                await supportGenerator.Create(null, CancellationToken.None);

                Assert.AreEqual(2, scene.Children.Count, "We should not have added support");
            }

            // Make a cube above the bed and a second above that. Ensure only one set of support material
            //   _________
            //   |       |
            //   |       |
            //   |_______|
            //   _________
            //   |       |
            //   |       |
            //   |_______|
            //_______________
            {
                InteractiveScene scene = new InteractiveScene();

                var cube5AboveBed = await CubeObject3D.Create(20, 20, 20);

                var aabb5Above = cube5AboveBed.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cube5AboveBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabb5Above.MinXYZ.Z + 5);
                scene.Children.Add(cube5AboveBed);

                var cube30AboveBed = await CubeObject3D.Create(20, 20, 20);

                var aabb30Above = cube30AboveBed.GetAxisAlignedBoundingBox();
                // move it so the bottom is 15 above the bed
                cube30AboveBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabb30Above.MinXYZ.Z + 30);
                scene.Children.Add(cube30AboveBed);

                var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
                supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
                await supportGenerator.Create(null, CancellationToken.None);

                Assert.Greater(scene.Children.Count, 1, "We should have added some support");
                foreach (var support in scene.Children.Where(i => i.OutputType == PrintOutputTypes.Support))
                {
                    Assert.AreEqual(0, support.GetAxisAlignedBoundingBox().MinXYZ.Z, .001, "Support columns are all on the bed");
                    Assert.AreEqual(5, support.GetAxisAlignedBoundingBox().ZSize, .02, "Support columns should be the right height from the bed");
                }
            }
        }
        public override void Load()
        {
            var library = ApplicationController.Instance.Library;

            long index        = DateTime.Now.Ticks;
            var  libraryItems = new List <GeneratorItem>()
            {
                new GeneratorItem(
                    () => "Cube".Localize(),
                    () => CubeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Pyramid".Localize(),
                    () => PyramidObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Wedge".Localize(),
                    () => WedgeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Wedge".Localize(),
                    () => HalfWedgeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Text".Localize(),
                    () => TextObject3D.Create().Result)
                {
                    DateCreated = new System.DateTime(index++)
                },
#if DEBUG
                new GeneratorItem(
                    () => "Text".Localize(),
                    () => TextPathObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
#endif
                new GeneratorItem(
                    () => "Cylinder".Localize(),
                    () => CylinderObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Cone".Localize(),
                    () => ConeObject3D.Create().Result)
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Cylinder".Localize(),
                    () => HalfCylinderObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Torus".Localize(),
                    () => TorusObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Ring".Localize(),
                    () => RingObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Sphere".Localize(),
                    () => SphereObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Sphere".Localize(),
                    () => HalfSphereObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Image Converter".Localize(),
                    () =>
                {
                    // Construct an image
                    var imageObject = new ImageObject3D()
                    {
                        AssetPath = AggContext.StaticData.ToAssetPath(Path.Combine("Images", "mh-logo.png"))
                    };

                    // Construct a scene
                    var tempScene = new InteractiveScene();
                    tempScene.Children.Add(imageObject);
                    tempScene.SelectedItem = imageObject;

                    // Invoke ImageConverter operation, passing image and scene
                    ApplicationController.Instance.Graph.Operations["ImageConverter"].Operation(imageObject, tempScene);

                    // Return replacement object constructed in ImageConverter operation
                    var constructedComponent = tempScene.SelectedItem;
                    tempScene.Children.Remove(constructedComponent);

                    return(constructedComponent);
                })
                {
                    DateCreated = new System.DateTime(index++)
                },
            };

            string title = "Primitive Shapes".Localize();

            foreach (var item in libraryItems)
            {
                item.Category = title;
                Items.Add(item);
            }
        }
        public override void Load()
        {
            var library = ApplicationController.Instance.Library;

            long index        = DateTime.Now.Ticks;
            var  libraryItems = new List <GeneratorItem>()
            {
                new GeneratorItem(
                    () => "Cube".Localize(),
                    async() => await CubeObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Pyramid".Localize(),
                    async() => await PyramidObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Wedge".Localize(),
                    async() => await WedgeObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Wedge".Localize(),
                    async() => await HalfWedgeObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Text".Localize(),
                    async() => await TextObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Cylinder".Localize(),
                    async() => await CylinderObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Cone".Localize(),
                    async() => await ConeObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Cylinder".Localize(),
                    async() => await HalfCylinderObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Torus".Localize(),
                    async() => await TorusObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Ring".Localize(),
                    async() => await RingObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Sphere".Localize(),
                    async() => await SphereObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Sphere".Localize(),
                    async() => await HalfSphereObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
#if DEBUG
                new GeneratorItem(
                    () => "SCAD Script".Localize(),
                    async() => await OpenScadScriptObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "MarchingSquares".Localize(),
                    async() => await MarchingSquaresObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
#endif
                new GeneratorItem(
                    () => "Image Converter".Localize(),
                    () =>
                {
                    // Construct an image
                    var imageObject = new ImageObject3D()
                    {
                        AssetPath = StaticData.Instance.ToAssetPath(Path.Combine("Images", "mh-logo.png"))
                    };

                    // Construct a scene
                    var bedConfig = new BedConfig(null);
                    var tempScene = bedConfig.Scene;
                    tempScene.Children.Add(imageObject);
                    tempScene.SelectedItem = imageObject;

                    // Invoke ImageConverter operation, passing image and scene
                    SceneOperations.ById("ImageConverter").Action(bedConfig);

                    // Return replacement object constructed in ImageConverter operation
                    var constructedComponent = tempScene.SelectedItem;
                    tempScene.Children.Remove(constructedComponent);

                    return(Task.FromResult(constructedComponent));
                })
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Measure Tool".Localize(),
                    async() => await MeasureToolObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Description".Localize(),
                    async() => await DescriptionObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Variable Sheet".Localize(),
                    async() => await SheetObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
            };

            string title = "Primitive Shapes".Localize();

            foreach (var item in libraryItems)
            {
                item.Category = title;
                Items.Add(item);
            }

            this.ChildContainers.Add(
                new DynamicContainerLink(
                    () => "Primitives 2D".Localize(),
                    StaticData.Instance.LoadIcon(Path.Combine("Library", "folder.png")),
                    StaticData.Instance.LoadIcon(Path.Combine("Library", "primitives_library_icon.png")),
                    () => new Primitives2DContainer())
            {
                IsReadOnly = true
            });
        }
        public async Task CombineTests()
        {
            StartupMC();

            // Combine has correct results
            {
                var root  = new Object3D();
                var cubeA = await CubeObject3D.Create(20, 20, 20);

                var cubeB = await CubeObject3D.Create(20, 20, 20);

                var offsetCubeB = new TranslateObject3D(cubeB, 10);
                Assert.IsTrue(offsetCubeB.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(
                                                                                 0, -10, -10,
                                                                                 20, 10, 10), .001));

                var union = new CombineObject3D_2();
                union.Children.Add(cubeA);
                union.Children.Add(offsetCubeB);
                root.Children.Add(union);

                Assert.IsTrue(union.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(
                                                                           -10, -10, -10,
                                                                           20, 10, 10), .001));

                Assert.IsTrue(root.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(
                                                                          -10, -10, -10,
                                                                          20, 10, 10), .001));

                union.Combine();
                Assert.IsTrue(union.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(
                                                                           -10, -10, -10,
                                                                           20, 10, 10), .001));

                union.Flatten(null);

                Assert.AreEqual(1, root.Children.Count());
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  20, 10, 10).Equals(rootAabb, .001));
            }

            // Combine has correct results when inner content is changed
            {
                var root  = new Object3D();
                var cubeA = await CubeObject3D.Create(20, 20, 20);

                var cubeB = await CubeObject3D.Create(20, 20, 20);

                var union = new CombineObject3D_2();
                union.Children.Add(cubeA);
                union.Children.Add(cubeB);
                root.Children.Add(union);

                union.Combine();

                Assert.AreEqual(5, root.Descendants().Count());
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  10, 10, 10).Equals(rootAabb, .001));

                var offsetCubeB = new TranslateObject3D(cubeB, 10);

                union.Combine();
                Assert.AreEqual(7, root.Descendants().Count());
                rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  20, 10, 10).Equals(rootAabb, .001));
            }

            // now make sure undo has the right results for flatten
            {
                var root  = new Object3D();
                var cubeA = await CubeObject3D.Create(20, 20, 20);

                var cubeB = await CubeObject3D.Create(20, 20, 20);

                var offsetCubeB = new TranslateObject3D(cubeB, 10);

                var combine = new CombineObject3D_2();
                combine.Children.Add(cubeA);
                combine.Children.Add(offsetCubeB);
                root.Children.Add(combine);
                Assert.AreEqual(5, root.Descendants().Count(), "Should have the 1 combine, 2 cubeA, 3 cubeB, 4 offset cubeB, 5 offset sourceItem");

                combine.Combine();
                Assert.AreEqual(7, root.Descendants().Count(), "Should have the 1 combine, 2 cubeA, 3 wrapped cubeA, 4 cubeB, 5 offset cubeB, 6 offset sourceItem, wrapped cubeB");
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  20, 10, 10).Equals(rootAabb, .001));

                var undoBuffer = new UndoBuffer();
                combine.Flatten(undoBuffer);

                Assert.AreEqual(1, root.Descendants().Count());
                Assert.AreEqual(1, root.Children.Count());
                rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  20, 10, 10).Equals(rootAabb, .001));

                undoBuffer.Undo();
                Assert.AreEqual(7, root.Descendants().Count(), "Should have the 1 combine, 2 cubeA, 3 wrapped cubeA, 4 cubeB, 5 offset cubeB, 6 offset sourceItem, wrapped cubeB");
            }

            // now make sure undo has the right results for remove
            {
                var root  = new Object3D();
                var cubeA = await CubeObject3D.Create(20, 20, 20);

                cubeA.Name = "cubeA";
                var cubeB = await CubeObject3D.Create(20, 20, 20);

                cubeB.Name = "cubeB";

                var combine = new CombineObject3D_2();
                combine.Children.Add(cubeA);
                combine.Children.Add(cubeB);
                root.Children.Add(combine);
                Assert.AreEqual(3, root.Descendants().Count(), "Should have the 1 combine, 2 cubeA, 3 cubeB");

                combine.Combine();
                Assert.AreEqual(5, root.Descendants().Count(), "Should have the 1 combine, 2 cubeA, 3 wrapped cubeA, 4 cubeB, 5 wrapped cubeB");
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  10, 10, 10).Equals(rootAabb, .001));

                var undoBuffer = new UndoBuffer();
                combine.Remove(undoBuffer);

                Assert.AreEqual(2, root.Descendants().Count(), "Should have the 1 cubeA, 2 cubeB");
                rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  10, 10, 10).Equals(rootAabb, .001));

                undoBuffer.Undo();
                Assert.AreEqual(5, root.Descendants().Count(), "Should have the 1 combine, 2 cubeA, 3 wrapped cubeA, 4 cubeB, 5 wrapped cubeB");
            }

            // now make sure undo has the right results for remove
            {
                var root  = new Object3D();
                var cubeA = await CubeObject3D.Create(20, 20, 20);

                var cubeB = await CubeObject3D.Create(20, 20, 20);

                var offsetCubeB = new TranslateObject3D(cubeB, 10);

                var combine = new CombineObject3D_2();
                combine.Children.Add(cubeA);
                combine.Children.Add(offsetCubeB);
                root.Children.Add(combine);
                Assert.AreEqual(5, root.Descendants().Count(), "Should have the 1 combine, 2 cubeA, 3 cubeB, 4 offset cubeB, 5 offset sourceItem");

                combine.Combine();
                Assert.AreEqual(7, root.Descendants().Count(), "Should have the 1 combine, 2 cubeA, 3 wrapped cubeA, 4 cubeB, 5 offset cubeB, 6 offset sourceItem, wrapped cubeB");
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  20, 10, 10).Equals(rootAabb, .001));

                var undoBuffer = new UndoBuffer();
                combine.Remove(undoBuffer);

                Assert.AreEqual(4, root.Descendants().Count(), "Should have the 1 cubeA, 2 cubeB, 3 offset cubeB, 4 offset sourceItem");
                rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  20, 10, 10).Equals(rootAabb, .001));

                undoBuffer.Undo();
                Assert.AreEqual(7, root.Descendants().Count(), "Should have the 1 combine, 2 cubeA, 3 wrapped cubeA, 4 cubeB, 5 offset cubeB, 6 offset sourceItem, wrapped cubeB");
            }

            // make sure the MatterCAD add function is working
            {
                var cubeA = await CubeObject3D.Create(20, 20, 20);

                var cubeB = await CubeObject3D.Create(20, 20, 20);

                var offsetCubeB = new TranslateObject3D(cubeB, 10);

                var plus = cubeA.Plus(offsetCubeB, true);

                Assert.AreEqual(0, plus.Children.Count());
                Assert.IsTrue(plus.Mesh != null);
                var aabb = plus.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  20, 10, 10).Equals(aabb, .001));
            }

            // test single object combine
            {
                var root  = new Object3D();
                var cubeA = await CubeObject3D.Create(20, 20, 20);

                var cubeB = await CubeObject3D.Create(20, 20, 20);

                var offsetCubeB = new TranslateObject3D(cubeB, 10);

                var group = new Object3D();
                group.Children.Add(cubeA);
                group.Children.Add(offsetCubeB);

                var union = new CombineObject3D_2();
                union.Children.Add(group);

                root.Children.Add(union);

                union.Combine();
                Assert.AreEqual(8, root.Descendants().Count(), "group, union, wa, a, wtb, tb, b");

                union.Flatten(null);
                Assert.AreEqual(1, root.Descendants().Count(), "Should have the union result");

                Assert.AreEqual(1, root.Children.Count());
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(new AxisAlignedBoundingBox(
                                  -10, -10, -10,
                                  20, 10, 10).Equals(rootAabb, .001));
            }
        }
Example #16
0
        public override void Load()
        {
            var library = ApplicationController.Instance.Library;

            long index        = DateTime.Now.Ticks;
            var  libraryItems = new List <GeneratorItem>()
            {
                new GeneratorItem(
                    () => "Cube".Localize(),
                    async() => await CubeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Pyramid".Localize(),
                    async() => await PyramidObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Wedge".Localize(),
                    async() => await WedgeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Wedge".Localize(),
                    async() => await HalfWedgeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Text".Localize(),
                    async() => await TextObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },

                new GeneratorItem(
                    () => "Cylinder".Localize(),
                    async() => await CylinderObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Cone".Localize(),
                    async() => await ConeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Cylinder".Localize(),
                    async() => await HalfCylinderObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Torus".Localize(),
                    async() => await TorusObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Ring".Localize(),
                    async() => await RingObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Sphere".Localize(),
                    async() => await SphereObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Sphere".Localize(),
                    async() => await HalfSphereObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
#if DEBUG
                new GeneratorItem(
                    () => "XY Calibration".Localize(),
                    async() => await XyCalibrationFaceObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
#endif
                new GeneratorItem(
                    () => "Image Converter".Localize(),
                    () =>
                {
                    // Construct an image
                    var imageObject = new ImageObject3D()
                    {
                        AssetPath = AggContext.StaticData.ToAssetPath(Path.Combine("Images", "mh-logo.png"))
                    };

                    // Construct a scene
                    var bedConfig = new BedConfig(null);
                    var tempScene = bedConfig.Scene;
                    tempScene.Children.Add(imageObject);
                    tempScene.SelectedItem = imageObject;

                    // Invoke ImageConverter operation, passing image and scene
                    SceneOperations.ById("ImageConverter").Action(bedConfig);

                    // Return replacement object constructed in ImageConverter operation
                    var constructedComponent = tempScene.SelectedItem;
                    tempScene.Children.Remove(constructedComponent);

                    return(Task.FromResult <IObject3D>(constructedComponent));
                })
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Measure Tool".Localize(),
                    async() => await MeasureToolObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
            };

            string title = "Primitive Shapes".Localize();

            foreach (var item in libraryItems)
            {
                item.Category = title;
                Items.Add(item);
            }
        }
        public async Task AabbCalculatedCorrectlyForPinchedFitObjects()
        {
            AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
            MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));

            // Automation runner must do as much as program.cs to spin up platform
            string platformFeaturesProvider = "MatterHackers.MatterControl.WindowsPlatformsFeatures, MatterControl.Winforms";

            AppContext.Platform = AggContext.CreateInstanceFrom <INativePlatformFeatures>(platformFeaturesProvider);
            AppContext.Platform.InitPluginFinder();
            AppContext.Platform.ProcessCommandline();

            // build without pinch
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                root.Children.Add(cube);
                Assert.IsTrue(root.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)), .001));
                root.Children.Remove(cube);
                var fit = await FitToBoundsObject3D_2.Create(cube);

                fit.SizeX = 50;
                fit.SizeY = 20;
                fit.SizeZ = 20;
                root.Children.Add(fit);
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-25, -10, -10), new Vector3(25, 10, 10)), .001));
            }

            // build with pinch
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                var fit = await FitToBoundsObject3D_2.Create(cube);

                fit.SizeX = 50;
                fit.SizeY = 20;
                fit.SizeZ = 20;

                var pinch = new PinchObject3D_2();
                pinch.Children.Add(fit);
                await pinch.Rebuild();

                root.Children.Add(pinch);
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10)), .001));
            }

            // build with translate
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                var translate = new TranslateObject3D(cube, 11, 0, 0);

                root.Children.Add(translate);
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(1, -10, -10), new Vector3(21, 10, 10)), .001));
            }

            // build with pinch and translate
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                var translate = new TranslateObject3D(cube, 11, 0, 0);

                var pinch = new PinchObject3D_2();
                pinch.Children.Add(translate);
                root.Children.Add(pinch);
                await pinch.Rebuild();

                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(1, -10, -10), new Vector3(21, 10, 10)), .001));
            }

            // build with pinch and translate
            {
                var root = new Object3D();
                var cube = await CubeObject3D.Create(20, 20, 20);

                var fit = await FitToBoundsObject3D_2.Create(cube);

                fit.SizeX = 50;
                fit.SizeY = 20;
                fit.SizeZ = 20;

                var translate = new TranslateObject3D(fit, 11, 0, 0);

                var pinch = new PinchObject3D_2();
                pinch.Children.Add(translate);
                await pinch.Rebuild();

                root.Children.Add(pinch);
                var rootAabb = root.GetAxisAlignedBoundingBox();
                Assert.IsTrue(rootAabb.Equals(new AxisAlignedBoundingBox(new Vector3(1, -10, -10), new Vector3(21, 10, 10)), .001));
            }
        }
        public async Task AlignObjectHasCorrectPositionsOnXAxis()
        {
            AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
            MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));

            // Automation runner must do as much as program.cs to spin up platform
            string platformFeaturesProvider = "MatterHackers.MatterControl.WindowsPlatformsFeatures, MatterControl.Winforms";

            AppContext.Platform = AggContext.CreateInstanceFrom <INativePlatformFeatures>(platformFeaturesProvider);
            AppContext.Platform.ProcessCommandline();

            var scene = new InteractiveScene();

            var cube = await CubeObject3D.Create(20, 20, 20);

            cube.Matrix = Matrix4X4.CreateTranslation(50, 60, 10);
            Assert.IsTrue(cube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 50, 0), new Vector3(60, 70, 20)), .01));
            scene.Children.Add(cube);

            var bigCube = await CubeObject3D.Create(40, 40, 40);

            bigCube.Matrix = Matrix4X4.CreateTranslation(20, 20, 20);
            Assert.IsTrue(bigCube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(0, 0, 0), new Vector3(40, 40, 40)), .01));
            scene.Children.Add(bigCube);

            // select them
            scene.SelectedItem = cube;
            scene.AddToSelection(bigCube);

            // create an align of them
            var align = new AlignObject3D();

            align.AddSelectionAsChildren(scene, scene.SelectedItem);

            var unalignedBounds = align.GetAxisAlignedBoundingBox();

            // assert the align in built correctly
            Assert.AreEqual(1, scene.Children.Count);
            Assert.AreEqual(2, align.Children.Count);
            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(0, 0, 0), new Vector3(60, 70, 40)), 1.0));

            align.SelectedChild = new SelectedChildren()
            {
                cube.ID.ToString()
            };

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(unalignedBounds, 1.0));

            // turn align on
            align.XAlign = Align.Min;
            await align.Rebuild();

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 0, 0), new Vector3(80, 70, 40)), 1.0));

            // turn it off
            align.XAlign = Align.None;
            await align.Rebuild();

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(unalignedBounds, 1.0));

            // turn it back on
            align.XAlign = Align.Min;
            await align.Rebuild();

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 0, 0), new Vector3(80, 70, 40)), 1.0));

            // remove the align and assert stuff moved back to where it started
            align.Remove(null);
            Assert.IsTrue(cube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 50, 0), new Vector3(60, 70, 20)), .01));
            Assert.IsTrue(bigCube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(0, 0, 0), new Vector3(40, 40, 40)), .01));
        }
        public override void Load()
        {
            var library = ApplicationController.Instance.Library;

            long index        = DateTime.Now.Ticks;
            var  libraryItems = new List <GeneratorItem>()
            {
                new GeneratorItem(
                    () => "Cube".Localize(),
                    () => CubeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Pyramid".Localize(),
                    () => PyramidObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Wedge".Localize(),
                    () => WedgeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Wedge".Localize(),
                    () => HalfWedgeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Text".Localize(),
                    () => TextObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Cylinder".Localize(),
                    () => CylinderObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Cone".Localize(),
                    () => ConeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Cylinder".Localize(),
                    () => HalfCylinderObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Torus".Localize(),
                    () => TorusObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Ring".Localize(),
                    () => RingObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Sphere".Localize(),
                    () => SphereObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Sphere".Localize(),
                    () => HalfSphereObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Image Converter".Localize(),
                    () =>
                {
                    // Build ImageConverter stack
                    var imageObject = new ImageObject3D()
                    {
                        AssetPath = AggContext.StaticData.ToAssetPath(Path.Combine("Images", "mh-logo.png"))
                    };
                    imageObject.Invalidate(new InvalidateArgs(imageObject, InvalidateType.Properties, null));

                    var path = new ImageToPathObject3D();
                    path.Children.Add(imageObject);
                    path.Invalidate(new InvalidateArgs(path, InvalidateType.Properties, null));

                    var smooth = new SmoothPathObject3D();
                    smooth.Children.Add(path);
                    smooth.Invalidate(new InvalidateArgs(smooth, InvalidateType.Properties, null));

                    var extrude = new LinearExtrudeObject3D();
                    extrude.Children.Add(smooth);
                    extrude.Invalidate(new InvalidateArgs(extrude, InvalidateType.Properties, null));

                    var baseObject = new BaseObject3D()
                    {
                        BaseType = BaseTypes.None
                    };
                    baseObject.Children.Add(extrude);
                    baseObject.Invalidate(new InvalidateArgs(baseObject, InvalidateType.Properties, null));

                    return(new ComponentObject3D(new [] { baseObject })
                    {
                        ComponentID = "4D9BD8DB-C544-4294-9C08-4195A409217A",
                        SurfacedEditors = new List <string>
                        {
                            "$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.Children<ImageToPathObject3D>.Children<ImageObject3D>",
                            "$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Height",
                            "$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.SmoothDistance",
                            "$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.Children<ImageToPathObject3D>",
                            "$.Children<BaseObject3D>",
                        }
                    });
                })
                {
                    DateCreated = new System.DateTime(index++)
                },
            };

            string title = "Primitive Shapes".Localize();

            foreach (var item in libraryItems)
            {
                item.Category = title;
                Items.Add(item);
            }
        }