Thursday, May 31, 2012

Which way am I looking?

One of the somewhat obscure but interesting features that I had been looking forward to in the Revit 2013 API, I finally got a chance to use recently when updating our Scan To BIM for Revit application.

That is - you can finally look at the ViewRange settings for a particular plan view. Now, there are a thousand posts out there about how View Range works, and I think you can also ask a hundred Revit users and get at least 30 different answers. The truth is, there are a LOT of complications to it.

From the API persective, there are 5 kinds of PlaneViewPlanes:

  • Top Clip Plane
  • Cut Plane
  • Bottom Clip Plane
  • View Depth Plane
  • Underlay Bottom Plane
Finding out the ViewRange is pretty easy:

PlanViewRange range = myPlanView.GetViewRange();
// for a given plane, find the associated level and offset
ElementId cutLevelId = range.GetLevelId( PlanViewPlane.CutPlane );
double cutLevelOffset = range.GetOffset( PlanViewPlane.CutPlane );
Of course, you can set the view range data as well.

The Real Reason For My Post: View Direction

This is all well and good, but now we come to the REAL reason for my post. As happens so often within the Revit API, you think you can see the way to get from point A to point B and accomplish your mission. And then you are blindsided by some strange Revit complexity that you might have heard about, but had not dealt with before.

The fundamental problem I was trying to solve was to identify what parts of a point cloud were visible in the Plan View. Much of this you can determine from the the PlanViewRange, shown above. But it soon became clear that there was a bit more to it than that. As you may know, Plan Views may face upwards or downwards within Revit. That is to say - a FloorPlan is always "looking down" at the floor - but a Reflected Ceiling Plan or Mechanical Plan is always "looking up" at the ceiling. Apparently structural views could not be decided, so you can actually edit the setting on the view type to be up or down for a model.

I had originally guessed that the ViewDirection property would be a different vector to represent the direction that you're looking ... but that's not the case. So - if you have to know the direction, how do you find it?

It hinges upon the ViewFamilyType (this concept existed as an Element in 2012, but has a fully exposed class in 2013 - so you wouldn't have been stuck in 2012). Views all derive from a ViewFamilyType. Inside the ViewFamilyType, there is a hidden BuiltInParameter (it's only a visible parameter on the aforementioned Structural ViewType). 

 // determine the view direction
ElementId vftId = vp.GetTypeId();
Element vft = vp.Document.GetElement(vftId);
if (vft == null) throw new ArgumentException("Unable to find view family type for view: " + vp.Name);
Parameter viewDirParam = vft.get_Parameter(BuiltInParameter.PLAN_VIEW_VIEW_DIR);

So once you have that, you're all set - the parameter tells you, for your view, whether you're looking up or down.

It's obscure, but as always, I hope you stumble upon this when it's useful to you!


Tuesday, June 28, 2011

Point Cloud Fix in Revit 2012 Web Update 1

One of the biggest problems that people have had with the new Point Cloud capabilities of Revit 2012 is how it dealt with multiple point clouds inserted into your Revit project.
If you had multiple scans that all were from the same origin, and you inserted them all origin-to-origin, then they would all line up, right? wrong...Some of the problem related to how Revit handled large coordinate values (as you may know, Revit doesn't like it when elements start showing up miles from the model origin). If you inserted a PCG file which was indexed from something where the coordinates were in state-plane (which is not all that uncommon) - Revit would basically reset the coordinates and insert it center-to-center. And then how are you going to insert the next one so that it is consistent?
The answer was supposed to be the third insert option: Auto - Origin to Last Placed (meaning that it would make sure that the origin matched the origin of the previous model). But it didn't work :).

So what's new in 2012 Web Update 1? It works!
Before:


After:



While no one likes to see bugs like this, it's nice to see decent turnaround on it. I had been worried it was going to involve having to re-index all of the PCG files - that would have been bad.

[Editor's Note: Jason Seck just pointed out to me... you might still be annoyed that they haven't addressed the "first cloud" issue... Your first large coordinate cloud is still going to come in Center-to-Center. All they have fixed is the "relative placement" of clouds issues. I think it will be a while before the "first cloud" issue is fixed, because to do that they would need to fix the "two-miles-from-the-origin issue", and that seems like a big one.]

Saturday, May 28, 2011

An oddity with Drafting View mirroring

So I was asked if it was possible to mirror a drafting view using the API (apparently the built-in project mirroring doesn't cover drafting views).

It seemed straightforward enough... so I wrote a quick test... and it didn't work...
- it worked fine in a floor plan view
- it didn't work in a drafting view
- the code completed just fine - it just didn't really seem to show any difference.

My initial code is below...
- Get all the elements in the current view
- Use the new ElementTransformUtil class to figure out which could be mirrored, and mirror them.



FilteredElementCollector coll =
new FilteredElementCollector(uiDoc.Document, uiDoc.ActiveView.Id);

IList elems = coll.ToElements();

// make sure that stuff can be mirrored
List toMirror = new List();

foreach (Element elem in elems)
{
if (ElementTransformUtils.CanMirrorElement(uiDoc.Document, elem.Id) == false) continue;
toMirror.Add(elem.Id);
}



So why did this complete successfully, but not show any difference?
The answer is one of those great undocumented elements in the wilds of the Revit database. When I looked in the debugger at what I was actually attempting to mirror, I saw this:




What I see here is a mystery element called "ExtentElem" which is being copied. I have a sneaking suspicion that it might be telling the view the actual extent of what is in it... So how can we exclude it? well - it has no actual category (which is probably a sign that in general we don't want to mirror an element like that!).


So - we add a line like:

if (elem.Category == null) continue;

and voila! we have our drafting view being mirrored.



I wish that I could say that all Revit database mysteries are "easily" solvable like this - there's plenty of times where you just run into a wall, and can't get to what you want... but today's story has a happy ending!

Monday, May 16, 2011

DWFplus for Revit 2012

Well, it has been forever since I've last posted... I missed the release of the 2012 API and a variety of other announcements. But I'm trying to get back on the horse.

To that end - a quick video to show what I think is a cool new feature of our Utilities for Revit 2012 product - a new utility called "DWFplus".

If you've ever looked at distributing a DWF file, and figuring that Revit ought to be making it chock-full of all my BIM data... you may have been slightly disappointed. The rules for when Revit published a parameter or didn't were arcane - and I'm still not sure if we've accurately reverse engineered them. And certain features like hyperlinks... how is it that AutoCAD can have hyperlinks but not Revit!

So DWFplus is an attempt to change that. It starts with a regular DWF export, but adds in a variety of neat stuff:


  • All parameters (or selected parameters) that you want to publish

  • Parameters are attached to Tags - not just the elements

  • Includes 2D Hyperlinks for any URL parameters (even multiples)

  • Parameters are published in 3D as well as 2D.

  • Includes some neat 3d viewpoints for 3D DWF views.

Here's a little video to demonstrate:






Note: IMAGINiT Utilities for Revit is available here, and is free for clients that keep their Revit subscription with IMAGINiT.

Thursday, April 22, 2010

Revit API 2011: Revit AddIn Manager – Almost Edit & Continue

(part of our ongoing series)
If you’ve been developing for Revit for a while – you groaned significantly when, in Revit 2010, changes were made to Revit that disabled the “Edit-and-Continue” capability within a Revit add-in. That is to say – if you wanted to make a minor code change while Revit was debugging – you had to close Revit (wait for Revit to be totally closed), perform the change, then restart Revit, re-load your model, and then try to get back to the same location. Argh – seems like 2+ minutes down the drain any time this happens.

Enter the “Revit AddIn Manager” – part of the Software Development Kit. This tool has been around since 2009, I think – it historically provided handy mechanism for a developer to test External commands or applications – even when they forgot to add them to the REVIT.INI file. It could both update the INI file for you, or even just launch the command in session.

image

What’s Different in 2011?

I suspect due to some conversations and posts that were had on Jeremy Tammik’s blog late in the development process, the AddIn Manager has been notably improved – such that while you can’t support edit-and-continue, you can now support updating your code while Revit is running, and just re-running your command inside of Revit.

How does this work? The Addin utility is doing some lifting behind the scenes, including copying the DLL and related files to a temporary folder, and loading the .NET assembly DLL from that location.

What does this mean for us? That when we start up Revit with the debugger attached, we can run the AddInManager. From the AddInManager we can launch our command in a way that loads it into memory before starting the debug process.

While we still cannot edit and continue, we CAN open a second copy of Visual Studio, and make changes by rebuilding the project.

- it allows us to overwrite the project, because the running project was copied to somewhere else.

- we are now able to just re-start the AddIn Manager in order to start our updated version of the command.

The Features of the AddIn Manager

The behind-the-scenes mechanics are described above. It also has (obviously) been enhanced to support the new “.addin file” mechanism rather than the Revit.INI mechanism of registering addins. The command also supports some additional options which can be a little confusing at first. The list of AddIn Manager commands looks like this:

image

What’s the deal with all this manual, automatic and faceless?

The Manual vs. Automatic entries refer to the new TransactionMode and RegenerationMode that must be assiged to each command. Because the AddIn Manager is going to invoke your AddIn, it would be a problem if AddInManager specified Automatic mode but your code specified manual mode. So you have to pick automatic or manual based on what YOUR command is defined as. NOTE: No mix/match on transaction and regeneration mode… you have to be either Auto/Auto or Manual/Manual. The application will stop you if you pick the wrong one (although the error message leaves something to be desired).

Faceless, while the mechanism seems a little clumsy – is a nice little feature. Fundamentally – it remembers the last command that you executed, and will just execute that again (no user interface, it just does it – that way you don’t need to re-browse, re-select, and re-run the command in question).

Conclusion

If you occasionally work with API developers – get a copy of the AddIn Manager to make it easier to test and setup API AddIns! If you’re a developer, there are now many good reasons to set up the AddIn Manager. So get to it! It’s in the Revit SDK installation folder.

Revit 2011 API: What’s New in Element Creation

(part of our ongoing series)
Each new version, I go through what is new in the specific API area of element creation. Every CAD API has some logical divisions, from information retrieval, to element creation, to interactivity – and you can tell from how strong each area is what the factory’s focus is in the API.

Revit’s start in this area was weak – the API was more about finding elements and updating parameters than actually creating new elements and geometry. In recent releases, Revit really played catch up – I believe it now supports 101 different element creation methods.

So what’s new in 2011 in this area: in short, not much… This was not an area of focus in 2011, so there’s only a few new things in this specific area:

  1. NewTruss() – now available in architecture
  2. NewRebarType()
  3. NewRebarHookType()
  4. NewRebarCoverType()
  5. FaceWall.Create()

The last one is of the greatest interest to me personally. This enables you to create a wall based on a face (typically a face that is on a mass element). This is an advanced technique used in Revit to create complex wall shapes.

Two other items deserve honorable mention here as well:

  • UIDocument.PromptForFamilyInstancePlacement() – while not technically a “Element Creation” capability, it opens up some significant doors to more interactive design applications within Revit – by letting the end-user help the developer place the family instance visually.
  • SolidSolidCutUtils – A new utility class to help with doing solid-to-solid cuts in the modeling environment. This is typically used either for GenericForm kind of family solids or family instances.

All in all, while this category doesn’t seem like it got much attention in 2011, the fact is that with 101 element types that can be created, it has attained a certain level of maturity. For example, if I scan the Home ribbon in 2011 – it is possible to create almost everything that is available on that toolbar (I think the exceptions are: Ceiling, Model Group (you can’t create a new one), Railing, Ramp, Stairs. That’s really not too bad – and the remaining ones are a little on the obscure/complex side.

So let me hear from you by comments? Are you really waiting for one of the missing elements that can’t be created? or are you just reluctant to do API work with geometry creation until it supports 100%? How many different kinds of elements are YOU creating in your app?

Saturday, April 17, 2010

Revit 2011 API Series: RevitLookup: The New Name for RvtMgdDbg

(part of our ongoing series)
Since the beginning of Revit development time – in the 8.0/8.1 range, the best way to learn about what is possible with the Revit API was to use a “Snoop Tool” – something that could interrogate all of the elements in the model and all of their properties.

In the beginning, there was RevitDbg – a tool by Fenton Webb at Autodesk. It used reflection to browse through a massive tree structure of all the elements in the model. It was slow, but cool.

Later, Jim Awe of Autodesk brought his Snoop tool (called “RvtMgdDbg”) from AutoCAD to Revit – bringing not just browsing of elements but also event testing as well as some test commands. This became the tool that most Revit developers cut their teeth on. That said – I’m still amazed at the number of developers who have tried to learn the API without the benefit of RvtMgdDbg… I have to imagine it’s like developing in the dark!

For all of its importance to Revit developers, RvtMgdDbg was always somewhat of a step-child at Autodesk… No one really owned it (so it was nice that they provided the source – at least 3 times over the past few years I had to upgrade it myself to support the latest version before someone at Autodesk took care of it). It was also unclear over time how it was going to be distributed – was it only for ADN members? Did you have to attend a particular AU session? Or did you just have to know the right people? Thankfully, in the past year or so Autodesk has caught on to how important RvtMgdDbg is to getting developers up-to-speed and has made it available to anyone, usually via Jeremy Tammik’s blog.

Which brings us to 2011… While not revolutionary – it is an important evolution for RvtMgdDbg. It has been adopted by the Revit API team – which means that there are resources devoted to updating it and providing it along with the SDK – under a new, more accessible name: RevitLookup. Kevin Vandecar as well as some of the Shanghai developers have done yeoman’s work in upgrading it (it is a grueling task – I know because I had to do it myself at least twice during the 2011 alpha/beta cycle).

RevitLookup can be found in the SDK folder under RevitLookup – it appears that you’ll have to build it yourself (binaries were not shipped) – but it’s great to see that this tool getting its proper due from Autodesk.

Thursday, April 08, 2010

Revit 2011 API: SDK Posted (a while ago)

We’re all still waiting anxiously for the official Revit 2011 product to become available… They set the expectation for today – but it’s not there yet! and it’s 7:58 AM! What’s the deal? :)

That said – I noticed last night that the final Revit 2011 SDK is available as a standalone download on the ADN page (posted back on 4/1 – and I didn’t notice).

In other news, I hope to get back onto posting the rest of my 2011 articles – I’m just temporarily buried in project work.

[Editor: And I can see that I have to go back and add to a few previously written articles. I can see at least 15 enhancements in the new SDK that were added late enough in the process that I was unaware of them! Woo-hoo, more toys!]