« DevCamp, Devlabs and Updated API Training Schedule | Main | Revit 2011 Product GUIDs »

March 29, 2010

Comments

Jeremy,

Any guidelines about how to port your code from 2010 to 2011 but keep it compiling on both versions?

How to use the new 2011-only features and make them be ignored by the 2010 compilation?

Are there any #if preprocessor directive which allow our code to guess it is being compiled along 2010 or 2011 SDK?

Most of times we cannot just trash our current version in favor of a smooth and definitive migration to the new SDK.

Cheers.

Dear Fernando,

Thank you for these very pertinent questions. Here are some quick and dirty spontaneous answers to them:

1. Nope.

2. Use an #if preprocessor directive.

3. Nothing predefined, but you can set them up yourself, of course. I added some #if _2010 directives to The Building Coder samples, but they are more decorative than functional, since I have no intention of compiling the ported version for 2010. I simply added them to preserve some 2010 version code here and there for comparison purposes, and intend to possibly use that to explain some of the main differences at some point.

4. Yes, I definitely understand and agree with that, and I would suggest that you do exactly what you are sort of suggesting, use a preprocessor directive to switch between 2010 and 2011 version code, or even other versions as well, if needed. You can of course also use .NET reflection to determine at runtime what version of Revit has loaded your add-in, and switch dynamically between differenc versions of your functions appropriately, cf. the end of

http://thebuildingcoder.typepad.com/blog/2009/10/revit-2010-subscription-pack.html#2

If you like, we can work together to set up a little sample demonstrating the technique for publishing here on the blog to explain to others how this works.

Cheers, Jeremy.

Jeremy,

I think this issue is pretty much related to the project configuration than the sample features itself.

I think if you get a sample which contains code that have changed significantly from 2010 to 2011 this would be a very nice example of the problems users may face when they are trying to migrate their codes.

You could show them how to create the #if preprocessor definition and how to address the namespaces changes, changed signatures, removed API methods, etc.

How does it sound for you?
Cheers.

Dear Fernando,

Yes, I absolutely agree. Please go ahead and send a minimal but not completey uninteresting sample along :-)

Please send me some free time as well. ;-)

Cheers, Jeremy.

Ok, I will think about something simple and representative.

If I can find some free time I will send you but it will cost some money...hehehe

Cheers.

Hi there,

we did the migration to 2011 keeping the 2010 even 2009 running.
Finally we create a seperate DLLs for 2011/2010/2009, but we use the same source code.

We addded special using statments for the major objects changed like:

#if Revit2011
using Autodesk.Revit.DB;
using RvtGeoElement = Autodesk.Revit.DB.GeometryElement;
using RvtGeoInstance = Autodesk.Revit.DB.GeometryInstance;
using Symbol = Autodesk.Revit.DB.ElementType;
...
#else
using RvtGeoElement = Autodesk.Revit.Geometry.Element;
using RvtGeoInstance = Autodesk.Revit.Geometry.Instance;
using Symbol = Autodesk.Revit.Symbol;
...
#endif

And it works fine for us.

Regards,
Steffen

Dear Steffen,

Thank you for the information.

That is exactly the kind of approach I had in mind.

Congratulations on handling all three versions so effectively and elegantly.

Do you have any bits of source code or other functionality that also need conditional compilation?

If so, which are they, please?

If you like, I will happily publish some small non-confidential parts of your code as an multi-version example.

Cheers, Jeremy.

Jeremy,

I still don't understand why Autodesk does not provide a some native SDK preprocessor symbols for each AutoCAD/Revit release. It is very annoying to keep creating custom preprocessor definitions for every single new product release.

Steffen,

Did you create different VStudio ouput configurations for each Revit release/platform?

Something like:

Release Revit 2009
Debug Revit 2009

Release x32 Revit 2010
Release x64 Revit 2010
Debug x32 Revit 2010
Debug x64 Revit 2010

Release x32 Revit 2011
Release x64 Revit 2011
Debug x32 Revit 2011
Debug x64 Revit 2011

It is a nightmare for us.
Cheers.

Dear Fernando,

The reason is simply the KISS principle, as described in

http://en.wikipedia.org/wiki/KISS_principle

There is no need for it, it would only complicate things unnecessarily for those who do not require that kind of support, and unnecessarily limit those who do.

Just imagine if we at Autodesk had designed support for all those platforms in our own fashion.

I promise you it would not fulfil your needs, AND it would make it MUCH harder for you to do so yourself, because you would have to battle our principles.

I am absolutely convinced that there is nothing in the world stopping you from creating a completely comfortable and efficient system to manage the different versions with no pain at all, and certainly no nightmares.

If you like, you can drop me a mail when a new release comes out and I will invent a pre-processor symbol for you :-)

Cheers, Jeremy.

Hi Fernando,

We only have different copies of the initial solution file from 2009 and added the define Revt2010 and now Revit2011.
Why different solutions? We need to add differnet files for the installaton packages.

Because we use .net we always compile with AnyCPU, so we only have two configurations for every sln. Debug/Release as usual.

Regards,
Steffen

Jeremy,

Sure we have a some more. The rest is very specific for our naming conventions.

Regards,
Steffen


1.)inside main class
#if Revit2011
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
#endif
public class Command : IExternalCommand


2.)inside Execute method
#if Revit2011
RevitCore.ActiveDocument = commandData.Application.ActiveUIDocument.Document;
RevitCore.Application = commandData.Application.Application;
RevitCore.Document = commandData.Application.ActiveUIDocument.Document;
RevitCore.RevitUIApplication = commandData.Application;
#else
RevitCore.ActiveDocument = commandData.Application.ActiveDocument;
RevitCore.Application = commandData.Application;
RevitCore.Document = commandData.Application.ActiveDocument;
#endif

3.)to create the ribbon
//create cpi pulldown menu
RibbonPanel rvtRibbonPanel = app.CreateRibbonPanel(NLS.Revit2010_TLB_PanelName);
#if Revit2011
PulldownButton cpiPullDownBtn = rvtRibbonPanel.AddItem(new PulldownButtonData(NLS.Revit2010_TLB_PullDownMenuName, NLS.Revit2010_TLB_PullDownMenuName)) as PulldownButton;
#else
PulldownButton cpiPullDownBtn = rvtRibbonPanel.AddPulldownButton(NLS.Revit2010_TLB_PullDownMenuName, NLS.Revit2010_TLB_PullDownMenuName);
#endif

#if Revit2011
PushButton cpiPushBtn = cpiPullDownBtn.AddPushButton(new PushButtonData(NLS.Revit2010_TLB_ButtonText, NLS.Revit2010_TLB_ButtonText, ExecutingAssemblyPath, "Commandclass"));
#else
PushButton cpiPushBtn = cpiPullDownBtn.AddItem(NLS.Revit2010_TLB_ButtonText, ExecutingAssemblyPath, "Commandclass");
#endif


4.)to get all elements
#if Revit2011
IEnumerator allElementsEnumerator = RevitCore.Document.get_Elements_Bridge();
#else
IEnumerator allElementsEnumerator = RevitCore.Document.Elements;
#endif

Dear Steffen,

Thank you very much for the useful examples, they are just like I would have imagined them.

I think the principle is totally clear.

Cheers, Jeremy.

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Your Information

(Name and email address are required. Email address will not be displayed with the comment.)

Jeremy Tammik

AboutTopicsIndexSource