How to find FamilyInstances in linked Rooms?

How to find FamilyInstances in linked Rooms?

dantartaglia8696
Advocate Advocate
1,309 Views
5 Replies
Message 1 of 6

How to find FamilyInstances in linked Rooms?

dantartaglia8696
Advocate
Advocate

Hi,

 

I have lightingFixtures in my active model that are positioned in linked rooms/ceilings. They are faced based. I cannot seem to be able to determine which rooms these lights exist in. The below code does not return any FamilyInstances in my linked rooms. The bounding box is the correct height and I tried other categories of FamilyInstances (sinks, desks, ect) without success (I commented out the line: .OfCategory(BuiltInCategory.OST_LightingFixtures)). Please let me know if you have any ideas.

 

P.S. the room I'm passing is from the link and the Document is the active file.

 

Thanks,

Dan

 

private List<FamilyInstance> LightingFixtsFromRoom(Room oRoom, Document oDocument)

{

List<FamilyInstance> oFamilyInstances = new List<FamilyInstance>();

try

{

BoundingBoxXYZ oBoundingBoxXYZ = oRoom.get_BoundingBox(null);

Outline outline = new Outline(oBoundingBoxXYZ.Min, oBoundingBoxXYZ.Max);

BoundingBoxIntersectsFilter filter

= new BoundingBoxIntersectsFilter(outline);

FilteredElementCollector collector = new FilteredElementCollector(oDocument)

.WhereElementIsNotElementType()

.WhereElementIsViewIndependent()

.OfCategory(BuiltInCategory.OST_LightingFixtures)

.OfClass(typeof(FamilyInstance))

.WherePasses(filter);

foreach (FamilyInstance oFamilyInstance in collector)

{

// Got my light fixtures

}

return oFamilyInstances;

}

catch

{

return oFamilyInstances = new List<FamilyInstance>();

}

}

 

0 Likes
1,310 Views
5 Replies
Replies (5)
Message 2 of 6

Mustafa.Salaheldin
Collaborator
Collaborator

Instead of that you can get the reference point of the fixtures then using the Room.IsPointInRoom Method you can check if it is in the room or not.


¯\_(ツ)_/¯
Let it work like a charm.

Mustafa Salaheldin


EESignature




Digital Integration Manager, DuPod

Facebook | Twitter | LinkedIn

0 Likes
Message 3 of 6

dantartaglia8696
Advocate
Advocate

Hi,

 

Thanks for the response. Jim Jia from Autodesk Support contacted me with the below answer as well. I have not had a chance to to test either but I'm sure they will work:

 

When building BoundingBoxFilter, you should apply the transformation of Rvt Linked instance: The Room.Get_BoundingBox will return BoundingBox in source rvt rather than actual BoundingBox in active document.

 

        public void GetLights(Autodesk.Revit.ApplicationServices.Application app, Document doc)
        {
            string xpath = null;
            //
            // this is sample code, it supposes the project has one link rvt only..
            // get external file reference so that we can open the link document to get room and its boundingbox
            Autodesk.Revit.DB.Transform trf = null;
            ICollection<ElementId> ids = ExternalFileUtils.GetAllExternalFileReferences(doc);
            foreach (ElementId id in ids)
            {
                Element teme = doc.GetElement(id);
                if (teme.IsExternalFileReference())
                {
                    ExternalFileReference fs = teme.GetExternalFileReference();
                    if (fs.ExternalFileReferenceType == ExternalFileReferenceType.RevitLink)
                    {
                        xpath = ModelPathUtils.ConvertModelPathToUserVisiblePath(fs.GetAbsolutePath());
                        RevitLinkType instype = teme as RevitLinkType;
                        FilteredElementCollector temcc = new FilteredElementCollector(doc);
                        temcc.OfClass(typeof(RevitLinkInstance));
                        foreach (var rli in temcc.ToElements())
                        {
                            if (rli.GetTypeId() == id)
                            {
                                // get transform of linked instance
                                RevitLinkInstance ins = rli as RevitLinkInstance;
                                trf = ins.GetTransform();
                            }
                            break;
                        }
                        if (null != trf)
                            break;
                    }
                }
            }
            //
            // find room in linked Rvt
            RoomFilter rmfilter = new RoomFilter();
            Autodesk.Revit.DB.Document xdoc = app.OpenDocumentFile(xpath);
            FilteredElementCollector temc = new FilteredElementCollector(xdoc);
            temc.WherePasses(rmfilter).WhereElementIsNotElementType();
            foreach (Room rm in temc)
            {
                BoundingBoxXYZ box = rm.get_BoundingBox(null);
                if (box != null)
                {
                    // !!!Important!!! apply the link instance transform to the boundingbox
                    Outline outline = new Outline(trf.OfPoint(box.Min), trf.OfPoint(box.Max));
                    BoundingBoxIntersectsFilter filter = new BoundingBoxIntersectsFilter(outline);
                    FilteredElementCollector mtemc = new FilteredElementCollector(doc);
                    mtemc.WhereElementIsNotElementType().WhereElementIsViewIndependent()
                        .OfCategory(BuiltInCategory.OST_LightingFixtures)
                        .OfClass(typeof(FamilyInstance)).WherePasses(filter);
                    if (mtemc.Count() != 0)
                        MessageBox.Show(mtemc.Count().ToString());
                }
            }
        }

0 Likes
Message 4 of 6

dantartaglia8696
Advocate
Advocate

Hi,

 

I just got back to this issue and realized Jim's response wants me to open each link in memory to process. There can be numorous Revit links and feel this will take took long. I'm currently using a combination of Mustafa's and Jim's suggestions as well as my approach. (Mustafa mentioned: Room.IsPointInRoom and Jim's room filtering). This is what I have so far, it works in my test models but need to verify on an actual project RVT (you know how that is). Please let me know if you see a more streamlined approach:

 

private void ProccessStart(UIApplication m_app)

{

try

{

// Make sure no other RVTs are open in Revit

if (MultipleRVTsOpen(m_app) == true)

{

TaskDialog.Show("Process Stopped", "Please only have one file open when running this tool");

return;

}

// Iterate through each document

foreach (Document oDocument in m_app.Application.Documents)

{

// Only process links

if (oDocument.IsLinked)

{

// Create a room collection from rooms in the current link

RoomFilter oRoomFilter = new RoomFilter();

FilteredElementCollector oFilteredElemCol = new FilteredElementCollector(oDocument);

oFilteredElemCol.WherePasses(oRoomFilter).WhereElementIsNotElementType();

// Iterate through each room

foreach (Room oRoom in oFilteredElemCol)

{

// Only process placed rooms

if (RoomIsPlaced(oRoom) == false)

continue;

// Get all LightingFixtures in the current room

List<FamilyInstance> oFamilyInstances =

LightingFixtsFromRoom(oRoom, m_app.ActiveUIDocument.Document);

}

}

}

}

catch (Exception ex)

{

TaskDialog.Show("Error", ex.Message);

}

}

private bool MultipleRVTsOpen(UIApplication m_app)

{

int intCntr = 0;

try

{

// Iterate through each document

foreach (Document oDocument in m_app.Application.Documents)

{

// Skip linked RVTs and families

if (!oDocument.IsLinked && !oDocument.IsFamilyDocument)

{

intCntr++;

if (intCntr > 1)

return true;

}

}

return false;

}

catch

{

return true;

}

}

private bool RoomIsPlaced(Room oRoom)

{

try

{

// Make sure the room does not contain a location or area value

if (null != oRoom.Location && Math.Round(oRoom.Area) != 0.0)

return true;

else

return false;

}

catch

{

return false;

}

}

private List<FamilyInstance> LightingFixtsFromRoom(Room oRoom, Document oDocument)

{

List<FamilyInstance> oFamilyInstances = new List<FamilyInstance>();

try

{

// Create a LightingFixture/FamilyIntance collection that exist in the active document

FilteredElementCollector oFilteredElemCol = new FilteredElementCollector(oDocument)

.WhereElementIsNotElementType()

.WhereElementIsViewIndependent()

.OfCategory(BuiltInCategory.OST_LightingFixtures)

.OfClass(typeof(FamilyInstance));

// Iterate through each instance

foreach (FamilyInstance oFamilyInstance in oFilteredElemCol)

{

try

{

// Get the boudning box of the instance

BoundingBoxXYZ oBoundingBoxXYZ = oFamilyInstance.get_BoundingBox(null);

if (oBoundingBoxXYZ == null)

continue;

// Get the center point of the instance (except Z, want to make sure recessed lights are found)

XYZ oCenterPoint = new XYZ((oBoundingBoxXYZ.Min.X + oBoundingBoxXYZ.Max.X) / 2,

(oBoundingBoxXYZ.Min.Y + oBoundingBoxXYZ.Max.Y) / 2,

(oBoundingBoxXYZ.Min.Z));

// Determine if the point exists within the bounding box/room

if (oRoom.IsPointInRoom(oCenterPoint) == true)

TaskDialog.Show("Got lights", "Light family name: " +

oFamilyInstance.Symbol.FamilyName + ", Room name: " + oRoom.Name);

}

catch

{

// continue processing

}

}

return oFamilyInstances;

}

catch

{

return oFamilyInstances = new List<FamilyInstance>();

}

}

 

Message 5 of 6

Mustafa.Salaheldin
Collaborator
Collaborator

It seems like your code goes fine. I've not tested it either but it seems right.

Good luck


¯\_(ツ)_/¯
Let it work like a charm.

Mustafa Salaheldin


EESignature




Digital Integration Manager, DuPod

Facebook | Twitter | LinkedIn

Message 6 of 6

JimJia
Alumni
Alumni
Dear Daniel Tartaglia,

I didn't find problems in your code shared though I didn't tested it either. Please let us know if you still have problem on this case.

Jim Jia
Autodesk Forge Evangelist
https://forge.autodesk.com
Developer Technical Services
Autodesk Developer Network
Email: Jim.Jia@autodesk.com
0 Likes