Working on new arrange toolAdding Remove and Bake to IObject3D

Made Localize() exist in agg
This commit is contained in:
Lars Brubaker 2018-02-12 15:28:26 -08:00
parent d870a0222f
commit 8f6f0f7162
32 changed files with 599 additions and 432 deletions

View file

@ -435,10 +435,10 @@ namespace MatterHackers.MatterControl
TitleResolver = () => "Align".Localize(),
Action = (scene) =>
{
scene.AddSelectionAsChildren(new ArangeObject3D());
if(scene.SelectedItem is ArangeObject3D arange)
scene.AddSelectionAsChildren(new ArrangeObject3D());
if(scene.SelectedItem is ArrangeObject3D arrange)
{
arange.Rebuild();
arrange.Rebuild();
}
},
//Icon = AggContext.StaticData.LoadIcon("array_linear.png").SetPreMultiply(),

View file

@ -45,8 +45,8 @@ namespace MatterHackers.MatterControl
{
protected static readonly int DefaultScrollBarWidth = 120;
private static ImageBuffer restoreNormal;
private static ImageBuffer restoreHover;
public static ImageBuffer RestoreNormal { get; private set; }
public static ImageBuffer RestoreHover { get; private set; }
private static ImageBuffer restorePressed;
private readonly int fizedHeightA = (int)(25 * GuiWidget.DeviceScale + .5);
@ -140,13 +140,13 @@ namespace MatterHackers.MatterControl
if (AggContext.OperatingSystem == OSType.Android)
{
restoreNormal = ColorCircle(size, new Color(200, 0, 0));
RestoreNormal = ColorCircle(size, new Color(200, 0, 0));
}
else
{
restoreNormal = ColorCircle(size, Color.Transparent);
RestoreNormal = ColorCircle(size, Color.Transparent);
}
restoreHover = ColorCircle(size, new Color("#DB4437"));
RestoreHover = ColorCircle(size, new Color("#DB4437"));
restorePressed = ColorCircle(size, new Color(255, 0, 0));
}
@ -375,10 +375,10 @@ namespace MatterHackers.MatterControl
{
return new Button(
new ButtonViewStates(
new ImageWidget(restoreNormal),
new ImageWidget(restoreHover),
new ImageWidget(RestoreNormal),
new ImageWidget(RestoreHover),
new ImageWidget(restorePressed),
new ImageWidget(restoreNormal)))
new ImageWidget(RestoreNormal)))
{
VAnchor = VAnchor.Center,
Margin = new BorderDouble(0, 0, 5, 0)

View file

@ -0,0 +1,186 @@
/*
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 MatterHackers.DataConverters3D;
using MatterHackers.VectorMath;
using Newtonsoft.Json;
namespace MatterHackers.MatterControl.DesignTools.Operations
{
using Aabb = AxisAlignedBoundingBox;
public class ArrangeObject3D : Object3D, IRebuildable
{
// We need to serialize this so we can remove the arrange and get back to the objects before arranging
public List<Aabb> ChildrenBounds = new List<Aabb>();
public ArrangeObject3D()
{
}
public enum Align { None, Min, Center, Max }
public override string ActiveEditor => "PublicPropertyEditor";
[Icons(new string[] {"align_left.png", "align_center_x.png", "align_right.png"})]
public Align XAlign { get; set; } = Align.None;
[Icons(new string[] { "align_left.png", "align_center_x.png", "align_right.png" })]
[EnableIf("XAlign", "!None")]
public Align XAlignTo { get; set; } = Align.None;
[EnableIf("XAlign", "!None")]
public double OffsetX { get; set; } = 0;
public Align YAlign { get; set; } = Align.None;
public Align YAlignTo { get; set; } = Align.None;
public double YOffset { get; set; } = 0;
public Align ZAlign { get; set; } = Align.None;
public Align ZAlignTo { get; set; } = Align.None;
public double ZOffset { get; set; } = 0;
public void Rebuild()
{
var aabb = this.GetAxisAlignedBoundingBox();
// TODO: check if the has code for the children
if (ChildrenBounds.Count == 0)
{
this.Children.Modify(list =>
{
foreach (var child in list)
{
ChildrenBounds.Add(child.GetAxisAlignedBoundingBox());
}
});
}
this.Children.Modify(list =>
{
var firstBounds = ChildrenBounds[0];
int i = 0;
foreach (var child in list)
{
if (i > 0)
{
if (XAlign == Align.None)
{
// make sure it is where it started
AlignAxis(0, Align.Min, ChildrenBounds[i].minXYZ.X, 0, child);
}
else
{
AlignAxis(0, XAlign, GetAlignToOffset(0, XAlignTo == Align.None ? XAlign : XAlignTo), OffsetX, child);
}
if (YAlign == Align.None)
{
AlignAxis(1, Align.Min, ChildrenBounds[i].minXYZ.Y, 0, child);
}
else
{
AlignAxis(1, YAlign, GetAlignToOffset(1, YAlignTo == Align.None ? YAlign : YAlignTo), YOffset, child);
}
if (ZAlign == Align.None)
{
AlignAxis(2, Align.Min, ChildrenBounds[i].minXYZ.Z, 0, child);
}
else
{
AlignAxis(2, ZAlign, GetAlignToOffset(2, ZAlignTo == Align.None ? ZAlign : ZAlignTo), ZOffset, child);
}
}
i++;
}
});
}
public override bool CanRemove => true;
public override bool CanBake => true;
public override void Remove()
{
// put everything back to where it was before the arange started
if(ChildrenBounds.Count == Children.Count)
{
int i = 0;
foreach(var child in Children)
{
// Where you are minus where you started to get back to where you started
child.Translate(child.GetAxisAlignedBoundingBox().minXYZ - ChildrenBounds[i++].minXYZ);
}
}
base.Remove();
}
private void AlignAxis(int axis, Align align, double alignTo, double offset,
IObject3D item)
{
var aabb = item.GetAxisAlignedBoundingBox();
var translate = Vector3.Zero;
switch (align)
{
case Align.Min:
translate[axis] = alignTo - aabb.minXYZ[axis] + offset;
break;
case Align.Center:
translate[axis] = alignTo - aabb.Center[axis] + offset;
break;
case Align.Max:
translate[axis] = alignTo - aabb.maxXYZ[axis] + offset;
break;
}
item.Translate(translate);
}
private double GetAlignToOffset(int axis, Align alignTo)
{
switch (alignTo)
{
case Align.Min:
return ChildrenBounds[0].minXYZ[axis];
case Align.Center:
return ChildrenBounds[0].Center[axis];
case Align.Max:
return ChildrenBounds[0].maxXYZ[axis];
default:
throw new NotImplementedException();
}
}
}
}

View file

@ -0,0 +1,98 @@
/*
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.Linq;
using MatterHackers.DataConverters3D;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools.Operations
{
public class ArrayAdvancedObject3D : Object3D, IRebuildable
{
public ArrayAdvancedObject3D()
{
}
public override string ActiveEditor => "PublicPropertyEditor";
public int Count { get; set; } = 3;
public double Rotate { get; set; } = 0;
public bool RotatePart { get; set; } = false;
public double Scale { get; set; } = 1;
public bool ScaleOffset { get; set; } = false;
public double XOffset { get; set; } = 30;
public double YOffset { get; set; } = 0;
public void Rebuild()
{
this.Children.Modify(list =>
{
IObject3D lastChild = list.First();
list.Clear();
list.Add(lastChild);
var offset = Vector3.Zero;
for (int i = 1; i < Count; i++)
{
var rotateRadians = MathHelper.DegreesToRadians(Rotate);
var nextOffset = new Vector2(XOffset, YOffset);
if (ScaleOffset)
{
for (int j = 1; j < i; j++)
{
nextOffset *= Scale;
}
}
nextOffset.Rotate(rotateRadians * i);
var next = lastChild.Clone();
next.Matrix *= Matrix4X4.CreateTranslation(nextOffset.X, nextOffset.Y, 0);
if (RotatePart)
{
next.ApplyAtBoundsCenter(Matrix4X4.CreateRotationZ(rotateRadians));
}
next.ApplyAtBoundsCenter(Matrix4X4.CreateScale(Scale));
list.Add(next);
lastChild = next;
}
});
}
}
public class DirectionAxis
{
public Vector3 Normal { get; set; }
public Vector3 Origin { get; set; }
}
public class DirectionVector
{
public Vector3 Normal { get; set; }
}
}

View file

@ -0,0 +1,65 @@
/*
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.Linq;
using MatterHackers.DataConverters3D;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools.Operations
{
public class ArrayLinearObject3D : Object3D, IRebuildable
{
public ArrayLinearObject3D()
{
}
public override string ActiveEditor => "PublicPropertyEditor";
public int Count { get; set; } = 3;
public DirectionVector Direction { get; set; } = new DirectionVector { Normal = new Vector3(1, 0, 0) };
public double Distance { get; set; } = 30;
public void Rebuild()
{
this.Children.Modify(list =>
{
IObject3D lastChild = list.First();
list.Clear();
list.Add(lastChild);
var offset = Vector3.Zero;
for (int i = 1; i < Count; i++)
{
var next = lastChild.Clone();
next.Matrix *= Matrix4X4.CreateTranslation(Direction.Normal.GetNormal() * Distance);
list.Add(next);
lastChild = next;
}
});
}
}
}

View file

@ -1,314 +0,0 @@
/*
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 MatterHackers.DataConverters3D;
using MatterHackers.VectorMath;
using Newtonsoft.Json;
namespace MatterHackers.MatterControl.DesignTools.Operations
{
using Aabb = AxisAlignedBoundingBox;
public class ArangeObject3D : Object3D, IRebuildable
{
[JsonIgnoreAttribute]
private List<Aabb> childrenBounds = new List<Aabb>();
public ArangeObject3D()
{
}
public enum Align { None, Min, Center, Max }
public override string ActiveEditor => "PublicPropertyEditor";
// Attributes - [SameLineAsLast, Icons(new string[] {"LeftX", "CenterX", "RightX"})]
public Align XAlign { get; set; } = Align.None;
// Attributes - [EnableIfNot("XAlign", "None"), Icons(new string[] {"NoneX", "LeftX", "CenterX", "RightX"})]
public Align XAlignTo { get; set; } = Align.None;
// Attributes - [EnableIfNot("XAlign", "None")]
public double OffsetX { get; set; } = 0;
public Align YAlign { get; set; } = Align.None;
public Align YAlignTo { get; set; } = Align.None;
public double YOffset { get; set; } = 0;
public Align ZAlign { get; set; } = Align.None;
public Align ZAlignTo { get; set; } = Align.None;
public double ZOffset { get; set; } = 0;
public void Rebuild()
{
var aabb = this.GetAxisAlignedBoundingBox();
// TODO: check if the has code for the children
if (childrenBounds.Count == 0)
{
this.Children.Modify(list =>
{
foreach (var child in list)
{
childrenBounds.Add(child.GetAxisAlignedBoundingBox());
}
});
}
this.Children.Modify(list =>
{
var firstBounds = childrenBounds[0];
int i = 0;
foreach (var child in list)
{
if (i > 0)
{
if (XAlign == Align.None)
{
// make sure it is where it started
AlignAxis(0, Align.Min, childrenBounds[i].minXYZ.X, 0, child);
}
else
{
AlignAxis(0, XAlign, GetAlignToOffset(0, XAlignTo == Align.None ? XAlign : XAlignTo), OffsetX, child);
}
if (YAlign == Align.None)
{
AlignAxis(1, Align.Min, childrenBounds[i].minXYZ.Y, 0, child);
}
else
{
AlignAxis(1, YAlign, GetAlignToOffset(1, YAlignTo == Align.None ? YAlign : YAlignTo), YOffset, child);
}
if (ZAlign == Align.None)
{
AlignAxis(2, Align.Min, childrenBounds[i].minXYZ.Z, 0, child);
}
else
{
AlignAxis(2, ZAlign, GetAlignToOffset(2, ZAlignTo == Align.None ? ZAlign : ZAlignTo), ZOffset, child);
}
}
i++;
}
});
}
private void AlignAxis(int axis, Align align, double alignTo, double offset,
IObject3D item)
{
var aabb = item.GetAxisAlignedBoundingBox();
var translate = Vector3.Zero;
switch (align)
{
case Align.Min:
translate[axis] = alignTo - aabb.minXYZ[axis] + offset;
break;
case Align.Center:
translate[axis] = alignTo - aabb.Center[axis] + offset;
break;
case Align.Max:
translate[axis] = alignTo - aabb.maxXYZ[axis] + offset;
break;
}
item.Translate(translate);
}
private double GetAlignToOffset(int axis, Align alignTo)
{
switch (alignTo)
{
case Align.Min:
return childrenBounds[0].minXYZ[axis];
case Align.Center:
return childrenBounds[0].Center[axis];
case Align.Max:
return childrenBounds[0].maxXYZ[axis];
default:
throw new NotImplementedException();
}
}
}
public class ArrayAdvancedObject3D : Object3D, IRebuildable
{
public ArrayAdvancedObject3D()
{
}
public override string ActiveEditor => "PublicPropertyEditor";
public int Count { get; set; } = 3;
public double Rotate { get; set; } = 0;
public bool RotatePart { get; set; } = false;
public double Scale { get; set; } = 1;
public bool ScaleOffset { get; set; } = false;
public double XOffset { get; set; } = 30;
public double YOffset { get; set; } = 0;
public void Rebuild()
{
this.Children.Modify(list =>
{
IObject3D lastChild = list.First();
list.Clear();
list.Add(lastChild);
var offset = Vector3.Zero;
for (int i = 1; i < Count; i++)
{
var rotateRadians = MathHelper.DegreesToRadians(Rotate);
var nextOffset = new Vector2(XOffset, YOffset);
if (ScaleOffset)
{
for (int j = 1; j < i; j++)
{
nextOffset *= Scale;
}
}
nextOffset.Rotate(rotateRadians * i);
var next = lastChild.Clone();
next.Matrix *= Matrix4X4.CreateTranslation(nextOffset.X, nextOffset.Y, 0);
if (RotatePart)
{
next.ApplyAtBoundsCenter(Matrix4X4.CreateRotationZ(rotateRadians));
}
next.ApplyAtBoundsCenter(Matrix4X4.CreateScale(Scale));
list.Add(next);
lastChild = next;
}
});
}
}
public class ArrayLinearObject3D : Object3D, IRebuildable
{
public ArrayLinearObject3D()
{
}
public override string ActiveEditor => "PublicPropertyEditor";
public int Count { get; set; } = 3;
public DirectionVector Direction { get; set; } = new DirectionVector { Normal = new Vector3(1, 0, 0) };
public double Distance { get; set; } = 30;
public void Rebuild()
{
this.Children.Modify(list =>
{
IObject3D lastChild = list.First();
list.Clear();
list.Add(lastChild);
var offset = Vector3.Zero;
for (int i = 1; i < Count; i++)
{
var next = lastChild.Clone();
next.Matrix *= Matrix4X4.CreateTranslation(Direction.Normal.GetNormal() * Distance);
list.Add(next);
lastChild = next;
}
});
}
}
public class ArrayRadialObject3D : Object3D, IRebuildable
{
public ArrayRadialObject3D()
{
}
public override string ActiveEditor => "PublicPropertyEditor";
public double Angle { get; set; } = 360;
public DirectionAxis Axis { get; set; } = new DirectionAxis() { Origin = Vector3.NegativeInfinity, Normal = Vector3.UnitZ };
public int Count { get; set; } = 3;
[DisplayName("Keep Within Angle")]
[Description("Keep the entire extents of the part within the angle described.")]
public bool KeepInAngle { get; set; } = false;
[DisplayName("Rotate Part")]
[Description("Rotate the part to the same angle as the array.")]
public bool RotatePart { get; set; } = true;
public void Rebuild()
{
if (Axis.Origin.X == double.NegativeInfinity)
{
// make it something reasonable (just to the left of the aabb of the object)
var aabb = this.GetAxisAlignedBoundingBox();
Axis.Origin = new Vector3(aabb.minXYZ.X - aabb.XSize / 2, aabb.Center.Y, 0);
}
this.Children.Modify(list =>
{
IObject3D first = list.First();
list.Clear();
list.Add(first);
var offset = Vector3.Zero;
for (int i = 1; i < Count; i++)
{
var next = first.Clone();
var normal = Axis.Normal.GetNormal();
var angleRadians = MathHelper.DegreesToRadians(Angle) / Count * i;
next.Rotate(Axis.Origin, normal, angleRadians);
if (!RotatePart)
{
next.Rotate(next.GetAxisAlignedBoundingBox().Center, normal, -angleRadians);
}
list.Add(next);
}
});
this.Invalidate();
}
}
public class DirectionAxis
{
public Vector3 Normal { get; set; }
public Vector3 Origin { get; set; }
}
public class DirectionVector
{
public Vector3 Normal { get; set; }
}
}

View file

@ -0,0 +1,90 @@
/*
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.ComponentModel;
using System.Linq;
using MatterHackers.DataConverters3D;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools.Operations
{
public class ArrayRadialObject3D : Object3D, IRebuildable
{
public ArrayRadialObject3D()
{
}
public override string ActiveEditor => "PublicPropertyEditor";
public double Angle { get; set; } = 360;
public DirectionAxis Axis { get; set; } = new DirectionAxis() { Origin = Vector3.NegativeInfinity, Normal = Vector3.UnitZ };
public int Count { get; set; } = 3;
[DisplayName("Keep Within Angle")]
[Description("Keep the entire extents of the part within the angle described.")]
public bool KeepInAngle { get; set; } = false;
[DisplayName("Rotate Part")]
[Description("Rotate the part to the same angle as the array.")]
public bool RotatePart { get; set; } = true;
public void Rebuild()
{
if (Axis.Origin.X == double.NegativeInfinity)
{
// make it something reasonable (just to the left of the aabb of the object)
var aabb = this.GetAxisAlignedBoundingBox();
Axis.Origin = new Vector3(aabb.minXYZ.X - aabb.XSize / 2, aabb.Center.Y, 0);
}
this.Children.Modify(list =>
{
IObject3D first = list.First();
list.Clear();
list.Add(first);
var offset = Vector3.Zero;
for (int i = 1; i < Count; i++)
{
var next = first.Clone();
var normal = Axis.Normal.GetNormal();
var angleRadians = MathHelper.DegreesToRadians(Angle) / Count * i;
next.Rotate(Axis.Origin, normal, angleRadians);
if (!RotatePart)
{
next.Rotate(next.GetAxisAlignedBoundingBox().Center, normal, -angleRadians);
}
list.Add(next);
}
});
this.Invalidate();
}
}
}

View file

@ -114,22 +114,6 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
scene.SelectedItem = wrapper;
}
public static void Unwrap(this IObject3D item, InteractiveScene scene)
{
foreach (var child in item.Children)
{
child.Matrix *= item.Matrix;
}
item.Parent.Children.Modify(list =>
{
list.Remove(item);
list.AddRange(item.Children);
});
scene.SelectedItem = null;
}
public static void ApplyAtBoundsCenter(this IObject3D object3DToApplayTo, Matrix4X4 transformToApply)
{
object3DToApplayTo.Matrix = ApplyAtCenter(object3DToApplayTo.GetAxisAlignedBoundingBox(Matrix4X4.Identity), object3DToApplayTo.Matrix, transformToApply);

View file

@ -27,10 +27,8 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System.Threading;
using MatterHackers.DataConverters3D;
using MatterHackers.PolygonMesh;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools
{
@ -140,9 +138,9 @@ public class ChairFoot2 : MatterCadObject3D
public override string ActiveEditor => "PublicPropertyEditor";
public double Width { get; set; } = 20;
public double Depth { get; set; } = 20;
public double Height { get; set; } = 20;
public double Width { get; set; } = 20;
public static CubeObject3D Create()
{

View file

@ -54,6 +54,28 @@ namespace MatterHackers.MatterControl.DesignTools
{
}
[AttributeUsage(AttributeTargets.Property)]
public class EnableIfAttribute : Attribute
{
public string PropertyName { get; private set; }
public string ExpectedValue { get; private set; }
public EnableIfAttribute(string propertyName, string expectedValue)
{
this.PropertyName = propertyName;
this.ExpectedValue = expectedValue;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class IconsAttribute : Attribute
{
public string[] IconPaths { get; private set; }
public IconsAttribute(string[] iconPaths)
{
this.IconPaths = iconPaths;
}
}
public class PublicPropertyEditor : IObject3DEditor
{
private IObject3D item;
@ -342,43 +364,12 @@ namespace MatterHackers.MatterControl.DesignTools
rowContainer.AddChild(textEditWidget);
editControlsContainer.AddChild(rowContainer);
}
// create a enum editor
// create an enum editor
else if (property.PropertyType.IsEnum)
{
// Enum keyed on name to friendly name
var enumItems = Enum.GetNames(property.PropertyType).Select(enumName =>
{
return new
{
Key = enumName,
Value = enumName.Replace('_', ' ')
};
});
FlowLayoutWidget rowContainer = CreateSettingsRow(property.DisplayName.Localize());
var dropDownList = new DropDownList("Name".Localize(), theme.Colors.PrimaryTextColor, Direction.Down, pointSize: theme.DefaultFontSize);
var sortableAttribute = property.PropertyInfo.GetCustomAttributes(true).OfType<SortableAttribute>().FirstOrDefault();
var orderedItems = sortableAttribute != null ? enumItems.OrderBy(n => n.Value) : enumItems;
foreach (var orderItem in orderedItems)
{
MenuItem newItem = dropDownList.AddItem(orderItem.Value);
var localOredrItem = orderItem;
newItem.Selected += (sender, e) =>
{
property.PropertyInfo.GetSetMethod().Invoke(
this.item,
new Object[] { Enum.Parse(property.PropertyType, localOredrItem.Key) });
rebuildable?.Rebuild();
};
}
dropDownList.SelectedLabel = property.Value.ToString().Replace('_', ' ');
rowContainer.AddChild(dropDownList);
editControlsContainer.AddChild(rowContainer);
editControlsContainer.AddChild(CreateEnumEditor(rebuildable,
property.PropertyInfo, property.PropertyType, property.Value, property.DisplayName,
theme));
}
}
@ -391,5 +382,46 @@ namespace MatterHackers.MatterControl.DesignTools
};
editControlsContainer.AddChild(updateButton);
}
private GuiWidget CreateEnumEditor(IRebuildable item,
PropertyInfo propertyInfo, Type propertyType, object value, string displayName,
ThemeConfig theme)
{
// Enum keyed on name to friendly name
var enumItems = Enum.GetNames(propertyType).Select(enumName =>
{
return new
{
Key = enumName,
Value = enumName.Replace('_', ' ')
};
});
FlowLayoutWidget rowContainer = CreateSettingsRow(displayName);
var dropDownList = new DropDownList("Name".Localize(), theme.Colors.PrimaryTextColor, Direction.Down, pointSize: theme.DefaultFontSize);
var sortableAttribute = propertyInfo.GetCustomAttributes(true).OfType<SortableAttribute>().FirstOrDefault();
var orderedItems = sortableAttribute != null ? enumItems.OrderBy(n => n.Value) : enumItems;
foreach (var orderItem in orderedItems)
{
MenuItem newItem = dropDownList.AddItem(orderItem.Value);
var localOredrItem = orderItem;
newItem.Selected += (sender, e) =>
{
propertyInfo.GetSetMethod().Invoke(
this.item,
new Object[] { Enum.Parse(propertyType, localOredrItem.Key) });
item?.Rebuild();
};
}
dropDownList.SelectedLabel = value.ToString().Replace('_', ' ');
rowContainer.AddChild(dropDownList);
return rowContainer;
}
}
}

View file

@ -38,7 +38,7 @@ namespace MatterHackers.MatterControl.DesignTools
scene.SelectedItem = operationContainer;
// wrap all the meshes with replacement meshes
foreach(var meshChild in child.Descendants().Where(x => x.Mesh != null).ToList())
foreach(var meshChild in child.DescendantsAndSelf().Where(x => x.Mesh != null).ToList())
{
var parent = meshChild.Parent;
@ -62,7 +62,7 @@ namespace MatterHackers.MatterControl.DesignTools
{
if(AngleDegrees > 0)
{
foreach (var meshChild in operationContainer.Descendants().Where(x => x.OwnerID == operationContainer.ID))
foreach (var meshChild in operationContainer.DescendantsAndSelf().Where(x => x.OwnerID == operationContainer.ID))
{
var firstChild = meshChild.Children.First();

View file

@ -44,6 +44,7 @@ namespace MatterHackers.Localizations
if (MatterControlTranslationMap == null)
{
MatterControlTranslationMap = new TranslationMap("Translations", UserSettings.Instance.Language);
TranslationMap.ActiveTranslationMap = MatterControlTranslationMap;
}
}
}
@ -52,10 +53,5 @@ namespace MatterHackers.Localizations
{
MatterControlTranslationMap = new TranslationMap("Translations", UserSettings.Instance.Language);
}
public static string Localize(this string englishString)
{
return MatterControlTranslationMap.Translate(englishString);
}
}
}

View file

@ -86,9 +86,12 @@
<Compile Include="ApplicationView\OemProfileDictionary.cs" />
<Compile Include="ApplicationView\WindowsPlatformsFeatures.cs" />
<Compile Include="DataStorage\ApplicationDataStorage.cs" />
<Compile Include="DesignTools\Operations\ArangeObject3D.cs" />
<Compile Include="DesignTools\Operations\ArrayAdvancedObject3D.cs" />
<Compile Include="DesignTools\Operations\ArrayLinearObject3D.cs" />
<Compile Include="DesignTools\Operations\ArrayRadialObject3D.cs" />
<Compile Include="DesignTools\Operations\Object3DExtensions.cs" />
<Compile Include="DesignTools\Operations\Align.cs" />
<Compile Include="DesignTools\Operations\ArrayObject3D.cs" />
<Compile Include="DesignTools\Operations\Scale.cs" />
<Compile Include="DesignTools\Operations\Rotate.cs" />
<Compile Include="DesignTools\Operations\SmoothPath.cs" />

View file

@ -42,6 +42,7 @@ using MatterHackers.MatterControl.DesignTools.Operations;
using System.Reflection;
using MatterHackers.VectorMath;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.Platform;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
@ -61,7 +62,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private Dictionary<Type, HashSet<IObject3DEditor>> objectEditorsByType;
private SectionWidget editorSection;
private TextButton editButton;
private TextButton removeButton;
private GuiWidget editorPanel;
private InlineTitleEdit inlineTitleEdit;
@ -188,17 +188,34 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
toolbar.AddChild(editButton);
removeButton = new TextButton("Remove".Localize(), theme)
// put in a bake button
var icon = AggContext.StaticData.LoadIcon("bake.png", 16, 16).SetPreMultiply();
var bakeButton = new IconButton(icon, theme)
{
BackgroundColor = theme.MinimalShade,
Margin = theme.ButtonSpacing
Margin = theme.ButtonSpacing,
ToolTipText = "Bake operation into parts".Localize()
};
removeButton.Click += async (s, e) =>
bakeButton.Click += (s, e) =>
{
this.item.Unwrap(printer.Bed.Scene);
scene.SelectedItem = null;
this.item.Bake();
};
toolbar.AddChild(removeButton);
scene.SelectionChanged += (s, e) => bakeButton.Enabled = scene.SelectedItem?.CanBake == true;
toolbar.AddChild(bakeButton);
// put in a remove button
var removeButton = new IconButton(ThemeConfig.RestoreNormal, theme)
{
Margin = theme.ButtonSpacing,
ToolTipText = "Remove operation from parts".Localize()
};
removeButton.Click += (s, e) =>
{
scene.SelectedItem = null;
this.item.Remove();
};
scene.SelectionChanged += (s, e) => removeButton.Enabled = scene.SelectedItem?.CanRemove == true;
toolbar.AddChild(removeButton);
// Add container used to host the current specialized editor for the selection
editorColumn.AddChild(editorPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)

View file

@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
{
bool first = true;
// set all but one mesh to look like holes
foreach (var item in group.Descendants().Where((obj) => obj.OwnerID == group.ID).ToList())
foreach (var item in group.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID).ToList())
{
item.OutputType = first ? PrintOutputTypes.Solid : PrintOutputTypes.Hole;
first = false;
@ -84,7 +84,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
reporter.Report(progressStatus);
var participants = group.Descendants().Where((obj) => obj.OwnerID == group.ID);
var participants = group.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID);
if (participants.Count() > 1)
{

View file

@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
{
bool first = true;
// set all but one mesh to look like holes
foreach (var item in group.Descendants().Where((obj) => obj.OwnerID == group.ID).ToList())
foreach (var item in group.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID).ToList())
{
item.OutputType = first ? PrintOutputTypes.Solid : PrintOutputTypes.Hole;
first = false;
@ -84,7 +84,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
reporter.Report(progressStatus);
var participants = group.Descendants().Where((obj) => obj.OwnerID == group.ID);
var participants = group.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID);
if (participants.Count() > 1)
{

View file

@ -65,7 +65,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
public void ResetMeshWrappers()
{
this.Mesh = null;
var participants = this.Descendants().Where(o => o.OwnerID == this.ID).ToList();
var participants = this.DescendantsAndSelf().Where(o => o.OwnerID == this.ID).ToList();
foreach (var item in participants)
{
item.Visible = true;

View file

@ -146,14 +146,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
// make sure the mesh on the group is not visible
group.ResetMeshWrappers();
var wrappedItems = item.Descendants().Where((obj) => obj.OwnerID == group.ID).ToList();
var wrappedItems = item.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID).ToList();
foreach (var meshWrapper in wrappedItems)
{
// and set the output type for this checkbox
meshWrapper.OutputType = checkBox.Checked ? PrintOutputTypes.Hole : PrintOutputTypes.Solid;
}
var allItems = group.Descendants().Where((obj) => obj.OwnerID == group.ID).ToList();
var allItems = group.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID).ToList();
int holeCount = allItems.Where((o) => o.OutputType == PrintOutputTypes.Hole).Count();
int solidCount = allItems.Where((o) => o.OutputType != PrintOutputTypes.Hole).Count();
updateButton.Enabled = allItems.Count() != holeCount && allItems.Count() != solidCount;
@ -162,11 +162,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
tabContainer.AddChild(rowContainer);
}
bool operationApplied = group.Descendants()
bool operationApplied = group.DescendantsAndSelf()
.Where((obj) => obj.OwnerID == group.ID)
.Where((objId) => objId.Mesh != objId.Children.First().Mesh).Any();
bool selectionHasBeenMade = group.Descendants()
bool selectionHasBeenMade = group.DescendantsAndSelf()
.Where((obj) => obj.OwnerID == group.ID && obj.OutputType == PrintOutputTypes.Hole)
.Any();
@ -199,7 +199,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
reporter.Report(progressStatus);
var participants = group.Descendants().Where((obj) => obj.OwnerID == group.ID).ToList();
var participants = group.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID).ToList();
var paintObjects = participants.Where((obj) => obj.OutputType == PrintOutputTypes.Hole).ToList();
var keepObjects = participants.Where((obj) => obj.OutputType != PrintOutputTypes.Hole).ToList();

View file

@ -127,14 +127,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
// make sure the mesh on the group is not visible
group.ResetMeshWrappers();
var wrappedItems = item.Descendants().Where((obj) => obj.OwnerID == group.ID).ToList();
var wrappedItems = item.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID).ToList();
foreach (var meshWrapper in wrappedItems)
{
// and set the output type for this checkbox
meshWrapper.OutputType = checkBox.Checked ? PrintOutputTypes.Hole : PrintOutputTypes.Solid;
}
var allItems = group.Descendants().Where((obj) => obj.OwnerID == group.ID).ToList();
var allItems = group.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID).ToList();
int holeCount = allItems.Where((o) => o.OutputType == PrintOutputTypes.Hole).Count();
int solidCount = allItems.Where((o) => o.OutputType != PrintOutputTypes.Hole).Count();
updateButton.Enabled = allItems.Count != holeCount && allItems.Count != solidCount;
@ -143,11 +143,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
tabContainer.AddChild(rowContainer);
}
bool operationApplied = group.Descendants()
bool operationApplied = group.DescendantsAndSelf()
.Where((obj) => obj.OwnerID == group.ID)
.Where((objId) => objId.Mesh != objId.Children.First().Mesh).Any();
bool selectionHasBeenMade = group.Descendants()
bool selectionHasBeenMade = group.DescendantsAndSelf()
.Where((obj) => obj.OwnerID == group.ID && obj.OutputType == PrintOutputTypes.Hole)
.Any();
@ -180,7 +180,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
reporter.Report(progressStatus);
var participants = group.Descendants().Where(o => o.OwnerID == group.ID).ToList();
var participants = group.DescendantsAndSelf().Where(o => o.OwnerID == group.ID).ToList();
var removeObjects = participants.Where((obj) => obj.OutputType == PrintOutputTypes.Hole).ToList();
var keepObjects = participants.Where((obj) => obj.OutputType != PrintOutputTypes.Hole).ToList();

View file

@ -173,7 +173,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
var clonedItem = item.Clone();
// make the name unique
var newName = agg_basics.GetNonCollidingName(item.Name, Scene.Descendants().Select((d) => d.Name));
var newName = agg_basics.GetNonCollidingName(item.Name, Scene.DescendantsAndSelf().Select((d) => d.Name));
clonedItem.Name = newName;
// add it to the scene
Scene.Children.Add(clonedItem);
@ -186,7 +186,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var clonedItem = sourceItem.Clone();
// make the name unique
var newName = agg_basics.GetNonCollidingName(sourceItem.Name, Scene.Descendants().Select((d) => d.Name));
var newName = agg_basics.GetNonCollidingName(sourceItem.Name, Scene.DescendantsAndSelf().Select((d) => d.Name));
clonedItem.Name = newName;
// More useful if it creates the part in the exact position and then the user can move it.
@ -341,11 +341,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
PlatingHelper.PlaceOnBed(objectToLayFlatGroup);
}
internal class ArangeUndoCommand : IUndoRedoCommand
internal class ArrangeUndoCommand : IUndoRedoCommand
{
private List<TransformCommand> allUndoTransforms = new List<TransformCommand>();
public ArangeUndoCommand(View3DWidget view3DWidget, List<Matrix4X4> preArrangeTarnsforms, List<Matrix4X4> postArrangeTarnsforms)
public ArrangeUndoCommand(View3DWidget view3DWidget, List<Matrix4X4> preArrangeTarnsforms, List<Matrix4X4> postArrangeTarnsforms)
{
for (int i = 0; i < preArrangeTarnsforms.Count; i++)
{

View file

@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project.
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.MeshVisualizer;
namespace MatterHackers.MatterControl.PartPreviewWindow
@ -51,7 +52,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
// This is the original do() case. The selection needs to be changed into a group and selected
// change it to a standard group
var newGroup = new Object3D();
var newGroup = new Object3D()
{
Name = "Group".Localize()
};
newGroup.Children.Modify((gChildren) =>
{
selectedItem.Children.Modify((sChildren) =>

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

BIN
StaticData/Icons/bake.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -1 +1 @@
Subproject commit 3badb0ba9d782ea89a0bb3a9f4f31daf54b8e4e7
Subproject commit 515eaedcb719f41e4127f566b7bdf5c3c222cf6d

View file

@ -116,6 +116,10 @@
<Project>{74F6BB6C-9D02-4512-A59A-21940E35C532}</Project>
<Name>Gui</Name>
</ProjectReference>
<ProjectReference Include="..\..\Submodules\agg-sharp\Localizations\Localizations.csproj">
<Project>{ca96058c-1a37-465d-a357-d6d695b13d25}</Project>
<Name>Localizations</Name>
</ProjectReference>
<ProjectReference Include="..\..\Submodules\agg-sharp\OpenGlGui\OpenGlGui.csproj">
<Project>{C958F745-156E-4BDC-A24A-3721C7BE7B8A}</Project>
<Name>OpenGlGui</Name>

View file

@ -274,10 +274,10 @@ namespace MatterHackers.PolygonMesh.UnitTests
{
var scene = SampleScene();
var superGroup = scene.Descendants().Where(d => d.Name == "SuperGroup").FirstOrDefault();
var redItem = scene.Descendants().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var greenItem = scene.Descendants().Where(d => d.Name == nameof(Color.Green)).FirstOrDefault();
var blueItem = scene.Descendants().Where(d => d.Name == nameof(Color.Blue)).FirstOrDefault();
var superGroup = scene.DescendantsAndSelf().Where(d => d.Name == "SuperGroup").FirstOrDefault();
var redItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var greenItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Green)).FirstOrDefault();
var blueItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Blue)).FirstOrDefault();
// Validate root
Assert.AreEqual(Color.Black, scene.Color, "Color property on root should be Black");
@ -307,10 +307,10 @@ namespace MatterHackers.PolygonMesh.UnitTests
{
var scene = SampleScene();
var superGroup = scene.Descendants().Where(d => d.Name == "SuperGroup").FirstOrDefault();
var redItem = scene.Descendants().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var greenItem = scene.Descendants().Where(d => d.Name == nameof(Color.Green)).FirstOrDefault();
var blueItem = scene.Descendants().Where(d => d.Name == nameof(Color.Blue)).FirstOrDefault();
var superGroup = scene.DescendantsAndSelf().Where(d => d.Name == "SuperGroup").FirstOrDefault();
var redItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var greenItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Green)).FirstOrDefault();
var blueItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Blue)).FirstOrDefault();
// Validate root
Assert.AreEqual(this.RootMaterialIndex, scene.MaterialIndex, "MaterialIndex property on root should be RootMaterialIndex");
@ -340,10 +340,10 @@ namespace MatterHackers.PolygonMesh.UnitTests
{
var scene = SampleScene();
var superGroup = scene.Descendants().Where(d => d.Name == "SuperGroup").FirstOrDefault();
var redItem = scene.Descendants().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var greenItem = scene.Descendants().Where(d => d.Name == nameof(Color.Green)).FirstOrDefault();
var blueItem = scene.Descendants().Where(d => d.Name == nameof(Color.Blue)).FirstOrDefault();
var superGroup = scene.DescendantsAndSelf().Where(d => d.Name == "SuperGroup").FirstOrDefault();
var redItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var greenItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Green)).FirstOrDefault();
var blueItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Blue)).FirstOrDefault();
// Validate root
Assert.AreEqual(this.RootMatrix, scene.Matrix, "Matrix property on root should be RootMatrix");
@ -373,10 +373,10 @@ namespace MatterHackers.PolygonMesh.UnitTests
{
var scene = SampleScene();
var superGroup = scene.Descendants().Where(d => d.Name == "SuperGroup").FirstOrDefault();
var redItem = scene.Descendants().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var greenItem = scene.Descendants().Where(d => d.Name == nameof(Color.Green)).FirstOrDefault();
var blueItem = scene.Descendants().Where(d => d.Name == nameof(Color.Blue)).FirstOrDefault();
var superGroup = scene.DescendantsAndSelf().Where(d => d.Name == "SuperGroup").FirstOrDefault();
var redItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var greenItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Green)).FirstOrDefault();
var blueItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Blue)).FirstOrDefault();
// Validate root
Assert.AreEqual(this.RootOutputType, scene.OutputType, "OutputType property on root should be RootOutputType");
@ -405,7 +405,7 @@ namespace MatterHackers.PolygonMesh.UnitTests
public void WorldFunctionNonExistingAncestorOverride()
{
var scene = SampleScene();
var redItem = scene.Descendants().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var redItem = scene.DescendantsAndSelf().Where(d => d.Name == nameof(Color.Red)).FirstOrDefault();
var nonAncestor = new Object3D();
// ************************************* WorldColor *************************************

View file

@ -85,6 +85,10 @@
<Project>{036BCCBA-52D8-457C-84AE-8821F209FE4A}</Project>
<Name>ImageProcessing</Name>
</ProjectReference>
<ProjectReference Include="..\Submodules\agg-sharp\Localizations\Localizations.csproj">
<Project>{ca96058c-1a37-465d-a357-d6d695b13d25}</Project>
<Name>Localizations</Name>
</ProjectReference>
<ProjectReference Include="..\Submodules\agg-sharp\MarchingSquares\MarchingSquares.csproj">
<Project>{DF6845CD-64C6-4263-8357-DA8066855739}</Project>
<Name>MarchingSquares</Name>