Beispiel #1
0
        private void DoTheRenumberingBeams()
        {
            Document  doc = uidoc.Document;
            Selection sel = uidoc.Selection;

            IList <Level> allLevel = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).OfClass(typeof(Level))
                                     .WhereElementIsNotElementType().Cast <Level>().OrderBy(l => l.Elevation).ToList();

            XYZ pointOfInterest = new XYZ(-9999, 9999, -9999);

            IList <Element> HorizontalBeams = allBeams.Where(b => verifyBeamOrientation(b) == BeamOrientation.Horizontal).OrderBy(e => GetNearestEndPoint(e, pointOfInterest).DistanceTo(pointOfInterest)).ToList();
            IList <Element> VerticalBeams   = allBeams.Where(b => verifyBeamOrientation(b) == BeamOrientation.Vertical).OrderBy(e => GetNearestEndPoint(e, pointOfInterest).DistanceTo(pointOfInterest)).ToList();

            int    counter       = 0;
            string prefix        = "V";
            int    decimalPlaces = 2;

            try
            {
                using (Transaction t = new Transaction(doc, Properties.Messages.RenumberBeams_RenumberBeams))
                {
                    t.Start();
                    foreach (Level currentLevel in allLevel)
                    {
                        LevelInfo lvlInfo = ONBOXApplication.storedBeamLevelInfo.Where(l => l.levelId == currentLevel.Id.IntegerValue).First() as LevelInfo;

                        //checks if the current level will be numbered
                        if (lvlInfo.willBeNumbered == false)
                        {
                            continue;
                        }

                        prefix        = lvlInfo.levelPrefix;
                        decimalPlaces = ONBOXApplication.BeamsDecimalPlaces;

                        IList <Element> HorizontalBeamsInLevel = HorizontalBeams.Where(b => b.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsElementId() == currentLevel.Id).ToList();
                        IList <Element> VerticalBeamsInLevel   = VerticalBeams.Where(b => b.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsElementId() == currentLevel.Id).ToList();
                        IList <Element> allBeamsInLevel        = allBeams.Where(b => b.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsElementId() == currentLevel.Id).ToList();

                        //Checks if the horizontal or vertical comes first, or allbeams
                        if (ONBOXApplication.storedBeamRenumOrder == BeamRenumberOrder.Horizontal)
                        {
                            RenumberListOfBeams(HorizontalBeamsInLevel, ref counter, prefix, decimalPlaces);
                            RenumberListOfBeams(VerticalBeamsInLevel, ref counter, prefix, decimalPlaces);
                        }
                        else if (ONBOXApplication.storedBeamRenumOrder == BeamRenumberOrder.Vertical)
                        {
                            RenumberListOfBeams(VerticalBeamsInLevel, ref counter, prefix, decimalPlaces);
                            RenumberListOfBeams(HorizontalBeamsInLevel, ref counter, prefix, decimalPlaces);
                        }
                        else
                        {
                            RenumberListOfBeams(allBeamsInLevel, ref counter, prefix, decimalPlaces);
                        }

                        //Reset counter for the next level if the user wants to
                        if (ONBOXApplication.isNumBeamLevel == true)
                        {
                            counter = 0;
                        }
                    }
                    t.Commit();
                }
            }
            catch (Exception excep)
            {
                ExceptionManager eManager = new ExceptionManager(excep);
            }
        }
Beispiel #2
0
        private void PopulateGridLevel(bool isFirstTime = false)
        {
            #region Populate DataGrid
            if (gridLevel != null)
            {
                if (gridLevel.HasItems)
                {
                    gridLevel.Columns.Clear();
                }

                if (isFirstTime)
                {
                    LevelInfoList = ColumnsFromDwg.GetAllLevelInfo();

                    if (ONBOXApplication.StoredColumnsDwgLevels.Count == 0)
                    {
                        ONBOXApplication.StoredColumnsDwgLevels = ColumnsFromDwg.GetAllLevelInfo();
                        ONBOXApplication.StoredColumnsDwgLevels.Last().willBeNumbered = false;
                    }

                    foreach (LevelInfo currentStoredLevelInfo in ONBOXApplication.StoredColumnsDwgLevels)
                    {
                        foreach (LevelInfo currentLevelInfo in LevelInfoList)
                        {
                            if (currentLevelInfo.levelId == currentStoredLevelInfo.levelId)
                            {
                                currentLevelInfo.willBeNumbered = currentStoredLevelInfo.willBeNumbered;
                            }
                        }
                        LevelInfoList.Last().willBeNumbered = false;
                    }
                }

                gridLevel.AutoGenerateColumns   = false;
                gridLevel.CanUserAddRows        = false;
                gridLevel.CanUserDeleteRows     = false;
                gridLevel.CanUserResizeRows     = false;
                gridLevel.CanUserReorderColumns = false;
                gridLevel.ItemsSource           = LevelInfoList.ToList();

                DataGridCheckBoxColumn dt0 = new DataGridCheckBoxColumn();
                dt0.Header      = Properties.WindowLanguage.ColumnsFromCAD_LevelUse;
                dt0.Binding     = new Binding("willBeNumbered");
                dt0.CanUserSort = false;
                dt0.Width       = 50;

                DataGridTextColumn dt1 = new DataGridTextColumn();
                dt1.Header      = Properties.WindowLanguage.ColumnsFromCAD_LevelName;
                dt1.Binding     = new Binding("levelName");
                dt1.CanUserSort = false;
                dt1.IsReadOnly  = true;
                dt1.Width       = 150;

                gridLevel.Columns.Add(dt1);
                gridLevel.Columns.Add(dt0);
            }
            #endregion

            #region Disable LastLevel

            gridLevel.IsSynchronizedWithCurrentItem = false;
            gridLevel.EnableColumnVirtualization    = false;
            gridLevel.EnableRowVirtualization       = false;

            int            lastNumber   = LevelInfoList.IndexOf(LevelInfoList.Last());
            LevelInfo      lastLvlInfo  = gridLevel.Items.GetItemAt(lastNumber) as LevelInfo;
            DataGridColumn targetColumn = gridLevel.Columns.ElementAt(1);

            //This process is to disable the last (higher) level from the gridLevels
            //We have to get down to the specific cell and get the content of the cell and then convert it to a checkbox since no other way worked as expected
            gridLevel.Focus();
            gridLevel.ScrollIntoView(lastLvlInfo);
            DataGridCellInfo cellInfo = new DataGridCellInfo(lastLvlInfo, targetColumn);
            gridLevel.CurrentCell = cellInfo;
            //gridLevel.BeginEdit();
            DataGridRow  row          = (DataGridRow)gridLevel.ItemContainerGenerator.ContainerFromIndex(gridLevel.Items.IndexOf(gridLevel.CurrentCell.Item));
            DataGridCell cel          = cellInfo.Column.GetCellContent(row).Parent as DataGridCell;
            CheckBox     lastCheckBox = cel.Content as CheckBox;
            lastCheckBox.IsEnabled = false;
            lastCheckBox.IsChecked = false;

            #endregion
        }
Beispiel #3
0
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            IList <Element> parkingElements = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Parking).WhereElementIsNotElementType().ToList();
            IList <Element> allLevels       = new FilteredElementCollector(doc).OfClass(typeof(Level)).ToList();

            Options op = new Options()
            {
                DetailLevel = ViewDetailLevel.Coarse, ComputeReferences = false, IncludeNonVisibleObjects = false
            };

            //Checks if theres parking slots instances placed in the project
            if (parkingElements.Count == 0)
            {
                message = Properties.Messages.RenumberParking_NoParking;
                return(Result.Failed);
            }

            //Calls the UI
            renumberParkingUI parkingUI = new renumberParkingUI();

            if (parkingUI.ShowDialog() == false)
            {
                return(Result.Cancelled);
            }

            try
            {
                //TODO Try to bring this to the UI instead (make a variable in the WPF form)
                #region Checks the ONBOXAppl to see what parkings will be numered

                IList <ElementId> typesThatWillBeNumbered = new List <ElementId>();

                foreach (ParkingTypesInfo currentParkingInfo in ONBOXApplication.storedParkingTypesInfo)
                {
                    if (currentParkingInfo.willBeNumbered == true)
                    {
                        typesThatWillBeNumbered.Add(new ElementId(currentParkingInfo.TypeId));
                    }
                }

                parkingElements = parkingElements.Where(e => typesThatWillBeNumbered.Contains(e.GetTypeId())).ToList();

                #endregion

                //The point of interest will be a far away point in the top left corner x negative and y positive if theres no preview park renumbered
                //Otherwise use the last park, so it will be sequenced
                XYZ pointOfInterest = new XYZ();
                if (ONBOXApplication.currentFirstParking == null)
                {
                    pointOfInterest = new XYZ(-99999, 99999, -99999);
                }
                else
                {
                    pointOfInterest = (ONBOXApplication.currentFirstParking.Location as LocationPoint).Point;
                }

                //Get All Parking Slots Instances
                parkingElements = parkingElements.Where(i => i is Element).OrderBy(e =>
                {
                    double locationX = (e.Location as LocationPoint).Point.DistanceTo(pointOfInterest);

                    return(locationX);
                }).ToList();

                int counter = 1;

                //TODO Again, try to remove these Global Variables
                if (ONBOXApplication.currentFirstParking == null) //since we removed the button that selects the first element this will be always true
                {
                    if (ONBOXApplication.parkingRenumType == ONBOXApplication.RenumberType.Ascending)
                    {
                        allLevels = allLevels.Where(i => i is Level).OrderBy(l => (l as Level).Elevation).ToList();
                    }
                    if (ONBOXApplication.parkingRenumType == ONBOXApplication.RenumberType.Descending)
                    {
                        allLevels = allLevels.Where(i => i is Level).OrderByDescending(l => (l as Level).Elevation).ToList();
                    }
                }
                #region FirstElement (will never run currently)
                else //currently it will never run this block of code because we remove the button in the renumberParking UI that set this condition
                {
                    double levelHeight           = (doc.GetElement(ONBOXApplication.currentFirstParking.LevelId) as Level).Elevation;
                    int    numberOfElementsUnder = 0;

                    allLevels = allLevels.Where(i => i is Level).OrderBy(l => ((l as Level).Elevation) - levelHeight).ToList();

                    foreach (Element currentLevel in allLevels)
                    {
                        foreach (Element currentParking in parkingElements)
                        {
                            if ((currentLevel.Id != ONBOXApplication.currentFirstParking.LevelId) && (ONBOXApplication.currentFirstParking.Id != currentParking.Id))
                            {
                                if ((doc.GetElement(currentParking.LevelId) as Level).Elevation - (doc.GetElement(ONBOXApplication.currentFirstParking.LevelId) as Level).Elevation < 0)
                                {
                                    numberOfElementsUnder++;
                                }
                            }
                        }
                    }
                    counter = counter - numberOfElementsUnder;
                }
                #endregion

                //Start the Renumbering process
                using (Transaction t = new Transaction(doc, Properties.Messages.RenumberParking_Transaction))
                {
                    t.Start();
                    //TODO Instead of looping trough the levels, try to loop trough the LevelInfo
                    foreach (Element eLevel in allLevels)
                    {
                        //The storedParkingLevelInfo is global variable and it got initialisead in the UI, calling the getAllLevels() method in this class
                        //TODO Again, move this to a local variable
                        LevelInfo lvlInfo = ONBOXApplication.storedParkingLevelInfo.Where(e => e.levelId == eLevel.Id.IntegerValue).First();

                        if (lvlInfo.willBeNumbered == false)
                        {
                            continue;
                        }

                        Element           prevElement = null;
                        IList <Element>   RemainingParkingsinLevel = new List <Element>();
                        IList <ElementId> UsedParkingsInLevel      = new List <ElementId>();
                        Element           firstElement             = null;
                        string            currentLevelPrefix       = "";

                        //Loop through all levell info and get the related prefix if there is one
                        //TODO use this in conjuntion with the storedParkingInfo so we only loop through the level info one time
                        foreach (LevelInfo currentLevelInfo in ONBOXApplication.storedParkingLevelInfo)
                        {
                            if (currentLevelInfo.levelId == eLevel.Id.IntegerValue)
                            {
                                currentLevelPrefix = currentLevelInfo.levelPrefix;
                            }
                        }

                        //Get All the parking Elements that belongs to this specific level
                        foreach (Element ePark in parkingElements)
                        {
                            if (ePark.LevelId == (eLevel as Level).Id)
                            {
                                RemainingParkingsinLevel.Add(ePark);
                            }
                        }

                        if (RemainingParkingsinLevel.Count == 0)
                        {
                            continue;
                        }

                        //We dont use foreach here because we will mess with the List inside of the block
                        //The other point is that we loop here based on the blocks (amount of parkings near each other)
                        //TODO Maybe find a diferent way to loop here, since 'While (true)' is a little dangerous
                        while (true) // continue the loop until there is no more parking slot to renumber
                        {
                            IList <Element> tempParkings = RemainingParkingsinLevel.ToList();
                            RemainingParkingsinLevel.Clear();

                            IList <Element> block = new List <Element>();

                            //Get All remaning parkings (the ones that havent been renamed yet)
                            //Here is another loop that probably could be optimized
                            //TODO Optimize this as well
                            foreach (Element tempPark in tempParkings)
                            {
                                if (!UsedParkingsInLevel.Contains(tempPark.Id))
                                {
                                    RemainingParkingsinLevel.Add(tempPark);
                                }
                            }

                            if (RemainingParkingsinLevel.Count == 0)
                            {
                                break;
                            }

                            //The next park to be renumbered will be the first one next to the point of interest
                            //See the pointOfInterest definition to know more
                            RemainingParkingsinLevel = RemainingParkingsinLevel.Where(e => e is Element).OrderBy(e =>
                            {
                                double location = (e.Location as LocationPoint).Point.DistanceTo(pointOfInterest);
                                return(location);
                            }).ToList();

                            foreach (Element ePark in RemainingParkingsinLevel)
                            {
                                //In the case that this is the first element to be renumbered
                                if (prevElement == null)
                                {
                                    if (counter == 0)
                                    {
                                        counter++;
                                    }

                                    //Again, thats a Global Variable
                                    //TODO Create a local Variable for this one as well
                                    string typePrefix = ONBOXApplication.storedParkingTypesInfo.Where(e => e.TypeId == ePark.GetTypeId().IntegerValue).First().TypePrefix;

                                    ePark.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(currentLevelPrefix + typePrefix + counter.ToString());
                                    counter++;
                                    UsedParkingsInLevel.Add(ePark.Id);
                                    prevElement  = ePark;
                                    firstElement = ePark;
                                }
                                else
                                {
                                    foreach (Element currentPark in RemainingParkingsinLevel)
                                    {
                                        double distance = (currentPark.Location as LocationPoint).Point.DistanceTo((prevElement.Location as LocationPoint).Point);
                                        distance = Utils.ConvertM.feetToM(distance);

                                        //TODO Gobal Variable to local
                                        ParkingTypesInfo currentTypeInfo = ONBOXApplication.storedParkingTypesInfo.Where(e => e.TypeId == currentPark.GetTypeId().IntegerValue).First();

                                        //The tolerance to include this parking as a part of the current block will be this
                                        double tolerance = currentTypeInfo.TypeWidth + 0.1;

                                        //Checks if the current parking is near the prev parking and if it wasnt already renumbered
                                        if ((distance < tolerance) && (!UsedParkingsInLevel.Contains(currentPark.Id)))
                                        {
                                            //Now we have to check if the park has the same orientation that the prevpark
                                            FamilyInstance currentParkInstance   = currentPark as FamilyInstance;
                                            XYZ            currenParkOrientation = currentParkInstance.FacingOrientation;
                                            FamilyInstance prevParkInstance      = prevElement as FamilyInstance;
                                            XYZ            prevParkOrientation   = prevParkInstance.FacingOrientation;

                                            if (currenParkOrientation.IsAlmostEqualTo(prevParkOrientation, 0.1))
                                            {
                                                block.Add(currentPark);
                                                if (counter == 0)
                                                {
                                                    counter++;
                                                }
                                                currentPark.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(currentLevelPrefix + currentTypeInfo.TypePrefix + counter.ToString());
                                                UsedParkingsInLevel.Add(currentPark.Id);
                                                counter++;
                                                prevElement = currentPark;
                                            }
                                        }
                                    }

                                    IList <Element> blockToRenumber = new List <Element>();

                                    foreach (Element currentParkinLevel in RemainingParkingsinLevel)
                                    {
                                        double distance = (currentParkinLevel.Location as LocationPoint).Point.DistanceTo((prevElement.Location as LocationPoint).Point);
                                        distance = Utils.ConvertM.feetToM(distance);

                                        ParkingTypesInfo currentTypeInfo = ONBOXApplication.storedParkingTypesInfo.Where(e => e.TypeId == currentParkinLevel.GetTypeId().IntegerValue).First();
                                        double           tolerance       = currentTypeInfo.TypeWidth + 0.1;

                                        if ((distance < tolerance) && (!UsedParkingsInLevel.Contains(currentParkinLevel.Id)))
                                        {
                                            FamilyInstance currentParkInstance   = currentParkinLevel as FamilyInstance;
                                            XYZ            currenParkOrientation = currentParkInstance.FacingOrientation;
                                            FamilyInstance prevParkInstance      = prevElement as FamilyInstance;
                                            XYZ            prevParkOrientation   = prevParkInstance.FacingOrientation;

                                            if (currenParkOrientation.IsAlmostEqualTo(prevParkOrientation, 0.1))
                                            {
                                                blockToRenumber.Add(currentParkinLevel);
                                                UsedParkingsInLevel.Add(currentParkinLevel.Id);
                                                prevElement = currentParkinLevel;
                                            }
                                        }
                                    }

                                    foreach (Element currentParking in blockToRenumber)
                                    {
                                        if (counter == 0)
                                        {
                                            counter++;
                                        }
                                        ParkingTypesInfo currentTypeInfo = ONBOXApplication.storedParkingTypesInfo.Where(e => e.TypeId == currentParking.GetTypeId().IntegerValue).First();
                                        currentParking.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(currentLevelPrefix + currentTypeInfo.TypePrefix + counter.ToString());
                                        counter++;
                                        UsedParkingsInLevel.Add(currentParking.Id);
                                    }

                                    if (blockToRenumber.Count == 0)
                                    {
                                        tempParkings.Clear();
                                        tempParkings = RemainingParkingsinLevel.ToList();
                                        IList <Element> remain = new List <Element>();

                                        foreach (Element currentParking in tempParkings)
                                        {
                                            if (!UsedParkingsInLevel.Contains(currentParking.Id))
                                            {
                                                remain.Add(currentParking);
                                            }
                                        }

                                        if (remain.Count == 0)
                                        {
                                            break;
                                        }

                                        remain = remain.Where(p => p is Element).OrderBy(e =>
                                        {
                                            double locationX = getMidPoint(e, op).DistanceTo(pointOfInterest);
                                            return(locationX);
                                        }).ToList();

                                        prevElement = remain.First();
                                    }
                                }
                            }
                        }
                        if (ONBOXApplication.isNumIndenLevel == true)
                        {
                            counter = 1;
                        }
                    }
                    t.Commit();
                }
            }
            catch (Exception excep)
            {
                ExceptionManager eManager = new ExceptionManager(excep);
                return(Result.Cancelled);
            }

            return(Result.Succeeded);
        }