public override List<MeshFilter> apply (Corner corner)
		{
			List<MeshFilter> meshes = new List<MeshFilter> ();
			Vector3 normal = corner.getNormal ();
			Vector3 p = corner.getVertex ().getPoint ();

			p = parent.TransformPoint (p);
			Vector3 scale = this.getCornerScale ();

			foreach (HighLevelEdge e in corner.getEdges()) {
				Vector3 direction = e.getDirection (corner).normalized;
//				Debug.DrawRay (p, direction * 0.2f, Color.cyan, 200);
				Quaternion rotation = Quaternion.FromToRotation(Vector3.forward, direction);
				Vector3 location = p + direction * scale.z / 2 + e.getNormal () * scale.x / 2;
				Cell c = new Cell (parent, location, scale, rotation, "BrickCorner");
				meshes.Add(c.getCell ().GetComponent<MeshFilter> ());
			}


//			p += Vector3.Scale(translateVector, dimensions / 2);

//			Cell c = new Cell (parent, p, scale, Quaternion.identity, "BrickCorner");
//			Color finalColor = Color.Lerp (color, Color.black, UnityEngine.Random.value * 0.3f);
//			c.setColor (finalColor);

			return meshes;
		}
		public List<HighLevelEdge> constructHLEdges(Corner source) {
			Vertex.VertexLabel vertexLabel = source.getVertex().getLabel ();
			if (vertexLabel == Vertex.VertexLabel.cornerConvex) {
				// Convex edge
				return constructHLEdgeConvex (source);
			} else {
				// Concave edge
				return constructHLEdgeConcave (source);
			}
		}
		public override List<MeshFilter> apply (Corner corner)
		{
			List<MeshFilter> meshes = new List<MeshFilter>();
			Vector3 translateVector = corner.getTranslateVector ();
			Vector3 p = corner.getVertex ().getPoint ();

			p = parent.TransformPoint (p);

			Vector3 scale = this.getCornerScale ();

			p += Vector3.Scale(translateVector, dimensions / 2);

			Cell c = new Cell (parent, p, scale, Quaternion.identity, "BrickCorner");
			Color finalColor = Color.Lerp (color, Color.black, UnityEngine.Random.value * 0.3f);
			c.setColor (finalColor);
			meshes.Add (c.getCell ().GetComponent<MeshFilter> ());
			return meshes;
		}
		public void construct() {
			foreach (Vertex v in sourceMesh.getCornerVertices()) {
				Corner c = new Corner (v);
				corners.Add (c);
				v.setParent (c);
			}

			foreach (Corner c in corners) {
				List<HighLevelEdge> edgeResult = constructHLEdges (c);
				edges.AddRange(edgeResult);
			}

//			Debug.Log ("We have: " + edges.Count + " HLEs..");
			createRegionsEdges (edges);
//			Debug.Log ("Started with: " + regions.Count + " regions..");
			while (mergeRegions ()) {
				// Merge until done!
			}
//			Debug.Log ("Ended with: " + regions.Count + " regions..");
		}
		public void setTo(Corner to) {
			this.to = to;
		}
		public Vector3 getDirection(Corner c) {
			if (c.Equals(from))
				return to.getVertex ().getPoint () - from.getVertex ().getPoint ();
			else
				return from.getVertex ().getPoint () - to.getVertex ().getPoint ();
		}
		public void setFrom(Corner from) {
			this.from = from;
		}
		public List<HighLevelEdge> constructHLEdgeConvex(Corner source) {
			return constructHLEdgeConvex (source, new List<Edge> ());
		}
		public HighLevelEdge processSingleDirectionEdge(Edge.EdgeLabel eLabel, Vector3 direction, Corner source) {
			bool changed = true;
			Vertex sourceVertex = source.getVertex ();
			Vertex current = sourceVertex;
			List<Edge> usedEdges = new List<Edge> ();
			while (changed) {
				changed = false;
				foreach (Edge e in current.getEdges()) {
					if (e.hasParent()) {
						continue;
					}
					if (e.getLabel() != eLabel) {
						// If this isn't a correct type of edge, go to the next
						continue;
					}
					// Get our target
					Vertex target = e.getTo () == sourceVertex ? e.getFrom () : e.getTo ();
					// Calculate direction
					Vector3 newDirection = (target.getPoint () - current.getPoint ()).normalized;

					// If the direction isn't the same, we're done
					if (direction != newDirection) {
						continue;
					}

					usedEdges.Add (e);
					// Get the target label
					Vertex.VertexLabel targetLabel = target.getLabel ();
					if (targetLabel == Vertex.VertexLabel.cornerConcave ||
						targetLabel == Vertex.VertexLabel.cornerConvex ||
						targetLabel == Vertex.VertexLabel.cornerSaddle) {
						// Create HLE, this is the end of our HLE
						HighLevelEdge hle = new HighLevelEdge();
						hle.addEdgeRange (usedEdges);
						// Get target corner
						Corner c = target.getParent();
						// Set from and to of hle
						hle.setFrom (source);
						hle.setTo (c);

						// Add edges to the corners
						c.addEdge (hle);
						source.addEdge (hle);

						// Set all edges to processed
						foreach (Edge en in usedEdges) {
							en.setParent (hle);
						}
						return hle;
					} else {
						Debug.Log ("next edge in sequence!");
						current = target;
						changed = true;
					}
				}
			}
			// No valid HLE :(
			return null;
		}
		public List<HighLevelEdge> constructHLEdgeConvex(Corner source, List<Edge> edges) {
			Vertex sourceVertex = source.getVertex ();
			List<HighLevelEdge> hlEdges = new List<HighLevelEdge> ();
			foreach (Edge e in sourceVertex.getEdges()) {
				if (e.hasParent())
					continue;
				Edge.EdgeLabel edgeLabel = e.getLabel ();
				Vertex target = e.getTo () == sourceVertex ? e.getFrom() : e.getTo();

				if (edgeLabel == Edge.EdgeLabel.convex) {
					// Get a direction vector for this label
					Vector3 direction = (target.getPoint () - sourceVertex.getPoint ()).normalized;
					// Process this edge
					HighLevelEdge hle = processSingleDirectionEdge(edgeLabel, direction, source);
					if (hle != null) {
						hlEdges.Add (hle);
					} 
				}
			}
			return hlEdges;
		}
		public void setParent(Corner c) {
			this.parent = c;
		}
		abstract public List<MeshFilter> apply(Corner corner);