Adding in pinch object
This commit is contained in:
parent
e86e3b127c
commit
dca46e22ab
7 changed files with 152 additions and 31 deletions
|
|
@ -493,6 +493,19 @@ namespace MatterHackers.MatterControl
|
||||||
Icon = AggContext.StaticData.LoadIcon("array_advanced.png").SetPreMultiply(),
|
Icon = AggContext.StaticData.LoadIcon("array_advanced.png").SetPreMultiply(),
|
||||||
IsEnabled = (scene) => scene.HasSelection && !(scene.SelectedItem is SelectionGroup),
|
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()
|
new SceneSelectionOperation()
|
||||||
{
|
{
|
||||||
TitleResolver = () => "Fit to Bounds".Localize(),
|
TitleResolver = () => "Fit to Bounds".Localize(),
|
||||||
|
|
@ -534,13 +547,6 @@ namespace MatterHackers.MatterControl
|
||||||
Action = (scene) => new BendObject3D(scene.SelectedItem),
|
Action = (scene) => new BendObject3D(scene.SelectedItem),
|
||||||
IsEnabled = (scene) => scene.HasSelection,
|
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
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
87
DesignTools/Operations/PinchEditor.cs
Normal file
87
DesignTools/Operations/PinchEditor.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -136,10 +136,35 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
return nameAttribute?.DisplayName ?? prop.Name.SplitCamelCase();
|
return nameAttribute?.DisplayName ?? prop.Name.SplitCamelCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetDescription(PropertyInfo prop)
|
public class EditableProperty
|
||||||
{
|
{
|
||||||
var nameAttribute = prop.GetCustomAttributes(true).OfType<DescriptionAttribute>().FirstOrDefault();
|
public Object Item { get; private set; }
|
||||||
return nameAttribute?.Description ?? null;
|
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)
|
private void CreateEditor(View3DWidget view3DWidget, FlowLayoutWidget editControlsContainer, ThemeConfig theme)
|
||||||
|
|
@ -150,18 +175,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
var rebuildable = item as IRebuildable;
|
var rebuildable = item as IRebuildable;
|
||||||
var propertyGridModifier = item as IPropertyGridModifier;
|
var propertyGridModifier = item as IPropertyGridModifier;
|
||||||
|
|
||||||
var editableProperties = this.item.GetType().GetProperties(OwnedPropertiesOnly)
|
var editableProperties = GetEditablePropreties(item);
|
||||||
.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
|
|
||||||
});
|
|
||||||
|
|
||||||
AddWebPageLinkIfRequired(editControlsContainer, theme);
|
AddWebPageLinkIfRequired(editControlsContainer, theme);
|
||||||
AddUnlockLinkIfRequired(editControlsContainer, theme);
|
AddUnlockLinkIfRequired(editControlsContainer, theme);
|
||||||
|
|
@ -453,16 +467,16 @@ namespace MatterHackers.MatterControl.DesignTools
|
||||||
editControlsContainer.AddChild(rowContainer);
|
editControlsContainer.AddChild(rowContainer);
|
||||||
}
|
}
|
||||||
// create an enum editor
|
// create an enum editor
|
||||||
else if (property.PropertyType.IsEnum)
|
else if (property.ptype.IsEnum)
|
||||||
{
|
{
|
||||||
rowContainer = CreateEnumEditor(rebuildable,
|
rowContainer = CreateEnumEditor(rebuildable,
|
||||||
property.PropertyInfo, property.PropertyType, property.Value, property.DisplayName,
|
property.PropertyInfo, property.ptype, property.Value, property.DisplayName,
|
||||||
theme, undoBuffer);
|
theme, undoBuffer);
|
||||||
editControlsContainer.AddChild(rowContainer);
|
editControlsContainer.AddChild(rowContainer);
|
||||||
}
|
}
|
||||||
// Use known IObject3D editors
|
// Use known IObject3D editors
|
||||||
else if (property.Value is IObject3D object3D
|
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);
|
rowContainer = editor.Create( object3D, view3DWidget, theme);
|
||||||
editControlsContainer.AddChild(rowContainer);
|
editControlsContainer.AddChild(rowContainer);
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@
|
||||||
<Compile Include="DesignTools\Operations\FitToBounds3D.cs" />
|
<Compile Include="DesignTools\Operations\FitToBounds3D.cs" />
|
||||||
<Compile Include="DesignTools\Operations\Object3DExtensions.cs" />
|
<Compile Include="DesignTools\Operations\Object3DExtensions.cs" />
|
||||||
<Compile Include="DesignTools\Operations\Package3D.cs" />
|
<Compile Include="DesignTools\Operations\Package3D.cs" />
|
||||||
|
<Compile Include="DesignTools\Operations\PinchEditor.cs" />
|
||||||
<Compile Include="DesignTools\Operations\Rotate.cs" />
|
<Compile Include="DesignTools\Operations\Rotate.cs" />
|
||||||
<Compile Include="DesignTools\Operations\Scale.cs" />
|
<Compile Include="DesignTools\Operations\Scale.cs" />
|
||||||
<Compile Include="DesignTools\Operations\SmoothPath.cs" />
|
<Compile Include="DesignTools\Operations\SmoothPath.cs" />
|
||||||
|
|
|
||||||
|
|
@ -86,18 +86,31 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
||||||
base.Bake();
|
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;
|
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(
|
scene.UndoBuffer.AddAndDo(
|
||||||
new ReplaceCommand(
|
new ReplaceCommand(
|
||||||
new List<IObject3D>(children),
|
new List<IObject3D>(originalItems),
|
||||||
new List<IObject3D> { meshWrapper }));
|
new List<IObject3D> { meshWrapper }));
|
||||||
|
|
||||||
meshWrapper.MakeNameNonColliding();
|
meshWrapper.MakeNameNonColliding();
|
||||||
|
|
|
||||||
BIN
StaticData/Icons/pinch.png
Normal file
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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue