//NOTE: we are currently only converting Stairs ToSpeckle //a ToNative method might come later on! private RevitStair StairToSpeckle(Stairs revitStair) { var stairType = Doc.GetElement(revitStair.GetTypeId()) as StairsType; var speckleStair = new RevitStair(); speckleStair.family = stairType.FamilyName; speckleStair.type = stairType.Name; speckleStair.level = ConvertAndCacheLevel(revitStair, BuiltInParameter.STAIRS_BASE_LEVEL_PARAM); speckleStair.topLevel = ConvertAndCacheLevel(revitStair, BuiltInParameter.STAIRS_TOP_LEVEL_PARAM); speckleStair.riserHeight = ScaleToSpeckle(revitStair.ActualRiserHeight); speckleStair.risersNumber = revitStair.ActualRisersNumber; speckleStair.treadDepth = ScaleToSpeckle(revitStair.ActualTreadDepth); speckleStair.treadsNumber = revitStair.ActualTreadsNumber; speckleStair.baseElevation = ScaleToSpeckle(revitStair.BaseElevation); speckleStair.topElevation = ScaleToSpeckle(revitStair.TopElevation); speckleStair.height = ScaleToSpeckle(revitStair.Height); speckleStair.numberOfStories = revitStair.NumberOfStories; speckleStair.runs = revitStair.GetStairsRuns().Select(x => StairRunToSpeckle(Doc.GetElement(x) as StairsRun)).ToList(); speckleStair.landings = revitStair.GetStairsLandings().Select(x => StairLandingToSpeckle(Doc.GetElement(x) as StairsLanding)).ToList(); speckleStair.supports = revitStair.GetStairsSupports().Select(x => StairSupportToSpeckle(Doc.GetElement(x))).ToList(); GetAllRevitParamsAndIds(speckleStair, revitStair, new List <string> { "STAIRS_BASE_LEVEL_PARAM", "STAIRS_TOP_LEVEL_PARAM" }); speckleStair.displayMesh = GetElementDisplayMesh(revitStair, new Options() { DetailLevel = ViewDetailLevel.Fine, ComputeReferences = false }); //Report.Log($"Converted Stair {revitStair.Id}"); return(speckleStair); }
// https://forums.autodesk.com/t5/revit-api-forum/paint-stair-faces/m-p/10388359 void PaintStairs(UIDocument uidoc, Material mat) { Document doc = uidoc.Document; Selection sel = uidoc.Selection; //FaceSelectionFilter filter = new FaceSelectionFilter(); Reference pickedRef = sel.PickObject( ObjectType.PointOnElement, //filter, "Please select a Face"); Element elem = doc.GetElement(pickedRef); GeometryObject geoObject = elem .GetGeometryObjectFromReference(pickedRef); Face fc = geoObject as Face; if (elem.Category.Id.IntegerValue == -2000120) // Stairs { bool flag = false; Stairs str = elem as Stairs; ICollection <ElementId> landings = str.GetStairsLandings(); ICollection <ElementId> runs = str.GetStairsLandings(); using (Transaction transaction = new Transaction(doc)) { transaction.Start("Paint Material"); foreach (ElementId id in landings) { doc.Paint(id, fc, mat.Id); flag = true; break; } if (!flag) { foreach (ElementId id in runs) { doc.Paint(id, fc, mat.Id); break; } } transaction.Commit(); } } }
/// <summary> /// Exports a staircase to IfcStair, composing into separate runs and landings. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="ifcEnumType">The stairs type.</param> /// <param name="stair">The stairs element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="numFlights">The number of flights for a multistory staircase.</param> /// <param name="productWrapper">The IFCProductWrapper.</param> public static void ExportStairsAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Stairs stair, GeometryElement geometryElement, int numFlights, IFCProductWrapper productWrapper) { if (stair == null || geometryElement == null) return; Document doc = stair.Document; Autodesk.Revit.ApplicationServices.Application app = doc.Application; IFCFile file = exporterIFC.GetFile(); Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); ElementId categoryId = CategoryUtil.GetSafeCategoryId(stair); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, stair)) { HashSet<ElementId> materialIds = new HashSet<ElementId>(); List<IFCAnyHandle> componentHandles = new List<IFCAnyHandle>(); IList<IFCExtrusionCreationData> componentExtrusionData = new List<IFCExtrusionCreationData>(); IFCAnyHandle contextOfItemsFootPrint = exporterIFC.Get3DContextHandle("FootPrint"); Transform trf = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, placementSetter.GetPlacement()); Plane boundaryPlane = new Plane(trf.BasisX, trf.BasisY, trf.Origin); XYZ boundaryProjDir = trf.BasisZ; IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string stairGUID = ExporterIFCUtils.CreateGUID(stair); string origStairName = exporterIFC.GetName(); string stairName = NamingUtil.GetNameOverride(stair, origStairName); string stairDescription = NamingUtil.GetDescriptionOverride(stair, null); string stairObjectType = NamingUtil.GetObjectTypeOverride(stair, NamingUtil.CreateIFCObjectName(exporterIFC, stair)); IFCAnyHandle stairLocalPlacement = placementSetter.GetPlacement(); string stairElementTag = NamingUtil.CreateIFCElementId(stair); IFCStairType stairType = GetIFCStairType(ifcEnumType); IFCAnyHandle stairContainerHnd = IFCInstanceExporter.CreateStair(file, stairGUID, ownerHistory, stairName, stairDescription, stairObjectType, stairLocalPlacement, null, stairElementTag, stairType); productWrapper.AddElement(stairContainerHnd, placementSetter.GetLevelInfo(), null, LevelUtil.AssociateElementToLevel(stair)); // Get List of runs to export their geometry. ICollection<ElementId> runIds = stair.GetStairsRuns(); int index = 0; foreach (ElementId runId in runIds) { index++; StairsRun run = doc.GetElement(runId) as StairsRun; using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.AllowVerticalOffsetOfBReps = false; ecData.SetLocalPlacement(placementSetter.GetPlacement()); ecData.ReuseLocalPlacement = false; GeometryElement runGeometryElement = run.get_Geometry(geomOptions); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); BodyData bodyData = BodyExporter.ExportBody(app, exporterIFC, run, categoryId, runGeometryElement, bodyExporterOptions, ecData); IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { ecData.ClearOpenings(); continue; } foreach (ElementId materialId in bodyData.MaterialIds) materialIds.Add(materialId); IList<IFCAnyHandle> reps = new List<IFCAnyHandle>(); reps.Add(bodyRep); Transform runBoundaryTrf = trf.Multiply(bodyData.BrepOffsetTransform); Plane runBoundaryPlane = new Plane(runBoundaryTrf.BasisX, runBoundaryTrf.BasisY, runBoundaryTrf.Origin); XYZ runBoundaryProjDir = runBoundaryTrf.BasisZ; CurveLoop boundary = run.GetFootprintBoundary(); IFCAnyHandle boundaryHnd = ExporterIFCUtils.CreateCurveFromCurveLoop(exporterIFC, boundary, runBoundaryPlane, runBoundaryProjDir); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(boundaryHnd)) { HashSet<IFCAnyHandle> geomSelectSet = new HashSet<IFCAnyHandle>(); geomSelectSet.Add(boundaryHnd); HashSet<IFCAnyHandle> boundaryItems = new HashSet<IFCAnyHandle>(); boundaryItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet)); IFCAnyHandle boundaryRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, run, categoryId, "FootPrint", contextOfItemsFootPrint, boundaryItems); reps.Add(boundaryRep); } CurveLoop walkingLine = run.GetStairsPath(); IFCAnyHandle walkingLineHnd = ExporterIFCUtils.CreateCurveFromCurveLoop(exporterIFC, walkingLine, runBoundaryPlane, runBoundaryProjDir); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(walkingLineHnd)) { HashSet<IFCAnyHandle> geomSelectSet = new HashSet<IFCAnyHandle>(); geomSelectSet.Add(walkingLineHnd); HashSet<IFCAnyHandle> walkingLineItems = new HashSet<IFCAnyHandle>(); walkingLineItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet)); IFCAnyHandle walkingLineRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, run, categoryId, "Axis", contextOfItemsFootPrint, walkingLineItems); reps.Add(walkingLineRep); } IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps); string runGUID = ExporterIFCUtils.CreateGUID(run); string origRunName = origStairName + " Run " + index; string runName = NamingUtil.GetNameOverride(run, origRunName); string runDescription = NamingUtil.GetDescriptionOverride(run, stairDescription); string runObjectType = NamingUtil.GetObjectTypeOverride(run, stairObjectType); IFCAnyHandle runLocalPlacement = ecData.GetLocalPlacement(); string runElementTag = NamingUtil.CreateIFCElementId(run); IFCAnyHandle stairFlightHnd = IFCInstanceExporter.CreateStairFlight(file, runGUID, ownerHistory, runName, runDescription, runObjectType, runLocalPlacement, representation, runElementTag, run.ActualRisersNumber, run.ActualTreadsNumber, stair.ActualRiserHeight, stair.ActualTreadDepth); componentHandles.Add(stairFlightHnd); componentExtrusionData.Add(ecData); productWrapper.AddElement(stairFlightHnd, placementSetter.GetLevelInfo(), ecData, false); ExporterCacheManager.HandleToElementCache.Register(stairFlightHnd, run.Id); } } // Get List of landings to export their geometry. ICollection<ElementId> landingIds = stair.GetStairsLandings(); index = 0; foreach (ElementId landingId in landingIds) { index++; StairsLanding landing = doc.GetElement(landingId) as StairsLanding; using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.AllowVerticalOffsetOfBReps = false; ecData.SetLocalPlacement(placementSetter.GetPlacement()); ecData.ReuseLocalPlacement = false; GeometryElement landingGeometryElement = landing.get_Geometry(geomOptions); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); BodyData bodyData = BodyExporter.ExportBody(app, exporterIFC, landing, categoryId, landingGeometryElement, bodyExporterOptions, ecData); IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { ecData.ClearOpenings(); continue; } foreach (ElementId materialId in bodyData.MaterialIds) materialIds.Add(materialId); // create Boundary rep. IList<IFCAnyHandle> reps = new List<IFCAnyHandle>(); reps.Add(bodyRep); Transform landingBoundaryTrf = trf.Multiply(bodyData.BrepOffsetTransform); Plane landingBoundaryPlane = new Plane(landingBoundaryTrf.BasisX, landingBoundaryTrf.BasisY, landingBoundaryTrf.Origin); XYZ landingBoundaryProjDir = landingBoundaryTrf.BasisZ; CurveLoop boundary = landing.GetFootprintBoundary(); IFCAnyHandle boundaryHnd = ExporterIFCUtils.CreateCurveFromCurveLoop(exporterIFC, boundary, landingBoundaryPlane, landingBoundaryProjDir); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(boundaryHnd)) { HashSet<IFCAnyHandle> geomSelectSet = new HashSet<IFCAnyHandle>(); geomSelectSet.Add(boundaryHnd); HashSet<IFCAnyHandle> boundaryItems = new HashSet<IFCAnyHandle>(); boundaryItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet)); IFCAnyHandle boundaryRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, landing, categoryId, "FootPrint", contextOfItemsFootPrint, boundaryItems); reps.Add(boundaryRep); } CurveLoop walkingLine = landing.GetStairsPath(); IFCAnyHandle walkingLineHnd = ExporterIFCUtils.CreateCurveFromCurveLoop(exporterIFC, walkingLine, landingBoundaryPlane, landingBoundaryProjDir); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(walkingLineHnd)) { HashSet<IFCAnyHandle> geomSelectSet = new HashSet<IFCAnyHandle>(); geomSelectSet.Add(walkingLineHnd); HashSet<IFCAnyHandle> walkingLineItems = new HashSet<IFCAnyHandle>(); walkingLineItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet)); IFCAnyHandle walkingLineRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, landing, categoryId, "Axis", contextOfItemsFootPrint, walkingLineItems); reps.Add(walkingLineRep); } string landingGUID = ExporterIFCUtils.CreateGUID(landing); string origLandingName = origStairName + " Landing " + index; string landingName = NamingUtil.GetNameOverride(landing, origLandingName); string landingDescription = NamingUtil.GetDescriptionOverride(landing, stairDescription); string landingObjectType = NamingUtil.GetObjectTypeOverride(landing, stairObjectType); IFCAnyHandle landingLocalPlacement = ecData.GetLocalPlacement(); string landingElementTag = NamingUtil.CreateIFCElementId(landing); IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps); IFCAnyHandle landingHnd = IFCInstanceExporter.CreateSlab(file, landingGUID, ownerHistory, landingName, landingDescription, landingObjectType, landingLocalPlacement, representation, landingElementTag, IFCSlabType.Landing); componentHandles.Add(landingHnd); componentExtrusionData.Add(ecData); productWrapper.AddElement(landingHnd, placementSetter.GetLevelInfo(), ecData, false); ExporterCacheManager.HandleToElementCache.Register(landingHnd, landing.Id); } } // Get List of supports to export their geometry. Supports are not exposed to API, so export as generic Element. ICollection<ElementId> supportIds = stair.GetStairsSupports(); index = 0; foreach (ElementId supportId in supportIds) { index++; Element support = doc.GetElement(supportId); using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.GetPlacement()); ecData.ReuseLocalPlacement = false; GeometryElement supportGeometryElement = support.get_Geometry(geomOptions); BodyData bodyData; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle representation = RepresentationUtil.CreateBRepProductDefinitionShape(app, exporterIFC, support, categoryId, supportGeometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); continue; } foreach (ElementId materialId in bodyData.MaterialIds) materialIds.Add(materialId); string supportGUID = ExporterIFCUtils.CreateGUID(support); string origSupportName = origStairName + " Stringer " + index; string supportName = NamingUtil.GetNameOverride(support, origSupportName); string supportDescription = NamingUtil.GetDescriptionOverride(support, stairDescription); string supportObjectType = NamingUtil.GetObjectTypeOverride(support, stairObjectType); IFCAnyHandle supportLocalPlacement = ecData.GetLocalPlacement(); string supportElementTag = NamingUtil.CreateIFCElementId(support); IFCAnyHandle type = GetMemberTypeHandle(exporterIFC, support); IFCAnyHandle supportHnd = IFCInstanceExporter.CreateMember(file, supportGUID, ownerHistory, supportName, supportDescription, supportObjectType, supportLocalPlacement, representation, supportElementTag); componentHandles.Add(supportHnd); componentExtrusionData.Add(ecData); productWrapper.AddElement(supportHnd, placementSetter.GetLevelInfo(), ecData, false); ExporterCacheManager.TypeRelationsCache.Add(type, supportHnd); } } StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(stairContainerHnd, componentHandles, null); ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(stair.Id, stairRampInfo); CategoryUtil.CreateMaterialAssociations(stair.Document, exporterIFC, stairContainerHnd, materialIds); ExportMultistoryStair(exporterIFC, stair, numFlights, stairContainerHnd, componentHandles, componentExtrusionData, materialIds, placementSetter, productWrapper); } tr.Commit(); } }
/// <summary> /// Prompt user to pick a face and paint it /// with the given material. If the face belongs /// to a stair run or landing, paint that part /// of the stair specifically. /// </summary> void PaintSelectedFace(UIDocument uidoc, Material mat) { Document doc = uidoc.Document; Selection sel = uidoc.Selection; List <String> errors = new List <string>(); //FaceSelectionFilter filter = new FaceSelectionFilter(); Reference pickedRef = sel.PickObject( ObjectType.PointOnElement, //filter, "Please select a face to paint"); Element elem = doc.GetElement(pickedRef); GeometryObject geoObject = elem .GetGeometryObjectFromReference(pickedRef); Face selected_face = geoObject as Face; using (Transaction transaction = new Transaction(doc)) { transaction.Start("Paint Selected Face"); if (elem.Category.Id.IntegerValue.Equals( (int)BuiltInCategory.OST_Stairs)) { Stairs str = elem as Stairs; bool IsLand = false; ICollection <ElementId> landings = str.GetStairsLandings(); ICollection <ElementId> runs = str.GetStairsRuns(); foreach (ElementId id in landings) { Element land = doc.GetElement(id); List <Solid> solids = GetElemSolids( land.get_Geometry(new Options())); IsLand = SolidsContainFace(solids, selected_face); if (IsLand) { break; } } if (IsLand) { foreach (ElementId id in landings) { doc.Paint(id, selected_face, mat.Id); break; } } else { foreach (ElementId id in runs) { doc.Paint(id, selected_face, mat.Id); break; } } } else { try { doc.Paint(elem.Id, selected_face, mat.Id); } catch (Exception ex) { TaskDialog.Show("Error painting selected face", ex.Message); } } transaction.Commit(); } }