/// <summary>
 ///     Initializes a new instance of the <see cref="EdgePartShape" /> class.
 /// </summary>
 /// <param name="part">The part.</param>
 /// <param name="edge">The edge.</param>
 /// <param name="lines">The lines.</param>
 public EdgePartShape([NotNull] EdgePart part, [NotNull] Edge edge, [NotNull] ShapeLines lines)
 {
     if (part == null)
     {
         throw new ArgumentNullException(nameof(part));
     }
     if (edge == null)
     {
         throw new ArgumentNullException(nameof(edge));
     }
     if (lines == null)
     {
         throw new ArgumentNullException(nameof(lines));
     }
     Part  = part;
     Edge  = edge;
     Lines = lines;
 }
Exemple #2
0
        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));
        }