//sometimes Revit internal rooms cannot capture flipped doors correctly.
        private DoorProperties AssignToFromRoom(FamilyInstance door)
        {
            DoorProperties dp = new DoorProperties(door);

            try
            {
                if (null != dp.FromPoint && null != dp.ToPoint)
                {
                    Room roomA = door.ToRoom;
                    Room roomB = door.FromRoom;

                    if (null != roomA)
                    {
                        if (roomA.IsPointInRoom(dp.ToPoint))
                        {
                            dp.ToRoom = roomA;
                        }
                        else if (roomA.IsPointInRoom(dp.FromPoint))
                        {
                            dp.FromRoom = roomA;
                        }
                    }
                    if (null != roomB)
                    {
                        if (roomB.IsPointInRoom(dp.ToPoint))
                        {
                            dp.ToRoom = roomB;
                        }
                        else if (roomB.IsPointInRoom(dp.FromPoint))
                        {
                            dp.FromRoom = roomB;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to assign To and From values in door properties.\n" + ex.Message, "Assign To and From Room", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            return(dp);
        }
        private bool CopyRoomData(List <FamilyInstance> doorInstances)
        {
            bool result = true;

            try
            {
                StringBuilder strBuilder = new StringBuilder();

                using (TransactionGroup tg = new TransactionGroup(m_doc, "Copy Room Data"))
                {
                    tg.Start();
                    try
                    {
                        foreach (FamilyInstance door in doorInstances)
                        {
                            using (Transaction trans = new Transaction(m_doc, "Copy Room"))
                            {
                                trans.Start();
                                try
                                {
                                    DoorProperties dp = AssignToFromRoom(door);
                                    if (null != dp.ToRoom)
                                    {
                                        string    roomNumber = GetRoomNumber(dp.ToRoom);
                                        string    roomName   = GetRoomName(dp.ToRoom);
                                        Parameter toParam    = door.LookupParameter(toRoomNumber);
                                        if (null != toParam)
                                        {
                                            toParam.Set(roomNumber);
                                        }
                                        toParam = door.LookupParameter(toRoomName);
                                        if (null != toParam)
                                        {
                                            toParam.Set(roomName);
                                        }
                                    }
                                    if (null != dp.FromRoom)
                                    {
                                        string    roomNumber = GetRoomNumber(dp.FromRoom);
                                        string    roomName   = GetRoomName(dp.FromRoom);
                                        Parameter fromParam  = door.LookupParameter(fromRoomNumber);
                                        if (null != fromParam)
                                        {
                                            fromParam.Set(roomNumber);
                                        }
                                        fromParam = door.LookupParameter(fromRoomName);
                                        if (null != fromParam)
                                        {
                                            fromParam.Set(roomName);
                                        }
                                    }
                                    trans.Commit();
                                }
                                catch (Exception ex)
                                {
                                    result = false;
                                    strBuilder.AppendLine(door.Id.IntegerValue + "\t" + door.Name + ": " + ex.Message);
                                    trans.RollBack();
                                }
                            }
                        }
                        tg.Assimilate();
                    }
                    catch (Exception ex)
                    {
                        string message = ex.Message;
                        tg.RollBack();
                    }
                }

                if (strBuilder.Length > 0)
                {
                    MessageBox.Show("The following doors have been skipped due to some issues.\n\n" + strBuilder.ToString(), "Skipped Door Elements", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to copy system room data to shared parameters.\n" + ex.Message, "Copy Room Data", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                result = false;
            }
            return(result);
        }
        private bool CopyLinkedRoomData(List <FamilyInstance> doorInstances)
        {
            bool result = true;

            try
            {
                Dictionary <int, LinkedInstanceProperties> linkedInstanceDictionary = CollectLinkedInstances();

                StringBuilder strBuilder = new StringBuilder();
                using (TransactionGroup tg = new TransactionGroup(m_doc, "Set Door Parameters"))
                {
                    tg.Start();
                    try
                    {
                        foreach (FamilyInstance door in doorInstances)
                        {
                            using (Transaction trans = new Transaction(m_doc, "Set Parameter"))
                            {
                                trans.Start();
                                try
                                {
                                    DoorProperties dp = new DoorProperties(door);
                                    if (null != dp.FromPoint && null != dp.ToPoint)
                                    {
                                        GeometryElement geomElem  = door.get_Geometry(new Options());
                                        XYZ             direction = door.FacingOrientation;

                                        Dictionary <int, LinkedRoomProperties> linkedRooms = new Dictionary <int, LinkedRoomProperties>();
                                        foreach (LinkedInstanceProperties lip in linkedInstanceDictionary.Values)
                                        {
                                            GeometryElement trnasformedElem = geomElem.GetTransformed(lip.TransformValue.Inverse);
                                            BoundingBoxXYZ  bb = trnasformedElem.GetBoundingBox();
                                            //extended bounding box

                                            XYZ midPt  = 0.5 * (bb.Min + bb.Max);
                                            XYZ extMin = bb.Min + (bb.Min - midPt).Normalize();
                                            XYZ extMax = bb.Max + (bb.Max - midPt).Normalize();

                                            Outline outline = new Outline(extMin, extMax);

                                            BoundingBoxIntersectsFilter bbIntersectFilter = new BoundingBoxIntersectsFilter(outline);
                                            BoundingBoxIsInsideFilter   bbInsideFilter    = new BoundingBoxIsInsideFilter(outline);
                                            LogicalOrFilter             orFilter          = new LogicalOrFilter(bbIntersectFilter, bbInsideFilter);
                                            FilteredElementCollector    collector         = new FilteredElementCollector(lip.LinkedDocument);
                                            List <Room> roomList = collector.OfCategory(BuiltInCategory.OST_Rooms).WherePasses(orFilter).WhereElementIsNotElementType().ToElements().Cast <Room>().ToList();
                                            if (roomList.Count > 0)
                                            {
                                                foreach (Room room in roomList)
                                                {
                                                    LinkedRoomProperties lrp = new LinkedRoomProperties(room);
                                                    lrp.LinkedInstance = lip;
                                                    if (!linkedRooms.ContainsKey(lrp.RoomId))
                                                    {
                                                        linkedRooms.Add(lrp.RoomId, lrp);
                                                    }
                                                }
                                            }
                                        }

                                        LinkedRoomProperties fromRoom = null;
                                        LinkedRoomProperties toRoom   = null;

                                        if (linkedRooms.Count > 0)
                                        {
                                            foreach (LinkedRoomProperties lrp in linkedRooms.Values)
                                            {
                                                XYZ tFrom = lrp.LinkedInstance.TransformValue.Inverse.OfPoint(dp.FromPoint);
                                                XYZ tTo   = lrp.LinkedInstance.TransformValue.Inverse.OfPoint(dp.ToPoint);

                                                if (lrp.RoomObject.IsPointInRoom(tFrom))
                                                {
                                                    dp.FromRoom = lrp.RoomObject;
                                                    fromRoom    = lrp;
                                                }
                                                if (lrp.RoomObject.IsPointInRoom(tTo))
                                                {
                                                    dp.ToRoom = lrp.RoomObject;
                                                    toRoom    = lrp;
                                                }
                                            }
                                        }

                                        if (null != fromRoom)
                                        {
                                            Parameter fParam = door.LookupParameter(fromRoomNumber);
                                            if (null != fParam)
                                            {
                                                fParam.Set(fromRoom.RoomNumber);
                                            }
                                            fParam = door.LookupParameter(fromRoomName);
                                            if (null != fParam)
                                            {
                                                fParam.Set(fromRoom.RoomName);
                                            }
                                        }


                                        if (null != toRoom)
                                        {
                                            Parameter tParam = door.LookupParameter(toRoomNumber);
                                            if (null != tParam)
                                            {
                                                tParam.Set(toRoom.RoomNumber);
                                            }
                                            tParam = door.LookupParameter(toRoomName);
                                            if (null != tParam)
                                            {
                                                tParam.Set(toRoom.RoomName);
                                            }
                                        }

                                        if (!doorDictionary.ContainsKey(dp.DoorId))
                                        {
                                            doorDictionary.Add(dp.DoorId, dp);
                                        }
                                    }
                                    trans.Commit();
                                }
                                catch (Exception ex)
                                {
                                    trans.RollBack();
                                    string message = ex.Message;
                                    result = false;
                                    strBuilder.AppendLine(door.Id.IntegerValue + "\t" + door.Name + ": " + ex.Message);
                                }
                            }
                        }
                        tg.Assimilate();
                    }
                    catch (Exception ex)
                    {
                        tg.RollBack();
                        string message = ex.Message;
                    }

                    if (strBuilder.Length > 0)
                    {
                        MessageBox.Show("The following doors have been skipped due to some issues.\n\n" + strBuilder.ToString(), "Skipped Door Elements", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to collect door data.\n" + ex.Message, "Collect Door Data", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            return(result);
        }