/// CompositeCutter can not use the base-class facetDrop, instead we here
        /// call facetDrop() on each cutter in turn, and pick the valid CC/CL point
        /// as the result for the CompositeCutter

        //********   facetDrop  ********************** */

        // call facetDrop on each cutter and pick a valid cc-point
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#:
//ORIGINAL LINE: bool facetDrop(CLPoint &cl, const Triangle &t) const
        public new bool facetDrop(CLPoint cl, Triangle t)
        {
            bool result = false;

            for (int n = 0; n < cutter.Count; ++n)
            {             // loop through cutters
                CLPoint cl_tmp = cl + new CLPoint(0, 0, zoffset[n]);
                CCPoint cc_tmp;
                if (cutter[n].facetDrop(cl_tmp, t))
                {
                    Debug.Assert(cl_tmp.cc != null);
                    if (ccValidRadius(n, cl_tmp))
                    {                     // cc-point is valid
                        cc_tmp = new CCPoint(cl_tmp.cc);
                        if (cl.liftZ(cl_tmp.z - zoffset[n]))
                        {                         // we need to lift the cutter
                            cc_tmp.type = CCType.FACET;
                            cl.cc       = cc_tmp;
                            result      = true;
                        }
                        else
                        {
                            if (cc_tmp != null)
                            {
                                cc_tmp.Dispose();
                            }
                        }
                    }
                }
            }
            return(result);
        }
        /// call edgeDrop on each cutter and pick the correct (highest valid CL-point) result

        //********   edge **************************************************** */
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#:
//ORIGINAL LINE: bool edgeDrop(CLPoint &cl, const Triangle &t) const
        public new bool edgeDrop(CLPoint cl, Triangle t)
        {
            bool result = false;

            for (int n = 0; n < cutter.Count; ++n)
            {             // loop through cutters
                CLPoint cl_tmp = cl + new Point(0, 0, zoffset[n]);
                CCPoint cc_tmp;
                if (cutter[n].edgeDrop(cl_tmp, t))
                {                 // drop sub-cutter against edge
                    if (ccValidRadius(n, cl_tmp))
                    {             // check if cc-point is valid
                        cc_tmp = new CCPoint(cl_tmp.cc);
                        if (cl.liftZ(cl_tmp.z - zoffset[n]))
                        {                         // we need to lift the cutter
                            cc_tmp.type = CCType.EDGE;
                            cl.cc       = cc_tmp;
                            result      = true;
                        }
                        else
                        {
                            if (cc_tmp != null)
                            {
                                cc_tmp.Dispose();
                            }
                        }
                    }
                }
            }
            return(result);
        }
        /// \brief drop cutter at (cl.x, cl.y) against the three vertices of Triangle t.
        /// calls this->height(r) on the subclass of MillingCutter we are using.
        /// if cl.z is too low, updates cl.z so that cutter does not cut any vertex.

        // general purpose vertex-drop which delegates to this->height(r) of subclass
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#:
//ORIGINAL LINE: bool vertexDrop(CLPoint &cl, const Triangle &t) const
        public bool vertexDrop(CLPoint cl, Triangle t)
        {
            bool result = false;

            foreach (Point p in t.p)
            {                                // test each vertex of triangle
                double q = cl.xyDistance(p); // distance in XY-plane from cl to p
                if (q <= radius)
                {                            // p is inside the cutter
                    CCPoint cc_tmp = new CCPoint(p, CCType.VERTEX);
                    if (cl.liftZ(p.z - this.height(q), cc_tmp))
                    {
                        result = true;
                    }
                }
            }
            return(result);
        }