private ShapeModel(
            ShapeStructure structure,
            IList<ShapeEdgeParams> edgeParams,
            IDictionary<Tuple<int, int>, ShapeEdgePairParams> edgePairParams,
            int rootEdgeIndex,
            double rootEdgeMeanLength,
            double rootEdgeLengthDeviation)
        {
            if (structure == null)
                throw new ArgumentNullException("structure");
            if (edgeParams == null)
                throw new ArgumentNullException("edgeParams");
            if (edgePairParams == null)
                throw new ArgumentNullException("edgePairParams");
            if (rootEdgeMeanLength <= 0)
                throw new ArgumentOutOfRangeException("rootEdgeMeanLength", "Parameter value should be positive.");
            if (rootEdgeLengthDeviation <= 0)
                throw new ArgumentOutOfRangeException("rootEdgeLengthDeviation", "Parameter value should be positive.");

            if (edgeParams.Count != structure.Edges.Count)
                throw new ArgumentException("Edge params count is not equal to edge count.");
            if (rootEdgeIndex < 0 || rootEdgeIndex >= structure.Edges.Count)
                throw new ArgumentOutOfRangeException("rootEdgeIndex", "Parameter value should be a valid edge index.");

            // Check edge pair constraints
            foreach (Tuple<int, int> edgePair in edgePairParams.Keys)
            {
                if (edgePair.Item1 < 0 || edgePair.Item1 >= structure.Edges.Count || edgePair.Item2 < 0 || edgePair.Item2 >= structure.Edges.Count)
                    throw new ArgumentOutOfRangeException("edgePairParams", "Invalid edge index given.");
                if (edgePair.Item1 == edgePair.Item2)
                    throw new ArgumentException("Edge pair constraint can't be specified for the single edge.", "edgePairParams");
                if (edgePairParams.ContainsKey(new Tuple<int, int>(edgePair.Item2, edgePair.Item1)))
                    throw new ArgumentException("Duplicate pairwise constraints specified for some pair of edges.", "edgePairParams");

                ShapeEdge edge1 = structure.Edges[edgePair.Item1];
                ShapeEdge edge2 = structure.Edges[edgePair.Item2];
                if (edge1.Index1 != edge2.Index1 && edge1.Index2 != edge2.Index1 &&
                    edge1.Index1 != edge2.Index2 && edge1.Index2 != edge2.Index2)
                {
                    throw new ArgumentException("Constrained edge pairs should be connected.", "edgePairParams");
                }
            }

            // Set
            this.Structure = structure;
            this.edgeParams = new List<ShapeEdgeParams>(edgeParams);
            this.edgePairParams = new Dictionary<Tuple<int, int>, ShapeEdgePairParams>(edgePairParams);
            this.rootEdgeIndex = rootEdgeIndex;
            this.rootEdgeMeanLength = rootEdgeMeanLength;
            this.rootEdgeLengthDeviation = rootEdgeLengthDeviation;
            this.PostInit();
        }
        public Shape(ShapeStructure structure, IEnumerable<Vector> vertexPositions, IEnumerable<double> edgeWidths)
        {
            if (structure == null)
                throw new ArgumentNullException("structure");
            if (vertexPositions == null)
                throw new ArgumentNullException("vertexPositions");
            if (edgeWidths == null)
                throw new ArgumentNullException("edgeWidths");

            this.Structure = structure;
            this.vertexPositions = new List<Vector>(vertexPositions);
            this.edgeWidths = new List<double>(edgeWidths);

            if (this.vertexPositions.Count != structure.VertexCount)
                throw new ArgumentException("Wrong number of vertex positions given.", "vertexPositions");
            if (this.edgeWidths.Count != structure.Edges.Count)
                throw new ArgumentException("Wrong number of edge widths given.", "edgeWidths");

            this.InitExposableCollections();
        }
        public static ShapeConstraints CreateFromBounds(
            ShapeStructure structure,
            Vector coordMin,
            Vector coordMax,
            double minEdgeWidth,
            double maxEdgeWidth)
        {
            ShapeConstraints result = new ShapeConstraints();
            result.ShapeStructure = structure;
            result.vertexConstraints = new List<VertexConstraints>();
            result.edgeConstraints = new List<EdgeConstraints>();

            for (int i = 0; i < structure.VertexCount; ++i)
                result.vertexConstraints.Add(new VertexConstraints(coordMin, coordMax));

            for (int i = 0; i < structure.Edges.Count; ++i)
                result.edgeConstraints.Add(new EdgeConstraints(minEdgeWidth, maxEdgeWidth));

            return result;
        }
        public ShapeLengthAngleRepresentation(ShapeStructure structure, Vector origin, IEnumerable<double> edgeLengths, IEnumerable<double> edgeAngles, IEnumerable<double> edgeWidths)
        {
            if (edgeLengths == null)
                throw new ArgumentNullException("edgeLengths");
            if (edgeAngles == null)
                throw new ArgumentNullException("edgeAngles");
            if (edgeWidths == null)
                throw new ArgumentNullException("edgeWidths");
            if (structure == null)
                throw new ArgumentNullException("structure");

            this.edgeLengths = new ExposableCollection<double>(edgeLengths.ToList());
            this.edgeAngles = new ExposableCollection<double>(edgeAngles.ToList());
            this.edgeWidths = new ExposableCollection<double>(edgeWidths.ToList());
            this.Structure = structure;
            this.Origin = origin;

            if (this.edgeLengths.Count != this.Structure.Edges.Count)
                throw new ArgumentException("Edge lengths count should be equal to edge count.", "edgeLengths");
            if (this.edgeAngles.Count != this.Structure.Edges.Count)
                throw new ArgumentException("Edge angles count should be equal to edge count.", "edgeAngles");
            if (this.edgeWidths.Count != this.Structure.Edges.Count)
                throw new ArgumentException("Edge widths count should be equal to edge count.", "edgeWidths");
        }
        public static ShapeConstraints CreateFromConstraints(
            ShapeStructure structure,
            IEnumerable<VertexConstraints> vertexConstraints,
            IEnumerable<EdgeConstraints> edgeConstraints)
        {
            if (structure == null)
                throw new ArgumentNullException("structure");
            if (vertexConstraints == null)
                throw new ArgumentNullException("vertexConstraints");
            if (edgeConstraints == null)
                throw new ArgumentNullException("edgeConstraints");
            
            ShapeConstraints result = new ShapeConstraints();
            result.ShapeStructure = structure;
            result.vertexConstraints = new List<VertexConstraints>(vertexConstraints);
            result.edgeConstraints = new List<EdgeConstraints>(edgeConstraints);

            if (result.vertexConstraints.Count != result.ShapeStructure.VertexCount)
                throw new ArgumentException("Vertex constraint should be given for every vertex (and for every vertex only).", "vertexConstraints");
            if (result.edgeConstraints.Count != result.ShapeStructure.Edges.Count)
                throw new ArgumentException("Edge constraint should be given for every edge (and for every vertex only).", "edgeConstraints");

            return result;
        }
 public static ShapeModel Create(
    ShapeStructure structure,
    IList<ShapeEdgeParams> edgeParams,
    IDictionary<Tuple<int, int>, ShapeEdgePairParams> edgePairParams)
 {
     const double bigDeviation = 1e+8;
     const double anyLength = 1;
     const int someEdgeIndex = 0;
     return new ShapeModel(structure, edgeParams, edgePairParams, someEdgeIndex, anyLength, bigDeviation);
 }
 public static ShapeModel Create(
     ShapeStructure structure,
     IList<ShapeEdgeParams> edgeParams,
     IDictionary<Tuple<int, int>, ShapeEdgePairParams> edgePairParams,
     int rootEdgeIndex,
     double rootEdgeMeanLength,
     double rootEdgeLengthDeviation)
 {
     return new ShapeModel(structure, edgeParams, edgePairParams, rootEdgeIndex, rootEdgeMeanLength, rootEdgeLengthDeviation);
 }