public void TriangulateFace(Autodesk.Revit.DB.Face vFace, Transform instTransform) { try { //setup utility class LuxExporter.UnitConverter Converter = new UnitConverter(); //process face Mesh vMesh = vFace.Triangulate(); //check if we have a quad mesh (4 edges to a face) if (vMesh.Vertices.Count == 4) { //increase face counter iNumberOfFaces++; //found quad Data.NumberOfVerticesinFace = 4; //loop through all vertices and add foreach (XYZ ii in vMesh.Vertices) { XYZ point = ii; XYZ transformedPoint; //transform geometry (only required in nested families / or elements like baluster if (instTransform == null) { transformedPoint = point; } else { transformedPoint = instTransform.OfPoint(point); } //get the normal XYZ NormalAtPoint; IntersectionResult IntResult= vFace.Project(ii); if (IntResult != null) { UV UVatPoint = IntResult.UVPoint; NormalAtPoint = new XYZ(vFace.ComputeNormal(UVatPoint).X, vFace.ComputeNormal(UVatPoint).Y, vFace.ComputeNormal(UVatPoint).Z); } else { //this needs fixing!!! NormalAtPoint = new XYZ(0, 0, 0); } //convert to meter transformedPoint = Converter.ConvertPointCoordToMeter(transformedPoint); //NormalAtPoint = Converter.ConvertPointCoordToMeter(NormalAtPoint); //add to ply class Data.AddVertice(transformedPoint,NormalAtPoint); } } else { // set pointer Data.NumberOfVerticesinFace = 3; //export all triangles in face for (int i = 0; i < vMesh.NumTriangles; i++) { //increase face counter iNumberOfFaces++; MeshTriangle objTriangular = vMesh.get_Triangle(i); for (int iPointsCounter = 0; iPointsCounter < 3; iPointsCounter++) { XYZ point = objTriangular.get_Vertex(iPointsCounter); XYZ transformedPoint; //transform geometry (only required in nested families / or elements like baluster if (instTransform == null) { transformedPoint = point; } else { transformedPoint = instTransform.OfPoint(point); } XYZ NormalAtPoint; //get the normal IntersectionResult IntResult = vFace.Project(point); if (IntResult!=null) { UV UVatPoint = IntResult.UVPoint; NormalAtPoint = new XYZ(vFace.ComputeNormal(UVatPoint).X,vFace.ComputeNormal(UVatPoint).Y,vFace.ComputeNormal(UVatPoint).Z); } else { //this needs fixing NormalAtPoint = new XYZ(0, 0, 0); } //convert to meter transformedPoint = Converter.ConvertPointCoordToMeter(transformedPoint); //NormalAtPoint = Converter.ConvertPointCoordToMeter(NormalAtPoint); //add to ply class Data.AddVertice(transformedPoint,NormalAtPoint); } } } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show("Error in module PLY_by_material::TriangulateMesh "+ex.Message); throw; } }
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; }