public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; if (doc.IsFamilyDocument) { message = "This command can only be used in a project, not in a family file."; return(Result.Failed); } // get the singleton project info element Element projInfoElem = LabUtils.GetProjectInfoElem(doc); if (null == projInfoElem) { message = "No project info elem found. Aborting command..."; return(Result.Failed); } // For simplicity, access invisible param by name rather than by GUID: try { Parameter param = projInfoElem.LookupParameter(LabConstants.ParamNameInvisible); // report OLD value int iOldValue = param.AsInteger(); LabUtils.InfoMsg("OLD value = " + iOldValue.ToString()); using (Transaction tx = new Transaction(doc)) { tx.Start("Set Parameter Value"); // set and report NEW value param.Set(iOldValue + 1); LabUtils.InfoMsg("NEW value = " + param.AsInteger().ToString()); tx.Commit(); } } catch (System.Exception e) { message = "Failed: " + e.Message; return(Result.Failed); } return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; try { #region 2.4 Retrieve all doors, move them and widen them: FilteredElementCollector doors = LabUtils.GetFamilyInstances( doc, BuiltInCategory.OST_Doors); using (Transaction tx = new Transaction(doc)) { tx.Start("Move Doors Up"); // move doors up 0.2 feet: XYZ v = 0.2 * XYZ.BasisZ; foreach (FamilyInstance door in doors) { //doc.Move( door, v ); // 2011 ElementTransformUtils.MoveElement(doc, door.Id, v); // 2012 // widen doors by one foot by changing parameter value: Parameter p = door.Symbol.get_Parameter( BuiltInParameter.WINDOW_WIDTH); if (null != p) { double width = p.AsDouble(); width += 1.0; p.Set(width); } } tx.Commit(); } return(Result.Succeeded); #endregion // 2.4 Retrieve all doors, move them and widen them } catch (Exception ex) { message = ex.Message; return(Result.Failed); } }
public Result OnStartup( UIControlledApplication a) { try { CreateRibbonItems(a); } catch (Exception ex) { LabUtils.InfoMsg(ex.Message); return(Result.Failed); } return(Result.Succeeded); }
public Result OnStartup( UIControlledApplication a) { try { // subscribe to the DocumentSaving event: a.ControlledApplication.DocumentSaving += new EventHandler <DocumentSavingEventArgs>( a_DocumentSaving); } catch (Exception ex) { LabUtils.InfoMsg(ex.Message); return(Result.Failed); } return(Result.Succeeded); }
// Show a message to decide whether to save the document. void a_DocumentSaving( object obj, DocumentSavingEventArgs args) { // Ask whether to prevent from saving: bool cancel = args.Cancellable && LabUtils.QuestionMsg( "Saving event handler was triggered.\r\n" + "Using the pre-event mechanism, we can cancel the save.\r\n" + "Continue saving the document?"); //args.Cancel = cancel; // 2011 if (cancel) { args.Cancel(); } // 2012 }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; FilteredElementCollector collector = LabUtils.GetFamilySymbols(doc, BuiltInCategory.OST_Columns); #region Test explicit LINQ statement and cast #if USE_EXPLICIT_LINQ_STATEMENT var column_types = from element in collector where element.Name.Equals("475 x 610mm") select element; FamilySymbol symbol = column_types .Cast <FamilySymbol>() .First <FamilySymbol>(); #endif // USE_EXPLICIT_LINQ_STATEMENT #if CAST_TO_FAMILY_SYMBOL FamilySymbol symbol = collector.First <Element>( e => e.Name.Equals("475 x 610mm")) as FamilySymbol; #endif // CAST_TO_FAMILY_SYMBOL #endregion // Test explicit LINQ statement and cast Element symbol = collector.First <Element>( e => e.Name.Equals("475 x 610mm")); using (Transaction t = new Transaction(doc)) { t.Start("Delete Family Type"); //doc.Delete( symbol ); // 2013 doc.Delete(symbol.Id); // 2014 t.Commit(); } return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { #region 2.2 List all model elements: UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; FilteredElementCollector collector = new FilteredElementCollector(doc) .WhereElementIsNotElementType(); List <string> a = new List <string>(); // we could use a LINQ query here instead: foreach (Element e in collector) { // && null != e.Materials // && 0 < e.Materials.Size if (null != e.Category && e.Category.HasMaterialQuantities) { a.Add(string.Format( "Category={0}; Name={1}; Id={2}", e.Category.Name, e.Name, e.Id.IntegerValue)); } } LabUtils.InfoMsg( "Project contains {0} model element{1}{2}", a); return(Result.Failed); #endregion // 2.2 List all model elements }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; List <string> a = new List <string>(); FilteredElementCollector families; #region 3.1.a Retrieve and iterate over all Family objects in document: // // retrieve all family elements in current document: // families = new FilteredElementCollector(doc); families.OfClass(typeof(Family)); foreach (Family f in families) { // Get its category name; notice that the Category property is not // implemented for the Family class; use FamilyCategory instead; // notice that that is also not always implemented; in that case, // use the workaround demonstrated below, looking at the contained // family symbols' category: a.Add(string.Format("Name={0}; Category={1}; FamilyCategory={2}", f.Name, ((null == f.Category) ? "?" : f.Category.Name), ((null == f.FamilyCategory) ? "?" : f.FamilyCategory.Name))); } #endregion // 3.1.a string msg = "{0} standard familie{1} are loaded in this model{2}"; LabUtils.InfoMsg(msg, a); // Loop through the collection of families, and now look at // the child symbols (types) as well. These symbols can be // used to determine the family category. foreach (Family f in families) { string catName; bool first = true; // Loop all contained symbols (types): //foreach( FamilySymbol s in f.Symbols ) // 2014 foreach (ElementId id in f.GetFamilySymbolIds()) // 2015 { FamilySymbol s = doc.GetElement(id) as FamilySymbol; // you can determine the family category from its first symbol. if (first) { first = false; #region 3.1.b Retrieve category name of first family symbol: catName = s.Category.Name; #endregion // 3.1.b msg = "Family: Name=" + f.Name + "; Id=" + f.Id.IntegerValue.ToString() + "; Category=" + catName + "\r\nContains Types:"; } msg += "\r\n " + s.Name + "; Id=" + s.Id.IntegerValue.ToString(); } // Show the symbols for this family and allow user to proceed // to the next family (OK) or cancel (Cancel) msg += "\r\nContinue?"; if (!LabUtils.QuestionMsg(msg)) { break; } } // // return all families whose name contains the substring "Round Duct": // IEnumerable <Family> round_duct_families = LabUtils.GetFamilies(doc, "Round Duct", true); int n = round_duct_families.Count(); return(Result.Failed); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; UIDocument uidoc = app.ActiveUIDocument; Document doc = uidoc.Document; // Find all wall types and their system families (or kinds): WallType newWallType = null; string msg = "All wall types and families in the model:"; string content = string.Empty; FilteredElementCollector wallTypes = new FilteredElementCollector(doc) .OfClass(typeof(WallType)); foreach (WallType wt in wallTypes) { content += "\nType=" + wt.Name + " Family=" + wt.Kind.ToString(); newWallType = wt; } content += "\n\nStored WallType " + newWallType.Name + " (Id=" + newWallType.Id.IntegerValue.ToString() + ") for later use."; LabUtils.InfoMsg(msg, content); // Find all floor types: FloorType newFloorType = null; msg = "All floor types in the model:"; content = string.Empty; //foreach( FloorType ft in doc.FloorTypes ) // 2014 FilteredElementCollector floorTypes // 2015 = new FilteredElementCollector(doc) .OfClass(typeof(FloorType)); foreach (FloorType ft in floorTypes) // 2015 { content += "\nType=" + ft.Name + ", Id=" + ft.Id.IntegerValue.ToString(); // In 9.0, the "Foundation Slab" system family from "Structural // Foundations" category ALSO contains FloorType class instances. // Be careful to exclude those as choices for standard floor types. Parameter p = ft.get_Parameter(BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM); string famName = null == p ? "?" : p.AsString(); Category cat = ft.Category; content += ", Family=" + famName + ", Category=" + cat.Name; // store for the new floor type only if it has the proper Floors category: if (cat.Id.Equals((int)BuiltInCategory.OST_Floors)) { newFloorType = ft; } } content += (null == newFloorType) ? "\n\nNo floor type found." : "\n\nStored FloorType " + newFloorType.Name + " (Id=" + newFloorType.Id.IntegerValue.ToString() + ") for later use"; LabUtils.InfoMsg(msg, content); // Change the type for selected walls and floors: using (Transaction t = new Transaction(doc)) { t.Start("Change Type of Walls and Floors"); msg = "{0} {1}: Id={2}" + "\r\n changed from old type={3}; Id={4}" + " to new type={5}; Id={6}."; //ElementSet sel = uidoc.Selection.Elements; // 2014 ICollection <ElementId> ids = uidoc.Selection.GetElementIds(); // 2015 int iWall = 0; int iFloor = 0; foreach (ElementId id in ids) { Element e = doc.GetElement(id); if (e is Wall) { ++iWall; Wall wall = e as Wall; WallType oldWallType = wall.WallType; // change wall type and report the old/new values wall.WallType = newWallType; LabUtils.InfoMsg(string.Format(msg, "Wall", iWall, wall.Id.IntegerValue, oldWallType.Name, oldWallType.Id.IntegerValue, wall.WallType.Name, wall.WallType.Id.IntegerValue)); } else if (null != newFloorType && e is Floor) { ++iFloor; Floor f = e as Floor; FloorType oldFloorType = f.FloorType; f.FloorType = newFloorType; LabUtils.InfoMsg(string.Format(msg, "Floor", iFloor, f.Id.IntegerValue, oldFloorType.Name, oldFloorType.Id.IntegerValue, f.FloorType.Name, f.FloorType.Id.IntegerValue)); } } 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; // retrieve all FamilySymbol objects of "Windows" category: BuiltInCategory bic = BuiltInCategory.OST_Windows; FilteredElementCollector symbols = LabUtils.GetFamilySymbols(doc, bic); List <string> a = new List <string>(); foreach (FamilySymbol s in symbols) { Family fam = s.Family; a.Add(s.Name + ", Id=" + s.Id.IntegerValue.ToString() + "; Family name=" + fam.Name + ", Family Id=" + fam.Id.IntegerValue.ToString()); } LabUtils.InfoMsg("{0} windows family symbol{1} loaded in the model{1}", a); // loop through the selection set and check for // standard family instances of "Windows" category: int iBic = (int)bic; string msg, content; ICollection <ElementId> ids = uidoc.Selection.GetElementIds(); foreach (ElementId id in ids) { Element e = doc.GetElement(id); if (e is FamilyInstance && null != e.Category && e.Category.Id.IntegerValue.Equals(iBic)) { msg = "Selected window Id=" + e.Id.IntegerValue.ToString(); FamilyInstance inst = e as FamilyInstance; #region 3.3 Retrieve the type of the family instance, and the family of the type: FamilySymbol fs = inst.Symbol; Family f = fs.Family; #endregion // 3.3 content = "FamilySymbol = " + fs.Name + "; Id=" + fs.Id.IntegerValue.ToString(); content += "\r\n Family = " + f.Name + "; Id=" + f.Id.IntegerValue.ToString(); LabUtils.InfoMsg(msg, content); } } 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; //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 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); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; FilteredElementCollector rooms = new FilteredElementCollector(doc); // // this is one way of obtaining rooms ... but see below for a better solution: // //rooms.OfClass( typeof( Room ) ); // Input type is of an element type that exists in the API, but not in Revit's native object model. Try using Autodesk.Revit.DB.Enclosure instead, and then postprocessing the results to find the elements of interest. //rooms.OfClass( typeof( Enclosure ) ); // this works but returns all Enclosure elements RoomFilter filter = new RoomFilter(); rooms.WherePasses(filter); if (0 == rooms.Count()) { LabUtils.InfoMsg("There are no rooms in this model."); } else { List <string> a = new List <string>(); /* * foreach( Enclosure e in rooms ) // todo: remove this * { * Room room = e as Room; // todo: remove this * if( null != room ) // todo: remove this * { */ foreach (Room room in rooms) { string roomName = room.Name; string roomNumber = room.Number; string s = "Room Id=" + room.Id.IntegerValue.ToString() + " Name=" + roomName + " Number=" + roomNumber + "\n"; // Loop all boundaries of this room //BoundarySegmentArrayArray boundaries = room.Boundary; // 2011 IList <IList <BoundarySegment> > boundaries // 2012 = room.GetBoundarySegments( // 2012 new SpatialElementBoundaryOptions()); // 2012; passing in a null value throws an exception // Check to ensure room has boundary if (null != boundaries) { int iB = 0; //foreach( BoundarySegmentArray boundary in boundaries ) // 2011 foreach (IList <BoundarySegment> boundary in boundaries) // 2012 { ++iB; s += " Boundary " + iB + ":\n"; int iSeg = 0; foreach (BoundarySegment segment in boundary) { ++iSeg; // Segment's curve Curve crv = segment.GetCurve(); if (crv is Line) { Line line = crv as Line; XYZ ptS = line.GetEndPoint(0); XYZ ptE = line.GetEndPoint(1); s += " Segment " + iSeg + " is a LINE: " + LabUtils.PointString(ptS) + " ; " + LabUtils.PointString(ptE) + "\n"; } else if (crv is Arc) { Arc arc = crv as Arc; XYZ ptS = arc.GetEndPoint(0); XYZ ptE = arc.GetEndPoint(1); double r = arc.Radius; s += " Segment " + iSeg + " is an ARC:" + LabUtils.PointString(ptS) + " ; " + LabUtils.PointString(ptE) + " ; R=" + LabUtils.RealString(r) + "\n"; } } } a.Add(s); } LabUtils.InfoMsg("{0} room{1} in the model{2}", a); } } return(Result.Failed); }
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); }
//static public BuiltInCategory Target = BuiltInCategory.OST_Walls; //static public string Target = "Drawing1.dwg"; //static public BuiltInCategory Target = BuiltInCategory.OST_IOSModelGroups; // doc.Settings.Categories.get_Item returns null //static public string Target = "Model Groups"; // doc.Settings.Categories.get_Item throws an exception SystemInvalidOperationException "Operation is not valid due to the current state of the object." //static public BuiltInCategory Target = BuiltInCategory.OST_Lines; // model lines //static public BuiltInCategory Target = BuiltInCategory.OST_SWallRectOpening; // Rectangular Straight Wall Openings, case 1260656 [Add Parameters Wall Opening] //static public BuiltInCategory Target = BuiltInCategory.OST_Materials; // can I attach a shared parameter to a material element? Yes, absolutely, no problem at all. 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 = null; #region Determine model group category #if DETERMINE_MODEL_GROUP_CATEGORY List <Element> modelGroups = new List <Element>(); //Filter fType = app.Create.Filter.NewTypeFilter( typeof( Group ) ); // "Binding the parameter to the category Model Groups is not allowed" Filter fType = app.Create.Filter.NewTypeFilter(typeof(GroupType)); // same result "Binding the parameter to the category Model Groups is not allowed" Filter fCategory = app.Create.Filter.NewCategoryFilter(BuiltInCategory.OST_IOSModelGroups); Filter f = app.Create.Filter.NewLogicAndFilter(fType, fCategory); if (0 < doc.get_Elements(f, modelGroups)) { cat = modelGroups[0].Category; } #endif // DETERMINE_MODEL_GROUP_CATEGORY #endregion // Determine model group category if (null == cat) { // The category we are defining the parameter for try { cat = doc.Settings.Categories.get_Item(Target); } catch (Exception ex) { message = "Error obtaining the shared param document category: " + ex.Message; return(Result.Failed); } if (null == cat) { message = "Unable to obtain the shared param document category."; return(Result.Failed); } } // Get the current shared params definition file DefinitionFile sharedParamsFile = LabUtils.GetSharedParamsFile(app); if (null == sharedParamsFile) { message = "Error getting the shared params file."; return(Result.Failed); } // Get or create the shared params group DefinitionGroup sharedParamsGroup = LabUtils.GetOrCreateSharedParamsGroup( sharedParamsFile, LabConstants.SharedParamsGroupAPI); if (null == sharedParamsGroup) { message = "Error getting the shared params group."; return(Result.Failed); } // Visibility of the new parameter: the // Category.AllowsBoundParameters property // determines whether a category is allowed to // have user-visible shared or project parameters. // If it is false, it may not be bound to visible // shared parameters using the BindingMap. 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 = LabUtils.GetOrCreateSharedParamsDefinition( sharedParamsGroup, ParameterType.Number, LabConstants.SharedParamsDefFireRating, 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 parameter. try { using (Transaction t = new Transaction(doc)) { t.Start("Bind Fire Rating Shared Parameter"); Binding binding = app.Create.NewInstanceBinding(catSet); // We could check if already bound, but looks // like Insert will just ignore it in that case. doc.ParameterBindings.Insert(fireRatingParamDef, binding); // You can also specify the parameter group here: //doc.ParameterBindings.Insert( fireRatingParamDef, binding, BuiltInParameterGroup.PG_GEOMETRY ); t.Commit(); } } catch (Exception ex) { message = ex.Message; return(Result.Failed); } return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; #region 2.3.a Filter to retrieve and list all walls: // get all wall elements: // // we could also call // // FilteredElementCollector walls = LabUtils.GetElementsOfType( // doc, typeof( Wall ), BuiltInCategory.OST_Walls ); FilteredElementCollector walls = new FilteredElementCollector(doc); walls.OfClass(typeof(Wall)); List <string> a = new List <string>(); foreach (Wall wall in walls) { a.Add(string.Format("Id={0}; Kind={1}; Type={2}", wall.Id.IntegerValue, wall.WallType.Kind.ToString(), wall.WallType.Name)); } LabUtils.InfoMsg("{0} wall{1} in the model{2}", a); #endregion // 2.3.a Filter to retrieve and list all walls a.Clear(); #region 2.3.b Filter to retrieve and list all doors: // get all door family instances: // // we could also call // // FilteredElementCollector doors = LabUtils.GetElementsOfType( // doc, typeof( FamilyInstance ), BuiltInCategory.OST_Doors ); // // or // // FilteredElementCollector doors = LabUtils.GetFamilyInstances( // doc, BuiltInCategory.OST_Doors ); FilteredElementCollector doors = new FilteredElementCollector(doc); doors.OfCategory(BuiltInCategory.OST_Doors); doors.OfClass(typeof(FamilyInstance)); foreach (FamilyInstance door in doors) { // For family instances, the element name property // returns the type name: a.Add(string.Format("Id={0}; Type={1}", door.Id.IntegerValue, door.Name)); } LabUtils.InfoMsg("{0} door family instance{1} in the model{2}", a); #endregion // 2.3.b Filter to retrieve and list all doors return(Result.Failed); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { try { WaitCursor waitCursor = new WaitCursor(); UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; Autodesk.Revit.Creation.Application createApp = app.Application.Create; Autodesk.Revit.Creation.Document createDoc = doc.Create; using (Transaction t = new Transaction(doc)) { t.Start("Create Little House"); // Determine the four corners of the rectangular house: double width = 7 * LabConstants.MeterToFeet; double depth = 4 * LabConstants.MeterToFeet; List <XYZ> corners = new List <XYZ>(4); corners.Add(XYZ.Zero); corners.Add(new XYZ(width, 0, 0)); corners.Add(new XYZ(width, depth, 0)); corners.Add(new XYZ(0, depth, 0)); #region Test creating two levels #if CREATE_TWO_LEVELS Level levelBottom = null; Level levelMiddle = null; Level levelTop = null; List <Element> levels = new List <Element>(); Filter filterType = createApp.Filter.NewTypeFilter( typeof(Level)); doc.get_Elements(filterType, levels); foreach (Element e in levels) { if (null == levelBottom) { levelBottom = e as Level; } else if (null == levelMiddle) { levelMiddle = e as Level; } else if (null == levelTop) { levelTop = e as Level; } else { break; } } BuiltInParameter topLevelParam = BuiltInParameter.WALL_HEIGHT_TYPE; Line line; Wall wall; Parameter param; ElementId topId = levelMiddle.Id; List <Wall> walls = new List <Wall>(8); for (int i = 0; i < 4; ++i) { line = createApp.NewLineBound( corners[i], corners[3 == i ? 0 : i + 1]); wall = createDoc.NewWall( line, levelBottom, false); param = wall.get_Parameter(topLevelParam); param.Set(ref topId); walls.Add(wall); } topId = levelTop.Id; for (int i = 0; i < 4; ++i) { line = createApp.NewLineBound( corners[i], corners[3 == i ? 0 : i + 1]); wall = createDoc.NewWall( line, levelMiddle, false); param = wall.get_Parameter(topLevelParam); param.Set(ref topId); walls.Add(wall); } List <Element> doorSymbols = LabUtils.GetAllFamilySymbols( app, BuiltInCategory.OST_Doors); Debug.Assert( 0 < doorSymbols.Count, "expected at least one door symbol" + " to be loaded into project"); FamilySymbol door = doorSymbols[0] as FamilySymbol; XYZ midpoint = LabUtils.Midpoint( corners[0], corners[1]); FamilyInstance inst0 = createDoc.NewFamilyInstance( midpoint, door, walls[0], levelBottom, StructuralType.NonStructural); midpoint.Z = levelMiddle.Elevation; FamilyInstance inst1 = createDoc.NewFamilyInstance( midpoint, door, walls[4], levelMiddle, StructuralType.NonStructural); #endif // CREATE_TWO_LEVELS #endregion // Test creating two levels // Determine the levels where the walls will be located: Level levelBottom = null; Level levelTop = null; if (!LabUtils.GetBottomAndTopLevels(doc, ref levelBottom, ref levelTop)) { message = "Unable to determine wall bottom and top levels"; return(Result.Failed); } Debug.Print(string.Format("Drawing walls on '{0}' up to '{1}'", levelBottom.Name, levelTop.Name)); // Create the walls: BuiltInParameter topLevelParam = BuiltInParameter.WALL_HEIGHT_TYPE; ElementId levelBottomId = levelBottom.Id; ElementId topLevelId = levelTop.Id; List <Wall> walls = new List <Wall>(4); for (int i = 0; i < 4; ++i) { Line line = Line.CreateBound(corners[i], corners[3 == i ? 0 : i + 1]); //Wall wall = createDoc.NewWall( line, levelBottom, false ); // 2012 Wall wall = Wall.Create(doc, line, levelBottomId, false); // 2013 Parameter param = wall.get_Parameter(topLevelParam); param.Set(topLevelId); walls.Add(wall); } // Determine wall thickness for tag offset and profile growth: //double wallThickness = walls[0].WallType.CompoundStructure.Layers.get_Item( 0 ).Thickness; // 2011 //double wallThickness = walls[0].WallType.GetCompoundStructure().GetLayers()[0].Width; // 2012 double wallThickness = walls[0].WallType.Width; // simpler and more direct property available in 2012 // Add door and windows to the first wall; // note that the NewFamilyInstance() api method does not automatically add door // and window tags, like the ui command does. we add tags here by making additional calls // to NewTag(): FamilySymbol door = LabUtils.GetFirstFamilySymbol(doc, BuiltInCategory.OST_Doors); if (null == door) { LabUtils.InfoMsg("No door symbol found."); return(Result.Failed); } FamilySymbol window = LabUtils.GetFirstFamilySymbol( doc, BuiltInCategory.OST_Windows); if (null == window) { LabUtils.InfoMsg("No window symbol found."); return(Result.Failed); } XYZ midpoint = LabUtils.Midpoint(corners[0], corners[1]); XYZ p = LabUtils.Midpoint(corners[0], midpoint); XYZ q = LabUtils.Midpoint(midpoint, corners[1]); double tagOffset = 3 * wallThickness; //double windowHeight = 1 * LabConstants.MeterToFeet; double windowHeight = levelBottom.Elevation + 0.3 * ( levelTop.Elevation - levelBottom.Elevation); p = new XYZ(p.X, p.Y, windowHeight); q = new XYZ(q.X, q.Y, windowHeight); View view = doc.ActiveView; door.Activate(); // 2016 FamilyInstance inst = createDoc.NewFamilyInstance( midpoint, door, walls[0], levelBottom, StructuralType.NonStructural); midpoint += tagOffset * XYZ.BasisY; //IndependentTag tag = createDoc.NewTag( // view, inst, false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.Horizontal, midpoint ); // 2017 IndependentTag tag = IndependentTag.Create( doc, view.Id, new Reference(inst), false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, midpoint); // 2018 IList <FamilyPointPlacementReference> fpprefs = inst.GetFamilyPointPlacementReferences(); IList <Reference> refs = inst.GetReferences(FamilyInstanceReferenceType.CenterLeftRight); //IndependentTag tag = IndependentTag.Create( doc, // view.Id, refs[0], false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.Horizontal, midpoint ); // 2018 window.Activate(); // 2016 inst = createDoc.NewFamilyInstance(p, window, walls[0], levelBottom, StructuralType.NonStructural); p += tagOffset * XYZ.BasisY; //tag = createDoc.NewTag( view, inst, // false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.Horizontal, p ); // 2017 tag = IndependentTag.Create( doc, view.Id, new Reference(inst), false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, p); // 2018 inst = createDoc.NewFamilyInstance(q, window, walls[0], levelBottom, StructuralType.NonStructural); q += tagOffset * XYZ.BasisY; //tag = createDoc.NewTag( view, inst, // false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.TAG_HORIZONTAL, q ); // 2011 //tag = createDoc.NewTag( view, inst, // false, TagMode.TM_ADDBY_CATEGORY, // TagOrientation.Horizontal, q ); // 2012 tag = IndependentTag.Create( doc, view.Id, new Reference(inst), false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, p); // 2018 // Grow the profile out by half the wall thickness, // so the floor and roof do not stop halfway through the wall: double w = 0.5 * wallThickness; corners[0] -= w * (XYZ.BasisX + XYZ.BasisY); corners[1] += w * (XYZ.BasisX - XYZ.BasisY); corners[2] += w * (XYZ.BasisX + XYZ.BasisY); corners[3] -= w * (XYZ.BasisX - XYZ.BasisY); CurveArray profile = new CurveArray(); for (int i = 0; i < 4; ++i) { //Line line = createApp.NewLineBound( // 2013 Line line = Line.CreateBound( // 2014 corners[i], corners[3 == i ? 0 : i + 1]); profile.Append(line); } // Add a floor, a roof and the roof slope: bool structural = false; Floor floor = createDoc.NewFloor( profile, structural); List <Element> roofTypes = new List <Element>( LabUtils.GetElementsOfType( doc, typeof(RoofType), BuiltInCategory.OST_Roofs)); Debug.Assert(0 < roofTypes.Count, "expected at least one roof type" + " to be loaded into project"); // Ensure that we get a valid roof type. // In Revit 2013, the first one encountered // is sloped glazing with zero entries in // its compound layers; actually, the entire // compound structure is null: //RoofType roofType = null; //foreach( RoofType rt in roofTypes ) //{ // CompoundStructure cs = rt.GetCompoundStructure(); // if( null != cs // && 0 < cs.GetLayers().Count ) // { // roofType = rt; // break; // } //} RoofType roofType = roofTypes .Cast <RoofType>() .FirstOrDefault <RoofType>(typ => null != typ.GetCompoundStructure()); ModelCurveArray modelCurves = new ModelCurveArray(); FootPrintRoof roof = createDoc.NewFootPrintRoof(profile, levelTop, roofType, out modelCurves); // Regenerate the model after roof creation, // otherwise the calls to set_DefinesSlope and // set_SlopeAngle throw the exception "Unable // to access curves from the roof sketch." doc.Regenerate(); // The argument to set_SlopeAngle is NOT an // angle, it is really a slope, i.e. relation // of height to distance, e.g. 0.5 = 6" / 12", // 0.75 = 9" / 12", etc. double slope = 0.3; foreach (ModelCurve curve in modelCurves) { roof.set_DefinesSlope(curve, true); roof.set_SlopeAngle(curve, slope); } // Add a room and a room tag: Room room = createDoc.NewRoom(levelBottom, new UV(0.5 * width, 0.5 * depth)); //RoomTag roomTag = createDoc.NewRoomTag( // room, new UV( 0.5 * width, 0.7 * depth ), // null ); // 2014 RoomTag roomTag = createDoc.NewRoomTag( new LinkElementId(room.Id), new UV(0.5 * width, 0.7 * depth), null); // 2015 //doc.AutoJoinElements(); // todo: remove this, the transaction should perform this automatically //LabUtils.InfoMsg( "Little house was created successfully." ); //#region Test setting BaseOffset and LimitOffset //// 11334196 [Failed to set Room.BaseOffset and Room.LimitOffset properties] //double h = 0.123; //room.BaseOffset = -h; //room.LimitOffset = h + h; //#endregion // Test setting BaseOffset and LimitOffset t.Commit(); return(Result.Succeeded); } } catch (Exception ex) { message = ex.Message; return(Result.Failed); } }
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 app = commandData.Application; Document doc = app.ActiveUIDocument.Document; if (doc.IsFamilyDocument) { message = "This command can only be used in a project, not in a family file."; return(Result.Failed); } using (Transaction tx = new Transaction(doc)) { tx.Start("Create per doc Parameters"); // get the current shared params definition file DefinitionFile sharedParamsFile = LabUtils.GetSharedParamsFile(app.Application); if (null == sharedParamsFile) { message = "Error getting the shared params file."; return(Result.Failed); } // get or create the shared params group DefinitionGroup sharedParamsGroup = LabUtils.GetOrCreateSharedParamsGroup( sharedParamsFile, LabConstants.ParamGroupName); if (null == sharedParamsGroup) { message = "Error getting the shared params group."; return(Result.Failed); } // visible param Definition docParamDefVisible = LabUtils.GetOrCreateSharedParamsDefinition( sharedParamsGroup, ParameterType.Integer, LabConstants.ParamNameVisible, true); if (null == docParamDefVisible) { message = "Error creating visible per-doc parameter."; return(Result.Failed); } // invisible param Definition docParamDefInvisible = LabUtils.GetOrCreateSharedParamsDefinition( sharedParamsGroup, ParameterType.Integer, LabConstants.ParamNameInvisible, false); if (null == docParamDefInvisible) { message = "Error creating invisible per-doc parameter."; return(Result.Failed); } // bind the param try { CategorySet catSet = app.Application.Create.NewCategorySet(); catSet.Insert(doc.Settings.Categories.get_Item( BuiltInCategory.OST_ProjectInformation)); Binding binding = app.Application.Create.NewInstanceBinding(catSet); doc.ParameterBindings.Insert(docParamDefVisible, binding); doc.ParameterBindings.Insert(docParamDefInvisible, binding); } catch (Exception e) { message = "Error binding shared parameter: " + e.Message; return(Result.Failed); } // set the initial values // get the singleton project info element Element projInfoElem = LabUtils.GetProjectInfoElem(doc); if (null == projInfoElem) { message = "No project info element found. Aborting command..."; return(Result.Failed); } // For simplicity, access params by name rather than by GUID // and simply the first best one found under that name: projInfoElem.LookupParameter(LabConstants.ParamNameVisible).Set(55); projInfoElem.LookupParameter(LabConstants.ParamNameInvisible).Set(0); tx.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; // Get all Group Types of Model Family: FilteredElementCollector modelGroupTypes = new FilteredElementCollector(doc); modelGroupTypes.OfClass(typeof(GroupType)); modelGroupTypes.OfCategory(BuiltInCategory.OST_IOSModelGroups); if (0 == modelGroupTypes.Count()) { message = "No model group types found in model."; return(Result.Failed); } FilteredElementCollector groups; groups = new FilteredElementCollector(doc); groups.OfClass(typeof(Group)); foreach (Group g in groups) { // Offer simple message box to swap the type // (one-by-one, stop if user confirms the change) foreach (GroupType gt in modelGroupTypes) { string msg = "Swap OLD Type=" + g.GroupType.Name + " with NEW Type=" + gt.Name + " for Group Id=" + g.Id.IntegerValue.ToString() + "?"; TaskDialogResult r = LabUtils.QuestionCancelMsg(msg); switch (r) { case TaskDialogResult.Yes: g.GroupType = gt; LabUtils.InfoMsg("Group type successfully swapped."); return(Result.Succeeded); case TaskDialogResult.Cancel: LabUtils.InfoMsg("Command cancelled."); return(Result.Cancelled); // else continue... } } } /* * // * // cannot modify group members after creation: * // * Element e = null; * ElementArray els = new ElementArray(); * els.Append( e ); * Group g = new Group(); * g.Members = els; // Property or indexer 'Autodesk.Revit.Elements.Group.Members' cannot be assigned to -- it is read only * Element e2 = null; * els.Append( e2 ); * g.Members = els; */ return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { #region TEST_1 #if TEST_1 // // you cannot create your own parameter, because the // constuctor is for internal use only. This is due // to the fact that a parameter cannot live on its own, // it is linked to a definition and needs to be hooked // up properly in the Revit database system to work // ... case 1245614 [Formatting units strings]: // bool iReallyWantToCrash = false; if (iReallyWantToCrash) { Parameter p = new Parameter(); p.Set(1.0); string s = p.AsDouble().ToString(); string t = p.AsValueString(); Debug.WriteLine("Value " + s); Debug.WriteLine("Value string " + t); } #endif // TEST #endregion // TEST_1 UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; // Loop through all pre-selected elements: foreach (ElementId id in uidoc.Selection.GetElementIds()) { Element e = doc.GetElement(id); string s = string.Empty; // set this variable to false to analyse the element's own parameters, // i.e. instance parameters for a family instance, and set it to true // to analyse a family instance's type parameters: bool analyseTypeParameters = false; if (analyseTypeParameters) { if (e is FamilyInstance) { FamilyInstance inst = e as FamilyInstance; if (null != inst.Symbol) { e = inst.Symbol; s = " type"; } } else if (e is Wall) { Wall wall = e as Wall; if (null != wall.WallType) { e = wall.WallType; s = " type"; } } // ... add support for other types if desired ... } // Loop through and list all UI-visible element parameters List <string> a = new List <string>(); #region 4.1.a Iterate over element parameters and retrieve their name, type and value: foreach (Parameter p in e.Parameters) { string name = p.Definition.Name; string type = p.StorageType.ToString(); string value = LabUtils.GetParameterValue2(p, uidoc.Document); //bool read_only = p.Definition.IsReadOnly; // 2013 bool read_only = p.IsReadOnly; // 2014 a.Add(string.Format( "Name={0}; Type={1}; Value={2}; ValueString={3}; read-{4}", name, type, value, p.AsValueString(), (read_only ? "only" : "write"))); } #endregion // 4.1.a string what = e.Category.Name + " (" + e.Id.IntegerValue.ToString() + ")"; LabUtils.InfoMsg(what + " has {0} parameter{1}{2}", a); // If we know which param we are looking for, then: // A) If a standard parameter, we can get it via BuiltInParam // signature of Parameter method: try { #region 4.1.b Retrieve a specific built-in parameter: Parameter p = e.get_Parameter( BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM); #endregion // 4.1.b if (null == p) { LabUtils.InfoMsg("FAMILY_BASE_LEVEL_OFFSET_PARAM is NOT available for this element."); } else { string name = p.Definition.Name; string type = p.StorageType.ToString(); string value = LabUtils.GetParameterValue2(p, doc); LabUtils.InfoMsg("FAMILY_BASE_LEVEL_OFFSET_PARAM: Name=" + name + "; Type=" + type + "; Value=" + value); } } catch (Exception) { LabUtils.InfoMsg("FAMILY_BASE_LEVEL_OFFSET_PARAM is NOT available for this element."); } // B) For a shared parameter, we can get it via "GUID" signature // of Parameter method ... this will be shown later in Labs 4 ... // C) or we can get the parameter by name: // alternatively, loop through all parameters and // search for the name (this works for either // standard or shared). Note that the same name // may occur multiple times: const string paramName = "Base Offset"; //Parameter parByName = e.get_Parameter( paramName ); // 2014 IList <Parameter> paramsByName = e.GetParameters(paramName); // 2015 if (0 == paramsByName.Count) { LabUtils.InfoMsg(paramName + " is NOT available for this element."); } else { foreach (Parameter p in paramsByName) { string parByNameName = p.Definition.Name; string parByNameType = p.StorageType.ToString(); string parByNameValue = LabUtils.GetParameterValue2(p, doc); LabUtils.InfoMsg(paramName + ": Name=" + parByNameName + "; Type=" + parByNameType + "; Value=" + parByNameValue); } } #region TEST_2 #if TEST_2 List <string> a = GetParameters(doc, e); foreach (string s2 in a) { Debug.WriteLine(s2); } #endif // TEST_2 #endregion // TEST_2 } return(Result.Failed); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; List <string> a = new List <string>(); // list groups: FilteredElementCollector collector; collector = new FilteredElementCollector(doc); collector.OfClass(typeof(Group)); foreach (Group g in collector) { a.Add("Id=" + g.Id.IntegerValue.ToString() + "; Type=" + g.GroupType.Name); } LabUtils.InfoMsg("{0} group{1} in the document{2}", a); // list groups types: BuiltInParameter bic = BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM; a.Clear(); collector = new FilteredElementCollector(doc); collector.OfClass(typeof(GroupType)); foreach (GroupType g in collector) { // determine the GroupType system family // (cf. Labs3 for standard symbols): Parameter p = g.get_Parameter(bic); string famName = (null == p) ? "?" : p.AsString(); a.Add("Name=" + g.Name + "; Id=" + g.Id.IntegerValue.ToString() + "; Family=" + famName); } LabUtils.InfoMsg("{0} group type{1} in the document{2}", a); // typically, only "Model" types will be needed. // create a filter by creating a provider and an evaluator. // we can reuse the collector we already set up for group // types, and just add another criteria to check to it: a.Clear(); #region Failed attempts /* * this returns zero elements: * * ParameterValueProvider provider * = new ParameterValueProvider( new ElementId( ( int ) bic ) ); * * FilterStringRuleEvaluator evaluator * = new FilterStringEquals(); * * string ruleString = _groupTypeModel; * bool caseSensitive = true; * * FilterRule rule = new FilterStringRule( provider, evaluator, ruleString, caseSensitive ); * * // Create an ElementParameter filter: * * ElementParameterFilter filter = new ElementParameterFilter( rule ); * * // Apply the filter to the elements in the active collector: * * collector.WherePasses( filter ).ToElements(); */ /* * this returns false: * * if( doc.Settings.Categories.Contains( _groupsTypeModel ) ) * { * Category cat = doc.Settings.Categories.get_Item( _groupsTypeModel ); * * foreach( GroupType g in collector ) * { * a.Add( "Name=" + g.Name + "; Id=" + g.Id.IntegerValue.ToString() ); * } * } */ #endregion // Failed attempts collector.OfCategory(BuiltInCategory.OST_IOSModelGroups); foreach (GroupType g in collector) { a.Add("Name=" + g.Name + "; Id=" + g.Id.IntegerValue.ToString()); } LabUtils.InfoMsg("{0} *model* group type{1} in the document{2}", a); return(Result.Failed); }
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) { #region 1.2.a. Examine command data input argument: // // access application, document, and current view: // UIApplication uiapp = commandData.Application; Application app = uiapp.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Document doc = uidoc.Document; View view = commandData.View; LanguageType lt = app.Language; ProductType pt = app.Product; string s = "Application = " + app.VersionName + "\r\nLanguage = " + lt.ToString() + "\r\nProduct = " + pt.ToString() + "\r\nVersion = " + app.VersionNumber + "\r\nDocument path = " + doc.PathName // empty if not yet saved + "\r\nDocument title = " + doc.Title + "\r\nView name = " + view.Name; LabUtils.InfoMsg(s); #endregion // 1.2.a. Examine command data input argument #region 1.2.b. List selection set content: // // list the current selection set: // Selection sel = uidoc.Selection; List <string> a = new List <string>(); foreach (ElementId id in sel.GetElementIds()) { Element e = doc.GetElement(id); string name = (null == e.Category) ? e.GetType().Name : e.Category.Name; a.Add(name + " Id=" + e.Id.IntegerValue.ToString()); } LabUtils.InfoMsg( "There are {0} element{1} in the selection set{2}", a); #endregion // 1.2.b. List selection set content #region 1.2.c. Populate return arguments: // We pretend that something is wrong with the // first element in the selection. Pass an error // message back to the user and indicate the // error result: ICollection <ElementId> ids = sel.GetElementIds(); if (0 < ids.Count) { //ElementSetIterator iter = sel.Elements.ForwardIterator(); //iter.MoveNext(); //Element errElem = iter.Current as Element; Element errElem = doc.GetElement(ids.First()); elements.Clear(); elements.Insert(errElem); message = "We pretend something is wrong with this " + " element and pass back this message to user"; return(Result.Failed); } else { // We return failed here as well. // As long as the message string and element set are empty, // it makes no difference to the user. // If they are not empty, the message is displayed to the // user and/or the elements in the set are highlighted. // If an automatic transaction is open, it is aborted, // avoiding marking the database as dirty. return(Result.Failed); } #endregion // 1.2.c. Populate return arguments }
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); }
/// <summary> /// This method will run automatically when Revit start up. /// It shows a message box. Initiative task can be done in this function. /// </summary> public Result OnStartup( UIControlledApplication a) { LabUtils.InfoMsg("Hello World from an external application in C#."); return(Result.Succeeded); }
/// <summary> /// Revit external command to list all valid built-in parameters for a given selected element. /// </summary> public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; Element e = LabUtils.GetSingleSelectedElementOrPrompt( uidoc); if (null == e) { return(Result.Cancelled); } bool isSymbol = false; #region Check for FamilyInstance #if CHECK_FOR_FAMILY_INSTANCE // // for a family instance, ask user whether to // display instance or type parameters; // in a similar manner, we could add dedicated // switches for Wall --> WallType, // Floor --> FloorType etc. ... // if (e is FamilyInstance) { FamilyInstance inst = e as FamilyInstance; if (null != inst.Symbol) { string symbol_name = LabUtils.ElementDescription( inst.Symbol, true); string family_name = LabUtils.ElementDescription( inst.Symbol.Family, true); string msg = "This element is a family instance, so it " + "has both type and instance parameters. " + "By default, the instance parameters are " + "displayed. If you select 'No', the type " + "parameters will be displayed instead. " + "Would you like to see the instance " + "parameters?"; if (!LabUtils.QuestionMsg(msg)) { e = inst.Symbol; isSymbol = true; } } } #endif // CHECK_FOR_FAMILY_INSTANCE #endregion // Check for FamilyInstance #region Check for element type #if CHECK_GET_TYPE_ID ElementId idType = e.GetTypeId(); if (ElementId.InvalidElementId != idType) { // The selected element has a type; ask user // whether to display instance or type // parameters. ElementType typ = doc.GetElement(idType) as ElementType; Debug.Assert(null != typ, "expected to retrieve a valid element type"); string type_name = LabUtils.ElementDescription( typ, true); string msg = "This element has an ElementType, so it has " + "both type and instance parameters. By " + "default, the instance parameters are " + "displayed. If you select 'No', the type " + "parameters will be displayed instead. " + "Would you like to see the instance " + "parameters?"; if (!LabUtils.QuestionMsg(msg)) { e = typ; isSymbol = true; } } #endif // CHECK_GET_TYPE_ID #endregion // Check for element type SortableBindingList <ParameterData> data = new SortableBindingList <ParameterData>(); { WaitCursor waitCursor = new WaitCursor(); Array bips = Enum.GetValues(typeof(BuiltInParameter)); int n = bips.Length; Parameter p; foreach (BuiltInParameter a in bips) { try { p = e.get_Parameter(a); #region Check for external definition #if CHECK_FOR_EXTERNAL_DEFINITION Definition d = p.Definition; ExternalDefinition e = d as ExternalDefinition; // this is never possible string guid = (null == e) ? null : e.GUID.ToString(); #endif // CHECK_FOR_EXTERNAL_DEFINITION #endregion // Check for external definition if (null != p) { //string value = LabUtils.GetParameterValue2( p, doc ); string valueString = (StorageType.ElementId == p.StorageType) ? LabUtils.GetParameterValue2(p, doc) : p.AsValueString(); data.Add(new ParameterData(a, p, valueString)); } } catch (Exception ex) { Debug.Print("Exception retrieving built-in parameter {0}: {1}", a, ex); } } } string description = LabUtils.ElementDescription(e, true) + (isSymbol ? " Type" : " Instance"); using (BuiltInParamsCheckerForm form = new BuiltInParamsCheckerForm(description, data)) { form.ShowDialog(); } return(Result.Succeeded); }