public Mesh MeshToSpeckle(DB.Mesh mesh, string units = null) { var vertices = new List <double>(mesh.Vertices.Count * 3); foreach (var vert in mesh.Vertices) { vertices.AddRange(PointToSpeckle(vert).ToList()); } var faces = new List <int>(mesh.NumTriangles * 4); for (int i = 0; i < mesh.NumTriangles; i++) { var triangle = mesh.get_Triangle(i); var A = triangle.get_Index(0); var B = triangle.get_Index(1); var C = triangle.get_Index(2); faces.Add(0); faces.AddRange(new int[] { (int)A, (int)B, (int)C }); } var u = units ?? ModelUnits; var speckleMesh = new Mesh(vertices, faces, units: u); return(speckleMesh); }
// This is to support raw geometry being sent to Revit (eg from rhino, gh, autocad...) public ApplicationPlaceholderObject DirectShapeToNative(Mesh mesh, BuiltInCategory cat = BuiltInCategory.OST_GenericModel) { // if it comes from GH it doesn't have an applicationId, the use the hash id if (mesh.applicationId == null) { mesh.applicationId = mesh.id; } var docObj = GetExistingElementByApplicationId(mesh.applicationId); //just create new one if (docObj != null) { Doc.Delete(docObj.Id); } var converted = new List <GeometryObject>(); var rMesh = MeshToNative(mesh); converted.AddRange(rMesh); var catId = Doc.Settings.Categories.get_Item(cat).Id; var revitDs = DB.DirectShape.CreateElement(Doc, catId); revitDs.ApplicationId = mesh.applicationId; revitDs.ApplicationDataId = Guid.NewGuid().ToString(); revitDs.SetShape(converted); revitDs.Name = "Mesh " + mesh.applicationId; return(new ApplicationPlaceholderObject { applicationId = mesh.applicationId, ApplicationGeneratedId = revitDs.UniqueId, NativeObject = revitDs }); }
public Mesh MeshToSpeckle(DB.Mesh mesh, string units = null) { var speckleMesh = new Mesh(); foreach (var vert in mesh.Vertices) { var vertex = PointToSpeckle(vert); speckleMesh.vertices.AddRange(new double[] { vertex.x, vertex.y, vertex.z }); } for (int i = 0; i < mesh.NumTriangles; i++) { var triangle = mesh.get_Triangle(i); var A = triangle.get_Index(0); var B = triangle.get_Index(1); var C = triangle.get_Index(2); speckleMesh.faces.Add(0); speckleMesh.faces.AddRange(new int[] { (int)A, (int)B, (int)C }); } speckleMesh.units = units ?? ModelUnits; return(speckleMesh); }
public DS.Mesh MeshToNative(Mesh mesh) { var points = ArrayToPointList(mesh.vertices, mesh.units); List <IndexGroup> faces = new List <IndexGroup>(); int i = 0; while (i < mesh.faces.Count) { if (mesh.faces[i] == 0) { // triangle var ig = IndexGroup.ByIndices((uint)mesh.faces[i + 1], (uint)mesh.faces[i + 2], (uint)mesh.faces[i + 3]); faces.Add(ig); i += 4; } else { // quad var ig = IndexGroup.ByIndices((uint)mesh.faces[i + 1], (uint)mesh.faces[i + 2], (uint)mesh.faces[i + 3], (uint)mesh.faces[i + 4]); faces.Add(ig); i += 5; } } var dsMesh = DS.Mesh.ByPointsFaceIndices(points, faces); dsMesh.SetDynamoProperties <DS.Mesh>(GetDynamicMembersFromBase(mesh)); return(dsMesh); }
private Mesh SolidToSpeckleMesh(Solid solid) { var mesh = new Mesh(); (mesh.faces, mesh.vertices) = GetFaceVertexArrFromSolids(new List <Solid> { solid }); mesh.units = ModelUnits; return(mesh); }
// Insipred by // https://github.com/DynamoDS/DynamoRevit/blob/master/src/Libraries/RevitNodes/GeometryConversion/ProtoToRevitMesh.cs public IList <GeometryObject> MeshToNative(Mesh mesh) { TessellatedShapeBuilderTarget target = TessellatedShapeBuilderTarget.Mesh; TessellatedShapeBuilderFallback fallback = TessellatedShapeBuilderFallback.Salvage; var tsb = new TessellatedShapeBuilder() { Fallback = fallback, Target = target, GraphicsStyleId = ElementId.InvalidElementId }; tsb.OpenConnectedFaceSet(false); var vertices = ArrayToPoints(mesh.vertices, mesh.units); int i = 0; while (i < mesh.faces.Count) { var points = new List <XYZ>(); if (mesh.faces[i] == 0) { // triangle points = new List <XYZ> { vertices[mesh.faces[i + 1]], vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 3]] }; var face = new TessellatedFace(points, ElementId.InvalidElementId); tsb.AddFace(face); i += 4; } else { // quad points = new List <XYZ> { vertices[mesh.faces[i + 1]], vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 4]] }; var face1 = new TessellatedFace(points, ElementId.InvalidElementId); tsb.AddFace(face1); points = new List <XYZ> { vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 3]], vertices[mesh.faces[i + 4]] }; var face2 = new TessellatedFace(points, ElementId.InvalidElementId); tsb.AddFace(face2); i += 5; } } tsb.CloseConnectedFaceSet(); tsb.Build(); var result = tsb.GetBuildResult(); return(result.GetGeometricalObjects()); }
/// <summary> /// Converts a Speckle mesh to a GameObject with a mesh renderer /// </summary> /// <param name="speckleMesh"></param> /// <returns></returns> public Mesh MeshToSpeckle(GameObject go) { //TODO: support multiple filters? var filter = go.GetComponent <MeshFilter>(); if (filter == null) { return(null); } //convert triangle array into speckleMesh faces List <int> faces = new List <int>(); int i = 0; //store them here, makes it like 1000000x faster? var triangles = filter.mesh.triangles; while (i < triangles.Length) { faces.Add(0); faces.Add(triangles[i + 0]); faces.Add(triangles[i + 2]); faces.Add(triangles[i + 1]); i += 3; } var mesh = new Mesh(); // get the speckle data from the go here // so that if the go comes from speckle, typed props will get overridden below AttachUnityProperties(mesh, go); mesh.units = ModelUnits; var vertices = filter.mesh.vertices; foreach (var vertex in vertices) { var p = go.transform.TransformPoint(vertex); var sp = PointToSpeckle(p); mesh.vertices.Add(sp.x); mesh.vertices.Add(sp.y); mesh.vertices.Add(sp.z); } mesh.faces = faces; return(mesh); }
// Meshes public Mesh MeshToSpeckle(DS.Mesh mesh, string units = null) { var u = units ?? ModelUnits; var vertices = PointListToFlatArray(mesh.VertexPositions); var defaultColour = System.Drawing.Color.FromArgb(255, 100, 100, 100); var faces = mesh.FaceIndices.SelectMany(f => { if (f.Count == 4) { return(new int[5] { 1, (int)f.A, (int)f.B, (int)f.C, (int)f.D }); } else { return(new int[4] { 0, (int)f.A, (int)f.B, (int)f.C }); } }) .ToArray(); var colors = Enumerable.Repeat(defaultColour.ToArgb(), vertices.Count()).ToArray(); //double[] textureCoords; //if (SpeckleRhinoConverter.AddMeshTextureCoordinates) //{ // textureCoords = mesh.TextureCoordinates.Select(pt => pt).ToFlatArray(); // return new SpeckleMesh(vertices, faces, Colors, textureCoords, properties: mesh.UserDictionary.ToSpeckle()); //} var speckleMesh = new Mesh(vertices, faces, colors, units: u); CopyProperties(speckleMesh, mesh); using (var box = ComputeMeshBoundingBox(mesh)) speckleMesh.bbox = BoxToSpeckle(box, u); return(speckleMesh); }
public RH.Mesh MeshToNative(Mesh mesh) { RH.Mesh m = new RH.Mesh(); m.Vertices.AddVertices(PointListToNative(mesh.vertices, mesh.units)); int i = 0; while (i < mesh.faces.Count) { if (mesh.faces[i] == 0) { // triangle m.Faces.AddFace(new MeshFace(mesh.faces[i + 1], mesh.faces[i + 2], mesh.faces[i + 3])); i += 4; } else { // quad m.Faces.AddFace(new MeshFace(mesh.faces[i + 1], mesh.faces[i + 2], mesh.faces[i + 3], mesh.faces[i + 4])); i += 5; } } try { m.VertexColors.AppendColors(mesh.colors.Select(c => System.Drawing.Color.FromArgb((int)c)).ToArray()); } catch { } if (mesh.textureCoordinates != null) { for (int j = 0; j < mesh.textureCoordinates.Count; j += 2) { m.TextureCoordinates.Add(mesh.textureCoordinates[j], mesh.textureCoordinates[j + 1]); } } return(m); }
public Mesh MeshToSpeckle(DB.Mesh mesh) { var speckleMesh = new Mesh(); foreach (var vert in mesh.Vertices) { speckleMesh.vertices.AddRange(new double[] { ScaleToSpeckle(vert.X), ScaleToSpeckle(vert.Y), ScaleToSpeckle(vert.Z) }); } for (int i = 0; i < mesh.NumTriangles; i++) { var triangle = mesh.get_Triangle(i); var A = triangle.get_Index(0); var B = triangle.get_Index(1); var C = triangle.get_Index(2); speckleMesh.faces.Add(0); speckleMesh.faces.AddRange(new int[] { (int)A, (int)B, (int)C }); } speckleMesh.units = ModelUnits; return(speckleMesh); }
// Meshes public Mesh MeshToSpeckle(RH.Mesh mesh, string units = null) { var u = units ?? ModelUnits; var verts = PointsToFlatArray(mesh.Vertices.ToPoint3dArray()); var Faces = mesh.Faces.SelectMany(face => { if (face.IsQuad) { return new int[] { 1, face.A, face.B, face.C, face.D } } ; return(new int[] { 0, face.A, face.B, face.C }); }).ToArray(); var Colors = mesh.VertexColors.Select(cl => cl.ToArgb()).ToArray(); var speckleMesh = new Mesh(verts, Faces, Colors, null, u); speckleMesh.volume = mesh.Volume(); speckleMesh.bbox = BoxToSpeckle(new RH.Box(mesh.GetBoundingBox(true)), u); return(speckleMesh); }
// Insipred by // https://github.com/DynamoDS/DynamoRevit/blob/master/src/Libraries/RevitNodes/GeometryConversion/ProtoToRevitMesh.cs public IList <GeometryObject> MeshToNative(Mesh mesh, TessellatedShapeBuilderTarget target = TessellatedShapeBuilderTarget.Mesh, TessellatedShapeBuilderFallback fallback = TessellatedShapeBuilderFallback.Salvage) { var tsb = new TessellatedShapeBuilder() { Fallback = fallback, Target = target, GraphicsStyleId = ElementId.InvalidElementId }; var valid = tsb.AreTargetAndFallbackCompatible(target, fallback); tsb.OpenConnectedFaceSet(target == TessellatedShapeBuilderTarget.Solid); var vertices = ArrayToPoints(mesh.vertices, mesh.units); int i = 0; while (i < mesh.faces.Count) { int n = mesh.faces[i]; if (n < 3) { n += 3; // 0 -> 3, 1 -> 4 to preserve backwards compatibility } var points = mesh.faces.GetRange(i + 1, n).Select(x => vertices[x]).ToArray(); if (IsNonPlanarQuad(points)) { //Non-planar quads will be triangulated as it's more desirable than `TessellatedShapeBuilder.Build`'s attempt to make them planar. //TODO consider triangulating all n > 3 polygons var triPoints = new List <XYZ> { points[0], points[1], points[3] }; var face1 = new TessellatedFace(triPoints, ElementId.InvalidElementId); tsb.AddFace(face1); triPoints = new List <XYZ> { points[1], points[2], points[3] };; var face2 = new TessellatedFace(triPoints, ElementId.InvalidElementId); tsb.AddFace(face2); } else { var face = new TessellatedFace(points, ElementId.InvalidElementId); tsb.AddFace(face); } i += n + 1; } tsb.CloseConnectedFaceSet(); try { tsb.Build(); } catch (Exception e) { Report.LogConversionError(e); return(null); } var result = tsb.GetBuildResult(); return(result.GetGeometricalObjects());
/// <summary> /// Converts a Speckle mesh to a GameObject with a mesh renderer /// </summary> /// <param name="speckleMesh">Mesh to convert</param> /// <param name="renderMaterial">If provided will override the renderMaterial on the mesh itself</param> /// <param name="properties">If provided will override the properties on the mesh itself</param> /// <returns></returns> public GameObject MeshToNative( Mesh speckleMesh, RenderMaterial renderMaterial = null, Dictionary <string, object> properties = null ) { if (speckleMesh.vertices.Count == 0 || speckleMesh.faces.Count == 0) { return(null); } var recenterMeshTransforms = true; //TODO: figure out how best to change this? var verts = ArrayToPoints(speckleMesh.vertices, speckleMesh.units); //convert speckleMesh.faces into triangle array List <int> tris = new List <int>(); int i = 0; // TODO: Check if this is causing issues with normals for mesh while (i < speckleMesh.faces.Count) { if (speckleMesh.faces[i] == 0) { //Triangles tris.Add(speckleMesh.faces[i + 1]); tris.Add(speckleMesh.faces[i + 3]); tris.Add(speckleMesh.faces[i + 2]); i += 4; } else { //Quads to triangles tris.Add(speckleMesh.faces[i + 1]); tris.Add(speckleMesh.faces[i + 3]); tris.Add(speckleMesh.faces[i + 2]); tris.Add(speckleMesh.faces[i + 1]); tris.Add(speckleMesh.faces[i + 4]); tris.Add(speckleMesh.faces[i + 3]); i += 5; } } var go = new GameObject { name = speckleMesh.speckle_type }; var mesh = new UnityEngine.Mesh { name = speckleMesh.speckle_type }; if (verts.Length >= 65535) { mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; } // center transform pivot according to the bounds of the model if (recenterMeshTransforms) { Bounds meshBounds = new Bounds { center = verts[0] }; foreach (var vert in verts) { meshBounds.Encapsulate(vert); } go.transform.position = meshBounds.center; // offset mesh vertices for (int l = 0; l < verts.Length; l++) { verts[l] -= meshBounds.center; } } mesh.SetVertices(verts); mesh.SetTriangles(tris, 0); if (speckleMesh.bbox != null) { var uv = GenerateUV(verts, (float)speckleMesh.bbox.xSize.Length, (float)speckleMesh.bbox.ySize.Length).ToList(); mesh.SetUVs(0, uv); } // BUG: causing some funky issues with meshes // mesh.RecalculateNormals( ); mesh.Optimize(); // Setting mesh to filter once all mesh modifying is done go.SafeMeshSet(mesh, true); var meshRenderer = go.AddComponent <MeshRenderer>(); var speckleMaterial = renderMaterial ?? (RenderMaterial)speckleMesh["renderMaterial"]; meshRenderer.sharedMaterial = GetMaterial(speckleMaterial); //Add mesh collider // MeshCollider mc = go.AddComponent<MeshCollider>( ); // mc.sharedMesh = mesh; //mc.convex = true; //attach properties on this very mesh //means the mesh originated in Rhino or similar if (properties == null) { var meshprops = typeof(Mesh).GetProperties(BindingFlags.Instance | BindingFlags.Public).Select(x => x.Name) .ToList(); properties = speckleMesh.GetMembers() .Where(x => !meshprops.Contains(x.Key)) .ToDictionary(x => x.Key, x => x.Value); } AttachSpeckleProperties(go, properties); return(go); }
public Brep BrepToSpeckle(Solid solid) { #if REVIT2021 // TODO: Incomplete implementation!! var brep = new Brep(); brep.units = ModelUnits; if (solid is null || solid.Faces.IsEmpty) { return(null); } var faceIndex = 0; var edgeIndex = 0; var curve2dIndex = 0; var curve3dIndex = 0; var loopIndex = 0; var trimIndex = 0; var surfaceIndex = 0; var speckleFaces = new Dictionary <Face, BrepFace>(); var speckleEdges = new Dictionary <Edge, BrepEdge>(); var speckleEdgeIndexes = new Dictionary <Edge, int>(); var speckle3dCurves = new ICurve[solid.Edges.Size]; var speckle2dCurves = new List <ICurve>(); var speckleLoops = new List <BrepLoop>(); var speckleTrims = new List <BrepTrim>(); foreach (var face in solid.Faces.Cast <Face>()) { var surface = FaceToSpeckle(face, out bool orientation, 0.0); var iterator = face.EdgeLoops.ForwardIterator(); var loopIndices = new List <int>(); while (iterator.MoveNext()) { var loop = iterator.Current as EdgeArray; var loopTrimIndices = new List <int>(); // Loop through the edges in the loop. var loopIterator = loop.ForwardIterator(); while (loopIterator.MoveNext()) { // Each edge should create a 2d curve, a 3d curve, a BrepTrim and a BrepEdge. var edge = loopIterator.Current as Edge; var faceA = edge.GetFace(0); // Determine what face side are we currently on. var edgeSide = face == faceA ? 0 : 1; // Get curve, create trim and save index var trim = edge.GetCurveUV(edgeSide); var sTrim = new BrepTrim(brep, edgeIndex, faceIndex, loopIndex, curve2dIndex, 0, BrepTrimType.Boundary, edge.IsFlippedOnFace(edgeSide), -1, -1); var sTrimIndex = trimIndex; loopTrimIndices.Add(sTrimIndex); // Add curve and trim, increase index counters. speckle2dCurves.Add(CurveToSpeckle(trim.As3DCurveInXYPlane())); speckleTrims.Add(sTrim); curve2dIndex++; trimIndex++; // Check if we have visited this edge before. if (!speckleEdges.ContainsKey(edge)) { // First time we visit this edge, add 3d curve and create new BrepEdge. var edgeCurve = edge.AsCurve(); speckle3dCurves[curve3dIndex] = CurveToSpeckle(edgeCurve); var sCurveIndex = curve3dIndex; curve3dIndex++; // Create a trim with just one of the trimIndices set, the second one will be set on the opposite condition. var sEdge = new BrepEdge(brep, sCurveIndex, new[] { sTrimIndex }, -1, -1, edge.IsFlippedOnFace(face), null); speckleEdges.Add(edge, sEdge); speckleEdgeIndexes.Add(edge, edgeIndex); edgeIndex++; } else { // Already visited this edge, skip curve 3d var sEdge = speckleEdges[edge]; var sEdgeIndex = speckleEdgeIndexes[edge]; sTrim.EdgeIndex = sEdgeIndex; // Update trim indices with new item. // TODO: Make this better. var trimIndices = sEdge.TrimIndices.ToList(); trimIndices.Append(sTrimIndex); sEdge.TrimIndices = trimIndices.ToArray(); } } var speckleLoop = new BrepLoop(brep, faceIndex, loopTrimIndices, BrepLoopType.Outer); speckleLoops.Add(speckleLoop); var sLoopIndex = loopIndex; loopIndex++; loopIndices.Add(sLoopIndex); } speckleFaces.Add(face, new BrepFace(brep, surfaceIndex, loopIndices, loopIndices[0], !face.OrientationMatchesSurfaceOrientation)); faceIndex++; brep.Surfaces.Add(surface); surfaceIndex++; } var mesh = new Mesh(); (mesh.faces, mesh.vertices) = GetFaceVertexArrFromSolids(new List <Solid> { solid }); mesh.units = ModelUnits; // TODO: Revit has no brep vertices. Must call 'brep.SetVertices()' in rhino when provenance is revit. // TODO: Set tolerances and flags in rhino when provenance is revit. brep.Faces = speckleFaces.Values.ToList(); brep.Curve2D = speckle2dCurves; brep.Curve3D = speckle3dCurves.ToList(); brep.Trims = speckleTrims; brep.Edges = speckleEdges.Values.ToList(); brep.Loops = speckleLoops; brep.displayValue = mesh; return(brep); #else throw new Exception("Converting BREPs to Speckle is currently only supported in Revit 2021."); #endif }
// Insipred by // https://github.com/DynamoDS/DynamoRevit/blob/master/src/Libraries/RevitNodes/GeometryConversion/ProtoToRevitMesh.cs public IList <GeometryObject> MeshToNative(Mesh mesh, TessellatedShapeBuilderTarget target = TessellatedShapeBuilderTarget.Mesh, TessellatedShapeBuilderFallback fallback = TessellatedShapeBuilderFallback.Salvage) { var tsb = new TessellatedShapeBuilder() { Fallback = fallback, Target = target, GraphicsStyleId = ElementId.InvalidElementId }; var valid = tsb.AreTargetAndFallbackCompatible(target, fallback); tsb.OpenConnectedFaceSet(target == TessellatedShapeBuilderTarget.Solid); var vertices = ArrayToPoints(mesh.vertices, mesh.units); int i = 0; while (i < mesh.faces.Count) { var points = new List <XYZ>(); if (mesh.faces[i] == 0) { // triangle points = new List <XYZ> { vertices[mesh.faces[i + 1]], vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 3]] }; var face = new TessellatedFace(points, ElementId.InvalidElementId); var check = !tsb.DoesFaceHaveEnoughLoopsAndVertices(face); tsb.AddFace(face); i += 4; } else { // quad points = new List <XYZ> { vertices[mesh.faces[i + 1]], vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 4]] }; var face1 = new TessellatedFace(points, ElementId.InvalidElementId); var check1 = tsb.DoesFaceHaveEnoughLoopsAndVertices(face1); tsb.AddFace(face1); points = new List <XYZ> { vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 3]], vertices[mesh.faces[i + 4]] }; var face2 = new TessellatedFace(points, ElementId.InvalidElementId); var check2 = tsb.DoesFaceHaveEnoughLoopsAndVertices(face2); tsb.AddFace(face2); i += 5; } } tsb.CloseConnectedFaceSet(); try { tsb.Build(); } catch (Exception e) { ConversionErrors.Add(e); return(null); } var result = tsb.GetBuildResult(); return(result.GetGeometricalObjects()); }