Пример #1
0
        private static Result placeTemporaryShoring(UIDocument uiDoc, BuildingLoadModel buildingLoadModel, List <ILoadModel> loadModels, string reshoringFamilyPathName, string reshoringFamilySymbol)
        {
            //Setup
            Document _doc = uiDoc.Document;

            //ToDo: it would be valuable to let users pick which Family & Type they want to use - so they can rapidly understand differences in layout for different reshores
            Dictionary <string, FamilyDefinition> _familyMappings = new List <string> {
                @"C:\ProgramData\Autodesk\Revit\Addins\2021\ApatosReshoring\Reshoring Poles 6x6.rfa",
                @"C:\ProgramData\Autodesk\Revit\Addins\2021\ApatosReshoring\Reshoring Poles Ellis 4x4.rfa",
                @"C:\ProgramData\Autodesk\Revit\Addins\2021\ApatosReshoring\Reshoring Poles Titan-HV.rfa",
                @"C:\ProgramData\Autodesk\Revit\Addins\2021\ApatosReshoring\Reshoring Poles Titan-XL.rfa",
            }.ToDictionary(p => Path.GetFileNameWithoutExtension(p),
                           p => FamilyHelpers.GetOrLoadFamilyDefinition(_doc, p));

            string       _familyName           = Path.GetFileNameWithoutExtension(reshoringFamilyPathName);
            FamilySymbol _temporaryShoreSymbol = null;

            if (_familyMappings.ContainsKey(_familyName))
            {
                Family _family = _familyMappings[_familyName]?.Family;
                foreach (ElementId _symbolID in _family.GetFamilySymbolIds())
                {
                    FamilySymbol _familySymbol = _doc.GetElement(_symbolID) as FamilySymbol;
                    if (_familySymbol == null)
                    {
                        continue;
                    }

                    if (_familySymbol.Name != reshoringFamilySymbol)
                    {
                        continue;
                    }

                    _temporaryShoreSymbol = _familySymbol;
                    if (_temporaryShoreSymbol != null)
                    {
                        break;
                    }
                }
            }

            if (_temporaryShoreSymbol == null)
            {
                return(Result.Failed);
            }
            if (_temporaryShoreSymbol.IsActive == false)
            {
                _temporaryShoreSymbol.Activate();
            }

            var _levels = Getters.GetLevels(uiDoc.Document).OrderByDescending(p => p.Elevation).ToList();
            var _floors = Getters.GetFloors(_doc).OrderBy(p => p.get_BoundingBox(null)?.Max.Z).ToList();

            Level _topLevel = _levels.FirstOrDefault();

            //Add Level Loads
            addLevelLoadModels(buildingLoadModel, _levels, _floors, _topLevel, loadModels);
            buildingLoadModel.ReadLoads();

            //Place Temporary Shores
            Dictionary <double, double> _clearShoreHeightCapacityMappings = getClearShoreHeightCapacityMappings(buildingLoadModel, _topLevel, _temporaryShoreSymbol);

            LevelLoadModel _levelLoadModelAbove = buildingLoadModel.LevelLoadModels.OfType <LevelLoadModel>().FirstOrDefault(p => p.Level.Id == _topLevel.Id);

            if (_levelLoadModelAbove == null)
            {
                return(Result.Failed);
            }

            Dictionary <LevelLoadModel, double> _levelLoadModelXDistances = new Dictionary <LevelLoadModel, double>();
            Dictionary <LevelLoadModel, double> _levelLoadModelYDistances = new Dictionary <LevelLoadModel, double>();
            LevelLoadModel _lowestReshoredLevelLoadModel = null;
            double         _levelAboveDemand             = _levelLoadModelAbove.ReshoreDemandPoundsForcePerSquareFoot;

            foreach (LevelLoadModel _levelLoadModel in buildingLoadModel.LevelLoadModels)
            {
                if (_levelAboveDemand > 0.0)
                {
                    if (_levelLoadModel.Level.Id == _topLevel.Id)
                    {
                        continue;
                    }

                    double _roundedClearShoreHeight = Math.Round(_levelLoadModel.ClearShoreHeight, 9);
                    if (_clearShoreHeightCapacityMappings.ContainsKey(_roundedClearShoreHeight) == false)
                    {
                        continue;
                    }

                    double _loadCapacityPerShore = _clearShoreHeightCapacityMappings[_roundedClearShoreHeight];
                    double _minimumAreaPerShore  = _loadCapacityPerShore / _levelAboveDemand;

                    double _allowedAreaSquareSideLength = Math.Sqrt(_minimumAreaPerShore);
                    double _roundedSideLength           = Math.Floor(_allowedAreaSquareSideLength);

                    //safer to round both down & have a smaller area
                    _levelLoadModelXDistances.Add(_levelLoadModel, _roundedSideLength);
                    _levelLoadModelYDistances.Add(_levelLoadModel, _roundedSideLength);

                    //Adjust our Capacity & Demand, then determine if we can stop adding temportary reshoring
                    _levelLoadModel.ReshoreDemandPoundsForcePerSquareFoot = _levelAboveDemand;

                    _levelAboveDemand -= _levelLoadModel.CapacityPoundsForcePerSquareFoot;
                }
                else
                {
                    if (_lowestReshoredLevelLoadModel == null)
                    {
                        _lowestReshoredLevelLoadModel = _levelLoadModelAbove;
                    }
                    _levelLoadModel.ReshoreDemandPoundsForcePerSquareFoot = 0.0;
                }

                _levelLoadModelAbove = _levelLoadModel;
            }

            //Update Level parameters
            foreach (LevelLoadModel _levelLoadModel in buildingLoadModel.LevelLoadModels)
            {
                _levelLoadModel.SetLevelParameters();
            }

            //Place temporary reshoring
            List <FamilyInstance> _temporaryShores = new List <FamilyInstance>();

            _levelLoadModelAbove = buildingLoadModel.LevelLoadModels.OfType <LevelLoadModel>().FirstOrDefault(p => p.Level.Id == _topLevel.Id);
            foreach (LevelLoadModel _levelLoadModel in buildingLoadModel.LevelLoadModels.Where(p => p.ReshoreDemandPoundsForcePerSquareFoot > 0.0))
            {
                if (_levelLoadModel.Level.Id == _topLevel.Id)
                {
                    continue;
                }

                if (_levelLoadModelXDistances.ContainsKey(_levelLoadModel) == false || _levelLoadModelYDistances.ContainsKey(_levelLoadModel) == false)
                {
                    break;
                }

                double _sideXLength = _levelLoadModelXDistances[_levelLoadModel];
                double _sideYLength = _levelLoadModelYDistances[_levelLoadModel];

                //ToDo: add 1, subtract 1 from each side & check if their total area is closer to the calculated area than a square
                //ToDo: do this twice, and take the "middle" option

                List <Floor> _levelAboveFloors = _floors.Where(p => p.LevelId == _levelLoadModelAbove.Level.Id).ToList();

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

                foreach (Floor _floor in _levelAboveFloors)
                {
                    BoundingBoxXYZ _currentFloorBounds = _floor.get_BoundingBox(null);

                    List <double> _xCoords = new List <double>();
                    for (double _x = 0.0; _x <= _currentFloorBounds.Max.X - _currentFloorBounds.Min.X; _x += _sideXLength)
                    {
                        _xCoords.Add(_x);
                    }

                    List <double> _yCoords = new List <double>();
                    for (double _y = 0.0; _y <= _currentFloorBounds.Max.Y - _currentFloorBounds.Min.Y; _y += _sideYLength)
                    {
                        _yCoords.Add(_y);
                    }

                    foreach (double _x in _xCoords)
                    {
                        foreach (double _y in _yCoords)
                        {
                            XYZ _insertionCoordinate = new XYZ(
                                _currentFloorBounds.Min.X + _x,
                                _currentFloorBounds.Min.Y + _y,
                                _levelLoadModel.ElevationFeet);

                            FamilyInstance _temporaryShore = _doc.Create.NewFamilyInstance(_insertionCoordinate, _temporaryShoreSymbol, Autodesk.Revit.DB.Structure.StructuralType.Column);

                            Parameter _heightParam = _temporaryShore.LookupParameter("Height");
                            if (_heightParam != null && _heightParam.IsReadOnly == false)
                            {
                                _heightParam.Set(_levelLoadModel.ClearShoreHeight);
                            }

                            _temporaryShores.Add(_temporaryShore);
                        }
                    }
                }
            }


            //Regenerate so that the latest locations are updated in the model for our newly placed reshores - the intersects filters below will fail without this
            _doc.Regenerate();

            var _scopeBoxes = Getters.GetScopeBoxes(_doc);
            Dictionary <ElementId, string> _shoreIdScopeBoxNames = new Dictionary <ElementId, string>();

            foreach (Element _scopeBox in _scopeBoxes)
            {
                List <Element> _columnsInScopeBox = Getters.GetInsideElements(_doc, _temporaryShores, _scopeBox.get_BoundingBox(null));

                foreach (Level _level in _levels)
                {
                    List <Element> _columnsInScopeBoxOnLevel = _columnsInScopeBox.Where(p => ((p.Location as LocationPoint)?.Point.Z - _level.Elevation) <= 1.0).ToList();

                    string _pourName = Helpers.Views.BoundedViewCreator.GetViewName(_level, _scopeBox, string.Empty, string.Empty);

                    foreach (Element _column in _columnsInScopeBoxOnLevel)
                    {
                        _column.get_Parameter(Ids.PourNameParameterId)?.Set(_pourName);
                    }
                }
            }

            return(Result.Succeeded);
        }