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(false); var x = face.get_Radius(0).ToVector(false); var y = face.get_Radius(1).ToVector(false); var tipPt = face.Origin.ToPoint(false); 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(); }
public static Surface ExtractSurface(Autodesk.Revit.DB.CylindricalFace face, IEnumerable<PolyCurve> edgeLoops) { // Note: Internal representation of the cylinder // S(u, v) = Origin + cos(u)*Radius[0] + sin(u)*Radius[1] + v*Axis edgeLoops = edgeLoops.ToList(); // Get some data from the face var axis = face.Axis.ToVector(false); var x = face.get_Radius(0).ToVector(false); var y = face.get_Radius(1).ToVector(false); var rad = x.Length; var oax = face.Origin.ToPoint(false); // project closest point on edge loop onto axis // this gives a more reliable origin as the revit origin // could be anywhere on the axis var pt = edgeLoops.First().StartPoint; var dir = pt.Subtract( oax.AsVector() ); var projLength = dir.AsVector().Dot(axis); var o = oax.Add(axis.Normalized().Scale(projLength)); // We don't know the start and end point of the cylindrical surface // so we use the maxLength of the edgeLoops as a conservative guess var maxLength = edgeLoops.Max(pc => pc.Length); // Get the "base point" of the cylinder var basePoint = o.Add(axis.Reverse().Scale(2 * maxLength)); // Build the "base circle" of the cylinder var pl1 = Autodesk.DesignScript.Geometry.Plane.ByOriginXAxisYAxis(basePoint, x.Normalized(), y.Normalized()); var c1 = Circle.ByPlaneRadius(pl1, rad); // extrude the cylindrical surface - again using the conservative maxLength return c1.Extrude(axis.Scale(4*maxLength)); }
public static Surface ExtractSurface(Autodesk.Revit.DB.RevolvedFace face, IEnumerable<PolyCurve> edgeLoops) { var crv = face.Curve.ToProtoType(false); var axis = face.Axis.ToVector(false); var o = face.Origin.ToVector(false); var x = face.get_Radius(0).ToVector(false); var y = face.get_Radius(1).ToVector(false); // Note: The profile curve is represented in the coordinate system of the revolve // so we need to transform it into the global coordinate system var revolveCs = CoordinateSystem.Identity(); var globalCs = CoordinateSystem.ByOriginVectors(o.AsPoint(), x, y); var crvTrf = (Autodesk.DesignScript.Geometry.Curve)crv.Transform(revolveCs, globalCs); var srf = Surface.ByRevolve(crvTrf, o.AsPoint(), axis.Normalized(), 0, 360) .FlipNormalDirection(); var ptOnSrf = srf.PointAtParameter(0.5, 0.5); var projRes = face.Project(ptOnSrf.ToXyz()); if (projRes == null) return srf; var uvOnFace = projRes.UVPoint; var normOnFace = face.ComputeNormal(uvOnFace).ToVector(); var normOnSrf = srf.NormalAtParameter(0.5, 0.5); // if the normal is reversed, reverse the surface if (normOnFace.Dot(normOnSrf) < 0) return srf.FlipNormalDirection(); return srf; }
public static Surface ExtractSurface(Autodesk.Revit.DB.RevolvedFace face, IEnumerable<PolyCurve> edgeLoops) { var crv = face.Curve.ToProtoType(); var axis = face.Axis.ToVector(); var o = face.Origin.ToVector(); var x = face.get_Radius(0).ToVector(); var y = face.get_Radius(1).ToVector(); // Note: The profile curve is represented in the coordinate system of the revolve // so we need to transform it into the global coordinate system var revolveCs = CoordinateSystem.Identity(); var globalCs = CoordinateSystem.ByOriginVectors(o.AsPoint(), x, y); crv = (Autodesk.DesignScript.Geometry.Curve) crv.Transform(revolveCs, globalCs); return Surface.ByRevolve(crv, o.AsPoint(), axis.Normalized(), 0, 360); }