protected void AddLayoutNodeInputs(BuildComponentFactory factory, LayoutNode layoutNode, bool trimTriangles, bool isTopLevel) { if (!isTopLevel && !string.IsNullOrEmpty(layoutNode.ComponentName) && !string.IsNullOrEmpty(layoutNode.ComponentType)) { AddComponentInputs(factory, layoutNode, trimTriangles); } else if (layoutNode is GridLayoutNode) { AddGridInputs(factory, (GridLayoutNode)layoutNode, trimTriangles); } else if (layoutNode is HalfSquareTriangleLayoutNode) { AddHalfSquareTriangleInputs(factory, (HalfSquareTriangleLayoutNode)layoutNode, trimTriangles); } else { var children = new List <Node>(); layoutNode.AddChildrenTo(children); foreach (var child in children) { AddNodeInputs(factory, child, trimTriangles); } } }
private void AddComponentInputs(BuildComponentFactory factory, LayoutNode layoutNode, bool trimTriangles) { var matchingComponent = FindLayout(BuildComponentLayout.CreateStyleKey(layoutNode.ComponentType, layoutNode.ComponentName, layoutNode.GetFabricStyles())); if (matchingComponent != null) { matchingComponent.Quantity += 1; } else { var component = factory.CreateBuildComponentLayout(layoutNode, trimTriangles); AddInput(component); } }
private void AddFlyingGooseInputs(BuildComponentFactory factory, FabricStyle fabricStyleBody, FabricStyle fabricStyleCorner, Area area, bool trimTriangles) { var matchingComponent = FindFlyingGoose(BuildComponentFlyingGoose.CreateStyleKey(fabricStyleBody, fabricStyleCorner, area)); if (matchingComponent != null) { matchingComponent.Quantity += 1; } else { var component = factory.CreateBuildComponentFlyingGooose(fabricStyleBody, fabricStyleCorner, area, trimTriangles); AddInput(component); } }
private void AddRectangleInput(BuildComponentFactory factory, Area area, FabricStyle fabricStyle) { var matchingComponent = FindRectangle(BuildComponentRectangle.CreateStyleKey(fabricStyle, area)); if (matchingComponent != null) { matchingComponent.Quantity += 1; } else { var component = factory.CreateBuildComponentRectangle(fabricStyle, area); AddInput(component); } }
private void AddNodeInputs(BuildComponentFactory factory, Node node, bool trimTriangles) { if (node is LayoutNode) { AddLayoutNodeInputs(factory, (LayoutNode)node, trimTriangles, false); } else if (node is ShapeNode) { AddShapeNodeInput(factory, (ShapeNode)node); } else { throw new InvalidOperationException("Unknown node type."); } }
private void ProcessComponent(IBuildComponent component, BuildComponentFactory factory) { var step = FindOrCreateStep(component); if (step != null) { int quantity = step.CanProduceQuantity(component.StyleKey); if (quantity < component.Quantity) { var splitComponent = component.Split(factory, component.Quantity - quantity); PushPendingComponent(splitComponent); } step.AddOutput(component); } }
private void AddOrUpdateInput(BuildComponentFactory factory, FabricStyle style, Area area) { foreach (var input in Consumes) { if (input is BuildComponentRectangle inputRectangle && inputRectangle.FabricStyle.Sku == style.Sku && inputRectangle.Area.Matches(area)) { inputRectangle.Quantity += 1; return; } } var component = factory.CreateBuildComponentRectangle(style, area); AddInput(component); }
private void AddShapeNodeInput(BuildComponentFactory factory, ShapeNode shapeNode) { if (shapeNode.Path.PathGeometry != PathGeometries.Rectangle) { throw new InvalidOperationException("Unsupported path geometry."); } var nodeBounds = shapeNode.Path.GetBounds(); var width = nodeBounds.MaximumX - nodeBounds.MinimumX; var height = nodeBounds.MaximumY - nodeBounds.MinimumY; width += s_seamAllowance; height += s_seamAllowance; var area = new Area(width, height).Round(); AddRectangleInput(factory, area, shapeNode.FabricStyle); }
public override void ComputeInputs(BuildComponentFactory factory) { //Consumes.Clear(); if (Produces.Count == 0) { return; } var cutShapes = new List <ICutShape>(); foreach (BuildComponentRectangle output in Produces) { for (int idx = 0; idx < output.Quantity; ++idx) { cutShapes.Add(new CutShape(output)); } } var cutPlan = CutPlanner.Plan(cutShapes); foreach (var cutStock in cutPlan.CutStocks) { var input = factory.CreateBuildComponentYardage(((BuildComponentRectangle)Produces[0]).FabricStyle, cutStock.AreaSize); foreach (var cutRegion in cutPlan.CutRegions) { if (cutRegion.CutStock == cutStock && cutRegion.CutShape != null) { input.Regions.Add( new BuildComponentYardageRegion( ((CutShape)cutRegion.CutShape).BuildComponentRectangle, cutRegion.Left, cutRegion.Top, cutRegion.Width, cutRegion.Height)); } } AddInput(input); } }
public override void ComputeInputs(BuildComponentFactory factory) { if (Produces.Count == 0) { return; } var output = (BuildComponentFlyingGoose)Produces.Where(r => r is BuildComponentFlyingGoose).First(); Dimension seamAllowance; if (output.Trim) { seamAllowance = new Dimension(0.875, DimensionUnits.Inch); } else { seamAllowance = new Dimension(1, DimensionUnits.Inch); } var producesCount = Produces.Where(r => r is BuildComponentFlyingGoose).Sum(r => r.Quantity); var bodyCount = producesCount; var bodyWidth = output.Area.Width + seamAllowance; var bodyHeight = output.Area.Height + seamAllowance; var bodyArea = new Area(bodyWidth, bodyHeight).Round(); var cornerCount = producesCount * 2; var cornerWidth = (output.Area.Width / 2) + seamAllowance; var cornerHeight = output.Area.Height + seamAllowance; var cornerArea = new Area(cornerWidth, cornerHeight).Round(); var input1 = factory.CreateBuildComponentRectangle(output.FabricStyles[0], bodyArea); input1.Quantity = bodyCount; AddInput(input1); var input2 = factory.CreateBuildComponentRectangle(output.FabricStyles[1], cornerArea); input2.Quantity = cornerCount; AddInput(input2); }
public override void ComputeInputs(BuildComponentFactory factory) { if (Consumes.Count != 0) { throw new InvalidOperationException("Inputs already computed."); } foreach (BuildComponentLayout output in Produces) { if (CanProduceQuantity(output.StyleKey) == 0) { throw new InvalidOperationException(string.Format("Output StyleKey {0} does not match ProducesStyleKey {1}.", output.StyleKey, m_producesStyleKey)); } for (int idx = 0; idx < output.Quantity; ++idx) { AddLayoutNodeInputs(factory, output.LayoutNode, output.TrimTriangles, true); } } }
public override void ComputeInputs(BuildComponentFactory factory) { //Consumes.Clear(); if (Produces.Count == 0) { return; } // BUG: Assumes all outputs are the same. // var output = (BuildComponentHalfSquareTriangle)Produces[0]; var seamAllowance = output.Trim ? new Dimension(0.875, DimensionUnits.Inch) : new Dimension(1, DimensionUnits.Inch); var producesCount = 0; foreach (var o in Produces) { producesCount += o.Quantity; } var inputCount = (producesCount + 1) / 2; var width = output.Area.Width + seamAllowance; var height = output.Area.Height + seamAllowance; var area = new Area(width, height).Round(); var input1 = factory.CreateBuildComponentRectangle(output.FabricStyles[0], area); input1.Quantity = inputCount; AddInput(input1); var input2 = factory.CreateBuildComponentRectangle(output.FabricStyles[1], area); input2.Quantity = inputCount; AddInput(input2); }
private void CreateBuildPlan() { var factory = new BuildComponentFactory(); var quilt = factory.CreateBuildComponentQuilt(m_kitSpecification, m_design); PushPendingComponent(quilt); while (true) { // Go through all outstanding components and create build steps. // { var component = PullPendingComponent(); while (component != null) { ProcessComponent(component, factory); component = PullPendingComponent(); } } // Pull a build step and add inputs. // { var step = PullPendingStep(); if (step == null) { // No more steps. Processing complete. return; } step.ComputeInputs(factory); foreach (BuildComponent component in step.Consumes) { PushPendingComponent(component); } } } }
private void AddHalfSquareTriangleInputs(BuildComponentFactory factory, HalfSquareTriangleLayoutNode layoutNode, bool trimTriangles) { var style1 = ((ShapeNode)layoutNode.LayoutSites[0].Node).FabricStyle; var style2 = ((ShapeNode)layoutNode.LayoutSites[1].Node).FabricStyle; var nodeBounds = layoutNode.Path.GetBounds(); var width = nodeBounds.MaximumX - nodeBounds.MinimumX; var height = nodeBounds.MaximumY - nodeBounds.MinimumY; var area = new Area(width, height).Round(); var matchingComponent = FindHalfSquareTriangle(BuildComponentHalfSquareTriangle.CreateStyleKey(style1, style2, area)); if (matchingComponent != null) { matchingComponent.Quantity += 1; } else { var component = factory.CreateBuildComponentHalfSquareTriangle(layoutNode, trimTriangles); AddInput(component); } }
public IBuildComponent Split(BuildComponentFactory factory, int quantity) { if (quantity >= Quantity) { throw new ArgumentException(string.Format("Value exceeds component quantity of {0}.", Quantity), nameof(quantity)); } if (ProducedBy != null) { throw new InvalidOperationException("Component is already produced by a build step."); } Quantity -= quantity; var component = Clone(factory); component.Quantity = quantity; if (ConsumedBy != null) { ConsumedBy.AddInput(component); } return(component); }
protected override IBuildComponent Clone(BuildComponentFactory factory) { return(factory.CreateBuildComponentHalfSquareTriangle(m_halfSquareTriangleLayoutNode, Trim)); }
public abstract void ComputeInputs(BuildComponentFactory factory);
protected abstract IBuildComponent Clone(BuildComponentFactory factory);
protected override IBuildComponent Clone(BuildComponentFactory factory) { return(factory.CreateBuildComponentLayout(LayoutNode, TrimTriangles)); }
private void AddGridInputs(BuildComponentFactory factory, GridLayoutNode grid, bool trimTriangles) { List <Tuple <int, int> > consumedNodes = new List <Tuple <int, int> >(); for (int row = 0; row < grid.RowCount; ++row) { for (int column = 0; column < grid.ColumnCount; ++column) { if (!consumedNodes.Exists(r => r.Item1 == row && r.Item2 == column)) { var layoutSite = grid.GetLayoutSite(row, column); var columnSpan = grid.GetColumnSpan(row, column); var rowSpan = grid.GetRowSpan(row, column); var fingerprint = GetFlyingGooseFingerprint(layoutSite.Node, layoutSite.PathOrientation.PointOffset); if (fingerprint != null) { bool flyingGooseCreated = false; LayoutSite layoutSiteRight = null; // Assume layout site does not exist. if (column + columnSpan < grid.ColumnCount) { if (grid.GetLayoutSite(row, column + columnSpan).Node != null) { if (grid.GetColumnSpan(row, column + columnSpan) == columnSpan && grid.GetRowSpan(row, column + columnSpan) == rowSpan) { layoutSiteRight = grid.GetLayoutSite(row, column + columnSpan); } } } if (layoutSiteRight != null) { var matchingRightFingerprint = GetFlyingGooseMatchingHorizontalFingerprint(layoutSite.Node, layoutSite.PathOrientation.PointOffset); var rightFingerprint = GetFlyingGooseFingerprint(layoutSiteRight.Node, layoutSiteRight.PathOrientation.PointOffset); if (rightFingerprint == matchingRightFingerprint) { var halfSquareTriangle = (HalfSquareTriangleLayoutNode)layoutSite.Node; FabricStyle fabricStyleBody; FabricStyle fabricStyleCorner; switch (layoutSite.PathOrientation.PointOffset) { case 0: case 1: fabricStyleCorner = ((ShapeNode)halfSquareTriangle.LayoutSites[0].Node).FabricStyle; fabricStyleBody = ((ShapeNode)halfSquareTriangle.LayoutSites[1].Node).FabricStyle; break; case 2: case 3: fabricStyleCorner = ((ShapeNode)halfSquareTriangle.LayoutSites[1].Node).FabricStyle; fabricStyleBody = ((ShapeNode)halfSquareTriangle.LayoutSites[0].Node).FabricStyle; break; default: throw new InvalidOperationException("Unexpected point offset."); } var nodeBounds = halfSquareTriangle.Path.GetBounds(); var width = nodeBounds.MaximumX - nodeBounds.MinimumX; var height = nodeBounds.MaximumY - nodeBounds.MinimumY; var area = new Area(width * 2, height).Round(); AddFlyingGooseInputs(factory, fabricStyleBody, fabricStyleCorner, area, trimTriangles); consumedNodes.Add(new Tuple <int, int>(row, column)); consumedNodes.Add(new Tuple <int, int>(row, column + columnSpan)); flyingGooseCreated = true; } } LayoutSite layoutSiteDown = null; // Assume layout site does not exist. if (row + rowSpan < grid.RowCount) { if (grid.GetLayoutSite(row + rowSpan, column).Node != null) { if (grid.GetColumnSpan(row + rowSpan, column) == columnSpan && grid.GetRowSpan(row + rowSpan, column) == rowSpan) { layoutSiteDown = grid.GetLayoutSite(row + rowSpan, column); } } } if (!flyingGooseCreated && layoutSiteDown != null) { var matchingDownFingerprint = GetFlyingGooseMatchingVerticalFingerprint(layoutSite.Node, layoutSite.PathOrientation.PointOffset); var downFingerprint = GetFlyingGooseFingerprint(layoutSiteDown.Node, layoutSiteDown.PathOrientation.PointOffset); if (downFingerprint == matchingDownFingerprint) { var halfSquareTriangle = (HalfSquareTriangleLayoutNode)layoutSite.Node; FabricStyle fabricStyleBody; FabricStyle fabricStyleCorner; switch (layoutSite.PathOrientation.PointOffset) { case 0: case 3: fabricStyleCorner = ((ShapeNode)halfSquareTriangle.LayoutSites[0].Node).FabricStyle; fabricStyleBody = ((ShapeNode)halfSquareTriangle.LayoutSites[1].Node).FabricStyle; break; case 1: case 2: fabricStyleCorner = ((ShapeNode)halfSquareTriangle.LayoutSites[1].Node).FabricStyle; fabricStyleBody = ((ShapeNode)halfSquareTriangle.LayoutSites[0].Node).FabricStyle; break; default: throw new InvalidOperationException("Unexpected point offset."); } var nodeBounds = halfSquareTriangle.Path.GetBounds(); var width = nodeBounds.MaximumX - nodeBounds.MinimumX; var height = nodeBounds.MaximumY - nodeBounds.MinimumY; var area = new Area(width * 2, height).Round(); AddFlyingGooseInputs(factory, fabricStyleBody, fabricStyleCorner, area, trimTriangles); consumedNodes.Add(new Tuple <int, int>(row, column)); consumedNodes.Add(new Tuple <int, int>(row + rowSpan, column)); } } } } } } for (int row = 0; row < grid.RowCount; ++row) { for (int column = 0; column < grid.ColumnCount; ++column) { if (!consumedNodes.Exists(r => r.Item1 == row && r.Item2 == column)) { var child = grid.GetLayoutSite(row, column).Node; if (child != null) { AddNodeInputs(factory, child, trimTriangles); } } } } }
protected override IBuildComponent Clone(BuildComponentFactory factory) { return(factory.CreateBuildComponentQuilt(KitSpecification, Design)); }
#pragma warning disable IDE0051 // Remove unused private members private IBuildComponent Split(BuildComponentFactory factory, IBuildComponent component, int quantity) #pragma warning restore IDE0051 // Remove unused private members { return(component.Split(factory, quantity)); }
protected override IBuildComponent Clone(BuildComponentFactory factory) { return(factory.CreateBuildComponentRectangle(FabricStyle, Area)); }
protected override IBuildComponent Clone(BuildComponentFactory factory) { return(factory.CreateBuildComponentFlyingGooose(FabricStyles[0], FabricStyles[1], Area, Trim)); }
public override void ComputeInputs(BuildComponentFactory factory) { if (Consumes.Count != 0) { throw new InvalidOperationException("Inputs already computed."); } if (Produces.Count != 1 || !(Produces[0] is BuildComponentQuilt)) { throw new InvalidOperationException("Invalid outputs."); } var output = Produces[0] as BuildComponentQuilt; // Add build components for quilt top. // AddLayoutNodeInputs(factory, output.PageLayoutNode, output.KitSpecification.TrimTriangles, true); // Add build components for binding. // { var bindingWidth = output.KitSpecification.BindingWidth; if (bindingWidth.Value > 0) { var maxBindingHeight = new Dimension(40, DimensionUnits.Inch); var bindingAllowance = new Dimension(12, DimensionUnits.Inch); var style = output.KitSpecification.BindingFabricStyle; var bindingHeight = (output.KitSpecification.Width * 2) + (output.KitSpecification.Height * 2) + bindingAllowance; while (bindingHeight > maxBindingHeight) { AddOrUpdateInput(factory, style, Area.CreateHorizontalArea(bindingWidth, maxBindingHeight)); bindingHeight -= maxBindingHeight; } { AddOrUpdateInput(factory, style, Area.CreateHorizontalArea(bindingWidth, bindingHeight)); } } } // Add build components for backing. { if (output.KitSpecification.HasBacking) { var maxBackingHeight = new Dimension(3 * 36, DimensionUnits.Inch); var maxBackingWidth = new Dimension(40, DimensionUnits.Inch); var style = output.KitSpecification.BackingFabricStyle; var backingHeight = output.KitSpecification.Height; while (backingHeight > maxBackingHeight) { var backingWidth = output.KitSpecification.Width; while (backingWidth > maxBackingWidth) { AddOrUpdateInput(factory, style, Area.CreateHorizontalArea(maxBackingWidth, maxBackingHeight)); backingWidth -= maxBackingWidth; } { AddOrUpdateInput(factory, style, Area.CreateHorizontalArea(backingWidth, maxBackingHeight)); } backingHeight -= maxBackingHeight; } { var backingWidth = output.KitSpecification.Width; while (backingWidth > maxBackingWidth) { AddOrUpdateInput(factory, style, Area.CreateHorizontalArea(maxBackingWidth, backingHeight)); backingWidth -= maxBackingWidth; } { AddOrUpdateInput(factory, style, Area.CreateHorizontalArea(backingWidth, backingHeight)); } } } } }