static internal void selectParking(renumberParkingUI UI) { Document doc = uidoc.Document; Selection sel = uidoc.Selection; try { ONBOXApplication.currentFirstParking = doc.GetElement(sel.PickObject(ObjectType.Element, new ParkingSelectionFilter(), "Selecione a primeira vaga de garagem")); ONBOXApplication.parkingRenumType = ONBOXApplication.RenumberType.FirstParking; } catch (Exception) { ONBOXApplication.currentFirstParking = null; ONBOXApplication.parkingRenumType = ONBOXApplication.RenumberType.Ascending; } finally { UI.comboFirstAdjust(); } }
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); }