Starting in December, we will archive content from the community that is 10 years and older. This FAQ provides more information.
Hello,
Is there a way to go through every component/element of the model extracting the information of each of the elements without having to do it by families, like the SDK of Material Quantities does?
Example:
m_elementsToProcess = collector.OfCategory(BuiltInCategory.OST_Floors).WhereElementIsNotElementType().ToElements();
Do something similar to this but without having to go through all the BuiltInCategories.
Regards,
JMGP
Yes, of course!
Take a look at The Building Coder topic group on element filtering and the samples, especially in the module CmdCollectorPerformance.cs:
Together, there must be a hundred examples in there, and almost all of them fulfil your requirements.
Cheers,
Jeremy
Hello @jeremytammik ,
Thank you for your reply, those posts to your blog have really interesting information, yet, after going over lots of them, they all had one thing in common: That is that we need to have the families specified before we do the search and/or filtering.
So I would like to ask you if there is a way of doing so without knowing the families that we have to search for. For example, what if I would like to retrieve all the objects that contain wood as a material, regardless of the family that they belong to.
Regards,
JMGP
You can still use filtered element collector for collecting all families in the active Revit Document.
Here is the sample code:
List<FamilySymbol> woodFamilies = new List<FamilySymbol>(); List<FamilySymbol> families = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).Cast<FamilySymbol>().ToList(); foreach (var family in families) { if (family.StructuralMaterialType == StructuralMaterialType.Wood) { woodFamilies.Add(family); } }
I hope this helps,
Recep.
Thank you @recepagah12 !
All of this results are using the Sample Architecture Project Model from Revit.
I've been playing around with the idea you proposed and I get the following:
If I use FamilySymbol the StructuralMaterialType turns out to be undefined.
After this and some reading, I changed FamilySymbol for FamilyInstance and now the StructuralMaterialType property different values in the different families. The families I get that have Concrete as a StructuralMaterialType have names like:
type Other
name wardrobe
type Concrete
name 600 x 600 x 900mm
type Steel
name 600mm Diameter
What is being printed as "name" is the family name of each element in families when instead we should get things like "Wall", "Roof" etc. Do you have any idea of why or how to get to that output?
Regards,
JMGP
You said "family". If you want to access to wall and roof, they have their own class, like Wall, Roof, Floor etc.
Here is the sample code.
I used the material name as "Wood" but you can change also If you know MaterialId which you want to take you can use it, If you don't know its Id you can snoop with Revit LookUp.
// This is the wood elements name list string woodElementNames = ""; // Collect walls and floors in the document List<Wall> walls = new FilteredElementCollector(doc).OfClass(typeof(Wall)).Cast<Wall>().ToList(); List<Floor> floors = new FilteredElementCollector(doc).OfClass(typeof(Floor)).Cast<Floor>().ToList(); List<FootPrintRoof> footPrintRoofs = new FilteredElementCollector(doc).OfClass(typeof(FootPrintRoof)).Cast<FootPrintRoof>().ToList(); List<ExtrusionRoof> extrusionRoofs = new FilteredElementCollector(doc).OfClass(typeof(ExtrusionRoof)).Cast<ExtrusionRoof>().ToList(); if (walls != null) { foreach (var wall in walls) { var wallLayers = wall.WallType.GetCompoundStructure().GetLayers(); foreach (var layer in wallLayers) { var material = doc.GetElement(layer.MaterialId) as Material; // I typed material name wood, If yours are different type it. if (layer.Function == MaterialFunctionAssignment.Structure && material.Name == "Wood") { woodElementNames += (wall.WallType.FamilyName +wall.WallType.Name + "\n"); } } } } if (floors != null) { foreach (var floor in floors) { // If you don't want to count paint material set to false var materialIds = floor.GetMaterialIds(false); foreach (var id in materialIds) { var material = doc.GetElement(id) as Material; if (material.Name == "Wood") { woodElementNames += (floor.FloorType.FamilyName + floor.FloorType.Name + "\n"); } } } } if (footPrintRoofs != null) { foreach (var roof in footPrintRoofs) { var materialIds = roof.GetMaterialIds(false); foreach (var id in materialIds) { var material = doc.GetElement(id) as Material; if (material.Name == "Wood") { woodElementNames += (roof.Name + "\n"); } } } } if (extrusionRoofs != null) { foreach (var roof in extrusionRoofs) { var materialIds = roof.GetMaterialIds(false); foreach (var id in materialIds) { var material = doc.GetElement(id) as Material; if (material.Name == "Wood") { woodElementNames += (roof.Name + "\n"); } } } } TaskDialog.Show("Wood Elements", woodElementNames);
I know the code is not looking clear, I pasted it from visual studio and everythin is a mess now 🙂
I tested and worked fine for me, I hope this works for you too.
Recep.
Can't find what you're looking for? Ask the community or share your knowledge.