Changing Family Type through C#

Changing Family Type through C#

Anonymous
Not applicable
6,811 Views
15 Replies
Message 1 of 16

Changing Family Type through C#

Anonymous
Not applicable

Hi,

      I need to change the type of the  revit family from multiple types available in the properties. I need to do this through C#.Please provide me the solution.

 

Thanks,

Vinoth.

6,812 Views
15 Replies
Replies (15)
Message 2 of 16

ollikat
Collaborator
Collaborator

Hi.

I doubt there's many who are willing to provide you a solution from scratch. Maybe you need to be a bit more specific, which is the area you are struggling with.

Anyway...the Element.ChangeTypeId() method is the key here. Furthermore you will need to iterate trough a Revit project to find correct type (id) that is to be used.

I believe you can also find few other similar post within this forum using the search...if you are lucky, there might be code snippets already waiting for you out there ;-).

0 Likes
Message 3 of 16

Anonymous
Not applicable

Hi Ollikat,

                  Thanks for your reply and sorry for the delayed response. I have solved this issue at the time of loading a family in to revit. At the time of loading we can get family type so easily we can set a new type to that family.

 

Thanks and Regards,

Vinoth.

0 Likes
Message 4 of 16

Anonymous
Not applicable

The problem not addressed by .ChangeTypeId is that if a family type has been defined (FamilySymbol) but does not yet have any occurrences in the file (FamilyInstance), there is no obvious way to change an existing instance.  NewFamilySymbol.GetTypeId() does NOT provide a valid ID to use for ExistingFamilyInstance.ChangeTypeId(NewTypeId).  The only method I can see for this is to create a brand new FamilyInstance, extract the TypeId, delete this new instance, and then change the family instance.  This method opens a whole new can of worms -- making sure it is created in a view that allows that family (such as a titleblock).  I have not been able to find a way to determine a valid FamilyInstance TypeId to use if the family type is not yet used.

0 Likes
Message 5 of 16

Revitalizer
Advisor
Advisor

Hi,

 

before assigning a FamilySymbol fsb, it needs to be activated.

 

if (!fsb.IsActive)
{
    fsb.Activate();
}

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 6 of 16

Revitalizer
Advisor
Advisor

Hi,

 

placing a FamilyInstance activates the symbol as well, but no need to do so, just yourFamilySymbol.Activate().

Can of worms can stay closed.

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 7 of 16

Anonymous
Not applicable
I tried .Activate(), but NewFamilySymbol.GetTypeId() STILL provides an invalid TypeId when I do OldFamilyInstance.ChangeTypeId(NewId), even after adding .Activate() after creating the NewFamilySymbol. I can always "Select All Instances" (of old Family Type) and change them to the new one, but this defeats the purpose of doing it via API.
0 Likes
Message 8 of 16

Revitalizer
Advisor
Advisor

Hi,

 

the FamilySymbol already IS the type.

You are trying to get the type of a type.

So just use NewFamilySymbol.Id instead of NewFamilySymbol.GetTypeId().

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





Message 9 of 16

Anonymous
Not applicable
Thanks, that did it. The source of my confusion is that .GetTypeId() was offered as an option to the NewFamilySymbol, which (as we've seen) is not a useful value, and apparently a meaningless one. It didn't occur to me to just use the ElementId of the FamilySymbol.
0 Likes
Message 10 of 16

Revitalizer
Advisor
Advisor

Hi,

 

since most of the API classes are derived from Element class, there may be some meaningless methods and properties, depending on the context.

 

E.g. an ElementType's / FamilySymbol's GetTypeId method but also a DesingOption's DesignOption property, a Phase's CreatedPhaseId property, and so on.

The ID of a Level is not represented by its LevelId but by its Id, analogously.

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





Message 11 of 16

0001des
Enthusiast
Enthusiast

I'm still not exactly sure how to make the NewFamilyInstance type without making a new FamilyInstance.  I don't have an existing family type to take the ID from.  How can I modify the FamilyInstance type to a new type with just the type string?  Like if I wanted to change a wall of type "Interior - Partition" to "Wall - Timber Clad."  

 

I found the code to load the family symbol...

 

FamilySymbol SSS;
doc.LoadFamilySymbol("", "Interior - Partition", out SSS);

However, I don't want to load some file when I know the type is already loaded in the file.   Is there a method to return the list of the loaded FamilySymbol types and the loaded Family types?  

 

 

 

0 Likes
Message 12 of 16

ollikat
Collaborator
Collaborator
public static ElementType FindWallType(Document doc, string typeName)
{
  FilteredElementCollector elemCollector = new FilteredElementCollector(doc);
  elemCollector.WhereElementIsElementType().WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Walls));

  var wte = elemCollector.FirstOrDefault((e) =>
  {
    if (string.Equals(e.Name, typeName))
      return true;

    return false;
  });

  return wte as ElementType;
}

Above is code getting the wall ElementType (i.e. family symbol) from the project by name. Maybe this helps you forward...

0 Likes
Message 13 of 16

0001des
Enthusiast
Enthusiast

Thanks for the code, but that won't help me. I need something much more generic. I need to be able to find any family from any builtincategory potentially.  So limiting it to OST_Walls means that all other BIC's will be ignored.  

 

Also, this only seems to work on walls that are currently in the model.  I'm looking for a list of the families that are loaded in the project, not just the wall types that reside in the 3D model.  

 

I'm a little surprised there isn't a method for retrieving all families loaded in the model in the API's.  There must be a way to extract this without using a Revit Collection filter.

0 Likes
Message 14 of 16

ollikat
Collaborator
Collaborator

Well, it didn't supposed to be more than an example. So it should be rather easy job you to modify it so that it's for generic purposes.

 

And it is NOT true that the code would only get stuff from 3D or only those that have an instance. It really searches from all types that are loaded into the project.


Seems to me that you have some kind of misunderstanding with the API. FilteredElementCollector is THE mechanism to get all possible stuff loaded in the project and filter classes are for...well...for filtering :-).


0 Likes
Message 15 of 16

0001des
Enthusiast
Enthusiast

If I knew the answer to this, I wouldn't be asking for help.

 

All the examples I've read on net show how to use the filter on a specific BuiltInCategory.  How can I run the filter to return all families from all BuiltInCategories?

 

Also, I made a loop using your wall filter example, and it returned most of the loaded types, except one.  I'm still not sure why.  Regardless, I'm more interested in the previous question. Thanks for you help.

0 Likes
Message 16 of 16

ollikat
Collaborator
Collaborator
// Initialize collector to get ALL family objects from ALL categories
var elemCollector = new FilteredElementCollector(doc); elemCollector = elemCollector.OfClass(typeof(Family));
// Initialize collector to get ALL family symbol (types) objects from ALL categories
var elemCollector = new FilteredElementCollector(doc); elemCollector = elemCollector.OfClass(typeof(FamilySymbol));

 And what comes to problem that you didn't get one certain family, just a wild guess, could it be related whether or not corresponding family symbol is "active. Please, see the "IsActive" Property in FamilySymbol.

0 Likes