/// <summary> /// Initializes a new instance of the <see cref="TileBase" /> class. /// </summary> /// <param name="tile">The base tile.</param> /// <param name="label">The tile label.</param> /// <param name="transform">The transform of this tile.</param> /// <exception cref="System.ArgumentNullException"><paramref name="label" /> or <paramref name="tile" /> was null.</exception> public TileInstance([NotNull] Tile tile, [NotNull] string label, Matrix3x2 transform) : base(label, tile.Shape, transform) { if (tile == null) throw new ArgumentNullException(nameof(tile)); Tile = tile; }
public Tiling CreateTiling( [NotNull] TilingDefinition tilingDefinition, [NotNull] ShapeSet shapes, [NotNull] StyleManager styleManager) { if (tilingDefinition == null) throw new ArgumentNullException(nameof(tilingDefinition)); if (shapes == null) throw new ArgumentNullException(nameof(shapes)); if (styleManager == null) throw new ArgumentNullException(nameof(styleManager)); if (!Tilings.Values.Contains(tilingDefinition)) { throw new ArgumentException( Strings.Template_CreateTiling_UnknownTilingDefinition, nameof(tilingDefinition)); } HashSet<ShapeTemplate> templates = new HashSet<ShapeTemplate>(shapes.Select(s => s.Template)); if (!templates.SetEquals(ShapeTemplates.Values)) throw new ArgumentException(Strings.Template_CreateTiling_WrongShapes, nameof(shapes)); Dictionary<int, ShapeLines> shapeLines = new Dictionary<int, ShapeLines>(); List<Tile> tiles = new List<Tile>(shapes.Count); // TODO Order shapes so that the nth shape is adjacent to at least one of the previous shapes foreach (Shape shape in shapes) { Debug.Assert(shape != null, "shape != null"); string label = null; Matrix3x2 transform = default(Matrix3x2); if (tiles.Count < 1) { label = tilingDefinition.AdjacentParts .Where(l => l.Value.ShapeTemplate == shape.Template) .OrderBy(l => l.Label, StringComparer.InvariantCulture) .First().Label; transform = Matrix3x2.Identity; } else { foreach (Tile t in tiles) { foreach (EdgePartShape partShape in t.PartShapes) { Debug.Assert(partShape != null, "partShape != null"); Labeled<EdgePart> adjacent; if (!tilingDefinition.AdjacentParts.TryGetAdjacent( partShape.Part.WithLabel(t.Label), out adjacent)) continue; Debug.Assert(adjacent.Value != null, "adjacent.Value != null"); if (adjacent.Value.ShapeTemplate != shape.Template) continue; label = adjacent.Label; transform = EdgePartPosition.Create(adjacent.Value, shape) .GetTransformTo(t.GetEdgePartPosition(partShape.Part)); } if (label != null) break; } if (label == null) throw new InvalidDataException(); } EdgePartShape[] partShapes = shape.Template.EdgeParts[tilingDefinition] .Select( ep => new EdgePartShape( ep, shapes.GetEdge(ep.EdgePattern.EdgeName), shapeLines.GetOrAdd(ep.PartShapeID, _ => ShapeLines.CreateDefault()))) .ToArray(); Tile tile = new Tile(label, shape, transform, partShapes); tile.Style = styleManager.GetStyle(tile); tiles.Add(tile); } return new Tiling(this, tilingDefinition, tiles, styleManager); }