|
|
@ -192,8 +192,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
{
|
||||
await Rebuild();
|
||||
}
|
||||
else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
|
||||
&& invalidateType.Source == this)
|
||||
else if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Properties) && invalidateType.Source == this)
|
||||
|| invalidateType.InvalidateType.HasFlag(InvalidateType.SheetUpdated))
|
||||
{
|
||||
await Rebuild();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
|
||||
[MaxDecimalPlaces(3)]
|
||||
[JsonIgnore]
|
||||
public DoubleOrExpression Width
|
||||
public double Width
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -150,14 +150,14 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
var children = UntransformedChildren;
|
||||
if (children != null)
|
||||
{
|
||||
FixIfLockedProportions(0, value.Value(this) / UntransformedChildren.GetAxisAlignedBoundingBox().XSize);
|
||||
FixIfLockedProportions(0, value / UntransformedChildren.GetAxisAlignedBoundingBox().XSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MaxDecimalPlaces(3)]
|
||||
[JsonIgnore]
|
||||
public DoubleOrExpression Depth
|
||||
public double Depth
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -174,14 +174,14 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
var children = UntransformedChildren;
|
||||
if (children != null)
|
||||
{
|
||||
FixIfLockedProportions(1, value.Value(this) / children.GetAxisAlignedBoundingBox().YSize);
|
||||
FixIfLockedProportions(1, value / children.GetAxisAlignedBoundingBox().YSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MaxDecimalPlaces(3)]
|
||||
[JsonIgnore]
|
||||
public DoubleOrExpression Height
|
||||
public double Height
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -198,7 +198,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
|
|||
var children = UntransformedChildren;
|
||||
if (children != null)
|
||||
{
|
||||
FixIfLockedProportions(2, value.Value(this) / children.GetAxisAlignedBoundingBox().ZSize);
|
||||
FixIfLockedProportions(2, value / children.GetAxisAlignedBoundingBox().ZSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ either expressed or implied, of the FreeBSD Project.
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MatterHackers.Agg;
|
||||
|
|
@ -62,31 +63,49 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
return item;
|
||||
}
|
||||
|
||||
public override Mesh Mesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.Children.Where(i => i.Mesh == null).Any())
|
||||
{
|
||||
this.Children.Modify((list) =>
|
||||
{
|
||||
list.Clear();
|
||||
Mesh border;
|
||||
using (Stream stlStream = StaticData.Instance.OpenStream(Path.Combine("Stls", "sheet_border.stl")))
|
||||
{
|
||||
border = StlProcessing.Load(stlStream, CancellationToken.None);
|
||||
}
|
||||
list.Add(new Object3D()
|
||||
{
|
||||
Mesh = border,
|
||||
Color = new Color("#9D9D9D")
|
||||
});
|
||||
Mesh boxes;
|
||||
using (Stream stlStream = StaticData.Instance.OpenStream(Path.Combine("Stls", "sheet_boxes.stl")))
|
||||
{
|
||||
boxes = StlProcessing.Load(stlStream, CancellationToken.None);
|
||||
}
|
||||
list.Add(new Object3D()
|
||||
{
|
||||
Mesh = boxes,
|
||||
Color = new Color("#117c43")
|
||||
});
|
||||
|
||||
var aabb = border.GetAxisAlignedBoundingBox();
|
||||
this.Matrix *= Matrix4X4.CreateScale(20 / aabb.XSize);
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
set => base.Mesh = value;
|
||||
}
|
||||
|
||||
public SheetObject3D()
|
||||
{
|
||||
Mesh border;
|
||||
using (Stream stlStream = StaticData.Instance.OpenStream(Path.Combine("Stls", "sheet_border.stl")))
|
||||
{
|
||||
border = StlProcessing.Load(stlStream, CancellationToken.None);
|
||||
}
|
||||
this.Children.Add(new Object3D()
|
||||
{
|
||||
Mesh = border,
|
||||
Color = new Color("#9D9D9D")
|
||||
});
|
||||
Mesh boxes;
|
||||
using (Stream stlStream = StaticData.Instance.OpenStream(Path.Combine("Stls", "sheet_boxes.stl")))
|
||||
{
|
||||
boxes = StlProcessing.Load(stlStream, CancellationToken.None);
|
||||
}
|
||||
this.Children.Add(new Object3D()
|
||||
{
|
||||
Mesh = boxes,
|
||||
Color = new Color("#117c43")
|
||||
});
|
||||
|
||||
var aabb = border.GetAxisAlignedBoundingBox();
|
||||
this.Matrix *= Matrix4X4.CreateScale(20 / aabb.XSize);
|
||||
}
|
||||
|
||||
public override bool Persistable => false;
|
||||
|
|
@ -109,51 +128,94 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
}
|
||||
}
|
||||
|
||||
internal class UpdateItem
|
||||
{
|
||||
internal int depth;
|
||||
internal IObject3D item;
|
||||
internal RebuildLock rebuildLock;
|
||||
}
|
||||
private void SendInvalidateToAll()
|
||||
{
|
||||
var updatedItems = new HashSet<IObject3D>();
|
||||
updatedItems.Add(this);
|
||||
var updateItems = new List<UpdateItem>();
|
||||
foreach (var sibling in this.Parent.Children)
|
||||
{
|
||||
SendInvalidateRecursive(sibling, updatedItems);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendInvalidateRecursive(IObject3D item, HashSet<IObject3D> updatedItems)
|
||||
{
|
||||
if (updatedItems.Contains(item))
|
||||
{
|
||||
return;
|
||||
if (sibling != this)
|
||||
{
|
||||
AddItemsToList(sibling, updateItems, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// process depth first
|
||||
foreach(var child in item.Children)
|
||||
// sort them
|
||||
updateItems.Sort((a, b) => a.depth.CompareTo(b.depth));
|
||||
// lock everything
|
||||
foreach (var depthItem in updateItems)
|
||||
{
|
||||
SendInvalidateRecursive(child, updatedItems);
|
||||
depthItem.rebuildLock = depthItem.item.RebuildLock();
|
||||
}
|
||||
|
||||
// and send the invalidate
|
||||
RunningInterval runningInterval = null;
|
||||
void RebuildWhenUnlocked()
|
||||
{
|
||||
if (!item.RebuildLocked)
|
||||
// get the last item from the list
|
||||
var index = updateItems.Count - 1;
|
||||
var updateItem = updateItems[index];
|
||||
// if it is locked from above
|
||||
if (updateItem.rebuildLock != null)
|
||||
{
|
||||
// release the lock and rebuild
|
||||
// and ask it to update
|
||||
var depthToBuild = updateItem.depth;
|
||||
for (int i = 0; i < updateItems.Count; i++)
|
||||
{
|
||||
if (updateItems[i].depth == updateItem.depth)
|
||||
{
|
||||
updateItems[i].rebuildLock.Dispose();
|
||||
updateItems[i].rebuildLock = null;
|
||||
updateItems[i].item.Invalidate(new InvalidateArgs(updateItems[i].item, InvalidateType.SheetUpdated));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (updateItems.Where(i => i.depth == updateItem.depth && i.item.RebuildLocked).Any())
|
||||
{
|
||||
// wait for the current rebuild to end
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove all items at this level
|
||||
for (int i = updateItems.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (updateItems[i].depth == updateItem.depth)
|
||||
{
|
||||
updateItems.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updateItems.Count == 0)
|
||||
{
|
||||
updatedItems.Add(item);
|
||||
UiThread.ClearInterval(runningInterval);
|
||||
item.Invalidate(new InvalidateArgs(item, InvalidateType.SheetUpdated));
|
||||
}
|
||||
}
|
||||
|
||||
if (!item.RebuildLocked)
|
||||
// rebuild depth first
|
||||
runningInterval = UiThread.SetInterval(RebuildWhenUnlocked, .01);
|
||||
}
|
||||
|
||||
private void AddItemsToList(IObject3D inItem, List<UpdateItem> updatedItems, int inDepth)
|
||||
{
|
||||
// process depth first
|
||||
foreach(var child in inItem.Children)
|
||||
{
|
||||
updatedItems.Add(item);
|
||||
item.Invalidate(new InvalidateArgs(item, InvalidateType.SheetUpdated));
|
||||
AddItemsToList(child, updatedItems, inDepth + 1);
|
||||
}
|
||||
else
|
||||
|
||||
updatedItems.Add(new UpdateItem()
|
||||
{
|
||||
// we need to get back to the user requested change when not locked
|
||||
runningInterval = UiThread.SetInterval(RebuildWhenUnlocked, .2);
|
||||
}
|
||||
depth = inDepth,
|
||||
item = inItem
|
||||
});
|
||||
}
|
||||
|
||||
public static T EvaluateExpression<T>(IObject3D owner, string inputExpression)
|
||||
|
|
|
|||
|
|
@ -398,7 +398,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
statusMessage = tasksContainer.AddChild(new TextWidget("")
|
||||
{
|
||||
Margin = new BorderDouble(5, 0, 0, 0),
|
||||
Margin = new BorderDouble(5, 0, 0, 3),
|
||||
TextColor = theme.TextColor,
|
||||
VAnchor = VAnchor.Center,
|
||||
PointSize = theme.FontSize9,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ using MatterHackers.Agg.UI;
|
|||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.DesignTools.Operations;
|
||||
using MatterHackers.PolygonMesh;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
||||
|
|
|
|||
|
|
@ -105,8 +105,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
{
|
||||
await Rebuild();
|
||||
}
|
||||
else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
|
||||
&& invalidateType.Source == this)
|
||||
else if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Properties) && invalidateType.Source == this)
|
||||
|| invalidateType.InvalidateType.HasFlag(InvalidateType.SheetUpdated))
|
||||
{
|
||||
await Rebuild();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
// Clear selection to ensure all root level children are arranged on the bed
|
||||
scene.SelectedItem = null;
|
||||
|
||||
var children = scene.Children.ToList().Where(item => item.Persistable == true).ToList();
|
||||
var children = scene.Children.ToList().Where(item =>
|
||||
{
|
||||
var aabb = item.WorldAxisAlignedBoundingBox();
|
||||
if (aabb.Center.Length > 1000)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return item.Persistable == true;
|
||||
}).ToList();
|
||||
var transformData = new List<TransformData>();
|
||||
foreach (var child in children)
|
||||
{
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 4.3 KiB |
BIN
StaticData/Images/Thumbnails/15936583715112407855-256x256.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
StaticData/Images/Thumbnails/16091828042932597356-256x256.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 8 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 4 KiB After Width: | Height: | Size: 4.7 KiB |
|
|
@ -1 +1 @@
|
|||
Subproject commit 78d54a573392075ebc0b7579d245eb17df539a39
|
||||
Subproject commit 4f3afb00997203e206eebef6e1dfc5858b0a2fe1
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 53e703573d54be5bf4962483abfbb8c91dff11c4
|
||||
Subproject commit 0b4c79769aa23a62df17f10ec771c0bb95cdb352
|
||||
|
|
@ -13,7 +13,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
public class PrimitiveAndSheetsTests
|
||||
{
|
||||
[Test]
|
||||
public async Task DimensionsWorkWithSheets()
|
||||
public async Task DimensionsWorkWhenNoSheet()
|
||||
{
|
||||
await MatterControlUtilities.RunTest((testRunner) =>
|
||||
{
|
||||
|
|
@ -83,5 +83,77 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
return Task.CompletedTask;
|
||||
}, overrideWidth: 1300, maxTimeToRun: 60);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ScaleObjectWorksWithAndWithoutSheet()
|
||||
{
|
||||
await MatterControlUtilities.RunTest((testRunner) =>
|
||||
{
|
||||
testRunner.OpenEmptyPartTab();
|
||||
|
||||
var primitive = "Cube";
|
||||
var primitiveName = "Row Item " + primitive;
|
||||
testRunner.DoubleClickByName(primitiveName);
|
||||
|
||||
// Get View3DWidget
|
||||
View3DWidget view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget;
|
||||
var scene = view3D.Object3DControlLayer.Scene;
|
||||
|
||||
testRunner.WaitForName(primitive);
|
||||
Assert.AreEqual(1, scene.Children.Count, "Should have 1 part");
|
||||
|
||||
var cube = testRunner.GetObjectByName(primitive, out _) as CubeObject3D;
|
||||
|
||||
Assert.AreEqual(20, cube.Width.Value(cube));
|
||||
|
||||
// Select scene object
|
||||
testRunner.Select3DPart(primitive);
|
||||
|
||||
// Scale it wider
|
||||
testRunner.DragDropByName("ScaleWidthRight",
|
||||
"ScaleWidthRight",
|
||||
offsetDrag: new Point2D(0, 0),
|
||||
offsetDrop: new Point2D(0, 10));
|
||||
Assert.Greater(cube.Width.Value(cube), 20.0);
|
||||
|
||||
testRunner.ClickByName("3D View Undo");
|
||||
Assert.AreEqual(20, cube.Width.Value(cube));
|
||||
|
||||
// try scaling by text entry
|
||||
testRunner.ClickByName("ScaleWidthLeft")
|
||||
.ClickByName("XValueDisplay")
|
||||
.Type("35")
|
||||
.Type("{Enter}");
|
||||
|
||||
Assert.AreEqual(35, cube.Width.Value(cube));
|
||||
|
||||
testRunner.ClickByName("3D View Undo");
|
||||
Assert.AreEqual(20, cube.Width.Value(cube));
|
||||
|
||||
// try scaling by text entry of an equation
|
||||
testRunner.ClickByName("Width Field")
|
||||
.Type("=40 + 5")
|
||||
.Type("{Enter}");
|
||||
|
||||
Assert.AreEqual(45, cube.Width.Value(cube));
|
||||
|
||||
// Select Nothing
|
||||
testRunner.ClickByName("View3DWidget");
|
||||
testRunner.Type(" ");
|
||||
Assert.AreEqual(null, scene.SelectedItem);
|
||||
// and re-select the object
|
||||
testRunner.Type("^a");
|
||||
Assert.AreEqual(1, scene.Children.Count);
|
||||
Assert.AreEqual(cube, scene.SelectedItem);
|
||||
|
||||
// now that has an equation in the width it should not have an x edge controls
|
||||
Assert.IsFalse(testRunner.NameExists("ScaleWidthRight", .2));
|
||||
|
||||
testRunner.ClickByName("3D View Undo");
|
||||
Assert.AreEqual(20, cube.Width.Value(cube));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}, overrideWidth: 1300, maxTimeToRun: 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||