/// <summary> /// Finds the face to which the given point belongs. /// </summary> /// <param name="point">The point to use when searching for the corresponding face.</param> /// <returns>The face to which the given point belongs.</returns> /// <remarks><para>Typically, the point will be on or close to the surface of the manifold, /// such that it is clear that it belongs to a particular face. It does not need to be near /// the surface, however, as each face implicitly defines a volume above and below it, and /// all points within that volume belong to that face.</para> /// <para>Depending on the shape of the manifold, not all faces returned by this method will /// be internal faces. For example, a rectangular manifold with no wrap-around edges contains /// a single external face that represents all areas outside the rectangle, and any point that /// lies on, above, or below this outer area will map to the external face. However, an empty /// face is guaranteed to never be returned by this method; every point is mappable to some /// face in the manifold, no matter the shape or topology of the manifold.</para></remarks> public Topology.Face FindFace(Vector3 point) { var partitionIndex = 0; while (true) { var partition = _partitionBinaryTree[partitionIndex]; if (partition.IsOver(point)) { if (partition._overPartitionIndex != 0) { partitionIndex = partition._overPartitionIndex; } else { var edge = _topology.faceEdges[partition._overEdgeIndex]; if ((edge.wrap & EdgeWrap.FaceToFace) == EdgeWrap.None || edge.isBoundary) { return(_topology.faceEdges[partition._overEdgeIndex].face); } else { point = _surface.ReverseOffsetFaceToFaceAttribute(point, edge.wrap); partitionIndex = 0; } } } else { if (partition._underPartitionIndex != 0) { partitionIndex = partition._underPartitionIndex; } else { return(_topology.faceEdges[partition._underEdgeIndex].face); } } } }
/// <summary> /// Lookup the attribute value for the face of the edge indicated, wrapping according to the attribute's surface if necessary. /// </summary> /// <param name="e">The edge whose face's attribute value is desired.</param> /// <returns>The attribute value for the far face of the edge indicated, relative to the edge's near face.</returns> /// <remarks><para>To get the raw value unwrapped, see <see cref="P:MakeIt.Tile.FaceArrayAttribute`1.Item(MakeIt.Tile.Topology.Face)"/></para></remarks> public override Vector3 this[Topology.FaceEdge e] { get { return(surface.OffsetFaceToFaceAttribute(array[e.face.index], e.wrap)); } set { array[e.face.index] = surface.ReverseOffsetFaceToFaceAttribute(array[e.face.index], e.wrap); } }