Moved the primitives contain into MatterControlLib

moved part sheet creator into MatterControlLib
moved some other experimental parts to MatterControlLib
This commit is contained in:
Lars Brubaker 2019-04-02 17:13:07 -07:00
parent f982a60ce6
commit ef17f38bb7
20 changed files with 3547 additions and 2 deletions

View file

@ -0,0 +1,67 @@
/*
Copyright (c) 2017, 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.Collections.Generic;
using System.Threading.Tasks;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.DesignTools;
using MatterHackers.MatterControl.Plugins.BrailleBuilder;
namespace MatterHackers.MatterControl.Library
{
public class BrailleContainer : LibraryContainer
{
public BrailleContainer()
{
Name = "Braille".Localize();
}
public override void Load()
{
var libraryItems = new List<GeneratorItem>()
{
new GeneratorItem(
() => "Braille".Localize(),
async () => await BrailleObject3D.Create()),
new GeneratorItem(
() => "Braille Card".Localize(),
async () => await BrailleCardObject3D.Create()),
};
string title = "Primitive Shapes".Localize();
foreach (var item in libraryItems)
{
item.Category = title;
Items.Add(item);
}
}
}
}

View file

@ -0,0 +1,188 @@
/*
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 MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.VectorMath;
using System;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
namespace MatterHackers.MatterControl.DesignTools
{
[UnlockLinkAttribute("mattercontrol-image-converter-add-on")]
public class ChairFootObject3D : Object3D
{
public enum OutputMode { Final_Part, Fit_Test };
//private static string permissionKey = "ag1zfm1oLWRmcy10ZXN0chgLEgtEaWdpdGFsSXRlbRiAgICA3pCBCgw";
public ChairFootObject3D()
{
//PermissionCheckRequest.CheckPermission(permissionKey);
}
//[Icons(new string[] { "424.png", "align_left.png", "align_center_x.png", "align_right.png" })]
public OutputMode Output { get; set; } = OutputMode.Final_Part;
[DisplayName("Angle")]
public double AngleDegrees { get; set; } = 3;
[DisplayName("Height")]
public double HeightFromFloorToBottomOfLeg { get; set; } = 10;
[DisplayName("Inner Size")]
public double InnerSize { get; set; } = 20;
[DisplayName("Reach")]
public double InsideReach { get; set; } = 10;
[DisplayName("Outer Size")]
public double OuterSize { get; set; } = 22;
public double BaseBevel { get; set; } = 2;
//public override bool Persistable { get => PermissionCheckRequest.UserAuthorized(permissionKey); }
public override bool CanFlatten => Persistable;
public override bool CanEdit => Persistable;
public static async Task<ChairFootObject3D> Create()
{
var chairFoot = new ChairFootObject3D();
await chairFoot.Rebuild();
return chairFoot;
}
private object locker = new object();
private bool inRebuild;
public override PolygonMesh.Mesh Mesh
{
get
{
lock (locker)
{
// Check a known condition for have persisted meshes or need to rebuild
if (!inRebuild
&& Children.Count > 0
&& !this.Descendants<RingObject3D>().Where((d) => d.Mesh != null).Any())
{
Rebuild();
}
return base.Mesh;
}
}
set => base.Mesh = value;
}
public async override Task Rebuild()
{
using (RebuildLock())
{
inRebuild = true;
if (AngleDegrees > 45)
{
AngleDegrees = 45;
}
using (new CenterAndHeightMantainer(this))
{
// This would be better expressed as the desired offset height (height from ground to bottom of chair leg).
double angleRadians = MathHelper.DegreesToRadians(AngleDegrees);
var insideReach = InsideReach;
var heightFromFloorToBottomOfLeg = HeightFromFloorToBottomOfLeg;
if (Output == OutputMode.Fit_Test)
{
insideReach = 4;
angleRadians = 0;
heightFromFloorToBottomOfLeg = 4;
}
double extraHeightForRotation = Math.Sinh(angleRadians) * OuterSize; // get the distance to clip off the extra bottom
double unclippedFootHeight = heightFromFloorToBottomOfLeg + extraHeightForRotation;
var baseBevelClamped = Math.Max(0, Math.Min(OuterSize / 2, BaseBevel));
RoundedRect footBase = new RoundedRect(-OuterSize / 2, -OuterSize / 2, OuterSize / 2, OuterSize / 2, baseBevelClamped)
{
ResolutionScale = 1000
};
IObject3D chairFoot = new Object3D()
{
Mesh = VertexSourceToMesh.Extrude(footBase, unclippedFootHeight)
};
IObject3D ring = new RingObject3D(InnerSize - 2, InnerSize - 6, insideReach, 60);
ring.Translate(0, 0, -insideReach / 2 - .02);
VertexStorage finShape = new VertexStorage();
finShape.MoveTo(0, 0);
finShape.LineTo(3, 0);
finShape.LineTo(3, ring.ZSize());
finShape.LineTo(0, ring.ZSize() - 3);
IObject3D fins = new Object3D()
{
Mesh = VertexSourceToMesh.Extrude(finShape, 1)
};
fins.Rotate(Vector3.Zero, Vector3.UnitX, -MathHelper.Tau / 4);
fins.Rotate(Vector3.Zero, Vector3.UnitZ, -MathHelper.Tau / 2);
fins = (new TranslateObject3D(fins, 1.48, 1, -ring.ZSize() - .02)).Plus(new TranslateObject3D(fins, 1.48, -1, -ring.ZSize() - .02));
fins = new TranslateObject3D(fins, InnerSize / 2 - .1);
ring = ring.Plus(new RotateObject3D(fins, 0, 0, MathHelper.DegreesToRadians(45)));
ring = ring.Plus(new RotateObject3D(fins, 0, 0, MathHelper.DegreesToRadians(45 + 90)));
ring = ring.Plus(new RotateObject3D(fins, 0, 0, MathHelper.DegreesToRadians(45 + 180)));
ring = ring.Plus(new RotateObject3D(fins, 0, 0, MathHelper.DegreesToRadians(45 - 90)));
chairFoot = chairFoot.Plus(new AlignObject3D(ring, FaceAlign.Bottom, chairFoot, FaceAlign.Top, 0, 0, -.1));
chairFoot = new RotateObject3D(chairFoot, 0, angleRadians, 0);
if (unclippedFootHeight != heightFromFloorToBottomOfLeg)
{
IObject3D clipBox = new AlignObject3D(await CubeObject3D.Create(OuterSize * 2, OuterSize * 2, unclippedFootHeight), FaceAlign.Top, chairFoot, FaceAlign.Bottom, 0, 0, extraHeightForRotation);
chairFoot = chairFoot.Minus(clipBox);
chairFoot = new TranslateObject3D(chairFoot, 0, 0, clipBox.GetAxisAlignedBoundingBox().MaxXYZ.Z);
}
this.Children.Modify(list =>
{
list.Clear();
list.Add(chairFoot);
});
}
inRebuild = false;
}
}
}
}

View file

@ -0,0 +1,294 @@
/*
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 ClipperLib;
using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.Transform;
using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters2D;
using MatterHackers.DataConverters3D;
using MatterHackers.DataConverters3D.UndoCommands;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.VectorMath;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MatterHackers.MatterControl.DesignTools
{
public class ImageCoinObject3D : Object3D, IVisualLeafNode
{
private readonly double innerDiameter = 35;
private readonly double outerDiameter = 40;
private object locker = new object();
public ImageCoinObject3D()
{
}
[JsonIgnore]
public ImageObject3D ImageObject { get { return this.Children.OfType<ImageObject3D>().FirstOrDefault(); } set { } }
[Description("Create a hook so that the coin can be hung from a chain.")]
public bool CreateHook { get; set; } = true;
[Description("Subtract the image from a disk so that the negative space will be printed.")]
public bool NegativeSpace { get; set; } = false;
[Description("Change the scale of the image within the coin.")]
public double ScalePercent { get; set; } = 90;
[Description("Normally the image is expanded to the edge. This will try to center the weight of the image visually.")]
public bool AlternateCentering { get; set; } = false;
[Description("Change the width of the image lines.")]
public double Inflate { get; set; }
public static async Task<ImageCoinObject3D> Create()
{
var imageCoin = new ImageCoinObject3D();
await imageCoin.Rebuild();
return imageCoin;
}
public override async void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Children)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh))
&& invalidateType.Source != this
&& !RebuildLocked)
{
await Rebuild();
}
else if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
&& invalidateType.Source == this)
{
await Rebuild();
}
else
{
base.OnInvalidate(invalidateType);
}
}
public override async Task Rebuild()
{
this.DebugDepth("Rebuild");
using (RebuildLock())
{
var currentAssetPath = ImageObject == null ? AggContext.StaticData.ToAssetPath(Path.Combine("Images", "mh-logo.png")) : ImageObject.AssetPath;
this.Children.Modify((list) =>
{
list.Clear();
});
var imageObject = new ImageObject3D()
{
AssetPath = currentAssetPath,
};
await imageObject.Rebuild();
this.Children.Add(imageObject);
IObject3D logoBase = new CylinderObject3D(outerDiameter, 3, 60);
IObject3D logoRing = new AlignObject3D(new RingObject3D(outerDiameter, innerDiameter, 2, 60), FaceAlign.Bottom, logoBase, FaceAlign.Top);
IObject3D coinBlank = logoBase.Plus(logoRing);
if (CreateHook)
{
var cube = await CubeObject3D.Create(4, 2, 4);
IObject3D connect = logoBase.Plus(new AlignObject3D(cube, FaceAlign.Front | FaceAlign.Bottom, logoBase, FaceAlign.Back | FaceAlign.Bottom, 0, -.5));
IObject3D hook = logoBase.Plus(new AlignObject3D(new RingObject3D(10, 7, 5, 30), FaceAlign.Front | FaceAlign.Bottom, connect, FaceAlign.Back | FaceAlign.Bottom, 0, -.5));
coinBlank = coinBlank.Plus(connect);
coinBlank = coinBlank.Plus(hook);
}
var imageToPath = new ImageToPathObject3D();
imageToPath.Children.Add(imageObject);
await imageToPath.Rebuild();
var inputShape = imageToPath.VertexSource;
if (Inflate != 0)
{
var bounds = inputShape.GetBounds();
var scale = Math.Max(bounds.Width, bounds.Height) / (17 * 4);
inputShape = inputShape.Offset(Inflate * scale);
}
if (AlternateCentering)
{
inputShape = new VertexSourceApplyTransform(inputShape, GetCenteringTransformVisualCenter(inputShape, innerDiameter / 2));
}
else
{
inputShape = new VertexSourceApplyTransform(inputShape, GetCenteringTransformExpandedToRadius(inputShape, innerDiameter / 2));
}
if (ScalePercent != 100
&& ScalePercent != 0)
{
inputShape = new VertexSourceApplyTransform(inputShape, Affine.NewScaling(ScalePercent / 100.0));
}
if (NegativeSpace)
{
var disk = new Ellipse(0, 0, innerDiameter / 2 + .2, innerDiameter / 2 + .2)
{
ResolutionScale = 1000
};
inputShape = disk.Minus(inputShape);
}
imageToPath.VertexSource = inputShape;
var pathExtrusion = new LinearExtrudeObject3D();
pathExtrusion.Children.Add(imageToPath);
await pathExtrusion.Rebuild();
IObject3D extrusionObject = imageObject;
var loadingScale = 32 / extrusionObject.XSize();
extrusionObject = new ScaleObject3D(extrusionObject, loadingScale, loadingScale, 1 / extrusionObject.ZSize());
extrusionObject = PlaceOnBase(logoBase, extrusionObject);
this.Children.Add(coinBlank);
this.Children.Add(extrusionObject);
}
Invalidate(InvalidateType.Mesh);
}
private static Affine GetCenteringTransformExpandedToRadius(IVertexSource vertexSource, double radius)
{
var circle = SmallestEnclosingCircle.MakeCircle(vertexSource.Vertices().Select((v) => new Vector2(v.position.X, v.position.Y)));
// move the circle center to the origin
var centering = Affine.NewTranslation(-circle.Center);
// scale to the fit size in x y
double scale = radius / circle.Radius;
var scalling = Affine.NewScaling(scale);
return centering * scalling;
}
private static Affine GetCenteringTransformVisualCenter(IVertexSource vertexSource, double goalRadius)
{
var outsidePolygons = new List<List<IntPoint>>();
// remove all holes from the polygons so we only center the major outlines
var polygons = vertexSource.CreatePolygons();
foreach(var polygon in polygons)
{
if(polygon.GetWindingDirection() == 1)
{
outsidePolygons.Add(polygon);
}
}
IVertexSource outsideSource = outsidePolygons.CreateVertexStorage();
Vector2 center = outsideSource.GetWeightedCenter();
outsideSource = new VertexSourceApplyTransform(outsideSource, Affine.NewTranslation(-center));
double radius = MaxXyDistFromCenter(outsideSource);
double scale = goalRadius / radius;
var scalling = Affine.NewScaling(scale);
var centering = Affine.NewTranslation(-center);
return centering * scalling;
}
private static double MaxXyDistFromCenter(IObject3D imageMesh)
{
double maxDistSqrd = 0.000001;
var center = imageMesh.GetAxisAlignedBoundingBox().Center;
var itemWithMesh = imageMesh.VisibleMeshes().First();
var matrix = itemWithMesh.WorldMatrix(imageMesh);
foreach (var vertex in itemWithMesh.Mesh.Vertices)
{
throw new NotImplementedException();
//var position = vertex.Position;
//var distSqrd = (new Vector2(position.X, position.Y) - new Vector2(center.X, center.Y)).LengthSquared;
//if (distSqrd > maxDistSqrd)
//{
// maxDistSqrd = distSqrd;
//}
}
return Math.Sqrt(maxDistSqrd);
}
private static double MaxXyDistFromCenter(IVertexSource vertexSource)
{
double maxDistSqrd = 0.000001;
var center = vertexSource.GetBounds().Center;
foreach (var vertex in vertexSource.Vertices())
{
var position = vertex.position;
var distSqrd = (new Vector2(position.X, position.Y) - new Vector2(center.X, center.Y)).LengthSquared;
if (distSqrd > maxDistSqrd)
{
maxDistSqrd = distSqrd;
}
}
return Math.Sqrt(maxDistSqrd);
}
private static IObject3D PlaceOnBase(IObject3D logoBase, IObject3D imageObject)
{
if (imageObject != null)
{
// put it at the right height
imageObject = new AlignObject3D(imageObject, FaceAlign.Bottom, logoBase, FaceAlign.Top);
// move it to the base center
imageObject = new TranslateObject3D(imageObject, -new Vector3(logoBase.GetCenter().X, logoBase.GetCenter().Y, 0));
}
return imageObject;
}
}
}

View file

@ -0,0 +1,141 @@
/*
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.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools
{
public class ElbowObject3D : PipeWorksBaseObject3D
{
public ElbowObject3D()
{
}
public static async Task<ElbowObject3D> Create()
{
var item = new ElbowObject3D();
await item.Rebuild();
return item;
}
[DisplayName("Inner Radius")]
public double InnerDiameter { get; set; }
[DisplayName("Outer Radius")]
public double OuterDiameter { get; set; }
public double Angle { get; set; } = 90;
public double BottomReach { get; set; }
public double FrontReach { get; set; }
public override async Task Rebuild()
{
using (RebuildLock())
{
using (new CenterAndHeightMantainer(this))
{
// validate the some of the values and store in user data if changed
InnerDiameter = ValidateValue(InnerDiameter, "PipeWorksInnerDiameter", 15);
OuterDiameter = ValidateValue(OuterDiameter, "PipeWorksOuterDiameter", 20);
BottomReach = ValidateValue(BottomReach, "PipeWorksBottomReach", 30);
FrontReach = ValidateValue(FrontReach, "PipeWorksFrontReach", 25);
IObject3D bottomReach = new RotateObject3D(CreateReach(BottomReach, InnerDiameter), -MathHelper.Tau / 4);
IObject3D frontReach = null;
IObject3D elbowConnect = null;
if (Angle < 90)
{
frontReach = bottomReach.Clone();
var translate = new Vector3(-OuterDiameter / 2, 0, 0);
bottomReach.Translate(translate);
frontReach = new RotateObject3D(frontReach, 0, 0, -MathHelper.DegreesToRadians(Angle));
translate = Vector3Ex.Transform(-translate, Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(Angle)));
frontReach.Translate(translate);
var torus = new TorusObject3D();
using (torus.RebuildLock())
{
torus.Advanced = true;
torus.InnerDiameter = 0;
OuterDiameter = OuterDiameter * 2;
torus.RingSides = Sides;
torus.Sides = Sides;
torus.StartingAngle = Angle;
torus.EndingAngle = 180;
}
torus.Invalidate(new InvalidateArgs(torus, InvalidateType.Properties));
elbowConnect = torus;
}
else if (Angle < 270)
{
bottomReach.Translate(0, -OuterDiameter / 2, 0);
IObject3D reachConnect = await CylinderObject3D.Create(OuterDiameter, OuterDiameter, Sides, Alignment.Y);
reachConnect = new AlignObject3D(reachConnect, FaceAlign.Front, bottomReach, FaceAlign.Back);
reachConnect = new SetCenterObject3D(reachConnect, bottomReach.GetCenter(), true, false, true);
bottomReach = bottomReach.Plus(reachConnect);
frontReach = bottomReach.Clone();
frontReach = new RotateObject3D(frontReach, 0, 0, -MathHelper.DegreesToRadians(Angle));
elbowConnect = new SphereObject3D(OuterDiameter, Sides);
}
// output multiple meshes for pipe connector
this.Children.Modify(list =>
{
list.Clear();
list.Add(elbowConnect);
list.Add(bottomReach);
list.Add(frontReach);
});
this.Color = Color.Transparent;
this.Mesh = null;
}
}
Invalidate(InvalidateType.Children);
}
}
}

View file

@ -0,0 +1,101 @@
/*
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.Collections.Generic;
using System.Threading.Tasks;
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools
{
public abstract class PipeWorksBaseObject3D : Object3D, IVisualLeafNode
{
protected int Sides => 50;
protected double ValidateValue(double currentValue, string keyName, double defaultValue)
{
double databaseValue = UserSettings.Instance.Fields.GetDouble(keyName, defaultValue);
if (currentValue == 0)
{
currentValue = databaseValue;
}
if (currentValue != databaseValue)
{
UserSettings.Instance.Fields.SetDouble(keyName, currentValue);
}
return currentValue;
}
public override void OnInvalidate(InvalidateArgs invalidateType)
{
if (invalidateType.InvalidateType.HasFlag(InvalidateType.Properties)
&& invalidateType.Source == this)
{
Rebuild();
}
else
{
base.OnInvalidate(invalidateType);
}
}
protected IObject3D CreateReach(double reach, double innerDiameter)
{
var finWidth = 4.0;
var finLength = innerDiameter;
var pattern = new VertexStorage();
pattern.MoveTo(0, 0);
pattern.LineTo(finLength/2, 0);
pattern.LineTo(finLength/2, reach - finLength / 8);
pattern.LineTo(finLength/2 - finLength / 8, reach);
pattern.LineTo(-finLength/2 + finLength / 8, reach);
pattern.LineTo(-finLength/2, reach - finLength / 8);
pattern.LineTo(-finLength/2, 0);
var fin1 = new Object3D()
{
Mesh = VertexSourceToMesh.Extrude(pattern, finWidth)
};
fin1 = new TranslateObject3D(fin1, 0, 0, -finWidth / 2);
//fin1.ChamferEdge(Face.Top | Face.Back, finLength / 8);
//fin1.ChamferEdge(Face.Top | Face.Front, finLength / 8);
fin1 = new RotateObject3D(fin1, -MathHelper.Tau / 4);
var fin2 = new SetCenterObject3D(new RotateObject3D(fin1, 0, 0, MathHelper.Tau / 4), fin1.GetCenter());
return new Object3D().SetChildren(new List<IObject3D>() { fin1, fin2 });
}
override abstract public Task Rebuild();
}
}

View file

@ -0,0 +1,67 @@
/*
Copyright (c) 2017, 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.Collections.Generic;
using System.Threading.Tasks;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.DesignTools;
using MatterHackers.MatterControl.Plugins.BrailleBuilder;
namespace MatterHackers.MatterControl.Library
{
public class PipeWorksContainer : LibraryContainer
{
public PipeWorksContainer()
{
Name = "Pipe Works".Localize();
}
public override void Load()
{
var libraryItems = new List<GeneratorItem>()
{
new GeneratorItem(
() => "Tee".Localize(),
async () => await TeeObject3D.Create()),
new GeneratorItem(
() => "Elbow".Localize(),
async () => await ElbowObject3D.Create()),
};
string title = "Primitive Shapes".Localize();
foreach (var item in libraryItems)
{
item.Category = title;
Items.Add(item);
}
}
}
}

View file

@ -0,0 +1,113 @@
/*
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.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools
{
public class TeeObject3D : PipeWorksBaseObject3D
{
public TeeObject3D()
{
}
public static async Task<TeeObject3D> Create()
{
var item = new TeeObject3D();
await item.Rebuild();
return item;
}
[DisplayName("Inner Radius")]
public double InnerDiameter { get; set; }
[DisplayName("Outer Radius")]
public double OuterDiameter { get; set; }
public double BottomReach { get; set; }
public double FrontReach { get; set; }
public double TopReach { get; set; }
public async override Task Rebuild()
{
using (RebuildLock())
{
using (new CenterAndHeightMantainer(this))
{
// validate the some of the values and store in user data if changed
InnerDiameter = ValidateValue(InnerDiameter, "PipeWorksInnerDiameter", 15);
OuterDiameter = ValidateValue(OuterDiameter, "PipeWorksOuterDiameter", 20);
BottomReach = ValidateValue(BottomReach, "PipeWorksBottomReach", 30);
FrontReach = ValidateValue(FrontReach, "PipeWorksFrontReach", 25);
TopReach = ValidateValue(TopReach, "PipeWorksTopReach", 30);
IObject3D topBottomConnect = await CylinderObject3D.Create(OuterDiameter, OuterDiameter, Sides, Alignment.Y);
IObject3D frontConnect = await CylinderObject3D.Create(OuterDiameter, OuterDiameter, Sides, Alignment.X);
frontConnect = new AlignObject3D(frontConnect, FaceAlign.Right, topBottomConnect, FaceAlign.Right);
IObject3D bottomReach = new RotateObject3D(CreateReach(BottomReach, InnerDiameter), -MathHelper.Tau / 4);
bottomReach = new AlignObject3D(bottomReach, FaceAlign.Back, topBottomConnect, FaceAlign.Front, 0, .02);
IObject3D topReach = new RotateObject3D(CreateReach(TopReach, InnerDiameter), MathHelper.Tau / 4);
topReach = new AlignObject3D(topReach, FaceAlign.Front, topBottomConnect, FaceAlign.Back, 0, -.02);
IObject3D frontReach = new RotateObject3D(CreateReach(FrontReach, InnerDiameter), 0, -MathHelper.Tau / 4);
frontReach = new AlignObject3D(frontReach, FaceAlign.Left, topBottomConnect, FaceAlign.Right, -.02);
// output multiple meshes for pipe connector
this.Children.Modify(list =>
{
list.Clear();
list.Add(topBottomConnect);
list.Add(frontConnect);
list.Add(bottomReach);
list.Add(topReach);
list.Add(frontReach);
});
this.Color = Color.Transparent;
this.Mesh = null;
}
}
Invalidate(InvalidateType.Children);
}
}
}

View file

@ -0,0 +1,91 @@
/*
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.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using MatterHackers.Agg.Font;
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools
{
public class RibbonWithNameObject3D : Object3D
{
public RibbonWithNameObject3D()
{
Rebuild();
}
[DisplayName("Name")]
public string NameToWrite { get; set; } = "MatterHackers";
public NamedTypeFace Font { get; set; } = new NamedTypeFace();
public override Task Rebuild()
{
IObject3D cancerRibbonStl = Object3D.Load("Cancer_Ribbon.stl", CancellationToken.None);
cancerRibbonStl = new RotateObject3D(cancerRibbonStl, MathHelper.DegreesToRadians(90));
var letterPrinter = new TypeFacePrinter(NameToWrite.ToUpper(), new StyledTypeFace(ApplicationController.GetTypeFace(Font), 12));
IObject3D nameMesh = new Object3D()
{
Mesh = VertexSourceToMesh.Extrude(letterPrinter, 5)
};
AxisAlignedBoundingBox textBounds = nameMesh.GetAxisAlignedBoundingBox();
var textArea = new Vector2(25, 6);
double scale = Math.Min(textArea.X / textBounds.XSize, textArea.Y / textBounds.YSize);
nameMesh = new ScaleObject3D(nameMesh, scale, scale, 2 / textBounds.ZSize);
nameMesh = new AlignObject3D(nameMesh, FaceAlign.Bottom | FaceAlign.Front, cancerRibbonStl, FaceAlign.Top | FaceAlign.Front, 0, 0, -1);
nameMesh = new SetCenterObject3D(nameMesh, cancerRibbonStl.GetCenter(), true, false, false);
nameMesh = new RotateObject3D(nameMesh, 0, 0, MathHelper.DegreesToRadians(50));
nameMesh = new TranslateObject3D(nameMesh, -37, -14, -1);
// output two meshes for card holder and text
this.Children.Modify(list =>
{
list.Clear();
list.Add(cancerRibbonStl);
list.Add(nameMesh);
});
this.Mesh = null;
this.Invalidate(InvalidateType.Children);
return Task.CompletedTask;
}
}
}