#region Copyright // // Copyright (C) 2010-2011 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // // Ported from old rac labs by Jeremy Tammik // #endregion // Copyright #region Namespaces using System; using System.Diagnostics; using System.Collections.Generic; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using System.IO; #endregion namespace IntroCs { /// /// Create a new shared parameter, then set and /// retrieve its value. /// In this example, we store a fire rating value /// on all doors. /// Please also look at the FireRating Revit SDK sample. /// /// ' To View Per-doc shared parameters in Revit 2013 //'Ribbon-> Manage Tab -> Project Information //' To view per-element shared parameter in Revit 2013 //' In the project browser -> Families --> Doors // --> Select any door type (say M_Single-Flush --> 0762 x 2032mm) //'Right-Click -> Type Properties [Autodesk.Revit.Attributes.Transaction (Autodesk.Revit.Attributes.TransactionMode.Manual)] [Autodesk.Revit.Attributes.Regeneration (Autodesk.Revit.Attributes.RegenerationOption.Manual)] class SharedParameter : IExternalCommand { const string kSharedParamsGroupAPI = "API Parameters"; const string kSharedParamsDefFireRating = "API FireRating"; const string kSharedParamsPath = "C:\\Temp\\SharedParams.txt"; public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements ) { UIDocument uidoc = commandData.Application.ActiveUIDocument; Application app = commandData.Application.Application; Document doc = uidoc.Document; // Get the current shared params definition file DefinitionFile sharedParamsFile = GetSharedParamsFile(app); if (null == sharedParamsFile) { message = "Error getting the shared params file."; return Result.Failed; } // Get or create the shared params group DefinitionGroup sharedParamsGroup = GetOrCreateSharedParamsGroup ( sharedParamsFile, kSharedParamsGroupAPI ); if (null == sharedParamsGroup) { message = "Error getting the shared params group."; return Result.Failed; } Category cat = doc.Settings.Categories.get_Item ( BuiltInCategory.OST_Doors ); // Visibility of the new parameter: // Category.AllowsBoundParameters property indicates // if a category can have shared or project parameters. // If it is false, it may not be bound to shared // parameters using the BindingMap. // Please note that non-user-visible parameters can // still be bound to these categories. bool visible = cat.AllowsBoundParameters; // Get or create the shared params definition Definition fireRatingParamDef = GetOrCreateSharedParamsDefinition ( sharedParamsGroup, ParameterType.Number, kSharedParamsDefFireRating, visible ); if (null == fireRatingParamDef) { message = "Error in creating shared parameter."; return Result.Failed; } // Create the category set for binding and add the // category we are interested in, doors or walls or // whatever: CategorySet catSet = app.Create.NewCategorySet(); try { catSet.Insert(cat); } catch (Exception) { message = string.Format ( "Error adding '{0}' category to parameters binding set.", cat.Name ); return Result.Failed; } // Bind the param try { Binding binding = app.Create.NewInstanceBinding ( catSet ); // We could check if already bound, but looks like // Insert will just ignore it in such case doc.ParameterBindings.Insert( fireRatingParamDef, binding ); } catch (Exception ex) { message = ex.Message; return Result.Failed; } return Result.Succeeded; } /// /// Helper to get shared parameters file. /// public static DefinitionFile GetSharedParamsFile(Application app) { // Get current shared params file name string sharedParamsFileName; try { sharedParamsFileName = app.SharedParametersFilename; } catch (Exception ex) { TaskDialog.Show( "Get shared params file", "No shared params file set:" + ex.Message ); return null; } if (0 == sharedParamsFileName.Length || !System.IO.File.Exists(sharedParamsFileName)) { StreamWriter stream; stream = new StreamWriter(kSharedParamsPath); stream.Close(); app.SharedParametersFilename = kSharedParamsPath; sharedParamsFileName = app.SharedParametersFilename; } // Get the current file object and return it DefinitionFile sharedParametersFile; try { sharedParametersFile = app.OpenSharedParameterFile(); } catch (Exception ex) { TaskDialog.Show( "Get shared params file", "Cannnot open shared params file:" + ex.Message); sharedParametersFile = null; } return sharedParametersFile; } public static DefinitionGroup GetOrCreateSharedParamsGroup ( DefinitionFile sharedParametersFile, string groupName ) { DefinitionGroup g = sharedParametersFile.Groups.get_Item(groupName); if (null == g) { try { g = sharedParametersFile.Groups.Create(groupName); } catch (Exception) { g = null; } } return g; } public static Definition GetOrCreateSharedParamsDefinition ( DefinitionGroup defGroup, ParameterType defType, string defName, bool visible ) { Definition definition = defGroup.Definitions.get_Item(defName); if (null == definition) { try { definition = defGroup.Definitions.Create( defName, defType, visible ); } catch (Exception) { definition = null; } } return definition; } } [Transaction(TransactionMode.Automatic)] public class PerDocParameter : IExternalCommand { public const string kParamGroupName = "Per-doc Params"; public const string kParamNameVisible = "Visible per-doc Integer"; public const string kParamNameInvisible = "Invisible per-doc Integer"; public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uiDoc = commandData.Application.ActiveUIDocument; Application app = commandData.Application.Application; Document doc = uiDoc.Document; // get the current shared params definition file DefinitionFile sharedParamsFile = SharedParameter.GetSharedParamsFile(app); if (null == sharedParamsFile) { TaskDialog.Show( "Per document parameter", "Error getting the shared params file." ); return Result.Failed; } // get or create the shared params group DefinitionGroup sharedParamsGroup = SharedParameter.GetOrCreateSharedParamsGroup ( sharedParamsFile, kParamGroupName ); if (null == sharedParamsGroup) { TaskDialog.Show ( "Per document parameter", "Error getting the shared params group." ); return Result.Failed; } // visible param Definition docParamDefVisible = SharedParameter.GetOrCreateSharedParamsDefinition ( sharedParamsGroup, ParameterType.Integer, kParamNameVisible, true ); if (null == docParamDefVisible) { TaskDialog.Show ( "Per document parameter", "Error creating visible per-doc parameter." ); return Result.Failed; } // invisible param Definition docParamDefInvisible = SharedParameter.GetOrCreateSharedParamsDefinition ( sharedParamsGroup, ParameterType.Integer, kParamNameInvisible, false ); if (null == docParamDefInvisible) { TaskDialog.Show ( "Per document parameter", "Error creating invisible per-doc parameter." ); return Result.Failed; } // bind the param try { CategorySet catSet = app.Create.NewCategorySet(); Category cat = doc.Settings.Categories.get_Item ( BuiltInCategory.OST_ProjectInformation ); catSet.Insert(cat); Binding binding = app.Create.NewInstanceBinding(catSet); doc.ParameterBindings.Insert ( docParamDefVisible, binding ); doc.ParameterBindings.Insert ( docParamDefInvisible, binding ); } catch (Exception e) { TaskDialog.Show ( "Per document parameter", "Error binding shared parameter: " + e.Message ); return Result.Failed; } // set the initial values // get the singleton project info element Element projInfoElem = GetProjectInfoElem(doc); if (null == projInfoElem) { TaskDialog.Show ( "Per document parameter", "No project info elem found. Aborting command..." ); return Result.Failed; } // for simplicity, access params by name rather than by GUID: projInfoElem.get_Parameter(kParamNameVisible).Set(55); projInfoElem.get_Parameter(kParamNameInvisible).Set(0); return Result.Succeeded; } /// /// Return the one and only project information element /// using Revit 2009 filtering by searching for the /// "Project Information" category. /// Only one such element exists. /// public static Element GetProjectInfoElem(Document doc) { FilteredElementCollector collector = new FilteredElementCollector(doc); collector.OfCategory ( BuiltInCategory.OST_ProjectInformation ); IList elems = collector.ToElements(); Debug.Assert(elems.Count == 1, "There should be exactly one of this object in the project"); return elems[0]; } } } // namespace