예제 #1
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            bool valuesChanged = false;

            using (RebuildLock())
            {
                var outerDiameter = OuterDiameter.Value(this);
                var innerDiameter = InnerDiameter.ClampIfNotCalculated(this, 0, outerDiameter - .1, ref valuesChanged);
                var sides         = Sides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged);
                var ringSides     = RingSides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged);

                var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged);
                var endingAngle   = EndingAngle.ClampIfNotCalculated(this, startingAngle + .01, 360, ref valuesChanged);

                var ringPhaseAngle = RingPhaseAngle.Value(this);
                if (!Advanced)
                {
                    ringSides      = Math.Max(3, (int)(sides / 2));
                    startingAngle  = 0;
                    endingAngle    = 360;
                    ringPhaseAngle = 0;
                }

                innerDiameter = Math.Min(outerDiameter - .1, innerDiameter);

                using (new CenterAndHeightMaintainer(this))
                {
                    var poleRadius     = (outerDiameter / 2 - innerDiameter / 2) / 2;
                    var toroidRadius   = innerDiameter / 2 + poleRadius;
                    var path           = new VertexStorage();
                    var angleDelta     = MathHelper.Tau / ringSides;
                    var ringStartAngle = MathHelper.DegreesToRadians(ringPhaseAngle);
                    var ringAngle      = ringStartAngle;
                    var circleCenter   = new Vector2(toroidRadius, 0);
                    path.MoveTo(circleCenter + new Vector2(poleRadius * Math.Cos(ringStartAngle), poleRadius * Math.Sin(ringStartAngle)));
                    for (int i = 0; i < ringSides - 1; i++)
                    {
                        ringAngle += angleDelta;
                        path.LineTo(circleCenter + new Vector2(poleRadius * Math.Cos(ringAngle), poleRadius * Math.Sin(ringAngle)));
                    }

                    path.LineTo(circleCenter + new Vector2(poleRadius * Math.Cos(ringStartAngle), poleRadius * Math.Sin(ringStartAngle)));

                    var startAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(startingAngle));
                    var endAngle   = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(endingAngle));
                    Mesh = VertexSourceToMesh.Revolve(path, sides, startAngle, endAngle);
                }
            }

            if (valuesChanged)
            {
                Invalidate(InvalidateType.DisplayValues);
            }

            Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
            return(Task.CompletedTask);
        }
예제 #2
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            bool valuesChanged = false;

            var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged);
            var endingAngle   = EndingAngle.ClampIfNotCalculated(this, startingAngle + .01, 360, ref valuesChanged);
            var sides         = Sides.Value(this);
            var axisPosition  = AxisPosition.Value(this);

            if (startingAngle > 0 || endingAngle < 360)
            {
                Sides = agg_basics.Clamp(sides, 1, 360, ref valuesChanged);
            }
            else
            {
                Sides = agg_basics.Clamp(sides, 3, 360, ref valuesChanged);
            }

            Invalidate(InvalidateType.DisplayValues);

            var rebuildLock = RebuildLock();

            // now create a long running task to process the image
            return(ApplicationController.Instance.Tasks.Execute(
                       "Revolve".Localize(),
                       null,
                       (reporter, cancellationToken) =>
            {
                var vertexSource = this.VertexSource;
                var pathBounds = vertexSource.GetBounds();
                vertexSource = vertexSource.Translate(-pathBounds.Left - axisPosition, 0);
                Mesh mesh = VertexSourceToMesh.Revolve(vertexSource,
                                                       sides,
                                                       MathHelper.DegreesToRadians(360 - endingAngle),
                                                       MathHelper.DegreesToRadians(360 - startingAngle),
                                                       false);

                // take the axis offset out
                mesh.Transform(Matrix4X4.CreateTranslation(pathBounds.Left + axisPosition, 0, 0));

                if (mesh.Vertices.Count == 0)
                {
                    mesh = null;
                }

                Mesh = mesh;

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

                return Task.CompletedTask;
            }));
        }
예제 #3
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            bool valuesChanged = false;

            using (RebuildLock())
            {
                var sides         = Sides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged);
                var latitudeSides = LatitudeSides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged);
                var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged);
                var endingAngle   = EndingAngle.ClampIfNotCalculated(this, startingAngle + .01, 360, ref valuesChanged);
                var diameter      = Diameter.Value(this);

                using (new CenterAndHeightMaintainer(this))
                {
                    if (sides != lastSides ||
                        latitudeSides != lastLatitudeSides ||
                        startingAngle != lastStartingAngle ||
                        endingAngle != lastEndingAngle ||
                        diameter != lastDiameter)
                    {
                        if (!Advanced)
                        {
                            startingAngle = 0;
                            endingAngle   = 360;
                            latitudeSides = sides;
                        }

                        Mesh = CreateSphere(diameter, sides, latitudeSides, startingAngle, endingAngle);
                    }

                    lastDiameter      = diameter;
                    lastEndingAngle   = endingAngle;
                    lastStartingAngle = startingAngle;
                    lastSides         = sides;
                    lastLatitudeSides = latitudeSides;
                }
            }

            if (valuesChanged)
            {
                Invalidate(InvalidateType.DisplayValues);
            }

            Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
            return(Task.CompletedTask);
        }
예제 #4
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            bool valuesChanged = false;

            double height        = Height.ClampIfNotCalculated(this, .01, 1000000, ref valuesChanged);
            var    diameter      = Diameter.ClampIfNotCalculated(this, .01, 1000000, ref valuesChanged);
            var    diameterTop   = DiameterTop.ClampIfNotCalculated(this, .01, 1000000, ref valuesChanged);
            var    sides         = Sides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged);
            var    startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged);
            var    endingAngle   = EndingAngle.ClampIfNotCalculated(this, StartingAngle.Value(this) + .01, 360, ref valuesChanged);

            if (valuesChanged)
            {
                Invalidate(InvalidateType.DisplayValues);
            }

            using (RebuildLock())
            {
                using (new CenterAndHeightMaintainer(this))
                {
                    if (!Advanced)
                    {
                        var path = new VertexStorage();
                        path.MoveTo(0, -height / 2);
                        path.LineTo(diameter / 2, -height / 2);
                        path.LineTo(diameter / 2, height / 2);
                        path.LineTo(0, height / 2);

                        Mesh = VertexSourceToMesh.Revolve(path, sides);
                    }
                    else
                    {
                        var path = new VertexStorage();
                        path.MoveTo(0, -height / 2);
                        path.LineTo(diameter / 2, -height / 2);
                        path.LineTo(diameterTop / 2, height / 2);
                        path.LineTo(0, height / 2);

                        Mesh = VertexSourceToMesh.Revolve(path, sides, MathHelper.DegreesToRadians(startingAngle), MathHelper.DegreesToRadians(endingAngle));
                    }
                }
            }

            Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
            return(Task.CompletedTask);
        }
예제 #5
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            bool valuesChanged = false;

            using (RebuildLock())
            {
                var outerDiameter = OuterDiameter.Value(this);
                var innerDiameter = InnerDiameter.ClampIfNotCalculated(this, 0, outerDiameter - .1, ref valuesChanged);
                var sides         = Sides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged);
                var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged);
                var endingAngle   = EndingAngle.ClampIfNotCalculated(this, startingAngle + .01, 360, ref valuesChanged);
                var height        = Height.Value(this);
                var roundSegments = RoundSegments.ClampIfNotCalculated(this, 2, 90, ref valuesChanged);

                using (new CenterAndHeightMaintainer(this, MaintainFlags.Origin | MaintainFlags.Bottom))
                {
                    if (!Advanced)
                    {
                        startingAngle = 0;
                        endingAngle   = 360;
                    }

                    innerDiameter = Math.Min(outerDiameter - .1, innerDiameter);

                    var path  = new VertexStorage();
                    var width = (outerDiameter - innerDiameter) / 2;
                    var r     = innerDiameter / 2;
                    path.MoveTo(r, 0);
                    path.LineTo(r + width, 0);
                    var range = 360 / 4.0;

                    if (!Advanced)
                    {
                        path.LineTo(r + width, height);
                        path.LineTo(r, height);
                    }
                    else
                    {
                        switch (Round)
                        {
                        case RoundTypes.None:
                            path.LineTo(r + width, height);
                            path.LineTo(r, height);
                            break;

                        case RoundTypes.Down:
                            if (Direction == RoundDirection.Inner)
                            {
                                path.LineTo(r + width, height);
                                for (int i = 1; i < roundSegments - 1; i++)
                                {
                                    var angle = range / (roundSegments - 1) * i;
                                    var rad   = MathHelper.DegreesToRadians(angle);
                                    path.LineTo(r + Math.Cos(rad) * width, height - Math.Sin(rad) * height);
                                }
                            }
                            else
                            {
                                for (int i = 1; i < roundSegments - 1; i++)
                                {
                                    var angle = range / (roundSegments - 1) * i;
                                    var rad   = MathHelper.DegreesToRadians(angle);
                                    path.LineTo(r + width - Math.Sin(rad) * width, height - Math.Cos(rad) * height);
                                }
                                path.LineTo(r, height);
                            }
                            break;

                        case RoundTypes.Up:
                            if (Direction == RoundDirection.Inner)
                            {
                                path.LineTo(r + width, height);
                                for (int i = 1; i < roundSegments - 1; i++)
                                {
                                    var angle = range / (roundSegments - 1) * i;
                                    var rad   = MathHelper.DegreesToRadians(angle);
                                    path.LineTo(r + width - Math.Sin(rad) * width, Math.Cos(rad) * height);
                                }
                            }
                            else
                            {
                                for (int i = 1; i < roundSegments - 1; i++)
                                {
                                    var angle = range / (roundSegments - 1) * i;
                                    var rad   = MathHelper.DegreesToRadians(angle);
                                    path.LineTo(r + Math.Cos(rad) * width, Math.Sin(rad) * height);
                                }
                                path.LineTo(r, height);
                            }
                            break;
                        }
                    }

                    var startAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(startingAngle));
                    var endAngle   = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(endingAngle));
                    Mesh = VertexSourceToMesh.Revolve(path, sides, startAngle, endAngle);
                }
            }

            Invalidate(InvalidateType.DisplayValues);

            Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
            return(Task.CompletedTask);
        }