//********   actual Composite-cutters  ******************************* */


        //  only constructors required, drop-cutter and push-cutter calls handled by base-class

        // TESTING
        public CompCylCutter(double diam2, double clength)
        {
            MillingCutter shaft = new CylCutter(diam2, clength);

            addCutter(shaft, diam2 / 2.0, clength, 0.0);
            length = clength;
        }
        }         // dummy, required(?) by python wrapper

        /// create cylconecutter
        public CylConeCutter(double diam1, double diam2, double angle)
        {
            MillingCutter cyl   = new CylCutter(diam1, 1);
            MillingCutter cone  = new ConeCutter(diam2, angle);
            MillingCutter shaft = new CylCutter(diam2, 20);             // FIXME: dummy height

            double cone_offset = -(diam1 / 2) / Math.Tan(angle);
            double cyl_height  = 0.0;
            double cone_height = (diam2 / 2.0) / Math.Tan(angle) + cone_offset;

            addCutter(cyl, diam1 / 2.0, cyl_height, 0.0);
            addCutter(cone, diam2 / 2.0, cone_height, cone_offset);
            addCutter(shaft, diam2 / 2.0, (diam2 / 2.0) / Math.Tan(angle) + 20, cone_height);
            length = cyl_height + cone_height + 10;             // Arbitrary 10 here!
        }
        }         // dummy, required(?) by python wrapper

        /// create cone-cone cutter with lower cone (diam1,angle1) and upper cone (diam2,angle2)
        /// we assume angle2 < angle1  and  diam2 > diam1.
        public ConeConeCutter(double diam1, double angle1, double diam2, double angle2)
        {
            MillingCutter c1    = new ConeCutter(diam1, angle1);          // at offset zero
            MillingCutter c2    = new ConeCutter(diam2, angle2);
            MillingCutter shaft = new CylCutter(diam2, 20);

            double height1      = (diam1 / 2.0) / Math.Tan(angle1);
            double tmp          = (diam1 / 2.0) / Math.Tan(angle2);
            double cone_offset  = -(tmp - height1);
            double height2      = (diam2 / 2.0) / Math.Tan(angle2) + cone_offset;
            double shaft_offset = height2;

            addCutter(c1, diam1 / 2.0, height1, 0.0);
            addCutter(c2, diam2 / 2.0, height2, cone_offset);
            addCutter(shaft, diam2 / 2.0, height2 + 20, shaft_offset);
            length = 30;
        }
        }         // dummy, required(?) by python wrapper

        /// create bullconecutter
        public BullConeCutter(double diam1, double radius1, double diam2, double angle)
        {
            MillingCutter c1    = new BullCutter(diam1, radius1, 1.0);          // at offset zero
            MillingCutter c2    = new ConeCutter(diam2, angle);
            MillingCutter shaft = new CylCutter(diam2, 20);

            double h1           = radius1 * Math.Sin(angle);     // the contact point is this much down from the toroid-ring
            double rad          = Math.Sqrt(ocl.GlobalMembers.square(radius1) - ocl.GlobalMembers.square(h1));
            double rcontact     = (diam1 / 2.0) - radius1 + rad; // radius of the contact-ring
            double cone_offset  = -(rcontact / Math.Tan(angle) - (radius1 - h1));
            double height1      = radius1 - h1;
            double height2      = (diam2 / 2.0) / Math.Tan(angle) + cone_offset;
            double shaft_offset = height2;

            addCutter(c1, rcontact, height1, 0.0);
            addCutter(c2, diam2 / 2.0, height2, cone_offset);
            addCutter(shaft, diam2 / 2.0, height2 + 20, shaft_offset);
            length = 30;
        }
        }         // dummy, required(?) by python wrapper

        /// create ballconecutter
        public BallConeCutter(double diam1, double diam2, double angle)
        {
            MillingCutter c1    = new BallCutter(diam1, 1);          // at offset zero
            MillingCutter c2    = new ConeCutter(diam2, angle);
            MillingCutter shaft = new CylCutter(diam2, 20);          // FIXME: length

            double radius1      = diam1 / 2.0;
            double radius2      = diam2 / 2.0;
            double rcontact     = radius1 * Math.Cos(angle);
            double height1      = radius1 - Math.Sqrt(ocl.GlobalMembers.square(radius1) - ocl.GlobalMembers.square(rcontact));
            double cone_offset  = -((rcontact) / Math.Tan(angle) - height1);
            double height2      = radius2 / Math.Tan(angle) + cone_offset;
            double shaft_offset = height2;

            // cutter, radivec, heightvec, zoffset
            addCutter(c1, rcontact, height1, 0.0);
            addCutter(c2, diam2 / 2.0, height2, cone_offset);
            addCutter(shaft, diam2 / 2.0, height2 + 20, shaft_offset);
            length = 30;
        }