public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; bool rc; using (Transaction t = new Transaction(doc)) { #region 3.2.a Load an entire RFA family file: // Load a whole Family // // Example for a family WITH TXT file: rc = doc.LoadFamily(LabConstants.WholeFamilyFileToLoad1); #endregion // 3.2.a if (rc) { LabUtils.InfoMsg("Successfully loaded family " + LabConstants.WholeFamilyFileToLoad1 + "."); } else { LabUtils.ErrorMsg("ERROR loading family " + LabConstants.WholeFamilyFileToLoad1 + "."); } // Example for a family WITHOUT TXT file: rc = doc.LoadFamily(LabConstants.WholeFamilyFileToLoad2); if (rc) { LabUtils.InfoMsg("Successfully loaded family " + LabConstants.WholeFamilyFileToLoad2 + "."); } else { LabUtils.ErrorMsg("ERROR loading family " + LabConstants.WholeFamilyFileToLoad2 + "."); } #region 3.2.b Load an individual type from a RFA family file: // Load only a specific symbol (type): rc = doc.LoadFamilySymbol( LabConstants.FamilyFileToLoadSingleSymbol, LabConstants.SymbolName); #endregion // 3.2.b if (rc) { LabUtils.InfoMsg("Successfully loaded family symbol " + LabConstants.FamilyFileToLoadSingleSymbol + " : " + LabConstants.SymbolName + "."); } else { LabUtils.ErrorMsg("ERROR loading family symbol " + LabConstants.FamilyFileToLoadSingleSymbol + " : " + LabConstants.SymbolName + "."); } t.Commit(); } return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; UIDocument uidoc = app.ActiveUIDocument; Document doc = uidoc.Document; FamilyInstance inst = LabUtils.GetSingleSelectedElementOrPrompt( uidoc, typeof(FamilyInstance)) as FamilyInstance; if (null == inst) { LabUtils.ErrorMsg( "Selected element is not a " + "standard family instance."); return(Result.Cancelled); } // determine selected instance category: Category instCat = inst.Category; Dictionary <string, List <FamilySymbol> > mapFamilyToSymbols = new Dictionary <string, List <FamilySymbol> >(); { WaitCursor waitCursor = new WaitCursor(); // Collect all types applicable to this category and sort them into // a dictionary mapping the family name to a list of its types. // // We create a collection of all loaded families for this category // and for each one, the list of all loaded types (symbols). // // There are many ways how to store the matching objects, but we choose // whatever is most suitable for the relevant UI. We could use Revit's // generic Map class, but it is probably more efficient to use the .NET // strongly-typed Dictionary with // KEY = Family name (String) // VALUE = list of corresponding FamilySymbol objects // // find all corresponding families and types: FilteredElementCollector families = new FilteredElementCollector(doc); families.OfClass(typeof(Family)); foreach (Family f in families) { bool categoryMatches = false; ISet <ElementId> ids = f.GetFamilySymbolIds(); // 2015 // we cannot trust f.Category or // f.FamilyCategory, so grab the category // from first family symbol instead: //foreach( FamilySymbol sym in f.Symbols ) // 2014 foreach (ElementId id in ids) // 2015 { Element symbol = doc.GetElement(id); categoryMatches = symbol.Category.Id.Equals( instCat.Id); break; } if (categoryMatches) { List <FamilySymbol> symbols = new List <FamilySymbol>(); //foreach( FamilySymbol sym in f.Symbols ) // 2014 foreach (ElementId id in ids) // 2015 { FamilySymbol symbol = doc.GetElement(id) as FamilySymbol; symbols.Add(symbol); } mapFamilyToSymbols.Add(f.Name, symbols); } } } // display the form allowing the user to select // a family and a type, and assign this type // to the instance. Lab3_4_Form form = new Lab3_4_Form(mapFamilyToSymbols); if (System.Windows.Forms.DialogResult.OK == form.ShowDialog()) { using (Transaction t = new Transaction(doc)) { t.Start("Change Selected Instance Type"); inst.Symbol = form.cmbType.SelectedItem as FamilySymbol; t.Commit(); } LabUtils.InfoMsg( "Successfully changed family : type to " + form.cmbFamily.Text + " : " + form.cmbType.Text); } return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; UIDocument uidoc = app.ActiveUIDocument; Document doc = uidoc.Document; //ElementSet ss = uidoc.Selection.Elements; // 2014 ICollection <ElementId> ids = uidoc.Selection.GetElementIds(); Wall wall = null; if (0 < ids.Count) { // old pre-selection handling: // must be one single element only: if (1 != ids.Count) { message = "Please pre-select a single wall element."; return(Result.Failed); } // must be a wall: //ElementSetIterator it = ss.ForwardIterator(); //it.MoveNext(); //Element e = it.Current as Element; ElementId id = ids.First <ElementId>(); Element e = doc.GetElement(id); if (!(e is Wall)) { message = "Selected element is NOT a wall."; return(Result.Failed); } wall = e as Wall; } else { // new prompt for filtered selection allowing only walls: try { Reference r = uidoc.Selection.PickObject( ObjectType.Element, new WallSelectionFilter(), "Please pick a wall"); //wall = r.Element as Wall; // 2011 wall = uidoc.Document.GetElement(r) as Wall; // 2012 } catch (OperationCanceledException) { message = "Selection cancelled."; return(Result.Cancelled); } } // wall must be constrained to a level at the top (more on parameters later): Level topLev = null; try { ElementId id = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId(); topLev = doc.GetElement(id) as Level; } catch (Exception) { topLev = null; } if (null == topLev) { message = "Selected wall is not constrained to a level at the top."; return(Result.Failed); } // get the bottom level as well (this should never fail): Level botLev = null; try { ElementId id = wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).AsElementId(); botLev = doc.GetElement(id) as Level; } catch (Exception) { botLev = null; } if (null == botLev) { message = "Selected wall is not constrained to a level at the bottom."; return(Result.Failed); } // Calculate the location points for the 3 columns (assuming straight wall) LocationCurve locCurve = wall.Location as LocationCurve; XYZ ptStart = locCurve.Curve.GetEndPoint(0); XYZ ptEnd = locCurve.Curve.GetEndPoint(1); XYZ ptMid = 0.5 * (ptStart + ptEnd); List <XYZ> locations = new List <XYZ>(3); locations.Add(ptStart); locations.Add(ptMid); locations.Add(ptEnd); string s = "{0} location{1} for the new columns in raw database coordinates, e.g. feet{2}"; List <string> a = new List <string>(); a.Add("Start: " + LabUtils.PointString(ptStart)); a.Add("Mid : " + LabUtils.PointString(ptMid)); a.Add("End : " + LabUtils.PointString(ptEnd)); LabUtils.InfoMsg(s, a); FilteredElementCollector collector = new FilteredElementCollector(doc); collector.OfCategory(BuiltInCategory.OST_Columns); collector.OfClass(typeof(FamilySymbol)); #if SEARCH_FOR_SPECIFIC_NAME // retrieve the family type for the new instances. // if needed, change the names to match a column // type available in the model: string family_name = "M_Wood Timber Column"; string type_name = "191 x 292mm"; // LINQ query to find element with given name: // // ... note that this could also be achieved by // filtering for the element name parameter value. var column_types = from element in collector //where ((FamilySymbol)element).Family.Name == family_name where element.Name == type_name select element; FamilySymbol symbol = null; try { symbol = column_types.Cast <FamilySymbol>().First <FamilySymbol>(); } catch { } if (null == symbol) { message = string.Format( "Cannot find type '{0}' in family '{1}' in the current model - please load it first.", type_name, family_name); return(Result.Failed); } #endif // SEARCH_FOR_SPECIFIC_NAME FamilySymbol symbol = collector.Cast <FamilySymbol>().First <FamilySymbol>(); if (null == symbol) { message = "Cannot find a suitable column type."; return(Result.Failed); } using (Transaction tx = new Transaction(doc)) { tx.Start("Insert Columns and Move Wall"); // insert column family instances: foreach (XYZ p in locations) { try { // Note: Currently there is a problem. // If we set the type as NonStructural, it is treated as Annotation instance, // and it shows only in plan view. // FamilyInstance column = doc.Create.NewFamilyInstance( p, symbol, botLev, StructuralType.NonStuctural ); FamilyInstance column = doc.Create.NewFamilyInstance( p, symbol, botLev, StructuralType.Column); Parameter paramTopLevel = column.get_Parameter( BuiltInParameter.FAMILY_TOP_LEVEL_PARAM); ElementId id = topLev.Id; paramTopLevel.Set(id); } catch (Exception) { LabUtils.ErrorMsg("Failed to create or adjust column."); } } // Finally, move the wall so the columns are visible. // We move the wall perpendicularly to its location // curve by one tenth of its length: XYZ v = new XYZ( -0.1 * (ptEnd.Y - ptStart.Y), 0.1 * (ptEnd.X - ptStart.X), 0); if (!wall.Location.Move(v)) { LabUtils.ErrorMsg("Failed to move the wall."); } tx.Commit(); } return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { #region 2.1.a. Access Revit doc and open output file: UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; // .NET exception handling should be done everywhere, // but will sometimes be omitted for clarity in the // following labs unless we expect exceptions: StreamWriter sw; try { sw = new StreamWriter(LabConstants.FilePath); } catch (Exception e) { LabUtils.ErrorMsg(string.Format("Cannot open '{0}': {1}", LabConstants.FilePath, e.Message)); return(Result.Failed); } #endregion // 2.1.a. Access Revit doc and open output file try { WaitCursor waitCursor = new WaitCursor(); #region 2.1.b. Set up element collector to retrieve all elements: // the Revit API does not expect an application // ever to need to iterate over all elements. // To do so, we need to use a trick: ask for all // elements fulfilling a specific criteria and // unite them with all elements NOT fulfilling // the same criteria: FilteredElementCollector collector = new FilteredElementCollector(doc) .WhereElementIsElementType(); FilteredElementCollector collector2 = new FilteredElementCollector(doc) .WhereElementIsNotElementType(); collector.UnionWith(collector2); #endregion // 2.1.b. Set up element collector to retrieve all elements #region 2.1.c. Loop over the elements, list their data, and close the file: string s, line; foreach (Element e in collector) { line = "Id=" + e.Id.IntegerValue.ToString(); // element id line += "; Class=" + e.GetType().Name; // element class, i.e. System.Type // The element category is not implemented for all classes, // and may return null; for Family elements, one can sometimes // use the FamilyCategory property instead. s = string.Empty; if (null != e.Category) { s = e.Category.Name; } if (0 == s.Length && e is Family && null != ((Family)e).FamilyCategory) { s = ((Family)e).FamilyCategory.Name; } if (0 == s.Length) { s = "?"; } line += "; Category=" + s; // The element Name has a different meaning for different classes, // but is mostly implemented "logically". More precise info on elements // can be obtained in class-specific ways. line += "; Name=" + e.Name; line += "; UniqueId=" + e.UniqueId; //line += "; Guid=" + GetGuid( e.UniqueId ); sw.WriteLine(line); } sw.Close(); LabUtils.InfoMsg("Element list has been written to " + LabConstants.FilePath + "."); #endregion // 2.1.c. Loop over the elements, list their data, and close the output file } catch (Exception e) { message = e.Message; } return(Result.Failed); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; Application app = uiapp.Application; Document doc = uiapp.ActiveUIDocument.Document; //BindingMap bindingMap = doc.ParameterBindings; // slow, fixed in 2009 wu 3, cf. case 1247995 Guid paramGuid = LabUtils.SharedParamGUID(app, LabConstants.SharedParamsGroupAPI, LabConstants.SharedParamsDefFireRating); // Let user select the Excel file. WinForms.OpenFileDialog dlg = new WinForms.OpenFileDialog(); dlg.Title = "Select source Excel file from which to update Revit shared parameters"; dlg.Filter = "Excel spreadsheet files (*.xls;*.xlsx)|*.xls;*.xlsx|All files (*)|*"; if (WinForms.DialogResult.OK != dlg.ShowDialog()) { return(Result.Cancelled); } // Launch/Get Excel via COM Interop: X.Application excel = new X.Application(); if (null == excel) { LabUtils.ErrorMsg("Failed to get or start Excel."); return(Result.Failed); } excel.Visible = true; X.Workbook workbook = excel.Workbooks.Open(dlg.FileName, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value); X.Worksheet worksheet = workbook.ActiveSheet as X.Worksheet; using (Transaction t = new Transaction(doc)) { t.Start("Import Fire Rating Values from Excel"); // Starting from row 2, loop the rows and extract Id and FireRating param. int id; double fireRatingValue; int row = 2; while (true) { try { // Extract relevant XLS values. X.Range r = worksheet.Cells[row, 1] as X.Range; if (null == r.Value2) { break; } double d = (double)r.Value2; id = (int)d; if (0 >= id) { break; } r = worksheet.Cells[row, 4] as X.Range; fireRatingValue = (double)r.Value2; // Get document's door element via Id ElementId elementId = new ElementId(id); Element door = doc.GetElement(elementId); // Set the param if (null != door) { //Parameter parameter = door.get_Parameter( LabConstants.SharedParamsDefFireRating ); Parameter parameter = door.get_Parameter(paramGuid); parameter.Set(fireRatingValue); } } catch (Exception) { break; } ++row; } t.Commit(); } #if ACTIVATE_REVIT // // Set focus back to Revit (there may be a better way, but this works :-) // #if USE_PROCESS_GET_PROCESSES foreach (Process p in Process.GetProcesses()) { try { if ("REVIT" == p.ProcessName.ToUpper().Substring(0, 5)) { // In VB, we can use AppActivate( p.Id ); // Pre-3.0, I think you may need to use p/invoke and call the native Windows // SetForegroundWindow() function directly. // http://www.codeproject.com/csharp/windowhider.asp?df=100 break; } } catch (Exception) { } } #endif // USE_PROCESS_GET_PROCESSES JtRevitWindow w = new JtRevitWindow(); w.Activate(); #endif // ACTIVATE_REVIT return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; Application app = uiapp.Application; Document doc = uiapp.ActiveUIDocument.Document; Category cat = doc.Settings.Categories.get_Item( Lab4_3_1_CreateAndBindSharedParam.Target); // Launch Excel (same as in Lab 4_2, so we really // should have better created some utils...) X.Application excel = new X.ApplicationClass(); if (null == excel) { LabUtils.ErrorMsg("Failed to get or start Excel."); return(Result.Failed); } excel.Visible = true; X.Workbook workbook = excel.Workbooks.Add(Missing.Value); X.Worksheet worksheet; //while( 1 < workbook.Sheets.Count ) //{ // worksheet = workbook.Sheets.get_Item( 0 ) as X.Worksheet; // worksheet.Delete(); //} worksheet = excel.ActiveSheet as X.Worksheet; worksheet.Name = "Revit " + cat.Name; worksheet.Cells[1, 1] = "ID"; worksheet.Cells[1, 2] = "Level"; worksheet.Cells[1, 3] = "Tag"; worksheet.Cells[1, 4] = LabConstants.SharedParamsDefFireRating; worksheet.get_Range("A1", "Z1").Font.Bold = true; List <Element> elems = LabUtils.GetTargetInstances(doc, Lab4_3_1_CreateAndBindSharedParam.Target); // Get Shared param Guid Guid paramGuid = LabUtils.SharedParamGUID(app, LabConstants.SharedParamsGroupAPI, LabConstants.SharedParamsDefFireRating); if (paramGuid.Equals(Guid.Empty)) { LabUtils.ErrorMsg("No Shared param found in the file - aborting..."); return(Result.Failed); } // Loop through all elements and export each to an Excel row int row = 2; foreach (Element e in elems) { worksheet.Cells[row, 1] = e.Id.IntegerValue; // ID // Level: //worksheet.Cells[row, 2] = e.Level.Name; // 2013 //worksheet.Cells[row, 2] = doc.GetElement( e.LevelId ).Name; // 2014 // When attaching a shared parameter to Material // elements, no valid level is defined, of course: ElementId levelId = e.LevelId; string levelName = ElementId.InvalidElementId == levelId ? "N/A" : doc.GetElement(levelId).Name; worksheet.Cells[row, 2] = levelName; // Tag: Parameter tagParameter = e.get_Parameter( BuiltInParameter.ALL_MODEL_MARK); if (null != tagParameter) { worksheet.Cells[row, 3] = tagParameter.AsString(); } // FireRating: Parameter parameter = e.get_Parameter(paramGuid); if (null != parameter) { worksheet.Cells[row, 4] = parameter.AsDouble(); } ++row; } return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; // Extract and group the data from Revit in a // dictionary, where the key is the category // name and the value is a list of elements. Stopwatch sw = Stopwatch.StartNew(); Dictionary <string, List <Element> > sortedElements = new Dictionary <string, List <Element> >(); // Iterate over all elements, both symbols and // model elements, and them in the dictionary. ElementFilter f = new LogicalOrFilter( new ElementIsElementTypeFilter(false), new ElementIsElementTypeFilter(true)); FilteredElementCollector collector = new FilteredElementCollector(doc) .WherePasses(f); string name; foreach (Element e in collector) { Category category = e.Category; if (null != category) { name = category.Name; // If this category was not yet encountered, // add it and create a new container for its // elements. if (!sortedElements.ContainsKey(name)) { sortedElements.Add(name, new List <Element>()); } sortedElements[name].Add(e); } } // Launch or access Excel via COM Interop: X.Application excel = new X.Application(); if (null == excel) { LabUtils.ErrorMsg( "Failed to get or start Excel."); return(Result.Failed); } excel.Visible = true; X.Workbook workbook = excel.Workbooks.Add( Missing.Value); X.Worksheet worksheet; // We cannot delete all work sheets, // Excel requires at least one. // //while( 1 < workbook.Sheets.Count ) //{ // worksheet = workbook.Sheets.get_Item(1) as X.Worksheet; // worksheet.Delete(); //} // Loop through all collected categories and // create a worksheet for each except the first. // We sort the categories and work trough them // from the end, since the worksheet added last // shows up first in the Excel tab. List <string> keys = new List <string>( sortedElements.Keys); keys.Sort(); keys.Reverse(); bool first = true; int nElements = 0; int nCategories = keys.Count; foreach (string categoryName in keys) { List <Element> elementSet = sortedElements[categoryName]; // Create and name the worksheet if (first) { worksheet = workbook.Sheets.get_Item(1) as X.Worksheet; first = false; } else { worksheet = excel.Worksheets.Add( Missing.Value, Missing.Value, Missing.Value, Missing.Value) as X.Worksheet; } name = (31 < categoryName.Length) ? categoryName.Substring(0, 31) : categoryName; name = name .Replace(':', '_') .Replace('/', '_'); worksheet.Name = name; // Determine the names of all parameters // defined for the elements in this set. List <string> paramNames = new List <string>(); foreach (Element e in elementSet) { ParameterSet parameters = e.Parameters; foreach (Parameter parameter in parameters) { name = parameter.Definition.Name; if (!paramNames.Contains(name)) { paramNames.Add(name); } } } paramNames.Sort(); // Add the header row in bold. worksheet.Cells[1, 1] = "ID"; worksheet.Cells[1, 2] = "IsType"; int column = 3; foreach (string paramName in paramNames) { worksheet.Cells[1, column] = paramName; ++column; } var range = worksheet.get_Range("A1", "Z1"); range.Font.Bold = true; range.EntireColumn.AutoFit(); int row = 2; foreach (Element e in elementSet) { // First column is the element id, // second a flag indicating type (symbol) // or not, both displayed as an integer. worksheet.Cells[row, 1] = e.Id.IntegerValue; worksheet.Cells[row, 2] = (e is ElementType) ? 1 : 0; column = 3; string paramValue; foreach (string paramName in paramNames) { paramValue = "*NA*"; //Parameter p = e.get_Parameter( paramName ); // 2014 // Careful! This returns the first best param found. Parameter p = e.LookupParameter(paramName); // 2015 if (null != p) { //try //{ paramValue = LabUtils.GetParameterValue(p); //} //catch( Exception ex ) //{ // Debug.Print( ex.Message ); //} } worksheet.Cells[row, column++] = paramValue; } // column ++nElements; ++row; } // row } // category == worksheet sw.Stop(); TaskDialog.Show("Parameter Export", string.Format( "{0} categories and a total " + "of {1} elements exported " + "in {2:F2} seconds.", nCategories, nElements, sw.Elapsed.TotalSeconds)); return(Result.Succeeded); }