Esempio n. 1
0
        //This method is to be used with the above constructor. It is private because it is not needed outside of this tool's use
        private static void PlaceSymbolsInView(UIApplication uiApp, string groupingParameter, string subgroupingParameter, Autodesk.Revit.DB.View placementView)
        {
            try
            {
                RVTDocument doc = uiApp.ActiveUIDocument.Document;

                //Start a transaction
                Transaction t = new Transaction(doc, "LoadMaterialSymbolsFamily");
                t.Start();

                //Get the family loaded into the project by its name, then close the family document in the background
                Family refFamily = RVTGetElementsByCollection.FamilyByFamilyName(uiApp, Path.GetFileNameWithoutExtension(Properties.Settings.Default.RevitFamilyMaterialsCMSSymbIdMaterialSchedule));

                //Add each family symbol (type) to a list of symbols and a dictionary of grouping values indexed by symbol
                Dictionary <Element, string> familyTypesDict = new Dictionary <Element, string>();
                List <Element> familyTypesList = new List <Element>();
                foreach (ElementId symbId in refFamily.GetFamilySymbolIds())
                {
                    FamilySymbol familySymbol = doc.GetElement(symbId) as FamilySymbol;
                    string       paramValue   = familySymbol.GetParameters(groupingParameter).First().AsString();
                    familyTypesList.Add(familySymbol);
                    familyTypesDict.Add(familySymbol, paramValue);
                }
                //Next, use Linq to group the family types by ID Use, then sort each group by Mark
                var familyTypesGroupedQuery =
                    from elemSymbol in familyTypesList
                    orderby elemSymbol.GetParameters(subgroupingParameter).First().AsString() ascending
                    group elemSymbol by elemSymbol.GetParameters(groupingParameter).First().AsString() into mainGroup
                    orderby mainGroup.First().GetParameters(groupingParameter).First().AsString() descending
                    select mainGroup;

                //The spacing is the distance between each symbol when it is placed in fractional feet. 0.08333 is about 1" which works well for the scale used in making the drafting view
                double spacing = 0.08333;
                int    rowNum  = 0;
                //Cycle through each group ID Use grouping
                foreach (var mainGroup in familyTypesGroupedQuery)
                {
                    int columnNum = 0;
                    //Then for each family symbol in the ID Use grouping, place them in the view, incrementing the X distance by (spacing x the column number) each time. They will be in order of their Mark value
                    foreach (FamilySymbol symbol in mainGroup)
                    {
                        doc.Create.NewFamilyInstance(new XYZ(Convert.ToDouble(columnNum) * spacing, Convert.ToDouble(rowNum) * spacing, 0), symbol, placementView);
                        columnNum++;
                    }
                    rowNum++;
                }
                t.Commit();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }
Esempio n. 2
0
        public FloorsCFBRRequest(UIApplication uiApp, String text)
        {
            MainUI     uiForm            = BARevitTools.Application.thisApp.newMainUi;
            UIDocument uidoc             = uiApp.ActiveUIDocument;
            FloorType  selectedFloorType = null;

            //Get the name of the floor type selected in the MainUI
            string selectedFloorTypeName = uiForm.floorsCFBRSelectFloorTypeComboBox.Text.ToString();
            //Create lists to use locally from the rooms selected from the MainUI, the collection of floor types, and to store newly created floors.
            List <Room>      roomElements = uiForm.floorsCFBRRoomsList;
            List <FloorType> floorTypes   = RVTGetElementsByCollection.DocumentFloorTypes(uiApp);
            List <Floor>     newFloors    = new List <Floor>();

            //First, make sure the user is running the tool from a plan view
            if (uidoc.ActiveView.GetType().ToString() != "Autodesk.Revit.DB.ViewPlan")
            {
                MessageBox.Show("Please run from a plan view");
            }
            else
            {
                //If they are int a plan view, start a transaction
                Transaction t1 = new Transaction(uidoc.Document, "CreateFloorsByRoom");
                t1.Start();
                //Cycle through the floor types in the project until the one with a name matching the one selected in the MainUI is found
                foreach (FloorType floorType in floorTypes)
                {
                    if (floorType.Name.ToString() == selectedFloorTypeName)
                    {
                        selectedFloorType = floorType;
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }

                try
                {
                    //Generate new GeometryOptions to allow evaluation of room volumes that may not be visible.
                    Options geomOptions = new Options();
                    geomOptions.IncludeNonVisibleObjects = true;

                    //For each room that was selected with the MainUI...
                    foreach (Room room in roomElements)
                    {
                        //Create a new iterable list for the CurveLoops reprsenting the edges of the room boundary
                        IList <CurveLoop> faceCurveLoops = null;
                        //Get the level associated with the room for floor creation
                        Level roomLevel = room.Level;

                        //Get the geometry of the room
                        GeometryElement roomGeomElements = room.get_Geometry(geomOptions);
                        Solid           roomSolid        = null;

                        //Cycle through the geometry associated with the room until the solid form is found
                        foreach (GeometryObject geom in roomGeomElements)
                        {
                            if (geom.GetType().ToString() == "Autodesk.Revit.DB.Solid")
                            {
                                roomSolid = geom as Solid;
                                break;
                            }
                        }

                        //If the solid form of the room was found, continue
                        if (roomSolid != null)
                        {
                            //Get the faces of the solid
                            FaceArray solidFaces = roomSolid.Faces;
                            foreach (PlanarFace solidFace in solidFaces)
                            {
                                //Check the direction of the face normal
                                XYZ faceNormal = solidFace.FaceNormal;
                                //If the face normal faced down, it is a bottom face. Because the room cannot be split into multiple portions,
                                //and a split level room is unlikely, it is safe to select the first downward face.
                                if (faceNormal.Z == -1)
                                {
                                    //Get the edges of the face as curve loops
                                    faceCurveLoops = solidFace.GetEdgesAsCurveLoops();
                                    break;
                                }
                            }
                        }

                        //If the face's curve loops were retrieved, continue
                        if (faceCurveLoops.Count != 0)
                        {
                            try
                            {
                                //Make a new CurveArray from the loops
                                CurveArray curveArray = new CurveArray();
                                foreach (CurveLoop cloop in faceCurveLoops)
                                {
                                    CurveLoopIterator cLoopIter = cloop.GetCurveLoopIterator();
                                    while (cLoopIter.MoveNext())
                                    {
                                        curveArray.Append(cLoopIter.Current);
                                    }
                                }
                                //The new floow will require the CurveArray, FloorType, Level, and boolean for making it structural (false for this tool's purpose)
                                Floor newFloor = uidoc.Document.Create.NewFloor(curveArray, selectedFloorType, roomLevel, false);
                                //After making the floor, add it to the list of new floors created
                                newFloors.Add(newFloor);
                            }
                            catch
                            {
                                //If the room had more than one edge loop, such as another room was enveloped by the selected room, the operation will fail because the API only allows one loop
                                MessageBox.Show(string.Format("Floor could not be made for {0}, which is likely due to the room having more than one boundary loop. The Revit API only allows for one contiuous loop.", room.Number.ToString()));
                            }
                        }
                    }
                    t1.Commit();
                    //Provide some feedback to the MainUI
                    uiForm.floorsCFBRDoneLabel.Visible = true;
                    uiForm.floorsCFBRRoomsList         = new List <Room>();
                }
                catch { t1.RollBack(); }

                //If the user wanted to offset the floors by their thickness, this will offset the newly made and collected floors
                if (uiForm.floorsCFBROffsetFinishFloorCheckBox.Checked)
                {
                    Transaction t2 = new Transaction(uidoc.Document, "ElevateFloors");
                    t2.Start();
                    try
                    {
                        //Cycle through the list of new floors
                        foreach (Floor floor in newFloors)
                        {
                            //Make a new set of geometry options
                            Options geomOptions = new Options();
                            geomOptions.IncludeNonVisibleObjects = true;
                            //Get the floor geometry and the bounding box of the geometry
                            GeometryElement floorGeometry = floor.get_Geometry(geomOptions);
                            BoundingBoxXYZ  floorBBox     = floorGeometry.GetBoundingBox();
                            //Use the minimum and maximum Z coordinates from the bounding box to determine the floor thickness because that's not natively supported in the Revit API
                            double bBoxMinZ       = floorBBox.Min.Z;
                            double bBoxMaxZ       = floorBBox.Max.Z;
                            double floorThickness = bBoxMaxZ - bBoxMinZ;
                            //Move the floor up with a translation in the Z axis by the thickness value
                            XYZ translation = new XYZ(0, 0, floorThickness);
                            ElementTransformUtils.MoveElement(uidoc.Document, floor.Id, translation);
                        }
                        t2.Commit();
                    }
                    catch { t2.RollBack(); }
                }
            }
        }
Esempio n. 3
0
        public MaterialsAMLRequest(UIApplication uiApp, String text)
        {
            DataGridView dgv = BARevitTools.Application.thisApp.newMainUi.materialsAMLDataGridView;
            RVTDocument  doc = uiApp.ActiveUIDocument.Document;

            //Get all of the line styles in the project and assign them to a dictionary indexed by line style name
            Dictionary <string, Category> lineStyleDict = new Dictionary <string, Category>();

            foreach (Category lineStyle in RVTGetElementsByCollection.DocumentLineStyles(uiApp))
            {
                lineStyleDict.Add(lineStyle.Name.Replace("ID ", ""), lineStyle);
            }

            //All new line styles will use the solid line pattern, so get that from the project
            ElementId solidPatternId = LinePatternElement.GetSolidPatternId();

            //Start the transaction to create the line styles
            Transaction t1 = new Transaction(doc, "CreateLineStyles");

            t1.Start();
            //Cycle through the rows of line styles in the MainUI form
            foreach (DataGridViewRow row in dgv.Rows)
            {
                //Get the color of the button in the row and convert it to a Revit color
                System.Drawing.Color buttonColor = row.Cells["Color"].Style.BackColor;
                Color revitColor = new Color(buttonColor.R, buttonColor.G, buttonColor.B);

                //If the Updated column cell is not null, continue
                if (row.Cells["Updated"].Value != null)
                {
                    //Assuming the user made a modification to the color for an existing line style and the Mark is part of the dictionary keys...
                    if (row.Cells["Updated"].Value.ToString() == "True" && lineStyleDict.Keys.Contains(row.Cells["Mark"].Value.ToString()))
                    {
                        try
                        {
                            //Get the line style by key name in the dictionary and update its line color to the one from the button
                            Category lineStyleToUpdate = lineStyleDict[row.Cells["Mark"].Value.ToString()];
                            lineStyleToUpdate.LineColor = revitColor;
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show(e.ToString());
                        }
                    }
                }

                //If the Select column cell is not null, continue
                if (row.Cells["Select"].Value != null)
                {
                    //Assuming the user checked the box in the Select column, Mark is not emtpy, and the dictionary of line styles does not already contain a line style with the same mark name...
                    if (row.Cells["Select"].Value.ToString() == "True" && row.Cells["Mark"].Value.ToString() != "" && !lineStyleDict.Keys.Contains(row.Cells["Mark"].Value.ToString()))
                    {
                        try
                        {
                            //Get the category for Lines
                            Category linesCategory = doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
                            //Make a new line style subcategory with the name of the mark value from the Mark column cell, prefixed with ID so it is easier to find during the sort
                            Category newLineStyleCategory = doc.Settings.Categories.NewSubcategory(linesCategory, "ID " + row.Cells["Mark"].Value.ToString());
                            //Set the line style's color, projection weight, and solid line pattern
                            newLineStyleCategory.LineColor = revitColor;
                            newLineStyleCategory.SetLineWeight(6, GraphicsStyleType.Projection);
                            newLineStyleCategory.SetLinePatternId(solidPatternId, GraphicsStyleType.Projection);
                            //Regenerate the document
                            doc.Regenerate();
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show(e.ToString());
                        }
                    }
                }
            }
            t1.Commit();

            //Update the DataGridView of the MainUI with the changes and new line styles
            BARevitTools.Application.thisApp.newMainUi.MaterialsAMLUpdateDGV(dgv);

            //Make another line style dictionary with the line styles indexed by name (mark)
            Dictionary <string, Category> newlineStyleDict = new Dictionary <string, Category>();

            foreach (Category lineStyle in RVTGetElementsByCollection.DocumentLineStyles(uiApp))
            {
                newlineStyleDict.Add(lineStyle.Name.Replace("ID ", ""), lineStyle);
            }

            //Add a default line style to the palette's combo box, then add the checked line styles to a list in alphabetical order
            SortedList <string, string> materialsToUseList = new SortedList <string, string>();

            BARevitTools.Application.thisApp.newMainUi.materialsAMLPalette.paletteMaterialComboBox.Items.Add("Default");
            foreach (DataGridViewRow row in dgv.Rows)
            {
                if (newlineStyleDict.Keys.Contains(row.Cells["Mark"].Value.ToString()) && row.Cells["Select"].Value.ToString() == "True")
                {
                    materialsToUseList.Add(row.Cells["Mark"].Value.ToString(), row.Cells["Mark"].Value.ToString());
                }
            }

            //Assuming there were checked linestyles to add to the palette's combo box, add them to the combo box
            if (materialsToUseList.Count != 0)
            {
                foreach (string item in materialsToUseList.Keys)
                {
                    BARevitTools.Application.thisApp.newMainUi.materialsAMLPalette.paletteMaterialComboBox.Items.Add(item);
                }
            }
            else
            {
                //If there were no additional line styles to add to the combo box, disable it and set it to Default
                BARevitTools.Application.thisApp.newMainUi.materialsAMLPalette.paletteMaterialComboBox.Text    = "Default";
                BARevitTools.Application.thisApp.newMainUi.materialsAMLPalette.paletteMaterialComboBox.Enabled = false;
            }

            //Show the palette and continue doing requests for the Accent Material Lines tool from there.
            BARevitTools.Application.thisApp.newMainUi.materialsAMLPalette.Show();
        }
Esempio n. 4
0
        public MaterialsCMSRequest(UIApplication uiApp, String text)
        {
            MainUI        uiForm          = BARevitTools.Application.thisApp.newMainUi;
            ProgressBar   progressBar     = uiForm.materialsCMSExcelCreateSymbolsProgressBar;
            DataGridView  dgv             = uiForm.materialsCMSExcelDataGridView;
            int           rowsCount       = dgv.Rows.Count;
            int           columnsCount    = dgv.Columns.Count;
            List <string> familyTypesMade = new List <string>();

            //Prepare the progress bar. The column count is one less because the first column is the column for family type names
            progressBar.Minimum = 0;
            progressBar.Maximum = (rowsCount) * (columnsCount - 1);
            progressBar.Step    = 1;
            progressBar.Visible = true;

            RVTDocument doc = uiApp.ActiveUIDocument.Document;

            //Reset the progress bar
            uiForm.materialsCMSExcelCreateSymbolsProgressBar.Value = 0;

            //First, try to use the family from the project. If that fails, use the family file
            Family familyToUse = RVTGetElementsByCollection.FamilyByFamilyName(uiApp, Path.GetFileNameWithoutExtension(Properties.Settings.Default.RevitFamilyMaterialsCMSSymbIdMaterialSchedule));

            //Assuming nothing went to hell in the process of loading one famiy...
            if (familyToUse != null)
            {
                //Save out the family to use
                RVTDocument tempFamDoc = doc.EditFamily(familyToUse);
                RVTOperations.SaveRevitFile(uiApp, tempFamDoc, @"C:\Temp\" + tempFamDoc.Title, true);

                //Open the family to use and get its FamilyManager
                RVTDocument   famDoc = RVTOperations.OpenRevitFile(uiApp, @"C:\Temp\" + Path.GetFileName(Properties.Settings.Default.RevitFamilyMaterialsCMSSymbIdMaterialSchedule));
                FamilyManager famMan = famDoc.FamilyManager;

                //Get the parameters from the Family Manager and add them to a dictionary
                FamilyParameterSet parameters = famMan.Parameters;
                Dictionary <string, FamilyParameter> famParamDict = new Dictionary <string, FamilyParameter>();
                foreach (FamilyParameter param in parameters)
                {
                    famParamDict.Add(param.Definition.Name, param);
                }

                //Start a new transaction to make the new family types in the family to use
                using (Transaction t1 = new Transaction(famDoc, "MakeNewTypes"))
                {
                    t1.Start();
                    //Cycle through the rows in the dgv
                    for (int i = 0; i < rowsCount; i++)
                    {
                        //The first column cell will be the type name
                        string newTypeName = dgv.Rows[i].Cells[0].Value.ToString();
                        //Get the family type names in the family
                        Dictionary <string, FamilyType> existingTypeNames = RVTOperations.GetFamilyTypeNames(famMan);
                        //If the family to make from the DGV does not exist in the dictionary keys...
                        if (!existingTypeNames.Keys.Contains(newTypeName))
                        {
                            //Make the family type and add it to the list of types made
                            FamilyType newType = famMan.NewType(newTypeName);
                            famMan.CurrentType = newType;
                            familyTypesMade.Add(newType.Name);
                        }
                        else
                        {
                            //If the type exists, set the current type it from the dictionary and add it to the list of types made
                            famMan.CurrentType = existingTypeNames[newTypeName];
                            familyTypesMade.Add(famMan.CurrentType.Name);
                        }

                        //Next, evaluate the columns that contain parameters
                        for (int j = 1; j < columnsCount; j++)
                        {
                            //The parameter names will be retrieved from the column HeaderText property
                            string paramName = dgv.Columns[j].HeaderText;
                            //Meanwhile the parameter value will come from the DGV cells
                            var paramValue = dgv.Rows[i].Cells[j].Value;

                            try
                            {
                                //If the parameter dictionary contains the parameter and the value to assign it is not empty, continue.
                                if (paramValue.ToString() != "" && famParamDict.Keys.Contains(paramName))
                                {
                                    //Get the family parameter and check if it is locked by a formula
                                    FamilyParameter param = famParamDict[paramName];
                                    if (!param.IsDeterminedByFormula)
                                    {
                                        //If it is not locked by a formula, set the parameter
                                        ParameterType paramType = param.Definition.ParameterType;
                                        RVTOperations.SetFamilyParameterValue(famMan, param, paramValue);
                                    }
                                }
                            }
                            catch
                            {; }
                            finally
                            {
                                //Always perform the step to indicate the progress.
                                progressBar.PerformStep();
                            }
                        }
                    }
                    t1.Commit();
                }

                //Use another transaction to delete the types that were not needed
                using (Transaction t2 = new Transaction(famDoc, "DeleteOldTypes"))
                {
                    t2.Start();
                    //Cycle through the family types and determine if it is in the list of types made
                    foreach (FamilyType type in famMan.Types)
                    {
                        if (!familyTypesMade.Contains(type.Name))
                        {
                            //If the type is not in the list of types made, delete it from the family file
                            famMan.CurrentType = type;
                            famMan.DeleteCurrentType();
                        }
                    }
                    t2.Commit();
                }

                //Save the family document at this point as all of the types and their parameters have been set
                famDoc.Close(true);

                using (Transaction t3 = new Transaction(doc, "LoadFamily"))
                {
                    t3.Start();
                    doc.LoadFamily(@"C:\Temp\" + Path.GetFileName(Properties.Settings.Default.RevitFamilyMaterialsCMSSymbIdMaterialSchedule), new RVTFamilyLoadOptions(), out Family loadedFamily);
                    t3.Commit();
                }

                //Get the drafting view type in the project for BA Drafting View, else just get the first drafting view type
                ViewDrafting   placementView    = null;
                var            draftingViews    = new FilteredElementCollector(doc).OfClass(typeof(ViewDrafting)).WhereElementIsNotElementType().ToElements();
                ViewFamilyType draftingViewType = null;
                try
                {
                    //From the view family types collection, get the first one where its name is BA Drafting View
                    draftingViewType = new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType)).WhereElementIsElementType().ToElements().Where(elem => elem.Name == "BA Drafting View").First() as ViewFamilyType;
                }
                catch
                {
                    //Well, crap. It doesn't exist. Just get the first type then and call it good.
                    draftingViewType = new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType)).WhereElementIsElementType().ToElements().First() as ViewFamilyType;
                }

                //Start a transaction for making the ID Material View and placing the family symbol types
                using (Transaction t4 = new Transaction(doc, "MakeIDMaterialView"))
                {
                    t4.Start();
                    foreach (ViewDrafting view in draftingViews)
                    {
                        //Find the view named ID Material View, or whatever jibberish someone typed in the CMS text box for the name to use. in the drafting views
                        if (view.Name == "ID Material View" || view.Name == uiForm.materialsCMSSetViewNameTextBox.Text)
                        {
                            //Delete the drafting view
                            doc.Delete(view.Id);
                            doc.Regenerate();
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }

                    //Make a new view
                    placementView       = ViewDrafting.Create(doc, draftingViewType.Id);
                    placementView.Scale = 1;
                    if (uiForm.materialsCMSSetViewNameTextBox.Text != "")
                    {
                        //If someone defined a custom view name, use that and strip out brackets if they exist
                        placementView.Name = uiForm.materialsCMSSetViewNameTextBox.Text.Replace("{", "").Replace("}", "");
                    }
                    else
                    {
                        //Otherwise, this will be the new ID Material View
                        placementView.Name = "ID Material View";
                    }

                    try
                    {
                        //Set the view sort parameters if they exist
                        placementView.GetParameters(Properties.Settings.Default.BAViewSort1).First().Set("2 Plans");
                        placementView.GetParameters(Properties.Settings.Default.BAViewSort2).First().Set("230 Finish Plans");
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.ToString());
                    }
                    doc.Regenerate();
                    t4.Commit();
                }


                //Do magic to place each symbol in its view by calling the method below in this class
                PlaceSymbolsInView(uiApp, "ID Use", "Mark", placementView);

                //Clean up the files from the operations
                GeneralOperations.CleanRfaBackups(GeneralOperations.GetAllRvtBackupFamilies(@"C:\Temp\", false));
                File.Delete(@"C:\Temp\" + Path.GetFileName(Properties.Settings.Default.RevitFamilyMaterialsCMSSymbIdMaterialSchedule));
                Application.thisApp.newMainUi.materialsCMSFamilyToUse = RVTGetElementsByCollection.FamilyByFamilyName(uiApp, Path.GetFileNameWithoutExtension(Properties.Settings.Default.RevitFamilyMaterialsCMSSymbIdMaterialSchedule));
            }
            else
            {
                //If the family could not be found, well, let the user know of this.
                MessageBox.Show(String.Format("The {0} family could not be found in the project.",
                                              Path.GetFileNameWithoutExtension(Properties.Settings.Default.RevitFamilyMaterialsCMSSymbIdMaterialSchedule)));
            }
        }