Adding in pinch object

This commit is contained in:
LarsBrubaker 2018-04-01 16:06:31 -07:00 committed by Lars Brubaker
parent e86e3b127c
commit dca46e22ab
7 changed files with 152 additions and 31 deletions

View file

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

View file

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

View file

@ -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<DescriptionAttribute>().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<DescriptionAttribute>().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<EditableProperty> 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);

View file

@ -105,6 +105,7 @@
<Compile Include="DesignTools\Operations\FitToBounds3D.cs" />
<Compile Include="DesignTools\Operations\Object3DExtensions.cs" />
<Compile Include="DesignTools\Operations\Package3D.cs" />
<Compile Include="DesignTools\Operations\PinchEditor.cs" />
<Compile Include="DesignTools\Operations\Rotate.cs" />
<Compile Include="DesignTools\Operations\Scale.cs" />
<Compile Include="DesignTools\Operations\SmoothPath.cs" />

View file

@ -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<IObject3D>(children.Select((i) => i.Clone())));
List<IObject3D> originalItems;
if (selectedItem.Children.Count() > 1)
{
originalItems = selectedItem.Children.ToList();
}
else
{
originalItems = new List<IObject3D> { selectedItem.Clone() };
}
var itemsToAdd = new List<IObject3D>(originalItems.Select((i) => i.Clone()));
meshWrapper.WrapAndAddAsChildren(itemsToAdd);
scene.UndoBuffer.AddAndDo(
new ReplaceCommand(
new List<IObject3D>(children),
new List<IObject3D>(originalItems),
new List<IObject3D> { meshWrapper }));
meshWrapper.MakeNameNonColliding();

BIN
StaticData/Icons/pinch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

@ -1 +1 @@
Subproject commit 58899e2087aefac4fe3ea0a480288f37cedb4c74
Subproject commit ab428fa57ac66a7030b6bb15106ad55ee26c63d9