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); }
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); }
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); }
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); } } }
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); }
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); }; } }
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; }
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); }; } }
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); }; } }