static TessellatedShapeBuilderResult GetTessellatedSolid( Document doc, Solid transientSolid) { TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); ElementId idMaterial = new FilteredElementCollector(doc) .OfClass(typeof(Material)) .FirstElementId(); ElementId idGraphicsStyle = new FilteredElementCollector(doc) .OfClass(typeof(GraphicsStyle)) .FirstOrDefault <Element>(gs => gs.Name.Equals("Walls")) .Id; builder.OpenConnectedFaceSet(true); FaceArray faceArray = transientSolid.Faces; foreach (Face face in faceArray) { List <XYZ> triFace = new List <XYZ>(3); Mesh mesh = face.Triangulate(); int triCount = mesh.NumTriangles; for (int i = 0; i < triCount; i++) { triFace.Clear(); for (int n = 0; n < 3; n++) { triFace.Add(mesh.get_Triangle(i).get_Vertex(n)); } builder.AddFace(new TessellatedFace( triFace, idMaterial)); } } builder.CloseConnectedFaceSet(); //return builder.Build( // TessellatedShapeBuilderTarget.Solid, // TessellatedShapeBuilderFallback.Abort, // idGraphicsStyle ); // 2016 builder.Fallback = TessellatedShapeBuilderFallback.Abort; builder.Target = TessellatedShapeBuilderTarget.Solid; builder.GraphicsStyleId = idGraphicsStyle; builder.Build(); // 2020 return(builder.GetBuildResult()); }
static internal IEnumerable <GeometryObject> ToHost(this Rhino.Geometry.Mesh mesh) { List <XYZ> faceVertices = new List <XYZ>(4); var builder = new TessellatedShapeBuilder(); builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; builder.Fallback = TessellatedShapeBuilderFallback.Mesh; Rhino.Geometry.Mesh[] pieces = mesh.DisjointMeshCount > 1 ? mesh.SplitDisjointPieces() : new Rhino.Geometry.Mesh[] { mesh }; foreach (var piece in pieces) { piece.Faces.ConvertNonPlanarQuadsToTriangles(Revit.ModelAbsolutePlanarTolerance, RhinoMath.UnsetValue, 5); bool isOriented = false; bool hasBoundary = false; bool isSolid = piece.IsClosed && piece.IsManifold(true, out isOriented, out hasBoundary) && isOriented; var vertices = piece.Vertices.ToPoint3dArray(); builder.OpenConnectedFaceSet(isSolid); foreach (var face in piece.Faces) { faceVertices.Add(vertices[face.A].ToHost()); faceVertices.Add(vertices[face.B].ToHost()); faceVertices.Add(vertices[face.C].ToHost()); if (face.IsQuad) { faceVertices.Add(vertices[face.D].ToHost()); } builder.AddFace(new TessellatedFace(faceVertices, ElementId.InvalidElementId)); faceVertices.Clear(); } builder.CloseConnectedFaceSet(); } IList <GeometryObject> objects = null; try { builder.Build(); objects = builder.GetBuildResult().GetGeometricalObjects(); } catch (Autodesk.Revit.Exceptions.ApplicationException e) { Debug.Fail(e.Source, e.Message); objects = new List <GeometryObject>(); } return(objects); }
/// <summary> /// Creates a solid from a list of points. Intented to create single face solids for solid operations. /// </summary> /// <param name="vertices">A list of XYZ vertices of the face.</param> /// <returns>A solid consisting of one face.</returns> public static Solid CreateSolid(IList <XYZ> vertices) { TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); //http://thebuildingcoder.typepad.com/blog/2014/05/directshape-performance-and-minimum-size.html builder.OpenConnectedFaceSet(false); builder.AddFace(new TessellatedFace(vertices, ElementId.InvalidElementId)); builder.CloseConnectedFaceSet(); builder.Build(); TessellatedShapeBuilderResult result = builder.GetBuildResult(); return(result.GetGeometricalObjects()[0] as Solid); }
// 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()); }
public static IList <GeometryObject> ToRevitType( this Autodesk.DesignScript.Geometry.Solid solid, TessellatedShapeBuilderTarget target = TessellatedShapeBuilderTarget.Mesh, TessellatedShapeBuilderFallback fallback = TessellatedShapeBuilderFallback.Salvage, ElementId MaterialId = null, bool performHostUnitConversion = true) { var rp = new DefaultRenderPackage(); if (performHostUnitConversion) { var newSolid = solid.InHostUnits(); newSolid.Tessellate(rp, new TessellationParameters()); newSolid.Dispose(); } else { solid.Tessellate(rp, new TessellationParameters()); } var tsb = new TessellatedShapeBuilder() { Fallback = fallback, Target = target, GraphicsStyleId = ElementId.InvalidElementId }; tsb.OpenConnectedFaceSet(false); var v = rp.MeshVertices.ToList(); for (int i = 0; i < v.Count; i += 9) { var a = new XYZ(v[i], v[i + 1], v[i + 2]); var b = new XYZ(v[i + 3], v[i + 4], v[i + 5]); var c = new XYZ(v[i + 6], v[i + 7], v[i + 8]); var face = new TessellatedFace(new List <XYZ>() { a, b, c }, MaterialId != null ? MaterialId : MaterialsManager.Instance.DynamoMaterialId); tsb.AddFace(face); } tsb.CloseConnectedFaceSet(); tsb.Build(); var result = tsb.GetBuildResult(); return(result.GetGeometricalObjects()); }
public static IList <GeometryObject> ToRevitType( this Autodesk.DesignScript.Geometry.Mesh mesh, TessellatedShapeBuilderTarget target = TessellatedShapeBuilderTarget.Mesh, TessellatedShapeBuilderFallback fallback = TessellatedShapeBuilderFallback.Salvage, ElementId MaterialId = null, bool performHostUnitConversion = true) { var verts = mesh.VertexPositions; var indices = mesh.FaceIndices; var tsb = new TessellatedShapeBuilder() { Fallback = fallback, Target = target, GraphicsStyleId = ElementId.InvalidElementId }; tsb.OpenConnectedFaceSet(false); for (int faceindex = 0, count = indices.Count(); faceindex < count; faceindex++) { var f = indices[faceindex]; //if this is a quad face triangulate it if (f.Count > 3) { //and add two triangles to the tessellated shape builder var tri1 = IndexGroup.ByIndices(f.B, f.C, f.A); var tri2 = IndexGroup.ByIndices(f.A, f.C, f.D); AddFace(tsb, tri1, verts, performHostUnitConversion, MaterialId); AddFace(tsb, tri2, verts, performHostUnitConversion, MaterialId); } else { AddFace(tsb, f, verts, performHostUnitConversion, MaterialId); } } tsb.CloseConnectedFaceSet(); tsb.Build(); var result = tsb.GetBuildResult(); foreach (IDisposable vert in verts) { vert.Dispose(); } return(result.GetGeometricalObjects()); }
/// <summary> /// 三角化Solid /// </summary> /// <param name="doc"></param> /// <param name="transientSolid"></param> /// <returns></returns> public static IList <GeometryObject> TessellateSolid(this Solid transientSolid, Document doc) { TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); ElementId idMaterial = new FilteredElementCollector(doc) .OfClass(typeof(Material)) .FirstElementId(); ElementId idGraphicsStyle = new FilteredElementCollector(doc) .OfClass(typeof(GraphicsStyle)) .FirstElementId(); builder.OpenConnectedFaceSet(true); FaceArray faceArray = transientSolid.Faces; foreach (Face face in faceArray) { List <XYZ> triFace = new List <XYZ>(3); Mesh mesh = face.Triangulate(); if (null == mesh) { continue; } int triCount = mesh.NumTriangles; for (int i = 0; i < triCount; i++) { triFace.Clear(); for (int n = 0; n < 3; n++) { triFace.Add(mesh.get_Triangle(i).get_Vertex(n)); } builder.AddFace(new TessellatedFace(triFace, idMaterial)); } } builder.CloseConnectedFaceSet(); // return builder.Build(TessellatedShapeBuilderTarget.Solid, TessellatedShapeBuilderFallback.Abort, idGraphicsStyle); return(builder.GetBuildResult().GetGeometricalObjects()); }
private void Execute(IEnumerable <List <XYZ> > triangles) { void Run(Document doc) { TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(false); foreach (List <XYZ> triangle in triangles) { TessellatedFace tessellatedFace = new TessellatedFace(triangle, ElementId.InvalidElementId); if (builder.DoesFaceHaveEnoughLoopsAndVertices(tessellatedFace)) { builder.AddFace(tessellatedFace); } } builder.CloseConnectedFaceSet(); builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; builder.Fallback = TessellatedShapeBuilderFallback.Mesh; builder.Build(); TessellatedShapeBuilderResult result = builder.GetBuildResult(); //var ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel)); //ds.ApplicationId = Assembly.GetExecutingAssembly().GetType().GUID.ToString(); //ds.ApplicationDataId = Guid.NewGuid().ToString(); //ds.Name = "NavisWorksShape"; //DirectShapeOptions dsOptions = ds.GetOptions(); //dsOptions.ReferencingOption = DirectShapeReferencingOption.Referenceable; //ds.SetOptions(dsOptions); //ds.SetShape(result.GetGeometricalObjects()); CreateDirectShape(doc, result.GetGeometricalObjects()); } _eventHandler.Action = Run; _eventHandler.TransactionName = "Importing navisWorks elements"; _externalEvent.Raise(); }
/// <summary> /// Create a geometry object(s) described by stored face sets, if possible. /// Usually a single-element IList conatining either Solid or Mesh is returned. /// A two-elemant IList containing a Solid as the 1st element and a Mesh as /// the 2nd is returned if while building multiple face sets, a fallback /// was used for some but not all sets. /// </summary> /// <returns>The IList created, or null. The IList can contain a Solid and/or a Mesh. /// If Solid is present, it always the 1st element.</returns> private IList <GeometryObject> CreateGeometryObjects(string guid, out bool hasInvalidData, out TessellatedShapeBuilderOutcome outcome) { try { TessellatedShapeBuilder.CloseConnectedFaceSet(); // The OwnerInfo is currently unused; the value doesn't really matter. TessellatedShapeBuilder.LogString = IFCImportFile.TheFileName; TessellatedShapeBuilder.LogInteger = IFCImportFile.TheBrepCounter; TessellatedShapeBuilder.OwnerInfo = guid != null ? guid : "Temporary Element"; TessellatedShapeBuilder.Target = TargetGeometry; TessellatedShapeBuilder.Fallback = FallbackGeometry; TessellatedShapeBuilder.GraphicsStyleId = GraphicsStyleId; TessellatedShapeBuilder.Build(); TessellatedShapeBuilderResult result = TessellatedShapeBuilder.GetBuildResult(); // It is important that we clear the TSB after we build above, otherwise we will "collect" geometries // in the DirectShape and create huge files with redundant data. ClearTessellatedShapeBuilder(); hasInvalidData = result.HasInvalidData; outcome = result.Outcome; return(result.GetGeometricalObjects()); } catch (Exception ex) { Importer.TheLog.LogError(CreatorId(), ex.Message, false); ClearTessellatedShapeBuilder(); hasInvalidData = true; outcome = TessellatedShapeBuilderOutcome.Nothing; return(null); } }
/// <summary> /// Create a new list of geometry objects from the /// given input. As input, we supply the result of /// Room.GetClosedShell. The output is the exact /// same solid lacking whatever flaws are present /// in the input solid. /// </summary> static IList <GeometryObject> CopyGeometry( GeometryElement geo, ElementId materialId, List <IntPoint3d> coords, List <TriangleIndices> indices) { TessellatedShapeBuilderResult result = null; TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); // Need to include the key in the value, otherwise // no way to access it later, cf. // https://stackoverflow.com/questions/1619090/getting-a-keyvaluepair-directly-from-a-dictionary Dictionary <XYZ, KeyValuePair <XYZ, int> > pts = new Dictionary <XYZ, KeyValuePair <XYZ, int> >( new XyzEqualityComparer()); int nSolids = 0; //int nFaces = 0; int nTriangles = 0; //int nVertices = 0; List <XYZ> vertices = new List <XYZ>(3); foreach (GeometryObject obj in geo) { Solid solid = obj as Solid; if (null != solid) { if (0 < solid.Volume) { ++nSolids; builder.OpenConnectedFaceSet(false); #region Create a new solid based on tessellation of the invalid room closed shell solid #if CREATE_NEW_SOLID_USING_TESSELATION Debug.Assert( SolidUtils.IsValidForTessellation(solid), "expected a valid solid for room closed shell"); SolidOrShellTessellationControls controls = new SolidOrShellTessellationControls() { // // Summary: // A positive real number specifying how accurately a triangulation should approximate // a solid or shell. // // Exceptions: // T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException: // When setting this property: The given value for accuracy must be greater than // 0 and no more than 30000 feet. // This statement is not true. I set Accuracy = 0.003 and an exception was thrown. // Setting it to 0.006 was acceptable. 0.03 is a bit over 9 mm. // // Remarks: // The maximum distance from a point on the triangulation to the nearest point on // the solid or shell should be no greater than the specified accuracy. This constraint // may be approximately enforced. Accuracy = 0.03, // // Summary: // An number between 0 and 1 (inclusive) specifying the level of detail for the // triangulation of a solid or shell. // // Exceptions: // T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException: // When setting this property: The given value for levelOfDetail must lie between // 0 and 1 (inclusive). // // Remarks: // Smaller values yield coarser triangulations (fewer triangles), while larger values // yield finer triangulations (more triangles). LevelOfDetail = 0.1, // // Summary: // A non-negative real number specifying the minimum allowed angle for any triangle // in the triangulation, in radians. // // Exceptions: // T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException: // When setting this property: The given value for minAngleInTriangle must be at // least 0 and less than 60 degrees, expressed in radians. The value 0 means to // ignore the minimum angle constraint. // // Remarks: // A small value can be useful when triangulating long, thin objects, in order to // keep the number of triangles small, but it can result in long, thin triangles, // which are not acceptable for all applications. If the value is too large, this // constraint may not be satisfiable, causing the triangulation to fail. This constraint // may be approximately enforced. A value of 0 means to ignore the minimum angle // constraint. MinAngleInTriangle = 3 * Math.PI / 180.0, // // Summary: // A positive real number specifying the minimum allowed value for the external // angle between two adjacent triangles, in radians. // // Exceptions: // T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException: // When setting this property: The given value for minExternalAngleBetweenTriangles // must be greater than 0 and no more than 30000 feet. // // Remarks: // A small value yields more smoothly curved triangulated surfaces, usually at the // expense of an increase in the number of triangles. Note that this setting has // no effect for planar surfaces. This constraint may be approximately enforced. MinExternalAngleBetweenTriangles = 0.2 * Math.PI }; TriangulatedSolidOrShell shell = SolidUtils.TessellateSolidOrShell(solid, controls); int n = shell.ShellComponentCount; Debug.Assert(1 == n, "expected just one shell component in room closed shell"); TriangulatedShellComponent component = shell.GetShellComponent(0); int coordsBase = coords.Count; int indicesBase = indices.Count; n = component.VertexCount; for (int i = 0; i < n; ++i) { XYZ v = component.GetVertex(i); coords.Add(new IntPoint3d(v)); } n = component.TriangleCount; for (int i = 0; i < n; ++i) { TriangleInShellComponent t = component.GetTriangle(i); vertices.Clear(); vertices.Add(component.GetVertex(t.VertexIndex0)); vertices.Add(component.GetVertex(t.VertexIndex1)); vertices.Add(component.GetVertex(t.VertexIndex2)); indices.Add(new TriangleIndices( coordsBase + t.VertexIndex0, coordsBase + t.VertexIndex1, coordsBase + t.VertexIndex2)); TessellatedFace tf = new TessellatedFace( vertices, materialId); if (builder.DoesFaceHaveEnoughLoopsAndVertices(tf)) { builder.AddFace(tf); ++nTriangles; } } #else // Iterate over the individual solid faces foreach (Face f in solid.Faces) { vertices.Clear(); #region Use face triangulation #if USE_FACE_TRIANGULATION Mesh mesh = f.Triangulate(); int n = mesh.NumTriangles; for (int i = 0; i < n; ++i) { MeshTriangle triangle = mesh.get_Triangle(i); XYZ p1 = triangle.get_Vertex(0); XYZ p2 = triangle.get_Vertex(1); XYZ p3 = triangle.get_Vertex(2); vertices.Clear(); vertices.Add(p1); vertices.Add(p2); vertices.Add(p3); TessellatedFace tf = new TessellatedFace( vertices, materialId); if (builder.DoesFaceHaveEnoughLoopsAndVertices(tf)) { builder.AddFace(tf); ++nTriangles; } } #endif // USE_FACE_TRIANGULATION #endregion // Use face triangulation #region Use original solid and its EdgeLoops #if USE_EDGELOOPS // This returns arbitrarily ordered and // oriented edges, so no solid can be // generated. foreach (EdgeArray loop in f.EdgeLoops) { foreach (Edge e in loop) { XYZ p = e.AsCurve().GetEndPoint(0); XYZ q = p; if (pts.ContainsKey(p)) { KeyValuePair <XYZ, int> kv = pts[p]; q = kv.Key; int n = kv.Value; pts[p] = new KeyValuePair <XYZ, int>( q, ++n); Debug.Print("Ignoring vertex at {0} " + "with distance {1} to existing " + "vertex {2}", p, p.DistanceTo(q), q); } else { pts[p] = new KeyValuePair <XYZ, int>( p, 1); } vertices.Add(q); ++nVertices; } } #endif // USE_EDGELOOPS #endregion // Use original solid and its EdgeLoops #region Use original solid and GetEdgesAsCurveLoops #if USE_AS_CURVE_LOOPS // The solids generated by this have some weird // normals, so they do not render correctly in // the Forge viewer. Revert to triangles again. IList <CurveLoop> loops = f.GetEdgesAsCurveLoops(); foreach (CurveLoop loop in loops) { foreach (Curve c in loop) { XYZ p = c.GetEndPoint(0); XYZ q = p; if (pts.ContainsKey(p)) { KeyValuePair <XYZ, int> kv = pts[p]; q = kv.Key; int n = kv.Value; pts[p] = new KeyValuePair <XYZ, int>( q, ++n); Debug.Print("Ignoring vertex at {0} " + "with distance {1} to existing " + "vertex {2}", p, p.DistanceTo(q), q); } else { pts[p] = new KeyValuePair <XYZ, int>( p, 1); } vertices.Add(q); ++nVertices; } } #endif // USE_AS_CURVE_LOOPS #endregion // Use original solid and GetEdgesAsCurveLoops builder.AddFace(new TessellatedFace( vertices, materialId)); ++nFaces; } #endif // CREATE_NEW_SOLID_USING_TESSELATION #endregion // Create a new solid based on tessellation of the invalid room closed shell solid builder.CloseConnectedFaceSet(); builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; // Solid failed builder.Fallback = TessellatedShapeBuilderFallback.Mesh; // use Abort if target is Solid builder.Build(); result = builder.GetBuildResult(); // Debug printout log of current solid's glTF facet data n = coords.Count - coordsBase; Debug.Print("{0} glTF vertex coordinates " + "in millimetres:", n); Debug.Print(string.Join(" ", coords .TakeWhile <IntPoint3d>((p, i) => coordsBase <= i) .Select <IntPoint3d, string>(p => p.ToString()))); n = indices.Count - indicesBase; Debug.Print("{0} glTF triangles:", n); Debug.Print(string.Join(" ", indices .TakeWhile <TriangleIndices>((ti, i) => indicesBase <= i) .Select <TriangleIndices, string>(ti => ti.ToString()))); } } } return(result.GetGeometricalObjects()); }
// 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()); }
private static IList <GeometryObject> GetGeometryObjectsFromFace(Face face) { IList <GeometryObject> shapeGeometries = null; try { List <CurveLoop> profiles = new List <CurveLoop>(); XYZ normal = face.ComputeNormal(new UV(0, 0)); IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops(); IList <IList <CurveLoop> > sortedCurveLoops = ExporterIFCUtils.SortCurveLoops(curveLoops); foreach (IList <CurveLoop> curveLoopList in sortedCurveLoops) { foreach (CurveLoop curveLoop in curveLoopList) { if (curveLoop.IsCounterclockwise(normal)) { profiles.Insert(0, curveLoop); } else { profiles.Add(curveLoop); } } } List <List <XYZ> > allLoopVertices = new List <List <XYZ> >(); for (int i = 0; i < profiles.Count; i++) { List <XYZ> vertices = new List <XYZ>(); CurveLoop curveLoop = profiles[i]; foreach (Curve curve in curveLoop) { IList <XYZ> tessellatedVertices = curve.Tessellate(); tessellatedVertices.RemoveAt(tessellatedVertices.Count - 1); vertices.AddRange(tessellatedVertices); } allLoopVertices.Add(vertices); } TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(false); TessellatedFace tesseFace = new TessellatedFace(allLoopVertices.ToArray(), ElementId.InvalidElementId); if (builder.DoesFaceHaveEnoughLoopsAndVertices(tesseFace)) { builder.AddFace(tesseFace); } builder.CloseConnectedFaceSet(); #if RELEASE2015 || RELEASE2016 TessellatedShapeBuilderResult result = builder.Build(TessellatedShapeBuilderTarget.AnyGeometry, TessellatedShapeBuilderFallback.Mesh, ElementId.InvalidElementId); #else builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; builder.Fallback = TessellatedShapeBuilderFallback.Mesh; builder.Build(); TessellatedShapeBuilderResult result = builder.GetBuildResult(); #endif shapeGeometries = result.GetGeometricalObjects(); } catch (Exception ex) { MessageBox.Show("Failed to get geometry objects from a face.\n" + ex.Message, "Get Geometry Objects", MessageBoxButtons.OK, MessageBoxIcon.Warning); } return(shapeGeometries); }
// Create a pyramid-shaped DirectShape using given material for the faces static public void CreateTessellatedShape(Document doc, ElementId materialId) { List <XYZ> loopVertices = new List <XYZ>(4); TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(true); // create a pyramid with a square base 4' x 4' and 5' high double length = 4.0; double height = 5.0; XYZ basePt1 = XYZ.Zero; XYZ basePt2 = new XYZ(length, 0, 0); XYZ basePt3 = new XYZ(length, length, 0); XYZ basePt4 = new XYZ(0, length, 0); XYZ apex = new XYZ(length / 2, length / 2, height); loopVertices.Add(basePt1); loopVertices.Add(basePt2); loopVertices.Add(basePt3); loopVertices.Add(basePt4); builder.AddFace(new TessellatedFace(loopVertices, materialId)); loopVertices.Clear(); loopVertices.Add(basePt1); loopVertices.Add(apex); loopVertices.Add(basePt2); builder.AddFace(new TessellatedFace(loopVertices, materialId)); loopVertices.Clear(); loopVertices.Add(basePt2); loopVertices.Add(apex); loopVertices.Add(basePt3); builder.AddFace(new TessellatedFace(loopVertices, materialId)); loopVertices.Clear(); loopVertices.Add(basePt3); loopVertices.Add(apex); loopVertices.Add(basePt4); builder.AddFace(new TessellatedFace(loopVertices, materialId)); loopVertices.Clear(); loopVertices.Add(basePt4); loopVertices.Add(apex); loopVertices.Add(basePt1); builder.AddFace(new TessellatedFace(loopVertices, materialId)); builder.CloseConnectedFaceSet(); builder.Target = TessellatedShapeBuilderTarget.Solid; builder.Fallback = TessellatedShapeBuilderFallback.Abort; builder.Build(); TessellatedShapeBuilderResult result = builder.GetBuildResult(); using (Transaction t = new Transaction(doc, "Create tessellated direct shape")) { t.Start(); DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel)); ds.ApplicationId = "Application id"; ds.ApplicationDataId = "Geometry object id"; ds.SetShape(result.GetGeometricalObjects()); t.Commit(); } }
public static void CreateCube(Document doc, XYZ min, XYZ max, string name) { List <XYZ> loopVertices = new List <XYZ>(4); TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(true); XYZ topLeftBack = new XYZ(min.X, max.Y, min.Z); XYZ topRightBack = new XYZ(max.X, max.Y, min.Z); XYZ bottomLeftBack = new XYZ(min.X, min.Y, min.Z); //min XYZ bottomRightBack = new XYZ(max.X, min.Y, min.Z); XYZ topLeftFront = new XYZ(min.X, max.Y, max.Z); XYZ topRightFront = new XYZ(max.X, max.Y, max.Z); //max XYZ bottomLeftFront = new XYZ(min.X, min.Y, max.Z); XYZ bottomRightFront = new XYZ(max.X, min.Y, max.Z); //Create the material ElementId materialId = ElementId.InvalidElementId; loopVertices.Add(topLeftBack); loopVertices.Add(topRightBack); loopVertices.Add(topRightFront); loopVertices.Add(topLeftFront); builder.AddFace(new TessellatedFace(loopVertices, materialId)); loopVertices.Clear(); loopVertices.Add(bottomLeftBack); loopVertices.Add(bottomRightBack); loopVertices.Add(bottomRightFront); loopVertices.Add(bottomLeftFront); builder.AddFace(new TessellatedFace(loopVertices, materialId)); loopVertices.Clear(); loopVertices.Add(topLeftBack); loopVertices.Add(topLeftFront); loopVertices.Add(bottomLeftFront); loopVertices.Add(bottomLeftBack); builder.AddFace(new TessellatedFace(loopVertices, materialId)); loopVertices.Clear(); loopVertices.Add(topLeftBack); loopVertices.Add(topLeftFront); loopVertices.Add(bottomRightFront); loopVertices.Add(bottomRightBack); builder.AddFace(new TessellatedFace(loopVertices, materialId)); loopVertices.Clear(); loopVertices.Add(topLeftBack); loopVertices.Add(topRightBack); loopVertices.Add(bottomRightBack); loopVertices.Add(bottomLeftBack); builder.AddFace(new TessellatedFace(loopVertices, materialId)); loopVertices.Clear(); loopVertices.Add(topLeftFront); loopVertices.Add(topRightFront); loopVertices.Add(bottomRightFront); loopVertices.Add(bottomLeftFront); builder.AddFace(new TessellatedFace(loopVertices, materialId)); builder.CloseConnectedFaceSet(); builder.Build(); TessellatedShapeBuilderResult result = builder.GetBuildResult(); using (Transaction t = new Transaction(doc, "Create tessellated direct shape")) { t.Start(); DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel)); ds.Name = name; ds.SetShape(result.GetGeometricalObjects()); t.Commit(); } }
public static void Execute( ExternalCommandData commandData) { Transaction trans = null; UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Document doc = uidoc.Document; try { Selection choices = uidoc.Selection; Reference faceref = choices.PickObject( ObjectType.Face); string rep = faceref .ConvertToStableRepresentation(doc); Debug.Assert(rep.EndsWith(":SURFACE"), "expected stable representation to end with SURFACE"); Debug.Print("Face reference picked: " + rep); Element el = doc.GetElement( faceref.ElementId); using (trans = new Transaction(doc)) { trans.Start("Create elements"); TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(false); // This may return a face in the family // symbol definition with no family instance // transform applied. Use the GeometryElement // GetTransformed method to retrieve the face // with the instance transformation applied. Face face = el.GetGeometryObjectFromReference( faceref) as Face; Debug.Print("Face reference property: " + ((null == face.Reference) ? "<nil>" : face.Reference.ConvertToStableRepresentation(doc))); Transform t = null; FamilyInstance fi = el as FamilyInstance; if (null != fi) { // Will this handle a face selected // in a nested family instance? // Some, yes, but not all. //t = fi.GetTransform(); // This also works for some instances // but not all. //Transform t1 = fi.GetTotalTransform(); Options opt = new Options(); opt.ComputeReferences = true; GeometryElement geo = el.get_Geometry(opt); GeometryElement geo2 = geo.GetTransformed( Transform.Identity); Stack <Transform> tstack = new Stack <Transform>(); if (GetTransformStackForObject(tstack, geo, doc, rep) && 0 < tstack.Count) { Debug.Print("GetTransformStackForObject " + "returned true with tstack count {0}", tstack.Count); t = Transform.Identity; while (0 < tstack.Count) { t *= tstack.Pop(); } } } Mesh mesh = face.Triangulate(); if (null != t) { mesh = mesh.get_Transformed(t); } XYZ[] triangleCorners = new XYZ[3]; for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle triangle = mesh.get_Triangle(i); triangleCorners[0] = triangle.get_Vertex(0); triangleCorners[1] = triangle.get_Vertex(1); triangleCorners[2] = triangle.get_Vertex(2); XYZ normal = GetNormal(triangleCorners); SketchPlane sketchPlane = GetSketchPlane( doc, triangleCorners[0], normal); DrawModelLineLoop(sketchPlane, triangleCorners); TessellatedFace tesseFace = new TessellatedFace(triangleCorners, ElementId.InvalidElementId); if (builder.DoesFaceHaveEnoughLoopsAndVertices( tesseFace)) { builder.AddFace(tesseFace); } } builder.CloseConnectedFaceSet(); //TessellatedShapeBuilderResult result // = builder.Build( // TessellatedShapeBuilderTarget.AnyGeometry, // TessellatedShapeBuilderFallback.Mesh, // ElementId.InvalidElementId ); // 2016 builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; // 2018 builder.Fallback = TessellatedShapeBuilderFallback.Mesh; // 2018 builder.Build(); // 2018 TessellatedShapeBuilderResult result = builder.GetBuildResult(); // 2018 ElementId categoryId = new ElementId( BuiltInCategory.OST_GenericModel); //DirectShape ds = DirectShape.CreateElement( // doc, categoryId, // Assembly.GetExecutingAssembly().GetType().GUID.ToString(), // Guid.NewGuid().ToString() ); // 2016 DirectShape ds = DirectShape.CreateElement( doc, categoryId); // 2018 ds.ApplicationId = Assembly.GetExecutingAssembly() .GetType().GUID.ToString(); // 2018 ds.ApplicationDataId = Guid.NewGuid().ToString(); // 2018 ds.SetShape(result.GetGeometricalObjects()); ds.Name = "MyShape"; trans.Commit(); } } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); } }
public static void Execute( ExternalCommandData commandData) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Document doc = uidoc.Document; Selection choices = uidoc.Selection; try { Reference reference = choices.PickObject( ObjectType.Face); Element el = doc.GetElement( reference.ElementId); Face face = el.GetGeometryObjectFromReference( reference) as Face; Mesh mesh = face.Triangulate(); var familyInstance = el as FamilyInstance; if (null != familyInstance) { var t = familyInstance .GetTotalTransform(); mesh = mesh.get_Transformed(t); } using (Transaction trans = new Transaction(doc)) { trans.Start("Create DirectShape from Face"); TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(false); List <XYZ> args = new List <XYZ>(3); XYZ[] triangleCorners = new XYZ[3]; for (int i = 0; i < mesh.NumTriangles; ++i) { MeshTriangle triangle = mesh.get_Triangle(i); triangleCorners[0] = triangle.get_Vertex(0); triangleCorners[1] = triangle.get_Vertex(1); triangleCorners[2] = triangle.get_Vertex(2); TessellatedFace tesseFace = new TessellatedFace(triangleCorners, ElementId.InvalidElementId); if (builder.DoesFaceHaveEnoughLoopsAndVertices( tesseFace)) { builder.AddFace(tesseFace); } } builder.CloseConnectedFaceSet(); //TessellatedShapeBuilderResult result // = builder.Build( // TessellatedShapeBuilderTarget.AnyGeometry, // TessellatedShapeBuilderFallback.Mesh, // ElementId.InvalidElementId ); // 2016 builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; // 2018 builder.Fallback = TessellatedShapeBuilderFallback.Mesh; // 2018 builder.Build(); // 2018 TessellatedShapeBuilderResult result = builder.GetBuildResult(); // 2018 ElementId categoryId = new ElementId( BuiltInCategory.OST_GenericModel); //DirectShape ds = DirectShape.CreateElement( // doc, categoryId, // Assembly.GetExecutingAssembly().GetType() // .GUID.ToString(), Guid.NewGuid().ToString() ); // 2016 DirectShape ds = DirectShape.CreateElement( doc, categoryId); // 2018 ds.ApplicationId = Assembly.GetExecutingAssembly() .GetType().GUID.ToString(); // 2018 ds.ApplicationDataId = Guid.NewGuid().ToString(); // 2018 ds.SetShape(result.GetGeometricalObjects()); ds.Name = "MyShape"; trans.Commit(); } } catch (Exception ex) { Debug.Print(ex.Message); } }
static internal IEnumerable <GeometryObject> Convert(IEnumerable <Rhino.Geometry.Mesh> meshes) { List <XYZ> faceVertices = new List <XYZ>(4); var builder = new TessellatedShapeBuilder(); builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; builder.Fallback = TessellatedShapeBuilderFallback.Mesh; foreach (var mesh in meshes) { Rhino.Geometry.Mesh[] pieces = mesh.DisjointMeshCount > 1 ? mesh.SplitDisjointPieces() : new Rhino.Geometry.Mesh[] { mesh }; foreach (var piece in pieces) { // Meshes with edges smaller than AbsoluteRevitTolerance (1/16 inch) are not welcome in Revit while (piece.CollapseFacesByEdgeLength(false, ModelAbsoluteTolerance) > 0) { ; } piece.Faces.ConvertNonPlanarQuadsToTriangles(RhinoMath.ZeroTolerance, RhinoMath.UnsetValue, 5); bool isOriented = false; bool hasBoundary = false; bool isSolid = piece.IsClosed && piece.IsManifold(true, out isOriented, out hasBoundary) && isOriented; var vertices = piece.Vertices; builder.OpenConnectedFaceSet(isSolid); foreach (var face in piece.Faces) { faceVertices.Add(Convert(vertices[face.A])); faceVertices.Add(Convert(vertices[face.B])); faceVertices.Add(Convert(vertices[face.C])); if (face.IsQuad) { faceVertices.Add(Convert(vertices[face.D])); } builder.AddFace(new TessellatedFace(faceVertices, ElementId.InvalidElementId)); faceVertices.Clear(); } builder.CloseConnectedFaceSet(); } } try { builder.Build(); } catch (Autodesk.Revit.Exceptions.ApplicationException e) { Debug.Fail(e.Source, e.Message); return(null); } TessellatedShapeBuilderResult result = builder.GetBuildResult(); return(result.GetGeometricalObjects()); }
/// <summary> /// Create a new DirectShape element from given /// list of faces and return the number of faces /// processed. /// Return -1 if a face vertex index exceeds the /// total number of available vertices, /// representing a fatal error. /// </summary> static int NewDirectShape( List <XYZ> vertices, FaceCollection faces, Document doc, ElementId graphicsStyleId, string appGuid, string shapeName) { int nFaces = 0; int nFacesFailed = 0; TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.LogString = shapeName; List <XYZ> corners = new List <XYZ>(4); builder.OpenConnectedFaceSet(false); foreach (Face f in faces) { builder.LogInteger = nFaces; if (corners.Capacity < f.Indices.Count) { corners = new List <XYZ>(f.Indices.Count); } corners.Clear(); foreach (Index i in f.Indices) { Debug.Assert(vertices.Count > i.vertex, "how can the face vertex index be larger " + "than the total number of vertices?"); if (i.vertex >= vertices.Count) { return(-1); } corners.Add(vertices[i.vertex]); } try { builder.AddFace(new TessellatedFace(corners, ElementId.InvalidElementId)); ++nFaces; } catch (Autodesk.Revit.Exceptions.ArgumentException ex) { // Remember something went wrong here. ++nFacesFailed; Debug.Print( "Revit API argument exception {0}\r\n" + "Failed to add face with {1} corners: {2}", ex.Message, corners.Count, string.Join(", ", corners.Select <XYZ, string>( p => Util.PointString(p)))); } } builder.CloseConnectedFaceSet(); // Refer to StlImport sample for more clever // handling of target and fallback and the // possible combinations. //TessellatedShapeBuilderResult r // 2015 // = builder.Build( // TessellatedShapeBuilderTarget.AnyGeometry, // TessellatedShapeBuilderFallback.Mesh, // graphicsStyleId ); builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; // 2017 builder.Fallback = TessellatedShapeBuilderFallback.Mesh; // 2017 builder.GraphicsStyleId = graphicsStyleId; // 2017 builder.Build(); // 2017 //TessellatedShapeBuilderResult r // 2015 DirectShape ds = DirectShape.CreateElement( //doc, _categoryId, appGuid, shapeName ); // 2015 doc, _categoryId); // 2017 ds.ApplicationId = appGuid; // 2017 ds.ApplicationDataId = shapeName; // 2017 //ds.SetShape( r.GetGeometricalObjects() ); // 2015 ds.SetShape(builder.GetBuildResult().GetGeometricalObjects()); // 2017 ds.Name = shapeName; Debug.Print( "Shape '{0}': added {1} face{2}, {3} face{4} failed.", shapeName, nFaces, Util.PluralSuffix(nFaces), nFacesFailed, Util.PluralSuffix(nFacesFailed)); return(nFaces); }
/// <summary> /// This is to create a bounding box mesh for geometries which have errors during the tessellating process /// </summary> /// <param name="minPoint"></param> /// <param name="maxPoint"></param> /// <param name="performHostUnitConversion"></param> /// <returns></returns> public static IList <GeometryObject> CreateBoundingBoxMeshForErrors(Autodesk.DesignScript.Geometry.Point minPoint, Autodesk.DesignScript.Geometry.Point maxPoint, bool performHostUnitConversion = true) { double x0 = minPoint.X; double y0 = minPoint.Y; double z0 = minPoint.Z; double x1 = maxPoint.X; double y1 = maxPoint.Y; double z1 = maxPoint.Z; x0 -= 1.0; y0 -= 1.0; z0 -= 1.0; x1 += 1.0; y1 += 1.0; z1 += 1.0; var tsb = new TessellatedShapeBuilder() { Fallback = TessellatedShapeBuilderFallback.Salvage, Target = TessellatedShapeBuilderTarget.Mesh, GraphicsStyleId = ElementId.InvalidElementId }; tsb.OpenConnectedFaceSet(false); var p0 = new XYZ(x0, y0, z0); var p1 = new XYZ(x1, y0, z0); var p2 = new XYZ(x1, y1, z0); var p3 = new XYZ(x0, y1, z0); var p4 = new XYZ(x0, y0, z1); var p5 = new XYZ(x1, y0, z1); var p6 = new XYZ(x1, y1, z1); var p7 = new XYZ(x0, y1, z1); var f1 = new TessellatedFace(new List <XYZ>() { p0, p1, p2 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f1); var f2 = new TessellatedFace(new List <XYZ>() { p2, p3, p0 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f2); var f3 = new TessellatedFace(new List <XYZ>() { p0, p1, p5 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f3); var f4 = new TessellatedFace(new List <XYZ>() { p5, p4, p0 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f4); var f5 = new TessellatedFace(new List <XYZ>() { p1, p2, p6 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f5); var f6 = new TessellatedFace(new List <XYZ>() { p6, p5, p1 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f6); var f7 = new TessellatedFace(new List <XYZ>() { p2, p3, p7 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f7); var f8 = new TessellatedFace(new List <XYZ>() { p7, p6, p2 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f8); var f9 = new TessellatedFace(new List <XYZ>() { p3, p0, p4 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f9); var f10 = new TessellatedFace(new List <XYZ>() { p4, p7, p3 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f10); var f11 = new TessellatedFace(new List <XYZ>() { p4, p5, p6 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f11); var f12 = new TessellatedFace(new List <XYZ>() { p6, p7, p4 }, MaterialsManager.Instance.DynamoErrorMaterialId); tsb.AddFace(f12); tsb.CloseConnectedFaceSet(); tsb.Build(); var result = tsb.GetBuildResult(); return(result.GetGeometricalObjects()); }
// 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());
public static void Execute1( ExternalCommandData commandData) { Transaction trans = null; UIDocument uidoc = commandData.Application .ActiveUIDocument; Document doc = uidoc.Document; try { Selection choices = uidoc.Selection; Reference reference = choices.PickObject( ObjectType.Face); Element el = doc.GetElement( reference.ElementId); trans = new Transaction(doc, "Create elements"); trans.Start(); TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(false); Face face = el.GetGeometryObjectFromReference( reference) as Face; Mesh mesh = face.Triangulate(); List <XYZ> args = new List <XYZ>(3); XYZ offset = new XYZ(); if (el.Location is LocationPoint) { LocationPoint locationPoint = el.Location as LocationPoint; offset = locationPoint.Point; } for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle triangle = mesh.get_Triangle( i); XYZ p1 = triangle.get_Vertex(0); XYZ p2 = triangle.get_Vertex(1); XYZ p3 = triangle.get_Vertex(2); p1 = p1.Add(offset); p2 = p2.Add(offset); p3 = p3.Add(offset); args.Clear(); args.Add(p1); args.Add(p2); args.Add(p3); TessellatedFace tesseFace = new TessellatedFace(args, ElementId.InvalidElementId); if (builder.DoesFaceHaveEnoughLoopsAndVertices( tesseFace)) { builder.AddFace(tesseFace); } } builder.CloseConnectedFaceSet(); //TessellatedShapeBuilderResult result // = builder.Build( // TessellatedShapeBuilderTarget.AnyGeometry, // TessellatedShapeBuilderFallback.Mesh, // ElementId.InvalidElementId ); // 2016 builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; // 2018 builder.Fallback = TessellatedShapeBuilderFallback.Mesh; // 2018 builder.Build(); // 2018 TessellatedShapeBuilderResult result = builder.GetBuildResult(); // 2018 ElementId categoryId = new ElementId( BuiltInCategory.OST_GenericModel); //DirectShape ds = DirectShape.CreateElement( // doc, categoryId, // Assembly.GetExecutingAssembly().GetType() // .GUID.ToString(), Guid.NewGuid().ToString() ); // 2016 DirectShape ds = DirectShape.CreateElement( doc, categoryId); // 2018 ds.ApplicationId = Assembly.GetExecutingAssembly() .GetType().GUID.ToString(); // 2018 ds.ApplicationDataId = Guid.NewGuid().ToString(); // 2018 ds.SetShape(result.GetGeometricalObjects()); ds.Name = "MyShape"; trans.Commit(); } catch (Exception ex) { if (trans != null) { trans.RollBack(); } Debug.Print(ex.Message); } }