public static Surface ExtractSurface(Autodesk.Revit.DB.HermiteFace face, IEnumerable<PolyCurve> edgeLoops) { // The number of interpolating points in the u direction is given by get_Params var uParams = face.get_Params(0).Cast<double>().ToArray(); var vParams = face.get_Params(1).Cast<double>().ToArray(); var numU = uParams.Length; var numV = vParams.Length; // unpack the points var points = face.Points; // structure the points as 2d array - numU x numV var ptArr = new Autodesk.DesignScript.Geometry.Point[numV][]; var count = 0; for (var i = 0; i < numV; i++) { ptArr[i] = new Autodesk.DesignScript.Geometry.Point[numU]; for (var j = 0; j < numU; j++) { ptArr[i][j] = points[count++].ToPoint(false); } } // unpack the tangents var uTangents = face.get_Tangents(0); var vTangents = face.get_Tangents(1); // structure the tangents as 2d array - numU x numV var uTangentsArr = new Vector[numV][]; var vTangentsArr = new Vector[numV][]; count = 0; for (var i = 0; i < numV; i++) { uTangentsArr[i] = new Vector[numU]; vTangentsArr[i] = new Vector[numU]; for (var j = 0; j < numU; j++) { uTangentsArr[i][j] = uTangents[count].ToVector(false); vTangentsArr[i][j] = vTangents[count].ToVector(false); count++; } } // u tangents run in increasing column direction var uStartTangents = uTangentsArr.Select(x => x[0]).ToArray(); var uEndTangents = uTangentsArr.Select(x => x[numU - 1]).ToArray(); // v tangents run in increasing row direction var vStartTangents = vTangentsArr[0]; var vEndTangents = vTangentsArr[numV-1]; // The mixed derivs are the twist vectors - dP / dUdV var md = face.MixedDerivs; Vector[] mds = { md[0].ToVector(false), md[numU - 1].ToVector(false), md[(md.Count - 1) - (numU-1)].ToVector(false), md[md.Count - 1].ToVector(false) }; return NurbsSurface.ByPointsTangentsKnotsDerivatives( ptArr, uStartTangents, uEndTangents, vStartTangents, vEndTangents, HermiteToNurbs.Clamp(uParams), HermiteToNurbs.Clamp(vParams), mds); }