I know most people relate falling in love with February 14th. ...being the geek at heart that I am, I think this holiday should be relocated to March 14...
That's right, 3/14.. or 3.14!! It's only one month exactly from the ever so improperly commercialized love holiday of 2.14!!!
Write your senators and let's get this taken care of once and for all!!! We all owe our livelihoods to simple arithmetic whether we know it or not and should celebrate our love of understanding it!!
And ladies... if you feel the same way, let's talk!!
Sunday, January 30, 2011
Tuesday, January 25, 2011
Top 10 Excuses All BIM Managers Hate
Do you have any users that refuse to follow the modernized BIM way of doing things and insist on using their outdated "proven" 2D garbage ways of doing things, yet complain about how the whole BIM craze is oversold and not worth their trouble? Do you remember the excuses they offer?... Do you think they are as funny as I do?...
Hopefully after reading this post you will stop wanting to stuff your head in a garbage disposal and dumping a gallon of boiling bleach in your wounds:
10. ) "If Revit can't handle an exploded 3D AutoCAD mesh of my custom imported roofing structure, then we need to find a better software to help us get our $hit done!!!" [slamming fists on table and storming out of the room]
9. ) "What is wrong with having a pile of elements off to the side of my building on each of the 63 levels of my model? It makes it easier for me to grab and place them where I need them in my design.... I didn't know that would upset the construction bid consultant"
8. ) "I turn my model background black so I can see my yellow walls better..."
7. ) Consultant: "I couldn't print my sheets because I didn't know where your firm's standard pen table was..."
6. ) "Drafting elevations in AutoCAD is so much easier... how are you supposed to reference in the plan view so you know where everything lines up in elevation?... I would have been done days ago in AutoCAD, sorry."
5. ) "I don't Sync to Central because every time I do, all this other crap pops up in my drawing that get in the way..."
4. ) "I was cleaning the rooms out of my schedule to display the rooms only on level 4 and now they are all gone in the model... I didn't know that would delete them from the model"
3. ) "If I knew you wanted to use Navisworks on this project, I would have not built all 127 lighting fixture families as 2D... DAMMIT... tell me next time!!!!"
2. ) "Drafted my door schedule in lines and text because I didn't know how else to get my drafted doors to show up in the schedule..."
And the number one excuse I hear that never fails to cheer me up....
1. ) "If this were anything like AutoCAD, I'd be done with my plan views and ready to start manually drafting my sections, elevations, and details... this crap is SLOW!"
Hopefully after reading this post you will stop wanting to stuff your head in a garbage disposal and dumping a gallon of boiling bleach in your wounds:
10. ) "If Revit can't handle an exploded 3D AutoCAD mesh of my custom imported roofing structure, then we need to find a better software to help us get our $hit done!!!" [slamming fists on table and storming out of the room]
9. ) "What is wrong with having a pile of elements off to the side of my building on each of the 63 levels of my model? It makes it easier for me to grab and place them where I need them in my design.... I didn't know that would upset the construction bid consultant"
8. ) "I turn my model background black so I can see my yellow walls better..."
7. ) Consultant: "I couldn't print my sheets because I didn't know where your firm's standard pen table was..."
6. ) "Drafting elevations in AutoCAD is so much easier... how are you supposed to reference in the plan view so you know where everything lines up in elevation?... I would have been done days ago in AutoCAD, sorry."
5. ) "I don't Sync to Central because every time I do, all this other crap pops up in my drawing that get in the way..."
4. ) "I was cleaning the rooms out of my schedule to display the rooms only on level 4 and now they are all gone in the model... I didn't know that would delete them from the model"
3. ) "If I knew you wanted to use Navisworks on this project, I would have not built all 127 lighting fixture families as 2D... DAMMIT... tell me next time!!!!"
2. ) "Drafted my door schedule in lines and text because I didn't know how else to get my drafted doors to show up in the schedule..."
And the number one excuse I hear that never fails to cheer me up....
1. ) "If this were anything like AutoCAD, I'd be done with my plan views and ready to start manually drafting my sections, elevations, and details... this crap is SLOW!"
Wednesday, January 19, 2011
Batch Family Fun for Everyone!!! Part 1
I bet you've been waking up recently in the middle of the night dreaming about how you could jockey the Revit API to batch process families, haven't you?... Well you're in luck because that's exactly what this post is for.
There's obviously a whole load of topics to dive into on batch processing families, so to keep it short and sweet I'll touch on how to open a family, add a shared parameter with a set value and close the family with the saved values. Later posts will build on even cooler family API processing ideas.
The first thing you will need to accomplish is get a reference to the local Revit application and document using a class that implements the IExternalCommand interface. The code belows shows the beginning of such a class...
The next thing we need is a quick and simple means of opening and closing external family files by calling their file paths as an argument to open the file. The functions below will open and close the active family respectively:
Now that we can open and close the families... lets add a shared parameter! That would be exciting, right? We can open a shared parameter using:
And now for some real excitement! The code below will search your active shared parameter file for a specific parameter by name and then add it to the family and set a value to it!:
So that's the basics! You now know how to open a family and add a shared parameter to it... Look for more batch family capabilities in future posts!
The first thing you will need to accomplish is get a reference to the local Revit application and document using a class that implements the IExternalCommand interface. The code belows shows the beginning of such a class...
Public Class ScribblesForBlog Private m_Manager As FamilyManager = Nothing Private m_App As UIApplication Private m_Doc As Document = Nothing Private m_SharedParamFile As DefinitionFile ''' <summary> ''' General Class Constructor ''' </summary> ''' <param name="CmdData"></param> ''' <remarks></remarks> Public Sub New(ByVal CmdData As ExternalCommandData) m_Doc = CmdData.Application.ActiveUIDocument.Document m_App = CmdData.Application If m_Doc.IsFamilyDocument Then m_Manager = m_Doc.FamilyManager ' Get a reference to the active shared parameter file if one exists Try m_SharedParamFile = m_App.Application.OpenSharedParameterFile Catch ex As Exception ' It is possible to have an empty value here (No Active Shared Parameter File) End Try End Sub End Class
The next thing we need is a quick and simple means of opening and closing external family files by calling their file paths as an argument to open the file. The functions below will open and close the active family respectively:
''' <summary> ''' Open an external family file and set the active doc reference to this family ''' </summary> ''' <param name="m_FileName">Full path to a valid rfa file</param> ''' <returns>Set the document object to this family on success</returns> ''' <remarks>www.RevitNet.blogspot.com RULES</remarks> Public Function OpenExternalFamily(ByVal m_FileName As String) As Boolean Try ' Open the family and set the active document object to the family m_Doc = m_App.Application.OpenDocumentFile(m_FileName) ' Verify the active document is the correct family (paranoia) If m_Doc.IsFamilyDocument And m_Doc.PathName.ToUpper = m_FileName.ToUpper Then ' Update the reference to the active family manager m_Manager = m_Doc.FamilyManager ' We're done, success Return True End If ' If we got to this line then something failed m_Manager = Nothing Return False Catch ex As Exception Return False End Try End Function ''' <summary> ''' Close the current family file ''' </summary> ''' <param name="p_SaveFile">Set to True will save the file on close</param> ''' <returns>Optional save, default is YES</returns> ''' <remarks></remarks> Public Function CloseActiveFamily(Optional ByVal p_SaveFile As Boolean = True) As Boolean Try ' This should only run on family files If m_Doc.IsFamilyDocument Then ' True means to save the file m_Doc.Close(p_SaveFile) End If ' We're done, success Return True Catch ex As Exception Return False End Try End Function
Now that we can open and close the families... lets add a shared parameter! That would be exciting, right? We can open a shared parameter using:
''' <summary> ''' Open as set the shared parameter file ''' </summary> ''' <param name="p_FileName">Full path to the shared parameter file</param> ''' <remarks></remarks> Public Sub OpenSharedParameterFile(ByVal p_FileName As String) If IO.File.Exists(p_FileName) Then Try m_App.Application.SharedParametersFilename = p_FileName m_SharedParamFile = m_App.Application.OpenSharedParameterFile Catch ex As Exception ' Should never fail... maybe a poorly formatted shared parameter file? End Try End If End Sub
And now for some real excitement! The code below will search your active shared parameter file for a specific parameter by name and then add it to the family and set a value to it!:
''' <summary> ''' Add a shared parameter to the current family and use a string ''' to set its value. A double formatted parameter can use 9'-4" (architectural) format ''' </summary> ''' <param name="SharedParameterName">The Name of the parameter to find and add</param> ''' <returns>True on Success</returns> ''' <remarks></remarks> Public Function AddSharedParameter(ByVal SharedParameterName As String, _ ByVal SharedParameterValue As String, _ ByVal isInstParameter As Boolean) As Boolean Try ' Make sure we are working with a valid family document If m_Doc.IsFamilyDocument Then ' make sure we have a valid shared parameter file If m_SharedParamFile IsNot Nothing Then ' Iterate the Parameter Groups For Each group As DefinitionGroup In m_SharedParamFile.Groups ' Iterate the Parameters in the Group For Each def As ExternalDefinition In group.Definitions ' Do we have a match? If def.Name.ToUpper <> SharedParameterName.ToUpper Then Continue For ' We found the parameter that we're after, ' does it already exist in the family? Dim param As FamilyParameter = m_Manager.Parameter(def.Name) ' If we have a valid parameter object, ' then it exists in the family (no need to add it) If param IsNot Nothing Then ' Start a new Family transaction Dim m_TransFam As New Transaction(m_Doc, "Family Transaction") m_TransFam.Start() Try ' Set the value from string... '9'-6" can set to a double or a string m_Manager.SetValueString(param, SharedParameterValue) m_TransFam.Commit() Catch ex As Exception ' Roll back on failure m_TransFam.RollBack() End Try Else ' Need to add the parameter... ' Start a new Family transaction Dim m_TransFam As New Transaction(m_Doc, "Family Transaction") ' Add the parameter as type or instance If param.IsInstance = isInstParameter Then m_TransFam.Start() Try ' First add the parameter m_Manager.AddParameter(def, def.ParameterGroup, isInstParameter) Dim fParam As FamilyParameter = m_Manager.Parameter(def.Name) If fParam IsNot Nothing Then ' Set the value from string... '9'-6" can set to a double or a string m_Manager.SetValueString(param, SharedParameterValue) End If m_TransFam.Commit() Catch ex As Exception ' Roll back on failure m_TransFam.RollBack() End Try End If End If Next Next End If End If Return True Catch ex As Exception ' Something did not go according to plan if we make it here Return False End Try End Function
So that's the basics! You now know how to open a family and add a shared parameter to it... Look for more batch family capabilities in future posts!
Tuesday, January 4, 2011
Visual Studio 2010 Revit 2011 Addin Templates
Have you begun using Visual Studio 2010 for your Addin development yet? Well if you have, then this post is for you! Just don't forget to always set your .NET Framework to 3.5
As you begin to develop with the Revit API, it can be annoying to have to duplicate your addin setup code and references to the Revit API. Did you know that you can create custom addin templates for your projects with all references and boiler plate code prepopulated? Just think of all the women that you can impress at the bar with a story about how you can do this!!!
Create a project with no special functionality but with all required references to the Revit API along with a basic command class setup the way you like and an application class as well. This will help make it easier to use the same template for both commands and applications. Links to the prebuilt template files that I use are at the bottom of this post.
You should maintain separate templates for each flavor of Revit that you develop for since the paths to the API references are different.
The provided "Command" class
The provided "Application" class
All you have to do is export a project as a template (the result will be a zip file) and place them under your current user's profile at:
"%USERPROFILE%\Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual Basic".
It is important to place your templates into a sub directory (we'll name ours "Revit 2011") and to NOT unzip the template files. Leave the zip files intact and this will work just fine. Your directory structure should look something like the image below.
Links to the above mentioned templates can be found here (for those that do not want or know how to create their own):
As you begin to develop with the Revit API, it can be annoying to have to duplicate your addin setup code and references to the Revit API. Did you know that you can create custom addin templates for your projects with all references and boiler plate code prepopulated? Just think of all the women that you can impress at the bar with a story about how you can do this!!!
Create a project with no special functionality but with all required references to the Revit API along with a basic command class setup the way you like and an application class as well. This will help make it easier to use the same template for both commands and applications. Links to the prebuilt template files that I use are at the bottom of this post.
You should maintain separate templates for each flavor of Revit that you develop for since the paths to the API references are different.
The provided "Command" class
'.NET common used namespaces Imports System Imports System.Windows.Forms Imports System.Collections.Generic 'Revit.NET common used namespaces Imports Autodesk.Revit.ApplicationServices Imports Autodesk.Revit.Attributes Imports Autodesk.Revit.DB Imports Autodesk.Revit.UI Imports Autodesk.Revit.UI.Selection <Transaction(TransactionMode.Automatic)> _ <Regeneration(RegenerationOption.Manual)> _ Public Class Commands Implements IExternalCommand ''' <summary> ''' Main entry point for every external command. ''' </summary> ''' <param name="commandData">Provides access to the Revit app and docs</param> ''' <param name="message">Return message</param> ''' <param name="elements">elements</param> ''' <returns>Cancelled, Failed or Succeeded Result code.</returns> Public Function Execute(ByVal commandData As ExternalCommandData, _ ByRef message As String, _ ByVal elements As ElementSet) As Result Implements IExternalCommand.Execute Try ' Add your code here Return Result.Succeeded Catch ex As Exception ' Add failure handling here Return Result.Failed End Try End Function End Class
The provided "Application" class
'.NET common used namespaces Imports System.Windows.Forms Imports System.Collections.Generic 'Revit.NET common used namespaces Imports Autodesk.Revit.ApplicationServices Imports Autodesk.Revit.Attributes Imports Autodesk.Revit.DB Imports Autodesk.Revit.UI Imports Autodesk.Revit.UI.Selection <Transaction(TransactionMode.Automatic)> _ <Regeneration(RegenerationOption.Manual)> _ Class Application Implements IExternalApplication ''' <summary> ''' Implement the external application when Revit starts ''' before a file or default template is actually loaded. ''' </summary> ''' <param name="application">Contains the controlled application.</param> ''' <returns>Return the status </returns> Public Function OnStartup(ByVal application As UIControlledApplication) _ As Result Implements IExternalApplication.OnStartup ' Add your code here ' Return Success Return Result.Succeeded End Function ''' <summary> ''' Implement the external application when Revit is about to exit. ''' Any documents must have been closed before this method is called. ''' </summary> ''' <param name="application">Contains the controlled application.</param> ''' <returns>Return the status</returns> Public Function OnShutdown(ByVal application As UIControlledApplication) _ As Result Implements IExternalApplication.OnShutdown ' Add your code here ' Return Success Return Result.Succeeded End Function End Class
All you have to do is export a project as a template (the result will be a zip file) and place them under your current user's profile at:
"%USERPROFILE%\Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual Basic".
It is important to place your templates into a sub directory (we'll name ours "Revit 2011") and to NOT unzip the template files. Leave the zip files intact and this will work just fine. Your directory structure should look something like the image below.
- RAC2011.zip - Revit Architecture 2011
- RME2011.zip - Revit MEP 2011
- RST2011.zip - Revit Structure 2011
Subscribe to:
Posts (Atom)