应用程序:AutoParameter

Revit 平台:所有

Revit 版本:2011.0

首次发布于:2010.0

编程语言:C#

技能水平:中级

类别:参数、族

类型:ExternalCommand (外部命令)

主题:将参数自动添加到族文档中。

摘要:此示例演示如何将参数(共享或不共享)自动添加到族文档中。

相关类:

Autodesk.Revit.UI.IExternalCommand

Autodesk.Revit.Document

Autodesk.Revit.DB.FamilyManager

Autodesk.Revit.DB.FamilyParameter

Autodesk.Revit.DB.ExternalDefinition

项目文件:

命令.cs

该文件包含两个类:AddParameterToFamily和AddParameterToFamily。AddParameterToFamily实现了Execute方法,用于将参数添加到激活的族文档中。AddParameterToFamilies实现Execute方法,用于将参数添加到“我的文档”文件夹下的“AutoParameter_families”文件夹中的所有族。

族参数分配器.cs

此文件包含类FamilyParameterAssigner。此类将所有参数添加到族文件中。

功能:

此示例使用FamilyManager类来实现功能:将参数(共享或不共享)添加到指定的族文件中。

-要添加族参数,请使用AddParameter(String paramName、BuiltInParameterGroup paramGroup、ParameterType paramType、bool isInstance)方法;

-要添加共享参数,请使用AddParameter(ExternalDefinition familyDefinition、BuiltInParameterGroup paramGroup、bool isInstance)方法;

实施

1.为了自动将参数添加到族文件中,用户应准备参数文件:族参数文件和共享参数文件。

族参数文件应命名为“familyParameter.txt”,并与示例DLL放在同一文件夹中。

共享参数文件应命名为“sharedParameter.txt”,并与示例DLL放在同一文件夹中。

以下是如何组织文件的示例:

根文件夹:

│  AutoParameter.dll(这是示例dll)

│      共享参数.txt

│       家庭参数.txt

2.参数文件格式:对于共享参数文件,采用Revit共享参数文件格式;对于族参数文件,它有类似的格式:以“#”或“*”开头的每一行都将被视为注释行并将被跳过,每个参数行都应遵循以下格式:“ParamName ParamGroup ParamType IsInstance”,并用空格分隔。

以下是族参数文件的模板:

#这是一个Revit族参数文件。

#允许手动编辑。

#确保“ParamGroup”和“ParamType”值正确(带或不带#“BuiltInParameterGroup.”和“ParameterType.”不会影响功能)。

*ParamName参数组参数类型IsInstance FamilyParam1 PG_TEXT TEXT false FamilyParam2内置参数组.PG_TEXT参数类型.TEXT true

3.要将参数添加到族文件中,请启动Revit,打开族文件,然后单击外部命令“AddParameterToFamily”,所有参数(共享或非共享)都将添加到激活的族文档中;

4.要将参数添加到多个族文件中,需要执行以下步骤:

a) 在“我的文档”文件夹中创建一个文件夹“AutoParameter_Families”;

b) 将所有族文件放在新文件夹中,确保所有文件都是可写的(如果某些文件是只读的,则无法添加参数);

c) 启动Revit,创建一个项目,单击外部命令“AddParameterToFamilies”,所有参数都将添加到“AutoParameter_Families”文件夹中的所有族文件中

完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码

FamilyParameterAssigner.cs

//
// (C) Copyright 2003-2019 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.
//

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Reflection;

using Autodesk.Revit;
using Autodesk.Revit.DB;

namespace Revit.SDK.Samples.AutoParameter.CS
{
   /// <summary>
   /// add parameters(family parameters/shared parameters) to the opened family file
   /// the parameters are recorded in txt file following certain formats
   /// </summary>
   class FamilyParameterAssigner
   {
      #region Memeber Fields
      private Autodesk.Revit.ApplicationServices.Application m_app;
      private FamilyManager m_manager = null;
      string m_assemblyPath;
      // indicate whether the parameter files have been loaded. If yes, no need to load again.
      bool m_paramLoaded;

      // set the paramName as key of dictionary for exclusiveness (the names of parameters should be unique)
      private Dictionary<string /*paramName*/, FamilyParam> m_familyParams;
      private DefinitionFile m_sharedFile;
      private string m_familyFilePath = string.Empty;
      private string m_sharedFilePath = string.Empty;
      #endregion

      /// <summary>
      /// constructor
      /// </summary>
      /// <param name="app">
      /// the active revit application
      /// </param>
      /// <param name="doc">
      /// the family document which will have parameters added in
      /// </param>
      public FamilyParameterAssigner(Autodesk.Revit.ApplicationServices.Application app, Document doc)
      {
         m_app = app;
         m_manager = doc.FamilyManager;
         m_familyParams = new Dictionary<string, FamilyParam>();
         m_assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
         m_paramLoaded = false;
      }

      /// <summary>
      /// load the family parameter file (if exists) and shared parameter file (if exists)
      /// only need to load once
      /// </summary>
      /// <returns>
      /// if succeeded, return true; otherwise false
      /// </returns>
      public bool LoadParametersFromFile()
      {
         if (m_paramLoaded)
         {
            return true;
         }
         // load family parameter file
         bool famParamFileExist;
         bool succeeded = LoadFamilyParameterFromFile(out famParamFileExist);
         if (!succeeded)
         {
            return false;
         }

         // load shared parameter file
         bool sharedParamFileExist;
         succeeded = LoadSharedParameterFromFile(out sharedParamFileExist);
         if (!(famParamFileExist || sharedParamFileExist))
         {
            MessageManager.MessageBuff.AppendLine("Neither familyParameter.txt nor sharedParameter.txt exists in the assembly folder.");
            return false;
         }
         if (!succeeded)
         {
            return false;
         }
         m_paramLoaded = true;
         return true;
      }

      /// <summary>
      /// load family parameters from the text file
      /// </summary>
      /// <returns>
      /// return true if succeeded; otherwise false
      /// </returns>
      private bool LoadFamilyParameterFromFile(out bool exist)
      {
         exist = true;
         // step 1: find the file "FamilyParameter.txt" and open it
         string fileName = m_assemblyPath + "\\FamilyParameter.txt";
         if (!File.Exists(fileName))
         {
            exist = false;
            return true;
         }

         FileStream file = null;
         StreamReader reader = null;
         try
         {
            file = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            reader = new StreamReader(file);

            // step 2: read each line, if the line records the family parameter data, store it
            // record the content of the current line
            string line;
            // record the row number of the current line
            int lineNumber = 0;
            while (null != (line = reader.ReadLine()))
            {
               ++lineNumber;
               // step 2.1: verify the line
               // check whether the line is blank line (contains only whitespaces)
               Match match = Regex.Match(line, @"^\s*$");
               if (true == match.Success)
               {
                  continue;
               }

               // check whether the line starts from "#" or "*" (comment line)
               match = Regex.Match(line, @"\s*['#''*'].*");
               if (true == match.Success)
               {
                  continue;
               }

               // step 2.2: get the parameter data
               // it's a valid line (has the format of "paramName   paramGroup    paramType    isInstance", separate by tab or by spaces)
               // split the line to an array containing parameter items (format of string[] {"paramName", "paramGroup", "paramType", "isInstance"})
               string[] lineData = Regex.Split(line, @"\s+");
               // check whether the array has blank items (containing only spaces)
               List<string> values = new List<string>();
               foreach (string data in lineData)
               {
                  match = Regex.Match(data, @"^\s*$");
                  if (true == match.Success)
                  {
                     continue;
                  }

                  values.Add(data);
               }

               // verify the parameter items (should have 4 items exactly: paramName, paramGroup, paramType and isInstance)
               if (4 != values.Count)
               {
                  MessageManager.MessageBuff.Append("Loading family parameter data from \"FamilyParam.txt\".");
                  MessageManager.MessageBuff.Append("Line [\"" + line + "]\"" + "doesn't follow the valid format.\n");
                  return false;
               }

               // get the paramName
               string paramName = values[0];
               // get the paramGroup
               string groupString = values[1];
               // in case the groupString is format of "BuiltInParameterGroup.PG_Text", need to remove the "BuiltInParameterGroup.",
               // keep the "PG_Text" only
               int index = -1;
               if (0 <= (index = groupString.ToLower().IndexOf("builtinparametergroup")))
               {
                  // why +1? need to remove the "." after "builtinparametergroup"
                  groupString = groupString.Substring(index + 1 + "builtinparametergroup".Length);
               }
               BuiltInParameterGroup paramGroup = (BuiltInParameterGroup)Enum.Parse(typeof(BuiltInParameterGroup), groupString);

               // get the paramType
               string typeString = values[2];
               if (0 <= (index = typeString.ToLower().IndexOf("parametertype")))
               {
                  // why +1? need to remove the "." after "builtinparametergroup"
                  typeString = typeString.Substring(index + 1 + "parametertype".Length);
               }
               ParameterType paramType = (ParameterType)Enum.Parse(typeof(ParameterType), typeString);
               // get data "isInstance"
               string isInstanceString = values[3];
               bool isInstance = Convert.ToBoolean(isInstanceString);

               // step 2.3: store the parameter fetched, check for exclusiveness (as the names of parameters should keep unique)
               FamilyParam param = new FamilyParam(paramName, paramGroup, paramType, isInstance, lineNumber);
               // the family parameter with the same name has already been stored to the dictionary, raise an error
               if (m_familyParams.ContainsKey(paramName))
               {
                  FamilyParam duplicatedParam = m_familyParams[paramName];
                  string warning = "Line " + param.Line + "has a duplicate parameter name with Line " + duplicatedParam.Line + "\n";
                  MessageManager.MessageBuff.Append(warning);
                  continue;
               }
               m_familyParams.Add(paramName, param);
            }
         }
         catch (System.Exception e)
         {
            MessageManager.MessageBuff.AppendLine(e.Message);
            return false;
         }
         finally
         {
            if (null != reader)
            {
               reader.Close();
            }
            if (null != file)
            {
               file.Close();
            }
         }

         return true;
      }

      /// <summary>
      /// load family parameters from the text file
      /// </summary>
      /// <param name="exist">
      /// indicate whether the shared parameter file exists
      /// </param>
      /// <returns>
      /// return true if succeeded; otherwise false
      /// </returns>
      private bool LoadSharedParameterFromFile(out bool exist)
      {
         exist = true;
         string filePath = m_assemblyPath + "\\SharedParameter.txt";
         if (!File.Exists(filePath))
         {
            exist = false;
            return true;
         }

         m_app.SharedParametersFilename = filePath;
         try
         {
            m_sharedFile = m_app.OpenSharedParameterFile();
         }
         catch (System.Exception e)
         {
            MessageManager.MessageBuff.AppendLine(e.Message);
            return false;
         }

         return true;
      }

      /// <summary>
      /// add parameters to the family file
      /// </summary>
      /// <returns>
      /// if succeeded, return true; otherwise false
      /// </returns>
      public bool AddParameters()
      {
         // add the loaded family parameters to the family
         bool succeeded = AddFamilyParameter();
         if (!succeeded)
         {
            return false;
         }

         // add the loaded shared parameters to the family
         succeeded = AddSharedParameter();
         if (!succeeded)
         {
            return false;
         }

         return true;
      }

      /// <summary>
      /// add family parameter to the family
      /// </summary>
      /// <returns>
      /// if succeeded, return true; otherwise false
      /// </returns>
      private bool AddFamilyParameter()
      {
         bool allParamValid = true;
         if (File.Exists(m_familyFilePath) && 
            0 == m_familyParams.Count)
         {
            MessageManager.MessageBuff.AppendLine("No family parameter available for adding.");
            return false;
         }

         foreach (FamilyParameter param in m_manager.Parameters)
         {
            string name = param.Definition.Name;
            if (m_familyParams.ContainsKey(name))
            {
               allParamValid = false;
               FamilyParam famParam = m_familyParams[name];
               MessageManager.MessageBuff.Append("Line " + famParam.Line + ": paramName \"" + famParam.Name + "\"already exists in the family document.\n");
            }
         }

         // there're errors in the family parameter text file
         if (!allParamValid)
         {
            return false;
         }

         foreach (FamilyParam param in m_familyParams.Values)
         {
            try
            {
               m_manager.AddParameter(param.Name, param.Group, param.Type, param.IsInstance);  
            }
            catch(Exception e)
            {
               MessageManager.MessageBuff.AppendLine(e.Message); 
               return false;
            }
         }

         return true;
      }

      /// <summary>
      /// load shared parameters from shared parameter file and add them to family
      /// </summary>
      /// <returns>
      /// if succeeded, return true; otherwise false
      /// </returns>
      private bool AddSharedParameter()
      {
         if (File.Exists(m_sharedFilePath) &&
             null == m_sharedFile)
         {
            MessageManager.MessageBuff.AppendLine("SharedParameter.txt has an invalid format.");
            return false;
         }

         foreach (DefinitionGroup group in m_sharedFile.Groups)
         {
            foreach (ExternalDefinition def in group.Definitions)
            {
               // check whether the parameter already exists in the document
               FamilyParameter param = m_manager.get_Parameter(def.Name);
               if (null != param)
               {
                  continue;
               }

               try
               {
                  m_manager.AddParameter(def, def.ParameterGroup, true);
               }
               catch (System.Exception e)
               {
                  MessageManager.MessageBuff.AppendLine(e.Message);
                  return false;
               }
            }
         }

         return true;
      }

   }// end of class "FamilyParameterAssigner"

   /// <summary>
   /// record the data of a parameter: its name, its group, etc
   /// </summary>
   class FamilyParam
   {
      string m_name;
      /// <summary>
      /// the caption of the parameter
      /// </summary>
      public string Name
      {
         get { return m_name; }
      }

      BuiltInParameterGroup m_group;
      /// <summary>
      /// the group of the parameter
      /// </summary>
      public BuiltInParameterGroup Group
      {
         get { return m_group; }
      }

      ParameterType m_type;
      /// <summary>
      /// the type of the parameter
      /// </summary>
      public ParameterType Type
      {
         get { return m_type; }
      }

      bool m_isInstance;
      /// <summary>
      /// indicate whether the parameter is an instance parameter or a type parameter
      /// </summary>
      public bool IsInstance
      {
         get { return m_isInstance; }
      }

      int m_line;
      /// <summary>
      /// record the location of this parameter in the family parameter file
      /// </summary>
      public int Line
      {
         get { return m_line; }
      }

      /// <summary>
      /// default constructor, hide this by making it "private"
      /// </summary>
      private FamilyParam() 
      { 
      }

      /// <summary>
      /// constructor which exposes for invoking
      /// </summary>
      /// <param name="name">
      /// parameter name
      /// </param>
      /// <param name="group">
      /// indicate which group the parameter belongs to
      /// </param>
      /// <param name="type">
      /// the type of the parameter
      /// </param>
      /// <param name="isInstance">
      /// indicate whethe the parameter is an instance parameter
      /// </param>
      /// <param name="line">
      /// record the location of this parameter in the family parameter file
      /// </param>
      public FamilyParam(string name, BuiltInParameterGroup group, ParameterType type, bool isInstance, int line)
      {
         m_name = name;
         m_group = group;
         m_type = type;
         m_isInstance = isInstance;
         m_line = line;
      }
   }
}