public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            var activeImage = AggContext.ImageIO.LoadImage(this.Image.AssetPath);

            ApplicationController.Instance.Tasks.Execute("Generating Lithophane".Localize(), null, (reporter, cancellationToken) =>
            {
                var generatedMesh = Lithophane.Generate(
                    new Lithophane.ImageBufferImageData(activeImage, this.Width),
                    this.Height,
                    0.4,
                    this.PixelsPerMM,
                    this.Invert,
                    reporter);

                this.Mesh = generatedMesh;

                // Remove old offset
                this.Matrix *= Matrix4X4.CreateTranslation(this.ImageOffset);

                // Set and store new offset
                var imageBounds  = generatedMesh.GetAxisAlignedBoundingBox();
                this.ImageOffset = imageBounds.Center + new Vector3(0, 0, -imageBounds.Center.Z);

                // Apply offset
                this.Matrix *= Matrix4X4.CreateTranslation(-this.ImageOffset);

                Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));

                return(Task.CompletedTask);
            });

            return(Task.CompletedTask);
        }
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            var activeImage = this.ImageChild.Image;

            if (activeImage == null ||
                activeImage.Width == 0 ||
                activeImage.Height == 0)
            {
                return(Task.CompletedTask);
            }

            activeImage.GetVisibleBounds(out RectangleInt visibleBounds);

            if (visibleBounds.Width == 0 ||
                visibleBounds.Height == 0)
            {
                return(Task.CompletedTask);
            }

            var rebuildLocks = this.RebuilLockAll();

            ApplicationController.Instance.Tasks.Execute("Generating Lithophane".Localize(), null, (reporter, cancellationToken) =>
            {
                var generatedMesh = Lithophane.Generate(
                    new Lithophane.ImageBufferImageData(activeImage, this.Width),
                    this.Height,
                    0.4,
                    this.PixelsPerMM,
                    this.Invert,
                    reporter);

                this.Mesh = generatedMesh;

                // Remove old offset
                this.Matrix *= Matrix4X4.CreateTranslation(this.ImageOffset);

                // Set and store new offset
                var imageBounds  = generatedMesh.GetAxisAlignedBoundingBox();
                this.ImageOffset = imageBounds.Center + new Vector3(0, 0, -imageBounds.Center.Z);

                // Apply offset
                this.Matrix *= Matrix4X4.CreateTranslation(-this.ImageOffset);

                UiThread.RunOnIdle(() =>
                {
                    rebuildLocks.Dispose();
                    Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
                });

                return(Task.CompletedTask);
            });

            return(Task.CompletedTask);
        }