public static void PlaceTextureOnFace(Face face, ImageBuffer textureToUse)
        {
            FaceTextureData faceData = FaceTextureData.Get(face);

            faceData.Textures.Add(textureToUse);
            int count = 0;

            foreach (FaceEdge faceEdge in face.FaceEdges())
            {
                FaceEdgeTextureUvData edgeUV = FaceEdgeTextureUvData.Get(faceEdge);
                switch (count++)
                {
                case 0:
                    edgeUV.TextureUV.Add(new Vector2(0, 0));
                    break;

                case 1:
                    edgeUV.TextureUV.Add(new Vector2(1, 0));
                    break;

                case 2:
                    edgeUV.TextureUV.Add(new Vector2(1, 1));
                    break;

                case 3:
                    edgeUV.TextureUV.Add(new Vector2(0, 1));
                    break;
                }
            }
        }
示例#2
0
 public static void RemoveTexture(this Face face, ImageBuffer texture, int index)
 {
     face.ContainingMesh.FaceTexture.Remove((face, index));
     foreach (FaceEdge faceEdge in face.FaceEdges())
     {
         face.ContainingMesh.TextureUV.Remove((faceEdge, index));
     }
 }
示例#3
0
 public static void PlaceTextureOnFace(this Face face, ImageBuffer textureToUse, Matrix4X4 textureCoordinateMapping)
 {
     face.SetTexture(0, textureToUse);
     foreach (FaceEdge faceEdge in face.FaceEdges())
     {
         Vector3 edgeStartPosition = faceEdge.FirstVertex.Position;
         Vector3 textureUv         = Vector3.Transform(edgeStartPosition, textureCoordinateMapping);
         faceEdge.SetUv(0, new Vector2(textureUv));
     }
     face.ContainingMesh.MarkAsChanged();
 }
示例#4
0
        public FaceEdge GetFaceEdge(Face faceToFindFaceEdgeFor)
        {
            foreach (FaceEdge faceEdge in faceToFindFaceEdgeFor.FaceEdges())
            {
                if (faceEdge.ContainingFace == faceToFindFaceEdgeFor)
                {
                    return(faceEdge);
                }
            }

            return(null);
        }
示例#5
0
        public static Matrix4X4 GetMaxFaceProjection(Face face, ImageBuffer textureToUse, Matrix4X4?initialTransform = null)
        {
            // If not set than make it identity
            var firstTransform = initialTransform == null ? Matrix4X4.Identity : (Matrix4X4)initialTransform;

            var textureCoordinateMapping = Matrix4X4.CreateRotation(new Quaternion(face.Normal, Vector3.UnitZ));

            var bounds = RectangleDouble.ZeroIntersection;

            foreach (FaceEdge faceEdge in face.FaceEdges())
            {
                var edgeStartPosition = faceEdge.FirstVertex.Position;
                var textureUv         = Vector3.Transform(edgeStartPosition, textureCoordinateMapping);
                bounds.ExpandToInclude(new Vector2(textureUv));
            }
            var centering = Matrix4X4.CreateTranslation(new Vector3(-bounds.Left, -bounds.Bottom, 0));
            var scaling   = Matrix4X4.CreateScale(new Vector3(1 / bounds.Width, 1 / bounds.Height, 1));

            return(textureCoordinateMapping * firstTransform * centering * scaling);
        }
示例#6
0
        public FaceEdge GetFaceEdge(Face faceToFindFaceEdgeFor)
        {
            foreach (FaceEdge faceEdge in faceToFindFaceEdgeFor.FaceEdges())
            {
                if (faceEdge.containingFace == faceToFindFaceEdgeFor)
                {
                    return faceEdge;
                }
            }

            return null;
        }
示例#7
0
        public void SplitFace(Face faceToSplit, Vertex splitStartVertex, Vertex splitEndVertex, out MeshEdge meshEdgeCreatedDuringSplit, out Face faceCreatedDuringSplit)
        {
            if (!ContainsVertex(splitStartVertex) || !ContainsVertex(splitEndVertex))
            {
                throw new Exception("The mesh must contain the vertices you intend to split between.");
            }

            // we may want to be able to double up an edge for some operations (we'll have to see).
            if (FindMeshEdges(splitStartVertex, splitEndVertex).Count > 0)
            {
                // this also ensures that the face is more than 2 sided.
                throw new Exception("You cannot split a face on an existing edge.");
            }

            FaceEdge faceEdgeAfterSplitStart = null;
            FaceEdge faceEdgeAfterSplitEnd   = null;
            int      count = 0;

            foreach (FaceEdge faceEdge in faceToSplit.FaceEdges())
            {
                if (faceEdge.firstVertex == splitStartVertex)
                {
                    faceEdgeAfterSplitStart = faceEdge;
                    count++;
                }
                else if (faceEdge.firstVertex == splitEndVertex)
                {
                    faceEdgeAfterSplitEnd = faceEdge;
                    count++;
                }
                if (count == 2)
                {
                    break;                     // stop if we found both face edges
                }
            }

            meshEdgeCreatedDuringSplit = CreateMeshEdge(splitStartVertex, splitEndVertex);
            faceCreatedDuringSplit     = new Face(faceToSplit);

            faces.Add(faceCreatedDuringSplit);

            FaceEdge newFaceEdgeExistingFace = new FaceEdge(faceToSplit, meshEdgeCreatedDuringSplit, splitStartVertex);
            FaceEdge newFaceEdgeForNewFace   = new FaceEdge(faceCreatedDuringSplit, meshEdgeCreatedDuringSplit, splitEndVertex);

            // get the new edges injected into the existing loop, spliting it in two.
            newFaceEdgeExistingFace.prevFaceEdge = faceEdgeAfterSplitStart.prevFaceEdge;
            newFaceEdgeForNewFace.prevFaceEdge   = faceEdgeAfterSplitEnd.prevFaceEdge;

            faceEdgeAfterSplitStart.prevFaceEdge.nextFaceEdge = newFaceEdgeExistingFace;
            faceEdgeAfterSplitEnd.prevFaceEdge.nextFaceEdge   = newFaceEdgeForNewFace;

            newFaceEdgeExistingFace.nextFaceEdge = faceEdgeAfterSplitEnd;
            newFaceEdgeForNewFace.nextFaceEdge   = faceEdgeAfterSplitStart;

            faceEdgeAfterSplitStart.prevFaceEdge = newFaceEdgeForNewFace;
            faceEdgeAfterSplitEnd.prevFaceEdge   = newFaceEdgeExistingFace;

            // make sure the first face edge of each face is valid
            faceToSplit.firstFaceEdge            = newFaceEdgeExistingFace;
            faceCreatedDuringSplit.firstFaceEdge = newFaceEdgeForNewFace;

            // make sure the FaceEdges of the new face all point to the new face.
            foreach (FaceEdge faceEdge in faceCreatedDuringSplit.firstFaceEdge.NextFaceEdges())
            {
                faceEdge.containingFace = faceCreatedDuringSplit;
            }

            newFaceEdgeExistingFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
            newFaceEdgeForNewFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
        }
示例#8
0
		public void SplitFace(Face faceToSplit, Vertex splitStartVertex, Vertex splitEndVertex, out MeshEdge meshEdgeCreatedDuringSplit, out Face faceCreatedDuringSplit)
		{
			if (!ContainsVertex(splitStartVertex) || !ContainsVertex(splitEndVertex))
			{
				throw new Exception("The mesh must contain the vertices you intend to split between.");
			}

			// we may want to be able to double up an edge for some operations (we'll have to see).
			if (FindMeshEdges(splitStartVertex, splitEndVertex).Count > 0)
			{
				// this also ensures that the face is more than 2 sided.
				throw new Exception("You cannot split a face on an existing edge.");
			}

			FaceEdge faceEdgeAfterSplitStart = null;
			FaceEdge faceEdgeAfterSplitEnd = null;
			int count = 0;
			foreach (FaceEdge faceEdge in faceToSplit.FaceEdges())
			{
				if (faceEdge.firstVertex == splitStartVertex)
				{
					faceEdgeAfterSplitStart = faceEdge;
					count++;
				}
				else if (faceEdge.firstVertex == splitEndVertex)
				{
					faceEdgeAfterSplitEnd = faceEdge;
					count++;
				}
				if (count == 2)
				{
					break; // stop if we found both face edges
				}
			}

			meshEdgeCreatedDuringSplit = CreateMeshEdge(splitStartVertex, splitEndVertex);
			faceCreatedDuringSplit = new Face(faceToSplit);

			faces.Add(faceCreatedDuringSplit);

			FaceEdge newFaceEdgeExistingFace = new FaceEdge(faceToSplit, meshEdgeCreatedDuringSplit, splitStartVertex);
			FaceEdge newFaceEdgeForNewFace = new FaceEdge(faceCreatedDuringSplit, meshEdgeCreatedDuringSplit, splitEndVertex);

			// get the new edges injected into the existing loop, spliting it in two.
			newFaceEdgeExistingFace.prevFaceEdge = faceEdgeAfterSplitStart.prevFaceEdge;
			newFaceEdgeForNewFace.prevFaceEdge = faceEdgeAfterSplitEnd.prevFaceEdge;

			faceEdgeAfterSplitStart.prevFaceEdge.nextFaceEdge = newFaceEdgeExistingFace;
			faceEdgeAfterSplitEnd.prevFaceEdge.nextFaceEdge = newFaceEdgeForNewFace;

			newFaceEdgeExistingFace.nextFaceEdge = faceEdgeAfterSplitEnd;
			newFaceEdgeForNewFace.nextFaceEdge = faceEdgeAfterSplitStart;

			faceEdgeAfterSplitStart.prevFaceEdge = newFaceEdgeForNewFace;
			faceEdgeAfterSplitEnd.prevFaceEdge = newFaceEdgeExistingFace;

			// make sure the first face edge of each face is valid
			faceToSplit.firstFaceEdge = newFaceEdgeExistingFace;
			faceCreatedDuringSplit.firstFaceEdge = newFaceEdgeForNewFace;

			// make sure the FaceEdges of the new face all point to the new face.
			foreach (FaceEdge faceEdge in faceCreatedDuringSplit.firstFaceEdge.NextFaceEdges())
			{
				faceEdge.containingFace = faceCreatedDuringSplit;
			}

			newFaceEdgeExistingFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
			newFaceEdgeForNewFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
		}