Friday, March 23, 2007

Revit 2008 API: New Creation Capabilities, Newly promoted Objects

In any new release of an API like Revit, it seems like everyone's first question is "what can it create now? can it create everything that I want/need? can it create everything that is in the interactive Revit product?". I however, am too mature to care too dearly about that :)

New Application Object Creation
In the application area, the following can now be created. Most of these are "mathematical" objects which are later used to create actual geometry.

  • Ellipse
  • NurbSpline
  • Select Element Set
  • Parameter List Item Array (apparently used in conjunction with some kind of external parameter item list).

New Document Object Creation
In the document element creation, the following objects can now be created:

  • Annotation Symbol
  • Area Reinforcement
  • Beam System
  • Detail Curve
  • Foundation Slab
  • Opening
  • Path Reinforcement
  • Room
  • Tag
  • Text Note
  • View Plan

Elements Promoted to Concrete Objects
If you've ever scanned a Revit model programmatically, you know that there are probably 30,000 elements in a very modestly sized model. If you look at their types, you know that a large number of those elements show up as "Autodesk.Revit.Element" - meaning that they are an abstract type with only limited information provided about them.

In 2008, a variety of Element types got promoted so that they are represented by full classes. This typically means that you can inquire about more detailed information on these types:

  • Blend
  • Extrusion
  • Sweep
  • Revolution
  • gbxmlElement
  • LinearArray
  • RadialArray
  • ProjectInfo
  • ProjectUnit
  • Sketch
  • SpotDimension
  • TextNote
  • ViewPlan
  • ViewSection
  • ViewSheet
  • Leader, LeaderArray

(In this series of postings, I'll continue to provide short commentary on what's new in the Revit 2008 API, and why I think it's interesting).

10 comments:

James said...

Hi Matt,
So do you know if creation of windows and doors is able to be supported in any fashion in the current version of the SDK? I am interested in creating window and door elements, but don't see how that is currently possible, which is a shame.

Thanks

J

Matt Mason said...

James,

Can I clarify your question?
If your question is "can you place doors/windows into existing walls" - then the answer is yes. You can make New Family Instances for almost all of the types.

If your question is whether you can programmatically create new families containing doors/windows? Then the answer is no, sorry.

James said...

Hi Matt,
Thanks for the reply, but I still have the question of "can you place doors/windows into existing walls programmatically?". When creating new family instances, I can't determine how to create that instance as a window.

Thanks

Matt Mason said...

James,

Here's a sample of how I've done it in the past. The trick is that you have to get the right family type (aka Family Symbol), then use that to make a new family instance, with the wall as the host element:

(my apologies for the formatting of this - it looks nasty when it's only 25 characters wide).



// Make a wall, just to work with.
Autodesk.Revit.Elements.Wall w1 = doc.Create.NewWall( app.Create.NewLineBound( new Autodesk.Revit.Geometry.XYZ(0,0,0), new Autodesk.Revit.Geometry.XYZ(0,100,0) ), doc.ActiveView.GenLevel, false );

// Get the family symbol for the door I want Autodesk.Revit.Symbols.FamilySymbol fs = getSymbol( doc, "Single-Flush", "36\" x 84\"" );

// place it Autodesk.Revit.Elements.FamilyInstance fi = doc.Create.NewFamilyInstance(new Autodesk.Revit.Geometry.XYZ(0, 50, 0), fs, w1, doc.ActiveView.GenLevel, Autodesk.Revit.Structural.Enums.StructuralType.NonStuctural);


private Autodesk.Revit.Symbols.FamilySymbol getSymbol( Document doc, string family, string symbol )
{
string upperFamily = family.ToUpper();
string upperSymbol = symbol.ToUpper();
ElementFilterIterator efi = doc.get_Elements( typeof( Autodesk.Revit.Elements.Family ) );

while (efi.MoveNext())
{
Autodesk.Revit.Elements.Family fam = (Autodesk.Revit.Elements.Family)efi.Current;
if (fam.Name.ToUpper() == upperFamily)
{
Autodesk.Revit.Symbols.FamilySymbolSetIterator fss = fam.Symbols.ForwardIterator();


while (fss.MoveNext())
{
Autodesk.Revit.Symbols.FamilySymbol fs = (Autodesk.Revit.Symbols.FamilySymbol)fss.Current;

if (fs.Name.ToUpper() == upperSymbol)
{
return fs;
}
}

return null; // found family but no symbol

}

}

return null; // found no family

}

James said...

Hi Matt,
That is perfect. Where I was getting hung up was specifying the family type/symbol. Thanks for the help.

James

James said...

Hi Matt,
Another question for you. To frame it, this is what I am trying to do: create an external application that could allow for a bit of complex configuration of windows before inserting them into Revit. In the past I have done some contract work that leads me to believe that architects could use this type of functionality for issues like grille alignment. Families appear to make this type of complex case difficult. So I was thinking about having an external app be able to do a lot of the heavy lifting and when I am done, insert the window into my project. In order to do this I wanted to procedurally generate the family (which isn't possible). My next idea was to create a generic family that I would insert the window as. In order to do this, I would need to at least be able to specify a type and also throw out all the components in the family and regenerate them based on dimensioning from my application.

Anyway, that is a verbose comment, but I am wondering what your take on such a project would be. You seem to be one of the few in the know folks concerning the Revit API at this point that I can find.

Matt Mason said...

James,

That's a tough one - with the way Revit and its API work today.

Off the top of my head, here's a couple disjointed thoughts:

1. I don't know how good you are at development of "good" Revit families - I think much of what you're talking about requires a very well-defined parametric Revit Family... but that's possible.

2. In the "smart-family" you'll probably have to make a bunch of the parametric dimensions, component switches, etc be instance parameters (because I suspect you'll be changing them on an instance basis rather than a "type" basis).

3. I'm pretty sure that there's no way currently to create a new FamilySymbol - so you have to work with the ones you have - either selecting the proper one, or tweaking the parameters on it to make what you want. (or make the driving parameters into instance parameters so that they can be set for each instance).

All in all, it's a tough road, but you might be able to make something that makes sense.

You might also try out the idea on manufactured or custom home builders (who also need a great deal of quick window selection/configuration).

Best Regards,
Matt

James said...

Hey Matt,
Thanks for the help, I am starting to work through what I might be capable of doing. One thing that has been driving me nuts that I wanted to ask you. Do your external applications ever just start not running? Mine will be running fine for a while, and then eventually I will click on them in the External Tools menu and nothing will happen. If I am in debug mode, it will not jump into the code, if I am in release mode nothing. No error or anything. Have you seen this at all?

Thanks!

J

Matt Mason said...

James,

I have not seen that.

The only time I've ever seen something which is on the menu be present, but not run anything when you click on it, is when the referenced assembly or classname did not exist.

It doesn't sound like that's what's happening to you - so I'm stumped.

-Matt

James said...

Yeah it is bizarre. It appears to happen when I load an external family. Once I load one up, my code will not get called again. I will let you know if I figure it out.