protected void generate(float fDiameter, float fHeight, float fWallThickness, float fBaseThickness)
        {
            base.reset_holes();

            CappedCylinderGenerator outer_cylgen = new CappedCylinderGenerator()
            {
                BaseRadius = fDiameter / 2, TopRadius = fDiameter / 2,
                Height     = fHeight + 10,
                Slices     = 60,
                Clockwise  = true
            };
            DMesh3 outer_mesh = outer_cylgen.Generate().MakeDMesh();

            float fInnerDiam = fDiameter - 2 * fWallThickness;
            CappedCylinderGenerator inner_cylgen = new CappedCylinderGenerator()
            {
                BaseRadius = fInnerDiam / 2, TopRadius = fInnerDiam / 2,
                Height     = fHeight + 10,
                Slices     = 60,
                Clockwise  = false
            };
            DMesh3 inner_mesh = inner_cylgen.Generate().MakeDMesh();

            MeshTransforms.Translate(inner_mesh, fBaseThickness * Vector3d.AxisY);

            DMesh3[] meshes = new DMesh3[2] {
                outer_mesh, inner_mesh
            };

            foreach (DMesh3 mesh in meshes)
            {
                Remesher r = new Remesher(mesh);
                r.SetTargetEdgeLength(TargetEdgeLength);
                r.SmoothSpeedT = 0.5f;
                r.SetExternalConstraints(new MeshConstraints());
                MeshConstraintUtil.FixAllGroupBoundaryEdges(r.Constraints, mesh, true);
                r.SetProjectionTarget(MeshProjectionTarget.Auto(mesh));
                for (int k = 0; k < 10; ++k)
                {
                    r.BasicRemeshPass();
                }
            }

            Vector3d vCutPos    = new Vector3d(0, fHeight, 0);
            Vector3d vCutNormal = Vector3d.AxisY;

            foreach (DMesh3 mesh in meshes)
            {
                MeshPlaneCut cut = new MeshPlaneCut(mesh, new Vector3d(0, fHeight, 0), Vector3d.AxisY);
                cut.Cut();
            }

            base.set_output_meshes(inner_mesh, outer_mesh);
        }