private bool GetFaceGeometry(Face face, out List <int> faceIndices, out List <int> faceVertices, out List <double> faceNormals, out XYZ centerPoint) { bool result = false; faceIndices = new List <int>(); faceVertices = new List <int>(); faceNormals = new List <double>(); centerPoint = new XYZ(); try { BoundingBoxUV bb = face.GetBoundingBox(); UV midUV = new UV((bb.Max.U - bb.Min.U) / 2, (bb.Max.V - bb.Min.V) / 2); centerPoint = face.Evaluate(midUV); Mesh mesh = m_face.Triangulate(); int nTriangles = mesh.NumTriangles; IList <XYZ> vertices = mesh.Vertices; int nVertices = vertices.Count; List <int> vertexCoordsMm = new List <int>(3 * nVertices); foreach (XYZ v in vertices) { vertexCoordsMm.Add(ConverterUtil.FootToMm(v.X)); vertexCoordsMm.Add(ConverterUtil.FootToMm(v.Y)); vertexCoordsMm.Add(ConverterUtil.FootToMm(v.Z)); } int[] triangleIndices = new int[3]; XYZ[] triangleCorners = new XYZ[3]; for (int i = 0; i < nTriangles; ++i) { faceIndices.Add(2); //triangle with material MeshTriangle triangle = mesh.get_Triangle(i); for (int j = 0; j < 3; ++j) { int k = (int)triangle.get_Index(j); triangleIndices[j] = k; triangleCorners[j] = vertices[k]; } // Calculate constant triangle facet normal. XYZ v = triangleCorners[1] - triangleCorners[0]; XYZ w = triangleCorners[2] - triangleCorners[0]; XYZ triangleNormal = v .CrossProduct(w) .Normalize(); for (int j = 0; j < 3; ++j) { int nFaceVertices = faceVertices.Count; faceIndices.Add(nFaceVertices / 3); int i3 = triangleIndices[j] * 3; // Rotate the X, Y and Z directions, // since the Z direction points upward // in Revit as opposed to sideways or // outwards or forwards in WebGL. faceVertices.Add(vertexCoordsMm[i3 + 1]); faceVertices.Add(vertexCoordsMm[i3 + 2]); faceVertices.Add(vertexCoordsMm[i3]); UV uv = m_face.Project( triangleCorners[j]).UVPoint; XYZ normal = m_face.ComputeNormal(uv); faceNormals.Add(normal.Y); faceNormals.Add(normal.Z); faceNormals.Add(normal.X); } faceIndices.Add(0); } result = true; } catch (Exception ex) { string message = "Cannot get face geometry: " + ex.Message; } return(result); }
private void WriteFaceJson(Face face) { try { List <int> fIndices = new List <int>(); List <int> fVertices = new List <int>(); List <double> fNormals = new List <double>(); XYZ centerPoint = null; if (GetFaceGeometry(face, out fIndices, out fVertices, out fNormals, out centerPoint)) { Color randomColor = new Color((byte)random.Next(0, 255), (byte)random.Next(0, 255), (byte)random.Next(0, 255)); int colorVal = ConverterUtil.ColorToInt(randomColor); JsonContainer.JsMaterial jsMaterial = new JsonContainer.JsMaterial(); jsMaterial.uuid = Guid.NewGuid().ToString(); jsMaterial.type = "MeshPhongMaterial"; jsMaterial.name = "AVF Material"; jsMaterial.color = colorVal; jsMaterial.ambient = colorVal; jsMaterial.emissive = 0; jsMaterial.specular = colorVal; jsMaterial.shininess = 1; jsMaterial.opacity = 1; jsMaterial.transparent = false; jsMaterial.wireframe = false; container.materials.Add(jsMaterial); JsonContainer.JsGeometry jsGeometry = new JsonContainer.JsGeometry(); jsGeometry.uuid = Guid.NewGuid().ToString(); jsGeometry.type = "Geometry"; jsGeometry.data = new JsonContainer.JsGeometryData(); jsGeometry.data.faces = new List <int>(); jsGeometry.data.vertices = new List <int>(); jsGeometry.data.normals = new List <double>(); jsGeometry.data.uvs = new List <double>(); jsGeometry.data.visible = true; jsGeometry.data.castShadow = true; jsGeometry.data.receiveShadow = false; jsGeometry.data.doubleSided = true; jsGeometry.data.scale = 1; jsGeometry.data.faces = fIndices; jsGeometry.data.vertices = fVertices; jsGeometry.data.normals = fNormals; container.geometries.Add(jsGeometry); JsonContainer.JsObject avfElement = new JsonContainer.JsObject(); avfElement.uuid = Guid.NewGuid().ToString(); avfElement.matrix = new double[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; avfElement.type = "RevitElement"; avfElement.material = jsMaterial.uuid; avfElement.userData = new Dictionary <string, string>(); avfElement.userData.Add("AVFReference", refString); avfElement.userData.Add("PointX", ConverterUtil.FootToMm(centerPoint.X).ToString()); avfElement.userData.Add("PointY", ConverterUtil.FootToMm(centerPoint.Y).ToString()); avfElement.userData.Add("PointZ", ConverterUtil.FootToMm(centerPoint.Z).ToString()); //avfElement.userData.Add("AnalysisValue", ""); avfElement.children = new List <JsonContainer.JsObject>(); JsonContainer.JsObject meshObj = new JsonContainer.JsObject(); meshObj.name = "AVF Mesh"; meshObj.geometry = jsGeometry.uuid; meshObj.matrix = new double[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; meshObj.type = "Mesh"; meshObj.uuid = Guid.NewGuid().ToString(); meshObj.material = jsMaterial.uuid; avfElement.children.Add(meshObj); container.obj.children.Add(avfElement); } } catch (Exception ex) { string message = "Cannot write face data: " + ex.Message; } }