From dca46e22abf718791662ea4fd09a23ce75cdb5ac Mon Sep 17 00:00:00 2001 From: LarsBrubaker Date: Sun, 1 Apr 2018 16:06:31 -0700 Subject: [PATCH] Adding in pinch object --- ApplicationView/ApplicationController.cs | 20 ++-- DesignTools/Operations/PinchEditor.cs | 87 ++++++++++++++++++ DesignTools/PublicPropertyEditor.cs | 50 ++++++---- MatterControl.csproj | 1 + .../View3D/Actions/MeshWrapperObject3D.cs | 23 ++++- StaticData/Icons/pinch.png | Bin 0 -> 234 bytes Submodules/MatterSlice | 2 +- 7 files changed, 152 insertions(+), 31 deletions(-) create mode 100644 DesignTools/Operations/PinchEditor.cs create mode 100644 StaticData/Icons/pinch.png diff --git a/ApplicationView/ApplicationController.cs b/ApplicationView/ApplicationController.cs index 4fc90d410..4cad9e684 100644 --- a/ApplicationView/ApplicationController.cs +++ b/ApplicationView/ApplicationController.cs @@ -493,6 +493,19 @@ namespace MatterHackers.MatterControl Icon = AggContext.StaticData.LoadIcon("array_advanced.png").SetPreMultiply(), IsEnabled = (scene) => scene.HasSelection && !(scene.SelectedItem is SelectionGroup), }, + new SceneSelectionSeparator(), + new SceneSelectionOperation() + { + TitleResolver = () => "Pinch".Localize(), + Action = (scene) => + { + var pinch = new PinchObject3D(); + MeshWrapperObject3D.WrapSelection(pinch, scene); + pinch.MakeNameNonColliding(); + }, + Icon = AggContext.StaticData.LoadIcon("pinch.png", 16, 16), + IsEnabled = (scene) => scene.HasSelection, + }, new SceneSelectionOperation() { TitleResolver = () => "Fit to Bounds".Localize(), @@ -534,13 +547,6 @@ namespace MatterHackers.MatterControl Action = (scene) => new BendObject3D(scene.SelectedItem), IsEnabled = (scene) => scene.HasSelection, }, - new SceneSelectionOperation() - { - // Should be a pinch command that makes a pinch object with the correct controls - TitleResolver = () => "Pinch".Localize(), - //Action = (scene) => scene.UndoBuffer.AddAndDo(new GroupCommand(scene, scene.SelectedItem)), - IsEnabled = (scene) => scene.HasSelection, - } #endif }; diff --git a/DesignTools/Operations/PinchEditor.cs b/DesignTools/Operations/PinchEditor.cs new file mode 100644 index 000000000..658148172 --- /dev/null +++ b/DesignTools/Operations/PinchEditor.cs @@ -0,0 +1,87 @@ +/* +Copyright (c) 2018, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MatterHackers.Agg; +using MatterHackers.Agg.Font; +using MatterHackers.Agg.UI; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.PartPreviewWindow; +using MatterHackers.MatterControl.PartPreviewWindow.View3D; +using MatterHackers.PolygonMesh; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl.DesignTools +{ + public class PinchObject3D : MeshWrapperObject3D, IRebuildable + { + [DisplayName("Back Ratio")] + public double PinchRatio { get; set; } = 1; + + public PinchObject3D() + { + } + + public void Rebuild(UndoBuffer undoBuffer) + { + var aabb = this.GetAxisAlignedBoundingBox(); + + var meshWrapper = this.Descendants() + .Where((obj) => obj.OwnerID == this.ID).ToList(); + + foreach (var meshes in meshWrapper.Select((mw) => (Original: mw.Children.First().Mesh, + Transformed: mw.Mesh))) + { + for (int i = 0; i < meshes.Original.Vertices.Count; i++) + { + var pos = meshes.Original.Vertices[i].Position; + + var ratioToApply = PinchRatio; + + var distFromCenter = pos.X - aabb.Center.X; + var distanceToPinch = distFromCenter * (1 - PinchRatio); + var delta = (aabb.Center.X + distFromCenter * ratioToApply) - pos.X; + + // find out how much to pinch based on y position + var amountOfRatio = (pos.Y - aabb.minXYZ.Y) / aabb.YSize; + meshes.Transformed.Vertices[i].Position = new Vector3(pos.X + delta * amountOfRatio, pos.Y, pos.Z); + } + + meshes.Transformed.MarkAsChanged(); + meshes.Transformed.CalculateNormals(); + } + } + } +} \ No newline at end of file diff --git a/DesignTools/PublicPropertyEditor.cs b/DesignTools/PublicPropertyEditor.cs index e9511d3d3..31a7393ea 100644 --- a/DesignTools/PublicPropertyEditor.cs +++ b/DesignTools/PublicPropertyEditor.cs @@ -136,10 +136,35 @@ namespace MatterHackers.MatterControl.DesignTools return nameAttribute?.DisplayName ?? prop.Name.SplitCamelCase(); } - private string GetDescription(PropertyInfo prop) + public class EditableProperty { - var nameAttribute = prop.GetCustomAttributes(true).OfType().FirstOrDefault(); - return nameAttribute?.Description ?? null; + public Object Item { get; private set; } + public PropertyInfo PropertyInfo { get; private set; } + public EditableProperty(PropertyInfo p, object item) + { + this.Item = item; + this.PropertyInfo = p; + } + + private string GetDescription(PropertyInfo prop) + { + var nameAttribute = prop.GetCustomAttributes(true).OfType().FirstOrDefault(); + return nameAttribute?.Description ?? null; + } + + public object Value => PropertyInfo.GetGetMethod().Invoke(Item, null); + public string DisplayName => GetDisplayName(PropertyInfo); + public string Description => GetDescription(PropertyInfo); + public Type ptype => PropertyInfo.PropertyType; + } + + public static IEnumerable GetEditablePropreties(Object item) + { + return item.GetType().GetProperties(OwnedPropertiesOnly) + .Where(pi => (allowedTypes.Contains(pi.PropertyType) || pi.PropertyType.IsEnum) + && pi.GetGetMethod() != null + && pi.GetSetMethod() != null) + .Select(p => new EditableProperty(p, item)); } private void CreateEditor(View3DWidget view3DWidget, FlowLayoutWidget editControlsContainer, ThemeConfig theme) @@ -150,18 +175,7 @@ namespace MatterHackers.MatterControl.DesignTools var rebuildable = item as IRebuildable; var propertyGridModifier = item as IPropertyGridModifier; - var editableProperties = this.item.GetType().GetProperties(OwnedPropertiesOnly) - .Where(pi => (allowedTypes.Contains(pi.PropertyType) || pi.PropertyType.IsEnum) - && pi.GetGetMethod() != null - && pi.GetSetMethod() != null) - .Select(p => new - { - Value = p.GetGetMethod().Invoke(this.item, null), - DisplayName = GetDisplayName(p), - Description = GetDescription(p), - PropertyType = p.PropertyType, - PropertyInfo = p - }); + var editableProperties = GetEditablePropreties(item); AddWebPageLinkIfRequired(editControlsContainer, theme); AddUnlockLinkIfRequired(editControlsContainer, theme); @@ -453,16 +467,16 @@ namespace MatterHackers.MatterControl.DesignTools editControlsContainer.AddChild(rowContainer); } // create an enum editor - else if (property.PropertyType.IsEnum) + else if (property.ptype.IsEnum) { rowContainer = CreateEnumEditor(rebuildable, - property.PropertyInfo, property.PropertyType, property.Value, property.DisplayName, + property.PropertyInfo, property.ptype, property.Value, property.DisplayName, theme, undoBuffer); editControlsContainer.AddChild(rowContainer); } // Use known IObject3D editors else if (property.Value is IObject3D object3D - && ApplicationController.Instance.GetEditorsForType(property.PropertyType)?.FirstOrDefault() is IObject3DEditor editor) + && ApplicationController.Instance.GetEditorsForType(property.ptype)?.FirstOrDefault() is IObject3DEditor editor) { rowContainer = editor.Create( object3D, view3DWidget, theme); editControlsContainer.AddChild(rowContainer); diff --git a/MatterControl.csproj b/MatterControl.csproj index 7458e65ea..d2952ccb6 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -105,6 +105,7 @@ + diff --git a/PartPreviewWindow/View3D/Actions/MeshWrapperObject3D.cs b/PartPreviewWindow/View3D/Actions/MeshWrapperObject3D.cs index a968cf175..7a43342e8 100644 --- a/PartPreviewWindow/View3D/Actions/MeshWrapperObject3D.cs +++ b/PartPreviewWindow/View3D/Actions/MeshWrapperObject3D.cs @@ -86,18 +86,31 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D base.Bake(); } - public static void WrapSelection(MeshWrapperObject3D meshWrapper, InteractiveScene scene) + public static void WrapSelection(MeshWrapperObject3D meshWrapper, InteractiveScene scene) { - if (scene.HasSelection && scene.SelectedItem.Children.Count() > 1) + if (scene.HasSelection) { - var children = scene.SelectedItem.Children; + var selectedItem = scene.SelectedItem; scene.SelectedItem = null; - meshWrapper.WrapAndAddAsChildren(new List(children.Select((i) => i.Clone()))); + List originalItems; + + if (selectedItem.Children.Count() > 1) + { + originalItems = selectedItem.Children.ToList(); + + } + else + { + originalItems = new List { selectedItem.Clone() }; + } + + var itemsToAdd = new List(originalItems.Select((i) => i.Clone())); + meshWrapper.WrapAndAddAsChildren(itemsToAdd); scene.UndoBuffer.AddAndDo( new ReplaceCommand( - new List(children), + new List(originalItems), new List { meshWrapper })); meshWrapper.MakeNameNonColliding(); diff --git a/StaticData/Icons/pinch.png b/StaticData/Icons/pinch.png new file mode 100644 index 0000000000000000000000000000000000000000..3632277cfe11acaea58702adf5d761d3c222014a GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7*pj^6T^Rm@;DWu&Co?cG za29w(7BevL9RXp+soH$f3=9nHC7!;n?2nju8I?7r>gZW8Fff#Rx;TbdoKD_T@llC+ zr$c=F{KnSC#>R!O+AKV!Zkxm%y6M9s!X#F+Y%#ORbS?t}gPMdUqZ4c)Uk}wMF^jBf zo2aF?V4nE2}~fdI7~H20D%v2KbsC#KkaVp dWbI;PP%DzjyqWTdn}LCW!PC{xWt~$(69CbOO;Z2> literal 0 HcmV?d00001 diff --git a/Submodules/MatterSlice b/Submodules/MatterSlice index 58899e208..ab428fa57 160000 --- a/Submodules/MatterSlice +++ b/Submodules/MatterSlice @@ -1 +1 @@ -Subproject commit 58899e2087aefac4fe3ea0a480288f37cedb4c74 +Subproject commit ab428fa57ac66a7030b6bb15106ad55ee26c63d9