How do I create a Frustum as a node?

How do I create a Frustum as a node that I can add to a scene? For example:

var frustum = new Frustum();

var tr = scene.RootNode.CreateChildNode(frustum).Transform;
tr.Scale = new Vector3(obj.Width, obj.Height, 3);  // for example

I want to create a right square solid frustum that can be exported to an STL file.

@ssides0123

We are checking it and will get back to your shortly.

@ssides0123

Frustum is not a solid entity, it’s the base class of Camera or Light, so this is impossible to import it to STL format. You can export the Box object to .stl, Box has width, height and length.

OK, but in the example TransformationToNodeByTransformationMatrix a cube is created, and a TransformMatrix is applied. The result is simply a cube. I’m not seeing a description of the TransformMatrix in the documentation. Is it possible to use it to transform a new Node(“cube”) into the shape of a right square frustum (a pyramid with the top cut off)?

@ssides0123

Can you please share the complete code snippet that you have tried so far? We will further proceed to assist you accordingly.

I have two issues. 1) I’m not sure how to build the code pasted below, and 2) I don’t know what the numbers mean in cubeNode.Transform.TransformMatrix.

I forked this repository GitHub - aspose-3d/Aspose.3D-for-.NET: Aspose.3D for .NET examples, plugins and showcases to GitHub - ssides/Aspose.3D-for-.NET: Aspose.3D for .NET examples, plugins and showcases and found the following code in …\Aspose.3D-for-.NET\Examples\CSharp\Geometry-and-Hierarchy\TransformationToNodeByTransformationMatrix.cs.

Scene scene = new Scene();

Node cubeNode = new Node("cube");

// [my comment: The name 'Common' does not exist in the current context
// and I'm not sure how to add it. ]
Mesh mesh = Common.CreateMeshUsingPolygonBuilder();

cubeNode.Entity = mesh;

cubeNode.Transform.TransformMatrix = new Matrix4(
    1, -0.3, 0, 0,
    0.4, 1, 0.3, 0,
    0, 0, 1, 0,
    0, 20, 0, 1
);

scene.RootNode.ChildNodes.Add(cubeNode);

scene.Save(_outputPath, FileFormat.STLASCII);

In Visual Studio 2022 17.4.4 I created a new .NET 6.0 console application. I used NuGet to install package Aspose.3D. But when I paste the code from the example, it can’t find Common.CreateMeshUsingPolygonBuilder(), and I don’t know how to add it.
I tried the same thing in Visual Studio 2017 with a .NET Framework 4.8 console application. Same issue.

We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

  Issue ID(s): THREEDNET-1323

You can obtain Paid Support services if you need support on a priority basis, along with the direct access to our Paid Support management team.

@ssides0123

Please check and use the below code snippet to achieve your requirements.

// <summary>
        /// Generate a Frustum facing +Z axis
        /// </summary>
        /// <param name="fovX">Field of view in X axis, measured in degrees</param>
        /// <param name="fovY">Field of view in Y axis, measured in degrees</param>
        /// <param name="near">Distance from eye to near plane</param>
        /// <param name="far">Distance from eye to far plane</param>
        /// <returns></returns>
        private static Mesh GenerateFrustum(float fovX, float fovY, float near, float far)
        {
            var cosX = Math.Cos(fovX / 2 / 180 * Math.PI);
            var cosY = Math.Cos(fovY / 2 / 180 * Math.PI);
            var nx = near / cosX;
            var ny = near / cosY;
            var fx = far / cosX;
            var fy = far / cosY;
            var mesh = new Mesh();
            //control points of near plane corners
            mesh.ControlPoints.Add(new Vector4(nx, ny, near));
            mesh.ControlPoints.Add(new Vector4(-nx, ny, near));
            mesh.ControlPoints.Add(new Vector4(-nx, -ny, near));
            mesh.ControlPoints.Add(new Vector4(nx, -ny, near));

            //control points of far plane corners
            mesh.ControlPoints.Add(new Vector4(fx, fy, far));
            mesh.ControlPoints.Add(new Vector4(-fx, fy, far));
            mesh.ControlPoints.Add(new Vector4(-fx, -fy, far));
            mesh.ControlPoints.Add(new Vector4(fx, -fy, far));

            mesh.CreatePolygon(0, 1, 2, 3);//near plane
            mesh.CreatePolygon(4, 5, 6, 7);//far plane
            mesh.CreatePolygon(0, 4, 5, 1);//top plane
            mesh.CreatePolygon(3, 2, 6, 7);//bottom plane
            mesh.CreatePolygon(1, 5, 6, 2);//left plane
            mesh.CreatePolygon(0, 3, 7, 4);//right plane

            return mesh;
        }
        private static void FrustumTest()
        {
            var f = GenerateFrustum(45, 45, 10, 20); //Generate a frustum solid geometry with field of view 45degree on both x/y axis and near plane is 10, far plane is 20
            new Scene(f).Save("frustum.stl");

        }

It looks good in the STL, but the gltf is not showing it as solid. I have not tried sending it off to be 3D printed.

internal class CreateFrustum
{
    private string _outputPath;

    public CreateFrustum(string outputPath)
    {
        _outputPath = outputPath;
    }

    public void CreateAndSave()
    {
        Scene scene = new Scene();

        var mesh = GenerateFrustumMesh(45, 45, 10, 20);

        Node frustum = scene.RootNode.CreateChildNode("frustum", mesh);

        scene.Save(_outputPath, FileFormat.STLASCII);

        scene.Save(Utilities.GetOutputPath(_outputPath, ".gltf"), Utilities.GetGLTFSaveOptions());
    }

    // <summary>
    /// Generate a Frustum facing +Z axis
    /// </summary>
    /// <param name="fovX">Field of view in X axis, measured in degrees</param>
    /// <param name="fovY">Field of view in Y axis, measured in degrees</param>
    /// <param name="near">Distance from eye to near plane</param>
    /// <param name="far">Distance from eye to far plane</param>
    /// <returns></returns>
    private Mesh GenerateFrustumMesh(float fovX, float fovY, float near, float far)
    {
        var cosX = Math.Cos(fovX / 2 / 180 * Math.PI);
        var cosY = Math.Cos(fovY / 2 / 180 * Math.PI);
        var nx = near / cosX;
        var ny = near / cosY;
        var fx = far / cosX;
        var fy = far / cosY;
        var mesh = new Mesh();
        //control points of near plane corners
        mesh.ControlPoints.Add(new Vector4(nx, ny, near));
        mesh.ControlPoints.Add(new Vector4(-nx, ny, near));
        mesh.ControlPoints.Add(new Vector4(-nx, -ny, near));
        mesh.ControlPoints.Add(new Vector4(nx, -ny, near));

        //control points of far plane corners
        mesh.ControlPoints.Add(new Vector4(fx, fy, far));
        mesh.ControlPoints.Add(new Vector4(-fx, fy, far));
        mesh.ControlPoints.Add(new Vector4(-fx, -fy, far));
        mesh.ControlPoints.Add(new Vector4(fx, -fy, far));

        mesh.CreatePolygon(0, 1, 2, 3);//near plane
        mesh.CreatePolygon(4, 5, 6, 7);//far plane
        mesh.CreatePolygon(0, 4, 5, 1);//top plane
        mesh.CreatePolygon(3, 2, 6, 7);//bottom plane
        mesh.CreatePolygon(1, 5, 6, 2);//left plane
        mesh.CreatePolygon(0, 3, 7, 4);//right plane

        return mesh;
    }

    private void FrustumTest()
    {
        var f = GenerateFrustumMesh(45, 45, 10, 20); //Generate a frustum solid geometry with field of view 45degree on both x/y axis and near plane is 10, far plane is 20
        new Scene(f).Save("frustum.stl");

    }
}

internal static GltfSaveOptions GetGLTFSaveOptions()
{
    GltfSaveOptions opt = new GltfSaveOptions(FileContentType.ASCII);
    opt.EmbedAssets = true;
    opt.UseCommonMaterials = true;
    opt.BufferFile = "gltfBuffer.bin";
    return opt;
}

I made three copies of it and mounted them on top of a box node and sent the STL off for 3D printing. I’ll reply here if it could be 3D printed successfully.

Scene scene = new Scene();
var box = new Box();
var mesh = GenerateFrustumMesh(45, 45, 10, 20);

var tr = scene.RootNode.CreateChildNode("frustum", mesh).Transform;
tr.Scale = new Vector3(0.3, 0.3, 0.3);
tr.Translation = new Vector3(-10, -10, -7);

tr = scene.RootNode.CreateChildNode("frustum2", mesh).Transform;
tr.Scale = new Vector3(0.3, 0.3, 0.3);
tr.Translation = new Vector3(-20, -20, -7);

tr = scene.RootNode.CreateChildNode("frustum3", mesh).Transform;
tr.Scale = new Vector3(0.3, 0.3, 0.3);
tr.Translation = new Vector3(-30, -30, -7);

tr = scene.RootNode.CreateChildNode(box).Transform;
tr.Scale = new Vector3(50, 50, 3);
tr.Translation = new Vector3(-25, -25, 0);

scene.Save(_outputPath, FileFormat.STLASCII);

@ssides0123

We have updated the ticket information accordingly and recorded your feedback. We will further check it and let you know once we have some updates.

This STL file 3D printed by https://craftcloud3d.com/ perfectly. Thank you so much.

@ssides0123

It is nice to know that your issue has been resolved. Please feel free to create a new topic in case you need further assistance.