using Autodesk.Revit.DB; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using KDCS.Utils; using KMBIM.Utils; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace KMBIM.Revit.Tools.Cmd.DuctSize { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)] [Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)] class DuctViCmd : IExternalCommand { UIApplication m_pUIApp; UIDocument uidoc = null; Document doc = null; List _added_emement_ids = new List(); Autodesk.Revit.DB.Mechanical.Duct m_duct; XYZ m_pt1, m_pt2; public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements) { try { if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded; m_pUIApp = commandData.Application; uidoc = m_pUIApp.ActiveUIDocument; doc = uidoc.Document; MechanicalSystemType ductSystemType = null; Selection sel1 = uidoc.Selection; DefinitionFile informationFile = OpenSharedParameter(); if (null == informationFile) { return Result.Failed; } List selIds = new List(); // 선택된 아이디 List visitedIds = new List(); // 방문한 덕트 아이디 uidoc.Selection.SetElementIds(visitedIds); var ductrefs = uidoc.Selection.PickObjects(ObjectType.Element, "풍량을 입력할 덕트 대행자 선택"); if (ductrefs == null) return Result.Failed; Autodesk.Revit.DB.Mechanical.Duct ductMain = doc.GetElement(ductrefs.First()) as Autodesk.Revit.DB.Mechanical.Duct; // 내부 흐름 기본 단위는 ft3/s; 1 ft3/s = 101.9406477312 m3/h, 1m3/h = 0.0098096296448581 // 1 m3/h = 0.009809629644857942 ft3/s double m3_per_h = 0.0098096296448581; // 1m3/h = 0.0098096296448581 ft3/s // 개별풍량, 전체풍량 파라미터 준비 InitDuctFlow(ductMain, informationFile, "IndividualFlow"); InitDuctFlow(ductMain, informationFile, "TotalFlow"); Autodesk.Revit.DB.Parameter paramIF = ductMain.LookupParameter("IndividualFlow"); double dblFlow = paramIF.AsDouble(); double cmh = dblFlow * 101.9406477312; FormDuctVi frmVi = new FormDuctVi(); frmVi.Flow = cmh; if (frmVi.ShowDialog() == DialogResult.OK) { using (Transaction trans = new Transaction(doc)) { trans.Start("Set Air Flow"); foreach (Reference refer in ductrefs) { ElementId idDuct = refer.ElementId; ductMain = doc.GetElement(idDuct) as Autodesk.Revit.DB.Mechanical.Duct; if (ductMain == null) return Result.Failed; // 개별풍량, 전체풍량 파라미터 준비 InitDuctFlow(ductMain, informationFile, "IndividualFlow"); InitDuctFlow(ductMain, informationFile, "TotalFlow"); paramIF = ductMain.LookupParameter("IndividualFlow"); paramIF.Set(frmVi.Flow * m3_per_h); // ft3/s Autodesk.Revit.DB.Parameter paramTF = ductMain.LookupParameter("TotalFlow"); paramTF.Set(0d); // ft3/s } trans.Commit(); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } return Result.Succeeded; } private void InitDuctFlow(Autodesk.Revit.DB.Mechanical.Duct ductMain, DefinitionFile informationFile, string parameterName) { Definition defIndividualFlow = null; Autodesk.Revit.DB.Parameter paramIF = ductMain.LookupParameter(parameterName); SharedParameterBindingManager manager = new SharedParameterBindingManager(); manager.parameterName = parameterName; #if _22 || _23 manager.parameterType = SpecTypeId.AirFlow; #else manager.parameterType = ParameterType.HVACAirflow; #endif manager.UserModifiable = true; if (paramIF == null) { DefinitionGroup defGroup = informationFile.Groups.get_Item("Duct"); if (defGroup != null) { defIndividualFlow = defGroup.Definitions.get_Item(parameterName); if (defIndividualFlow != null) { // Create a new Binding object with the categories to which the parameter will be bound. CategorySet categories = m_pUIApp.Application.Create.NewCategorySet(); // get door category and insert into the CategorySet. Category ductCategory = m_pUIApp.ActiveUIDocument.Document.Settings.Categories. get_Item(BuiltInCategory.OST_PlaceHolderDucts); categories.Insert(ductCategory); InstanceBinding instanceBinding = m_pUIApp.Application.Create.NewInstanceBinding(categories); BindingMap bindingMap = m_pUIApp.ActiveUIDocument.Document.ParameterBindings; // for "IndividualFlow" if (!AlreadyAddedSharedParameter(m_pUIApp.ActiveUIDocument.Document, parameterName, BuiltInCategory.OST_PlaceHolderDucts)) { Definition instanceIndividualFlow = defGroup.Definitions.get_Item(parameterName); if (null == instanceIndividualFlow) { #if _23 ExternalDefinitionCreationOptions ExternalDefinitionCreationOptions2 = new ExternalDefinitionCreationOptions(parameterName, SpecTypeId.AirFlow); #else ExternalDefinitionCreationOptions ExternalDefinitionCreationOptions2 = new ExternalDefinitionCreationOptions(parameterName, ParameterType.HVACAirflow); #endif instanceIndividualFlow = defGroup.Definitions.Create(ExternalDefinitionCreationOptions2); } using (Transaction trans = new Transaction(doc)) { trans.Start("Add Shared Parameter"); // Add the binding and definition to the document. bindingMap.Insert(instanceIndividualFlow, instanceBinding, BuiltInParameterGroup.PG_MECHANICAL_AIRFLOW); trans.Commit(); } } } } } } private DefinitionFile OpenSharedParameter() { //Method's return DefinitionFile informationFile = null; // create shared parameter file var location = Util.GetKMBIMLibraryFolder("SharedParameter"); string sharedParameterFile = Path.Combine(location, "KMBIMSharedParameter.txt"); if (File.Exists(sharedParameterFile)) { m_pUIApp.Application.SharedParametersFilename = sharedParameterFile; informationFile = m_pUIApp.Application.OpenSharedParameterFile(); } return informationFile; } /// /// Has the specific document shared parameter already been added ago? /// /// Revit project in which the shared parameter will be added. /// the name of the shared parameter. /// Which category the parameter will bind to /// Returns true if already added ago else returns false. private bool AlreadyAddedSharedParameter(Document doc, string paraName, BuiltInCategory boundCategory) { try { BindingMap bindingMap = doc.ParameterBindings; DefinitionBindingMapIterator bindingMapIter = bindingMap.ForwardIterator(); while (bindingMapIter.MoveNext()) { if (bindingMapIter.Key.Name.Equals(paraName)) { ElementBinding binding = bindingMapIter.Current as ElementBinding; CategorySet categories = binding.Categories; foreach (Category category in categories) { if (category.Id.IntegerValue.Equals((int)boundCategory)) { return true; } } } } } catch (Exception) { return false; } return false; } } }