示例#1
0
        public static Surface ExtractSurface(Autodesk.Revit.DB.ConicalFace face, IEnumerable <PolyCurve> edgeLoops)
        {
            // Note: Internal representation of the cone
            // S(u, v) = Origin + v*[sin(HalfAngle)*(cos(u)*Radius[0] + sin(u)*Radius[1]) + cos(HalfAngle)*Axis]

            edgeLoops = edgeLoops.ToList();

            // Get some data from the face
            var axis  = face.Axis.ToVector();
            var x     = face.get_Radius(0).ToVector();
            var y     = face.get_Radius(1).ToVector();
            var tipPt = face.Origin.ToPoint();
            var ang   = face.HalfAngle;

            // We use the max length in order to help find the lowest possible base point for the cone
            var maxLength = edgeLoops.Max(pc => pc.Length);

            // We don't know the "base" point of the cone, so we build it here
            // by projecting a point on the edge loops onto the axis
            var pt         = edgeLoops.First().StartPoint;
            var dir        = pt.Subtract(tipPt.AsVector());
            var projLength = dir.AsVector().Dot(axis);
            var height     = projLength + 2 * maxLength;
            var o          = tipPt.Add(axis.Normalized().Scale(height));

            // there's not an easy way to create a conical surface in protogeometry outside of this
            // note this coordinate system has the z axis reversed because we're building the cone
            // from it's flat bottom surface
            var baseCS = CoordinateSystem.ByOriginVectors(o, x, y.Reverse());

            // Construct the radius
            var rad  = Math.Cos(ang) * height;
            var cone = Cone.ByCoordinateSystemHeightRadius(baseCS, height, rad);

            // PB: this is iffy code - we need to extract the surface that's not touching the origin
            //return cone.Faces.Select(f => f.SurfaceGeometry()).First(s => s.DistanceTo(o) > 1e-5);

            // the flat face of the cone is currently the second face in the Faces enumeration
            return(cone.Faces[1].SurfaceGeometry());
        }