示例#1
0
        // There can be a singleton of this because GL must always render on the UI thread and can't overlap this array
        private static void DrawToGLUsingBsp(Mesh meshToRender, Matrix4X4 meshToViewTransform, Matrix4X4 invMeshToViewTransform)
        {
            ImageBuffer lastFaceTexture = null;
            var         bspFaceList     = FaceBspTree.GetFacesInVisibiltyOrder(meshToRender.Faces, meshToRender.FaceBspTree, meshToViewTransform, invMeshToViewTransform);

            foreach (var face in bspFaceList)
            {
                if (face == null)
                {
                    continue;
                }

                ImageBuffer faceTexture;
                meshToRender.FaceTexture.TryGetValue((face, 0), out faceTexture);
                if (faceTexture != lastFaceTexture)
                {
                    // Make sure the GLMeshPlugin has a reference to hold onto the image so it does not go away before this.
                    if (faceTexture != null)
                    {
                        ImageGlPlugin glPlugin = ImageGlPlugin.GetImageGlPlugin(faceTexture, true);
                        GL.Enable(EnableCap.Texture2D);
                        GL.BindTexture(TextureTarget.Texture2D, glPlugin.GLTextureHandle);
                    }
                    else
                    {
                        GL.Disable(EnableCap.Texture2D);
                    }

                    lastFaceTexture = faceTexture;
                }

                GL.Begin(BeginMode.Triangles);
                GL.Normal3(face.Normal.X, face.Normal.Y, face.Normal.Z);
                // load up the uvs
                if (faceTexture != null)
                {
                    foreach (var vertex in face.AsUvTriangles())
                    {
                        GL.TexCoord2(vertex.v0.uv);
                        GL.Vertex3(vertex.v0.p);

                        GL.TexCoord2(vertex.v1.uv);
                        GL.Vertex3(vertex.v1.p);

                        GL.TexCoord2(vertex.v2.uv);
                        GL.Vertex3(vertex.v2.p);
                    }
                }
                else
                {
                    foreach (var vertex in face.AsTriangles())
                    {
                        GL.Vertex3(vertex.p0);
                        GL.Vertex3(vertex.p1);
                        GL.Vertex3(vertex.p2);
                    }
                }
                GL.End();
            }
        }
示例#2
0
        // There can be a singleton of this because GL must always render on the UI thread and can't overlap this array
        private static void DrawToGLZSorted(Mesh mesh, Matrix4X4 meshToViewTransform, Matrix4X4 invMeshToViewTransform)
        {
            ImageBuffer lastFaceTexture = null;

            // var zSortedFaceList2 = mesh.GetFacesInVisibiltyOrder(meshToViewTransform);
            var zSortedFaceList = FaceBspTree.GetFacesInVisibiltyOrder(mesh, mesh.FaceBspTree, meshToViewTransform, invMeshToViewTransform);

            foreach (var face in zSortedFaceList)
            {
                if (face == -1)
                {
                    continue;
                }

                FaceTextureData faceTexture;
                mesh.FaceTextures.TryGetValue(face, out faceTexture);
                if (faceTexture != null &&
                    faceTexture.image != lastFaceTexture)
                {
                    // Make sure the GLMeshPlugin has a reference to hold onto the image so it does not go away before this.
                    if (faceTexture != null)
                    {
                        var glPlugin = ImageGlPlugin.GetImageGlPlugin(faceTexture.image, true);
                        GL.Enable(EnableCap.Texture2D);
                        GL.BindTexture(TextureTarget.Texture2D, glPlugin.GLTextureHandle);
                    }
                    else
                    {
                        GL.Disable(EnableCap.Texture2D);
                    }

                    lastFaceTexture = faceTexture.image;
                }

                GL.Begin(BeginMode.Triangles);
                var normal = mesh.Faces[face].normal;
                GL.Normal3(normal.X, normal.Y, normal.Z);
                // load up the uvs
                if (faceTexture != null)
                {
                    GL.TexCoord2(faceTexture.uv0);
                    GL.Vertex3(mesh.Vertices[mesh.Faces[face].v0]);

                    GL.TexCoord2(faceTexture.uv1);
                    GL.Vertex3(mesh.Vertices[mesh.Faces[face].v1]);

                    GL.TexCoord2(faceTexture.uv2);
                    GL.Vertex3(mesh.Vertices[mesh.Faces[face].v2]);
                }
                else
                {
                    GL.Vertex3(mesh.Vertices[mesh.Faces[face].v0]);
                    GL.Vertex3(mesh.Vertices[mesh.Faces[face].v1]);
                    GL.Vertex3(mesh.Vertices[mesh.Faces[face].v2]);
                }

                GL.End();
            }
        }
示例#3
0
        public void CreateBspFaceTrees()
        {
            // a simple list of 3 faces
            //
            // Index 1 ^------------------- z = 3
            //
            // Index 0 ^------------------- z = 2
            //
            // Index 2 ^------------------- z = 1

            var testMesh = new Mesh();

            testMesh.CreateFace(new Vector3[]
            {
                new Vector3(0, 0, 2),
                new Vector3(10, 0, 2),
                new Vector3(5, 5, 2)
            });

            testMesh.CreateFace(new Vector3[]
            {
                new Vector3(0, 0, 3),
                new Vector3(10, 0, 3),
                new Vector3(5, 5, 3)
            });
            testMesh.CreateFace(new Vector3[]
            {
                new Vector3(0, 0, 1),
                new Vector3(10, 0, 1),
                new Vector3(5, 5, 1)
            });

            // test they are in the right order
            {
                var root = FaceBspTree.Create(testMesh);

                Assert.IsTrue(root.Index == 1);
                Assert.IsTrue(root.BackNode.Index == 0);
                Assert.IsTrue(root.BackNode.BackNode.Index == 2);

                var renderOredrList = FaceBspTree.GetFacesInVisibiltyOrder(testMesh, root, Matrix4X4.Identity, Matrix4X4.Identity).ToList();
                Assert.IsTrue(renderOredrList[0] == 1);
                Assert.IsTrue(renderOredrList[1] == 0);
                Assert.IsTrue(renderOredrList[2] == 2);
            }
        }
示例#4
0
        public void EnsureTransparentSorting()
        {
            var localMesh = Mesh;

            if (localMesh != null &&
                localMesh.FaceBspTree == null &&
                localMesh.Faces.Count < 2000 &&
                !buildingFaceBsp)
            {
                this.buildingFaceBsp = true;
                Task.Run(() =>
                {
                    // TODO: make a SHA1 based cache for the sorting on this mesh and use them from memory or disk
                    var bspTree = FaceBspTree.Create(localMesh);
                    UiThread.RunOnIdle(() => localMesh.FaceBspTree = bspTree);
                    this.buildingFaceBsp = false;
                });
            }
        }
        public void CreatePrintBed(Vector3 displayVolume, Vector2 bedCenter, BedShape bedShape)
        {
            if (MeshViewerWidget.BedCenter == bedCenter &&
                MeshViewerWidget.bedShape == bedShape &&
                MeshViewerWidget.displayVolume == displayVolume)
            {
                return;
            }

            MeshViewerWidget.BedCenter     = bedCenter;
            MeshViewerWidget.bedShape      = bedShape;
            MeshViewerWidget.displayVolume = displayVolume;
            Vector3 displayVolumeToBuild = Vector3.ComponentMax(displayVolume, new Vector3(1, 1, 1));

            double sizeForMarking = Math.Max(displayVolumeToBuild.X, displayVolumeToBuild.Y);
            double divisor        = 10;
            int    skip           = 1;

            if (sizeForMarking > 1000)
            {
                divisor = 100;
                skip    = 10;
            }
            else if (sizeForMarking > 300)
            {
                divisor = 50;
                skip    = 5;
            }

            switch (bedShape)
            {
            case BedShape.Rectangular:
                if (displayVolumeToBuild.Z > 0)
                {
                    buildVolume = PlatonicSolids.CreateCube(displayVolumeToBuild);
                    for (int i = 0; i < buildVolume.Vertices.Count; i++)
                    {
                        buildVolume.Vertices[i] = buildVolume.Vertices[i] + new Vector3Float(0, 0, displayVolumeToBuild.Z / 2);
                    }
                    var bspTree = FaceBspTree.Create(buildVolume);
                    buildVolume.FaceBspTree = bspTree;
                }

                printerBed = PlatonicSolids.CreateCube(displayVolumeToBuild.X, displayVolumeToBuild.Y, 1.8);
                {
                    printerBed.PlaceTextureOnFace(0, BedImage);
                }
                break;

            case BedShape.Circular:
            {
                throw new NotImplementedException();
                //if (displayVolumeToBuild.Z > 0)
                //{
                //	buildVolume = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.X / 2, displayVolumeToBuild.Y / 2), displayVolumeToBuild.Z);
                //	foreach (Vertex vertex in buildVolume.Vertices)
                //	{
                //		vertex.Position = vertex.Position + new Vector3(0, 0, .2);
                //	}
                //}
                //CreateCircularBedGridImage((int)(displayVolumeToBuild.X / divisor), (int)(displayVolumeToBuild.Y / divisor), skip);
                //printerBed = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.X / 2, displayVolumeToBuild.Y / 2), 2);
                //{
                //	foreach (Face face in printerBed.Faces)
                //	{
                //		if (face.Normal.Z > 0)
                //		{
                //			face.SetTexture(0, BedImage);
                //			foreach (FaceEdge faceEdge in face.FaceEdges())
                //			{
                //				faceEdge.SetUv(0, new Vector2((displayVolumeToBuild.X / 2 + faceEdge.FirstVertex.Position.X) / displayVolumeToBuild.X,
                //					(displayVolumeToBuild.Y / 2 + faceEdge.FirstVertex.Position.Y) / displayVolumeToBuild.Y));
                //			}
                //		}
                //	}
                //}
            }
            break;

            default:
                throw new NotImplementedException();
            }

            var zTop = printerBed.GetAxisAlignedBoundingBox().MaxXYZ.Z;

            for (int i = 0; i < printerBed.Vertices.Count; i++)
            {
                printerBed.Vertices[i] = printerBed.Vertices[i] - new Vector3Float(-bedCenter, zTop + .02);
            }

            if (buildVolume != null)
            {
                for (int i = 0; i < buildVolume.Vertices.Count; i++)
                {
                    buildVolume.Vertices[i] = buildVolume.Vertices[i] - new Vector3Float(-bedCenter, zTop + .02);
                }
            }

            Invalidate();
        }
        public static (Mesh bed, Mesh volume) CreatePrintBedAndVolume(PrinterConfig printer)
        {
            Mesh printerBed  = null;
            Mesh buildVolume = null;

            Vector3 displayVolumeToBuild = Vector3.ComponentMax(printer.Bed.ViewerVolume, new Vector3(1, 1, 1));

            ImageBuffer bedplateImage = CreatePrintBedImage(printer);

            switch (printer.Bed.BedShape)
            {
            case BedShape.Rectangular:
                if (displayVolumeToBuild.Z > 0)
                {
                    buildVolume = PlatonicSolids.CreateCube(displayVolumeToBuild);
                    foreach (Vertex vertex in buildVolume.Vertices)
                    {
                        vertex.Position = vertex.Position + new Vector3(0, 0, displayVolumeToBuild.Z / 2);
                    }
                    var bspTree = FaceBspTree.Create(buildVolume);
                    buildVolume.FaceBspTree = bspTree;
                }

                printerBed = PlatonicSolids.CreateCube(displayVolumeToBuild.X, displayVolumeToBuild.Y, 1.8);
                {
                    Face face = printerBed.Faces[0];
                    MeshHelper.PlaceTextureOnFace(face, bedplateImage);
                }
                break;

            case BedShape.Circular:
            {
                if (displayVolumeToBuild.Z > 0)
                {
                    buildVolume = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.X / 2, displayVolumeToBuild.Y / 2), displayVolumeToBuild.Z);
                    foreach (Vertex vertex in buildVolume.Vertices)
                    {
                        vertex.Position = vertex.Position + new Vector3(0, 0, .2);
                    }
                }

                printerBed = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.X / 2, displayVolumeToBuild.Y / 2), 1.8);
                {
                    foreach (Face face in printerBed.Faces)
                    {
                        if (face.Normal.Z > 0)
                        {
                            face.SetTexture(0, bedplateImage);
                            foreach (FaceEdge faceEdge in face.FaceEdges())
                            {
                                faceEdge.SetUv(0, new Vector2((displayVolumeToBuild.X / 2 + faceEdge.FirstVertex.Position.X) / displayVolumeToBuild.X,
                                                              (displayVolumeToBuild.Y / 2 + faceEdge.FirstVertex.Position.Y) / displayVolumeToBuild.Y));
                            }
                        }
                    }
                }
            }
            break;

            default:
                throw new NotImplementedException();
            }

            var zTop = printerBed.GetAxisAlignedBoundingBox().maxXYZ.Z;

            foreach (Vertex vertex in printerBed.Vertices)
            {
                vertex.Position = vertex.Position - new Vector3(-printer.Bed.BedCenter, zTop + .02);
            }

            if (buildVolume != null)
            {
                foreach (Vertex vertex in buildVolume.Vertices)
                {
                    vertex.Position = vertex.Position - new Vector3(-printer.Bed.BedCenter, 2.2);
                }
            }

            return(printerBed, buildVolume);
        }
        public static (Mesh bed, Mesh volume) CreatePrintBedAndVolume(PrinterConfig printer)
        {
            Mesh printerBed  = null;
            Mesh buildVolume = null;

            Vector3 displayVolumeToBuild = Vector3.ComponentMax(printer.Bed.ViewerVolume, new Vector3(1, 1, 1));

            ImageBuffer bedplateImage = CreatePrintBedImage(printer);

            switch (printer.Bed.BedShape)
            {
            case BedShape.Rectangular:
                if (displayVolumeToBuild.Z > 0)
                {
                    buildVolume = PlatonicSolids.CreateCube(displayVolumeToBuild);
                    for (int i = 0; i < buildVolume.Vertices.Count; i++)
                    {
                        buildVolume.Vertices[i] = buildVolume.Vertices[i] + new Vector3Float(0, 0, displayVolumeToBuild.Z / 2);
                    }
                    var bspTree = FaceBspTree.Create(buildVolume);
                    buildVolume.FaceBspTree = bspTree;
                }

                printerBed = PlatonicSolids.CreateCube(displayVolumeToBuild.X, displayVolumeToBuild.Y, 1.8);
                {
                    printerBed.PlaceTextureOnFaces(0, bedplateImage);
                }
                break;

            case BedShape.Circular:
            {
                if (displayVolumeToBuild.Z > 0)
                {
                    buildVolume = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.X / 2, displayVolumeToBuild.Y / 2), displayVolumeToBuild.Z);
                }

                printerBed = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.X / 2, displayVolumeToBuild.Y / 2), 1.8);
                printerBed.PlaceTextureOnFaces(0, bedplateImage);
            }
            break;

            default:
                throw new NotImplementedException();
            }

            var zTop = printerBed.GetAxisAlignedBoundingBox().MaxXYZ.Z;

            for (int i = 0; i < printerBed.Vertices.Count; i++)
            {
                printerBed.Vertices[i] = printerBed.Vertices[i] - new Vector3Float(-printer.Bed.BedCenter, zTop + .02);
            }

            if (buildVolume != null)
            {
                for (int i = 0; i < buildVolume.Vertices.Count; i++)
                {
                    buildVolume.Vertices[i] = buildVolume.Vertices[i] - new Vector3Float(-printer.Bed.BedCenter, zTop + .02);
                }
            }

            return(printerBed, buildVolume);
        }
        public static (Mesh bed, Mesh volume) CreatePrintBedAndVolume(PrinterConfig printer)
        {
            Mesh printerBed;
            Mesh buildVolume = null;

            var displayVolumeToBuild = Vector3.ComponentMax(printer.Bed.ViewerVolume, new Vector3(1, 1, 1));

            // Temporarily assign a placeholder image as the mesh texture. This will be replaced with a themed image by the view
            var placeHolderImage = new ImageBuffer(5, 5);
            var graphics         = placeHolderImage.NewGraphics2D();

            graphics.Clear(Color.Gray.WithAlpha(40));

            switch (printer.Bed.BedShape)
            {
            case BedShape.Rectangular:
                if (displayVolumeToBuild.Z > 0)
                {
                    buildVolume = PlatonicSolids.CreateCube(displayVolumeToBuild);
                    for (int i = 0; i < buildVolume.Vertices.Count; i++)
                    {
                        buildVolume.Vertices[i] = buildVolume.Vertices[i] + new Vector3Float(0, 0, displayVolumeToBuild.Z / 2);
                    }

                    var bspTree = FaceBspTree.Create(buildVolume);
                    buildVolume.FaceBspTree = bspTree;
                }

                printerBed = PlatonicSolids.CreateCube(displayVolumeToBuild.X, displayVolumeToBuild.Y, 1.8);
                printerBed.PlaceTextureOnFaces(0, placeHolderImage);
                break;

            case BedShape.Circular:
            {
                if (displayVolumeToBuild.Z > 0)
                {
                    buildVolume = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.X / 2, displayVolumeToBuild.Y / 2), displayVolumeToBuild.Z);
                }

                printerBed = VertexSourceToMesh.Extrude(new Ellipse(new Vector2(), displayVolumeToBuild.X / 2, displayVolumeToBuild.Y / 2), 1.8);
                printerBed.PlaceTextureOnFaces(0, placeHolderImage);
            }
            break;

            default:
                throw new NotImplementedException();
            }

            var zTop = printerBed.GetAxisAlignedBoundingBox().MaxXYZ.Z;

            for (int i = 0; i < printerBed.Vertices.Count; i++)
            {
                printerBed.Vertices[i] = printerBed.Vertices[i] - new Vector3Float(-printer.Bed.BedCenter, zTop + .02);
            }

            if (buildVolume != null)
            {
                for (int i = 0; i < buildVolume.Vertices.Count; i++)
                {
                    buildVolume.Vertices[i] = buildVolume.Vertices[i] - new Vector3Float(-printer.Bed.BedCenter, zTop + .02);
                }
            }

            return(printerBed, buildVolume);
        }