Пример #1
0
        private Color GetItemColor(IObject3D item, IObject3D selectedItem)
        {
            Color drawColor = item.WorldColor();

            if (item.WorldOutputType() == PrintOutputTypes.Support)
            {
                drawColor = new Color(Color.Yellow, 120);
            }
            else if (item.WorldOutputType() == PrintOutputTypes.WipeTower)
            {
                drawColor = new Color(Color.Cyan, 120);
            }

            // If there is a printer - check if the object is within the bed volume (has no AABB outside the bed volume)
            if (sceneContext.Printer != null)
            {
                if (!sceneContext.Printer.InsideBuildVolume(item))
                {
                    drawColor = new Color(drawColor, 65);
                }
            }

            // check if we should be rendering materials (this overrides the other colors)
            if (sceneContext.ViewState.RenderType == RenderTypes.Materials)
            {
                drawColor = MaterialRendering.Color(item.WorldMaterialIndex());
            }

            if (drawColor.alpha != 255 &&
                item is Object3D item3D)
            {
                item3D.EnsureTransparentSorting();
            }

            if (selectedItem is ISelectableChildContainer selectableChildContainer)
            {
                if (item.AncestorsAndSelf().Any(i => selectableChildContainer.SelectedChildren.Contains(i.ID)))
                {
                    drawColor = new Color(drawColor, 200);
                }
            }

            if (!sceneContext.ViewState.ModelView)
            {
                if (modelRenderStyle == ModelRenderStyle.WireframeAndSolid)
                {
                    drawColor = gCodeMeshColor;
                }
                else if (modelRenderStyle == ModelRenderStyle.Wireframe)
                {
                    drawColor = new Color(gCodeMeshColor, 1);
                }
                else if (modelRenderStyle == ModelRenderStyle.None)
                {
                    drawColor = Color.Transparent;
                }
            }

            return(drawColor);
        }
Пример #2
0
        public ItemMaterialButton(PrinterConfig printer, ThemeConfig theme, int initialMaterialIndex)
        {
            this.currentIndex = initialMaterialIndex;
            this.ToolTipText  = "Material".Localize();
            var scaledButtonSize = 24 * GuiWidget.DeviceScale;

            Width  = 30 * GuiWidget.DeviceScale;
            Height = 30 * GuiWidget.DeviceScale;

            var menuTheme = AppContext.MenuTheme;

            this.Name = "ItemMaterialButton";

            this.DynamicPopupContent = () =>
            {
                var materialControl = new MaterialControls(printer, menuTheme, currentIndex)
                {
                    Padding         = theme.DefaultContainerPadding,
                    BackgroundColor = menuTheme.BackgroundColor,
                    HAnchor         = HAnchor.Fit,
                    VAnchor         = VAnchor.Fit,
                };

                materialControl.IndexChanged += (s, e) =>
                {
                    currentIndex = e;
                    MaterialChanged?.Invoke(this, e);
                    materialColorButton.BackgroundColor = MaterialRendering.Color(printer, currentIndex, theme.BorderColor);
                };

                return(materialControl);
            };

            materialColorButton = new ColorButton(MaterialRendering.Color(printer, currentIndex, theme.BorderColor))
            {
                Width                  = scaledButtonSize,
                Height                 = scaledButtonSize,
                BackgroundRadius       = scaledButtonSize / 2,
                BackgroundOutlineWidth = 1,
                HAnchor                = HAnchor.Center,
                VAnchor                = VAnchor.Center,
                DisabledColor          = theme.MinimalShade,
                BorderColor            = theme.TextColor,
                Selectable             = false,
            };

            this.AddChild(materialColorButton);
        }
Пример #3
0
        public ItemMaterialButton(ThemeConfig theme, int initialMaterialIndex)
        {
            this.ToolTipText = "Material".Localize();
            var scaledButtonSize = 14 * GuiWidget.DeviceScale;

            Width  = 30 * GuiWidget.DeviceScale;
            Height = 30 * GuiWidget.DeviceScale;

            this.DynamicPopupContent = () =>
            {
                var materialControl = new MaterialControls(theme, initialMaterialIndex)
                {
                    Padding         = theme.DefaultContainerPadding,
                    BackgroundColor = this.HoverColor,
                    HAnchor         = HAnchor.Fit,
                    VAnchor         = VAnchor.Fit,
                };

                materialControl.IndexChanged += (s, e) =>
                {
                    MaterialChanged?.Invoke(this, e);
                };

                return(materialControl);
            };

            materialColorButton = new ColorButton(MaterialRendering.Color(initialMaterialIndex, theme.BorderColor))
            {
                Width         = scaledButtonSize,
                Height        = scaledButtonSize,
                HAnchor       = HAnchor.Center,
                VAnchor       = VAnchor.Center,
                DrawGrid      = true,
                DisabledColor = theme.MinimalShade,
                Selectable    = false,
            };

            this.AddChild(materialColorButton);
        }
Пример #4
0
        private void DrawGlContent(DrawEventArgs e)
        {
            var gcodeOptions = sceneContext.RendererOptions;

            if (gcodeOptions.GCodeModelView)
            {
                modelRenderStyle = ModelRenderStyle.WireframeAndSolid;
            }
            else
            {
                modelRenderStyle = ModelRenderStyle.None;
            }

            foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.First))
            {
                if (drawable.Enabled)
                {
                    drawable.Draw(this, e, Matrix4X4.Identity, this.World);
                }
            }

            GLHelper.SetGlContext(this.World, renderSource.TransformToScreenSpace(renderSource.LocalBounds), lighting);

            foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.OpaqueContent))
            {
                if (drawable.Enabled)
                {
                    drawable.Draw(this, e, Matrix4X4.Identity, this.World);
                }
            }

            // Draw solid objects, extract transparent
            var transparentMeshes = new List <Object3DView>();

            var  selectedItem       = scene.SelectedItem;
            bool suppressNormalDraw = false;

            if (selectedItem != null)
            {
                // Invoke existing IEditorDraw when iterating items
                if (selectedItem is IEditorDraw editorDraw)
                {
                    // TODO: Putting the drawing code in the IObject3D means almost certain bindings to MatterControl in IObject3D. If instead
                    // we had a UI layer object that used binding to register scene drawing hooks for specific types, we could avoid the bindings
                    editorDraw.DrawEditor(this, transparentMeshes, e, ref suppressNormalDraw);
                }
            }

            foreach (var item in scene.Children)
            {
                if (item.Visible &&
                    (item != selectedItem || suppressNormalDraw == false))
                {
                    DrawObject(item, transparentMeshes, e);
                }
            }

            if (sceneContext.Printer?.Connection?.serialPort is PrinterEmulator.Emulator emulator)
            {
                void NozzlePositionChanged(object s, EventArgs e2)
                {
                    // limit max number of updates per second to 10
                    if (UiThread.CurrentTimerMs > lastEmulatorDrawMs + 100)
                    {
                        UiThread.RunOnIdle(Invalidate);
                        // set it to now
                        lastEmulatorDrawMs = UiThread.CurrentTimerMs;
                    }
                }

                var matrix = Matrix4X4.CreateTranslation(emulator.CurrentPosition + new Vector3(.5, .5, 5));
                GLHelper.Render(emulatorNozzleMesh,
                                MaterialRendering.Color(emulator.ExtruderIndex),
                                matrix,
                                RenderTypes.Shaded,
                                matrix * World.ModelviewMatrix);

                if (!emulatorHooked)
                {
                    emulator.DestinationChanged += NozzlePositionChanged;
                    emulatorHooked = true;
                }

                Closed += (s, e3) => emulator.DestinationChanged -= NozzlePositionChanged;
            }

            transparentMeshes.Sort(BackToFrontXY);

            var bedNormalInViewSpace  = Vector3Ex.TransformNormal(Vector3.UnitZ, World.ModelviewMatrix).GetNormal();
            var pointOnBedInViewSpace = Vector3Ex.Transform(new Vector3(10, 10, 0), World.ModelviewMatrix);
            var lookingDownOnBed      = Vector3Ex.Dot(bedNormalInViewSpace, pointOnBedInViewSpace) < 0;

            floorDrawable.LookingDownOnBed = lookingDownOnBed;

            if (lookingDownOnBed)
            {
                floorDrawable.Draw(this, e, Matrix4X4.Identity, this.World);
            }

            var wireColor = Color.Transparent;

            switch (modelRenderStyle)
            {
            case ModelRenderStyle.Wireframe:
                wireColor = darkWireframe;
                break;

            case ModelRenderStyle.WireframeAndSolid:
                wireColor = lightWireframe;
                break;
            }

            // Draw transparent objects
            foreach (var item in transparentMeshes)
            {
                var object3D = item.Object3D;
                GLHelper.Render(
                    object3D.Mesh,
                    item.Color,
                    object3D.WorldMatrix(),
                    RenderTypes.Outlines,
                    object3D.WorldMatrix() * World.ModelviewMatrix,
                    wireColor,
                    allowBspRendering: transparentMeshes.Count < 1000);
            }

            if (!lookingDownOnBed)
            {
                floorDrawable.Draw(this, e, Matrix4X4.Identity, this.World);
            }

            DrawInteractionVolumes(e);

            foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.TransparentContent))
            {
                if (drawable.Enabled)
                {
                    drawable.Draw(this, e, Matrix4X4.Identity, this.World);
                }
            }

            GLHelper.UnsetGlContext();

            // Invoke DrawStage.Last item drawables
            foreach (var item in scene.Children)
            {
                // HACK: Consider how shared code in DrawObject can be reused to prevent duplicate execution
                bool isSelected = selectedItem != null &&
                                  selectedItem.DescendantsAndSelf().Any((i) => i == item);

                foreach (var itemDrawable in itemDrawables.Where(d => d.DrawStage == DrawStage.Last && d.Enabled))
                {
                    itemDrawable.Draw(this, item, isSelected, e, Matrix4X4.Identity, this.World);
                }
            }

            // Invoke DrawStage.Last scene drawables
            foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.Last))
            {
                if (drawable.Enabled)
                {
                    drawable.Draw(this, e, Matrix4X4.Identity, this.World);
                }
            }
        }
Пример #5
0
        private Color GetItemColor(IObject3D item, IObject3D selectedItem)
        {
            Color drawColor = item.WorldColor();

            if (item.WorldOutputType() == PrintOutputTypes.Support)
            {
                drawColor = new Color(Color.Yellow, 120);
            }
            else if (item.WorldOutputType() == PrintOutputTypes.WipeTower)
            {
                drawColor = new Color(Color.Cyan, 120);
            }
            else if (sceneContext.ViewState.RenderType == RenderTypes.Materials)
            {
                // check if we should be rendering materials (this overrides the other colors)
                drawColor = MaterialRendering.Color(item.WorldMaterialIndex());
            }

            if (sceneContext.Printer is PrinterConfig printer)
            {
                if (printer.InsideBuildVolume(item))
                {
                    if (printer.Settings.Helpers.HotendCount() > 1)
                    {
                        var materialIndex = item.WorldMaterialIndex();
                        if (materialIndex == -1)
                        {
                            materialIndex = 0;
                        }

                        bool isWipeTower = item?.OutputType == PrintOutputTypes.WipeTower;

                        // Determine if the given item is outside the bounds of the given extruder
                        if (materialIndex < printer.Settings.ToolBounds.Length ||
                            isWipeTower)
                        {
                            var itemAABB   = item.WorldAxisAlignedBoundingBox();
                            var itemBounds = new RectangleDouble(new Vector2(itemAABB.MinXYZ), new Vector2(itemAABB.MaxXYZ));

                            var activeHotends = new HashSet <int>(new[] { materialIndex });

                            if (isWipeTower)
                            {
                                activeHotends.Add(0);
                                activeHotends.Add(1);
                            }

                            // Validate against active hotends
                            foreach (var hotendIndex in activeHotends)
                            {
                                var hotendBounds = printer.Settings.ToolBounds[hotendIndex];
                                if (!hotendBounds.Contains(itemBounds))
                                {
                                    // Draw in red outside of the bounds for the hotend
                                    drawColor = Color.Red.WithAlpha(90);
                                }
                            }
                        }
                    }
                }
                else
                {
                    // Outside of printer build volume
                    drawColor = new Color(drawColor, 65);
                }
            }

            if (drawColor.alpha != 255 &&
                item is Object3D item3D)
            {
                item3D.EnsureTransparentSorting();
            }

            if (selectedItem is ISelectableChildContainer selectableChildContainer)
            {
                if (item.AncestorsAndSelf().Any(i => selectableChildContainer.SelectedChildren.Contains(i.ID)))
                {
                    drawColor = new Color(drawColor, 200);
                }
            }

            if (!sceneContext.ViewState.ModelView)
            {
                if (modelRenderStyle == ModelRenderStyle.WireframeAndSolid)
                {
                    drawColor = gCodeMeshColor;
                }
                else if (modelRenderStyle == ModelRenderStyle.Wireframe)
                {
                    drawColor = new Color(gCodeMeshColor, 1);
                }
                else if (modelRenderStyle == ModelRenderStyle.None)
                {
                    drawColor = Color.Transparent;
                }
            }

            return(drawColor);
        }
Пример #6
0
        public MaterialControls(ThemeConfig theme, int initialMaterialIndex)
            : base(FlowDirection.TopToBottom)
        {
            this.theme   = theme;
            this.HAnchor = HAnchor.Fit;
            this.VAnchor = VAnchor.Fit;

            materialButtons.Clear();
            int extruderCount = 4;

            for (int extruderIndex = -1; extruderIndex < extruderCount; extruderIndex++)
            {
                var name = $"{"Material".Localize()} {extruderIndex +1}";
                if (extruderIndex == -1)
                {
                    name = "Default".Localize();
                }

                var buttonView = new FlowLayoutWidget()
                {
                    HAnchor = HAnchor.Fit,
                    VAnchor = VAnchor.Fit
                };

                var scaledButtonSize = 16 * GuiWidget.DeviceScale;

                buttonView.AddChild(new ColorButton(MaterialRendering.Color(extruderIndex, theme.MinimalHighlight))
                {
                    Width    = scaledButtonSize,
                    Height   = scaledButtonSize,
                    VAnchor  = VAnchor.Center,
                    DrawGrid = true,
                });

                buttonView.AddChild(new TextWidget(name, pointSize: theme.DefaultFontSize, textColor: theme.Colors.PrimaryTextColor)
                {
                    VAnchor = VAnchor.Center
                });

                var radioButtonView = new RadioButtonView(buttonView)
                {
                    TextColor = theme.Colors.PrimaryTextColor
                };
                radioButtonView.RadioCircle.Margin = radioButtonView.RadioCircle.Margin.Clone(right: 5);

                var radioButton = new RadioButton(radioButtonView)
                {
                    HAnchor   = HAnchor.Fit,
                    VAnchor   = VAnchor.Fit,
                    TextColor = theme.Colors.PrimaryTextColor,
                    Checked   = extruderIndex == initialMaterialIndex
                };
                materialButtons.Add(radioButton);
                this.AddChild(radioButton);

                int localExtruderIndex = extruderIndex;
                radioButton.Click += (sender, e) =>
                {
                    IndexChanged?.Invoke(this, localExtruderIndex);
                };
            }
        }
Пример #7
0
        public MaterialControls(InteractiveScene scene, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.theme   = theme;
            this.scene   = scene;
            this.HAnchor = HAnchor.Stretch;
            this.VAnchor = VAnchor.Fit;

            materialButtons.Clear();
            int extruderCount = 4;

            for (int extruderIndex = -1; extruderIndex < extruderCount; extruderIndex++)
            {
                var name = $"{"Material".Localize()} {extruderIndex +1}";
                if (extruderIndex == -1)
                {
                    name = "Default".Localize();
                }

                var buttonView = new FlowLayoutWidget()
                {
                    HAnchor = HAnchor.Fit,
                    VAnchor = VAnchor.Fit
                };

                var scaledButtonSize = 16 * GuiWidget.DeviceScale;

                buttonView.AddChild(new ColorButton(extruderIndex == -1 ? Color.Black : MaterialRendering.Color(extruderIndex))
                {
                    Margin  = new BorderDouble(right: 5),
                    Width   = scaledButtonSize,
                    Height  = scaledButtonSize,
                    VAnchor = VAnchor.Center,
                });

                buttonView.AddChild(new TextWidget(name, pointSize: theme.DefaultFontSize, textColor: theme.Colors.PrimaryTextColor)
                {
                    VAnchor = VAnchor.Center
                });

                var radioButtonView = new RadioButtonView(buttonView)
                {
                    TextColor = theme.Colors.PrimaryTextColor
                };
                radioButtonView.RadioCircle.Margin = radioButtonView.RadioCircle.Margin.Clone(right: 5);

                var radioButton = new RadioButton(radioButtonView)
                {
                    HAnchor   = HAnchor.Stretch,
                    VAnchor   = VAnchor.Fit,
                    TextColor = theme.Colors.PrimaryTextColor
                };
                materialButtons.Add(radioButton);
                this.AddChild(radioButton);

                int extruderIndexCanPassToClick = extruderIndex;
                radioButton.Click += (sender, e) =>
                {
                    var selectedItem = scene.SelectedItem;
                    if (selectedItem != null)
                    {
                        selectedItem.MaterialIndex = extruderIndexCanPassToClick;
                        scene.Invalidate(new InvalidateArgs(null, InvalidateType.Material));
                    }
                };
            }

            scene.SelectionChanged += Scene_SelectionChanged;
        }
Пример #8
0
        public MaterialControls(PrinterConfig printer, ThemeConfig theme, int initialMaterialIndex)
            : base(FlowDirection.TopToBottom)
        {
            this.theme   = theme;
            this.HAnchor = HAnchor.Fit;
            this.VAnchor = VAnchor.Fit;

            materialButtons.Clear();
            int extruderCount = 4;

            for (int extruderIndex = -1; extruderIndex < extruderCount; extruderIndex++)
            {
                var name = $"{"Material".Localize()} {extruderIndex + 1}";
                if (extruderIndex == -1)
                {
                    name = "Default".Localize();
                }

                var buttonView = new FlowLayoutWidget()
                {
                    HAnchor = HAnchor.Fit,
                    VAnchor = VAnchor.Fit
                };

                var scaledButtonSize = 24 * GuiWidget.DeviceScale;

                GuiWidget colorButton;
                buttonView.AddChild(colorButton = new ItemColorButton(theme, MaterialRendering.Color(printer, extruderIndex, theme.BorderColor))
                {
                    Width                  = scaledButtonSize,
                    Height                 = scaledButtonSize,
                    BackgroundRadius       = scaledButtonSize / 2,
                    BackgroundOutlineWidth = 1,
                    BorderColor            = theme.TextColor,
                    VAnchor                = VAnchor.Center,
                    Margin                 = new BorderDouble(3, 0, 5, 0),
                });

                buttonView.AddChild(new TextWidget(name, pointSize: theme.DefaultFontSize, textColor: theme.TextColor)
                {
                    VAnchor = VAnchor.Center
                });

                var radioButtonView = new RadioButtonView(buttonView)
                {
                    TextColor  = theme.TextColor,
                    Selectable = false
                };
                radioButtonView.RadioCircle.Margin = radioButtonView.RadioCircle.Margin.Clone(right: 5);

                var radioButton = new RadioButton(radioButtonView)
                {
                    HAnchor   = HAnchor.Fit,
                    VAnchor   = VAnchor.Fit,
                    TextColor = theme.TextColor,
                    Checked   = extruderIndex == initialMaterialIndex,
                    Name      = name + " Button"
                };
                materialButtons.Add(radioButton);
                this.AddChild(radioButton);

                int localExtruderIndex = extruderIndex;
                radioButton.Click += (sender, e) =>
                {
                    IndexChanged?.Invoke(this, localExtruderIndex);
                };
            }
        }
Пример #9
0
        public MaterialControls(PrinterConfig printer, ThemeConfig theme, int initialMaterialIndex)
            : base(FlowDirection.TopToBottom)
        {
            this.theme   = theme;
            this.HAnchor = HAnchor.Fit;
            this.VAnchor = VAnchor.Fit;

            materialButtons.Clear();
            int extruderCount = 4;

            for (int extruderIndex = -1; extruderIndex < extruderCount; extruderIndex++)
            {
                var name = $"{"Material".Localize()} {extruderIndex + 1}";
                if (extruderIndex == -1)
                {
                    name = "Default".Localize();
                }

                var buttonView = new FlowLayoutWidget()
                {
                    HAnchor = HAnchor.Fit,
                    VAnchor = VAnchor.Fit
                };

                var scaledButtonSize = 16 * GuiWidget.DeviceScale;

                GuiWidget colorButton;
                buttonView.AddChild(colorButton = new ItemColorButton(theme, MaterialRendering.Color(printer, extruderIndex, theme.BorderColor))
                {
                    Width   = scaledButtonSize,
                    Height  = scaledButtonSize,
                    VAnchor = VAnchor.Center,
                    Margin  = new BorderDouble(3, 0, 5, 0),
                });

                buttonView.AddChild(new TextWidget(name, pointSize: theme.DefaultFontSize, textColor: theme.TextColor)
                {
                    VAnchor = VAnchor.Center
                });

                var radioButtonView = new RadioButtonView(buttonView)
                {
                    TextColor = theme.TextColor
                };
                radioButtonView.RadioCircle.Margin = radioButtonView.RadioCircle.Margin.Clone(right: 5);

                var radioButton = new RadioButton(radioButtonView)
                {
                    HAnchor   = HAnchor.Fit,
                    VAnchor   = VAnchor.Fit,
                    TextColor = theme.TextColor,
                    Checked   = extruderIndex == initialMaterialIndex,
                    Name      = name + " Button"
                };
                materialButtons.Add(radioButton);
                this.AddChild(radioButton);

                radioButton.MouseMove += (s, e) =>
                {
                    var screenSpace      = radioButton.TransformToScreenSpace(e.Position);
                    var colorButtonSpace = colorButton.TransformFromScreenSpace(screenSpace);
                    if (colorButton.LocalBounds.Contains(colorButtonSpace))
                    {
                        var parent = colorButton.Parent;
                        while (parent != radioButton)
                        {
                            parent.Selectable = true;
                            parent            = parent.Parent;
                        }
                    }
                    else
                    {
                        var parent = colorButton.Parent;
                        while (parent != radioButton)
                        {
                            parent.Selectable = false;
                            parent            = parent.Parent;
                        }
                    }
                };

                radioButton.MouseLeaveBounds += (s, e) =>
                {
                };

                int localExtruderIndex = extruderIndex;
                radioButton.Click += (sender, e) =>
                {
                    IndexChanged?.Invoke(this, localExtruderIndex);
                };
            }
        }