PDA

View Full Version : First API attempt.. turning off imported categories in visibility/graphics



r.howarth
2007-10-17, 02:31 AM
G'day all,

I am trying to learn the Revit API from scratch. My first task is to turn off "show imported categories" in this view in the imported categories tab of 'visibility/graphics' menu in revit structure.

I'm stumped as to how to do this.. I know there is a category class, and there is a view class, but how do I go about doing this? I can't really see anything too easy in there.

Is there any beginners guides other than the SDK samples ?

mmason.65315
2007-10-17, 12:18 PM
G'day Rod,

On the View class, check out the "setVisibility( Category )" member.

Regarding figuring out whether a category is imported or not... I'm not 100% sure of the best approach.

1. By name (the category of an imported file tends to be its filename, so if it ends in .DWG...)

2. By ElementId... It seems like the "Built in" categories have negative numbers - while imported categories are positive.

3. You could probably compare it to the Enumerated Type BuiltInCategory and see if it matched anything.

Best of luck,
Matt

GuyR
2007-10-17, 08:16 PM
Is there any beginners guides other than the SDK samples ?

The VisibilityControl SDK sample shows you the basics for doing what you're attempting.
Autodesk.Revit.BuiltInCategory.OST_ImportObjectStyles is the category you want.

From that the SubCategories() method of the ImportObjectStyles category will allow you to find the category of the DWG you're interested in.

For .NET tutorials the video tutorials on the MS site are good. Other than that get a good book and do lots of reading/experimenting.

HTH,

Guy

r.howarth
2007-10-19, 04:43 AM
Thanks guys! What a great forum.

I have had a look at the visibility control one and I think I know what to do now, I'm just trying to get it into a new solution and deploy it now. Hopefully this should get me started!

r.howarth
2007-10-30, 12:21 AM
ok, I got it working basically.

I searched through each category in document.settings.categories for the active document and for any ending in .dwg i'd set the visibility to the opposite of what it was.

This works fine, I import a .dwg file, run it, it dissapears, the tick box is gone in the menu too. I run it again, and it comes back. perfect.

However, if I delete the .dwg, and run it, it comes up with an error. Or if I run it before I import a .dwg, then import one and run it - it does nothing.

It has some sort of memory, the list of categories is not being updated. How do I force it to re-check the categories every time? is there some way of fully unloading it and not leaving anything in memory after I do it (wouldn't this chew up resources anyway?)

GuyR
2007-10-30, 12:31 AM
Rod,

Post the project/code. It's hard to debug otherwise. No static properties? The other thing to do is make sure you're disposing objects properly. Good to know you're nearly there.

Guy


ok, I got it working basically.

I searched through each category in document.settings.categories for the active document and for any ending in .dwg i'd set the visibility to the opposite of what it was.

This works fine, I import a .dwg file, run it, it dissapears, the tick box is gone in the menu too. I run it again, and it comes back. perfect.

However, if I delete the .dwg, and run it, it comes up with an error. Or if I run it before I import a .dwg, then import one and run it - it does nothing.

It has some sort of memory, the list of categories is not being updated. How do I force it to re-check the categories every time? is there some way of fully unloading it and not leaving anything in memory after I do it (wouldn't this chew up resources anyway?)

r.howarth
2007-10-30, 12:42 AM
Here's my code, I've pretty much just cut down and changed the visibilitycontrol sample to meet my needs, I'm trying to take it all in as I go - it's all new to me.

namespace ImportedCategoriesToggle
{
public class Command : IExternalCommand
{

private Autodesk.Revit.Document m_document; // the active document
private Hashtable m_allCategories; // all categories name with its visibility
private Hashtable m_categoriesWithName; // all categories with its name

public virtual IExternalCommand.Result Execute(ExternalCommandData commandData
, ref string message, ElementSet elements)
{
try
{
MessageBox.Show("running");
m_document = commandData.Application.ActiveDocument;
if (null == m_document)
{
throw new ArgumentNullException("document");
}


// initialize the two table

m_allCategories = new Hashtable();
m_categoriesWithName = new Hashtable();

m_allCategories.Clear();
m_categoriesWithName.Clear();

foreach (Category category in m_document.Settings.Categories)
{

if (category.Name.EndsWith(".dwg"))
{

MessageBox.Show("Changing " + category.Name + " " + category.get_Visible(m_document.ActiveView));
m_allCategories.Add(category.Name, category.get_Visible(m_document.ActiveView));
m_categoriesWithName.Add(category.Name, category);

if (category.get_Visible(m_document.ActiveView))
SetVisibility(false, category.Name);
else
SetVisibility(true, category.Name);

}
}

return IExternalCommand.Result.Succeeded;
}
catch (Exception ex)
{

MessageBox.Show(" An error in a BWTools Macro has occured, please show the following to ITQC: " + ex.ToString());
return IExternalCommand.Result.Failed;

}
}

public bool SetVisibility(bool visible, string name)
{
try
{
Category cat = m_categoriesWithName[name] as Category;
m_document.ActiveView.setVisibility(cat, visible);
//or cat.set_Visible(m_document.ActiveView, visible);
m_allCategories[cat.Name] = visible;
}
catch (Exception ex)
{
MessageBox.Show("An error in a BWTools Macro has occured, please show the following to ITQC: " + ex.ToString());
return false;
}

return true;
}
}
}

----------------------------------------------------------------

It can probably do with some cleaning up, any feedback on the code is welcomed as well.

I think perhaps I need to properly close some stuff, not sure what ones and how to though.

Thanks heaps for your help

r.howarth
2007-10-30, 01:37 AM
I've uploaded the code in .txt format (so indenting is there)
and i've uploaded a screenshot of the error thats generated when you run it after deleting your dwg file.

GuyR
2007-10-31, 02:02 AM
Rod,

Good news is there is nothing wrong with your code, the bad news is it's a bug. AFAICT if the project opened has the DWG loaded already then it's OK. The category doesn't get added to the CategorySet for some reason. Done some more testing. If you run the command before adding a DWG on a new project then it doesn't catch the DWG. If you run the command after adding a DWG on a new project then it does catch the DWG. Even if you explicitly dispose the document object it makes no difference.

There is a very valid workaround (will be slightly slower). Walk the tree checking if an object is an instance. Autodesk.Revit.Elements.Instance . Then check these element categories for the DWG name.

Have logged the category issue with ADesk.

HTH,

Guy

r.howarth
2007-11-01, 11:06 PM
Glad to hear it wasn't just me!
I might give the alternate go a try,
Thanks again!

I'm interested in any feedback on my code, is there anyway to do it better, do I really need the hashtables etc (just left them there because it 'just worked')

GuyR
2007-11-07, 09:55 PM
Confirmed. Revit API bug. So you need to walk the tree and check for instances as suggested for now.

Guy