public MaterialsCMSLoadFamilyRequest(UIApplication uiApp, String text) { RVTDocument doc = uiApp.ActiveUIDocument.Document; //Get version of the family file used for the ID Material Schedule symbol that matches the version of Revit running string familyFile = Properties.Settings.Default.RevitFamilyMaterialsCMSSymbIdMaterialSchedule; string versionedFamilyFile = ""; try { versionedFamilyFile = RVTOperations.GetVersionedFamilyFilePath(uiApp, familyFile); } catch { //But if that fails, just take the original version and upgrade it versionedFamilyFile = familyFile; } using (Transaction t1 = new Transaction(doc, "LoadFamily")) { t1.Start(); uiApp.ActiveUIDocument.Document.LoadFamily(versionedFamilyFile, out Family loadedFamily); Application.thisApp.newMainUi.materialsCMSFamilyToUse = loadedFamily; t1.Commit(); } }
public MaterialsAMLPaletteRequest(UIApplication uiApp, String text) { RVTDocument doc = uiApp.ActiveUIDocument.Document; MaterialsAMLPalette materialsPalette = BARevitTools.Application.thisApp.newMainUi.materialsAMLPalette; //Get the versioned symbol family FamilySymbol familySymbol = null; string versionedFamily = RVTOperations.GetVersionedFamilyFilePath(uiApp, Properties.Settings.Default.RevitIDAccentMatTag); //Try loading the family symbol Transaction loadSymbolTransaction = new Transaction(doc, "LoadFamilySymbol"); loadSymbolTransaction.Start(); try { try { IFamilyLoadOptions loadOptions = new RVTFamilyLoadOptions(); doc.LoadFamilySymbol(versionedFamily, "Legend Tag (Fake)", loadOptions, out FamilySymbol symb); familySymbol = symb; } catch { MessageBox.Show(String.Format("Could not get the 'Legend Tag (Fake)' type from {0}", versionedFamily), "Family Symbol Load Error"); } loadSymbolTransaction.Commit(); } catch (Exception transactionException) { loadSymbolTransaction.RollBack(); MessageBox.Show(transactionException.ToString()); } //Get the line style to use, or create the default Element lineStyle = null; if (materialsPalette.paletteMaterialComboBox.Text == "Default") { try { lineStyle = doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines).SubCategories.get_Item("6 BA ID ACCENT").GetGraphicsStyle(GraphicsStyleType.Projection); } catch { try { Category linesCategory = doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines); Category newLineStyleCategory = doc.Settings.Categories.NewSubcategory(linesCategory, "6 BA ID ACCENT"); newLineStyleCategory.LineColor = new Color(0, 0, 0); newLineStyleCategory.SetLineWeight(6, GraphicsStyleType.Projection); newLineStyleCategory.SetLinePatternId(LinePatternElement.GetSolidPatternId(), GraphicsStyleType.Projection); doc.Regenerate(); lineStyle = newLineStyleCategory.GetGraphicsStyle(GraphicsStyleType.Projection); } catch (Exception e) { MessageBox.Show(e.ToString()); } } } else { lineStyle = doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines).SubCategories.get_Item("ID " + materialsPalette.paletteMaterialComboBox.Text).GetGraphicsStyle(GraphicsStyleType.Projection); } //Assure the view being used is a floor plan if (doc.ActiveView.ViewType != ViewType.FloorPlan) { MessageBox.Show("This tool should be used ina a Floor Plan or Area Plan view"); } else { //Create a loop for picking points. Change the palette background color based on the number of points picked List <XYZ> pickedPoints = new List <XYZ>(); bool breakLoop = false; int pickCount = 0; while (breakLoop == false) { try { //Have the user begin picking points. The number of clicks to start the UI color change is 1 because the first click is usually to activate the window. XYZ point = uiApp.ActiveUIDocument.Selection.PickPoint(Autodesk.Revit.UI.Selection.ObjectSnapTypes.Endpoints, "Click points for the line to follow. Then click once to the side where the lines should be drawn. Hit ESC to finish"); pickedPoints.Add(point); if (pickCount == 1) { materialsPalette.BackColor = System.Drawing.Color.Firebrick; } else if (pickCount == 2) { materialsPalette.BackColor = System.Drawing.Color.Orange; } else if (pickCount > 2) { //After three clicks in the window, the user has made the minimum point selection to generate the lines from the start, end, and positive side points. materialsPalette.BackColor = System.Drawing.Color.GreenYellow; } else { ; } pickCount++; } catch { materialsPalette.BackColor = MaterialsAMLPalette.DefaultBackColor; breakLoop = true; } } //Get rid of the first point from clicking into the Revit view. This point is not needed. pickedPoints.RemoveAt(0); if (pickedPoints.Count > 2) { Transaction createLinesTransaction = new Transaction(doc, "CreateAccentLines"); createLinesTransaction.Start(); try { //These points will be used in determining the start, end, and room points XYZ firstPoint = pickedPoints[0]; XYZ roomPoint = pickedPoints[pickedPoints.Count - 1]; XYZ lastPoint = pickedPoints[pickedPoints.Count - 2]; //Create a list of points for the polyline that excludes the room point List <XYZ> polyLinePoints = new List <XYZ>(); for (int i = 0; i < pickedPoints.Count - 1; i++) { polyLinePoints.Add(pickedPoints[i]); } //Create a polyline from the list of picked points and then get make lines from the points on the poly line PolyLine guidePolyLine = PolyLine.Create(polyLinePoints); IList <XYZ> polyPoints = guidePolyLine.GetCoordinates(); List <Line> guideLines = new List <Line>(); for (int i = 0; i < polyLinePoints.Count - 1; i++) { guideLines.Add(Line.CreateBound(polyLinePoints[i], polyLinePoints[i + 1])); } //Get the direction of the line offset by measuring the first offset for positive and negative values and comparing their distances with the room point bool positiveZ = false; List <Line> offsetLines = new List <Line>(); Line positiveOffsetLine = guideLines.Last().CreateOffset(0.6666666667d, XYZ.BasisZ) as Line; Line negativeOffsetLine = guideLines.Last().CreateOffset(-0.6666666667d, XYZ.BasisZ) as Line; XYZ positiveOffsetMidPoint = positiveOffsetLine.Evaluate(0.5d, true); XYZ negativeOffsetMidPoint = negativeOffsetLine.Evaluate(0.5d, true); Double positiveOffsetDistance = positiveOffsetMidPoint.DistanceTo(roomPoint); Double negativeOffsetDistance = negativeOffsetMidPoint.DistanceTo(roomPoint); //If the positive offset side resulted in a shorter distance to the point inside the room, then the offset should have a positive Z normal. if (positiveOffsetDistance < negativeOffsetDistance) { positiveZ = true; } //Knowing whether or not to use a positive or negative offset, begin creating offset lines for each guide line foreach (Line guideLine in guideLines) { if (positiveZ) { offsetLines.Add(guideLine.CreateOffset(0.6666666667d, XYZ.BasisZ) as Line); } else { offsetLines.Add(guideLine.CreateOffset(-0.6666666667d, XYZ.BasisZ) as Line); } } //Determine if the number of line segments is 1 or more Line firstLine = offsetLines.First(); Line lastLine = null; if (offsetLines.Count > 1) { lastLine = offsetLines.Last(); } //If there is only one line segment, both end operations must be performed on it if (lastLine == null) { double lineLength = firstLine.Length; double fractionOfLength = 0.6666666667d / lineLength; //Checking fractions to ensure they are not greater than 1 for the normalization if (fractionOfLength > 1) { fractionOfLength = 0.25d; } //Re-evaluating where to place the start and end point of the line XYZ shiftedStartPoint = firstLine.Evaluate(fractionOfLength, true); XYZ shiftedEndPoint = firstLine.Evaluate(1 - fractionOfLength, true); firstLine = Line.CreateBound(shiftedStartPoint, shiftedEndPoint); //Creating the angled corner lines Line firstCornerLine = Line.CreateBound(firstPoint, firstLine.GetEndPoint(0)); Line lastCornerLine = Line.CreateBound(lastPoint, firstLine.GetEndPoint(1)); //Create the detail lines from the lines DetailCurve newAccentLine1 = doc.Create.NewDetailCurve(doc.ActiveView, firstCornerLine); DetailCurve newAccentLine2 = doc.Create.NewDetailCurve(doc.ActiveView, firstLine); DetailCurve newAccentLine3 = doc.Create.NewDetailCurve(doc.ActiveView, lastCornerLine); //Assign a line style to the newly created detail lines newAccentLine1.LineStyle = lineStyle; newAccentLine2.LineStyle = lineStyle; newAccentLine3.LineStyle = lineStyle; XYZ tagPlacementPoint = firstLine.Evaluate(0.5d, true); XYZ direction = firstLine.Direction; Line axisLine = Line.CreateUnbound(tagPlacementPoint, XYZ.BasisZ); double rotationAngle = direction.AngleTo(XYZ.BasisX); //Get the midpoint of the line, its direction, and create the rotation and axis if (familySymbol != null) { //Create the tag instance FamilyInstance newTag = doc.Create.NewFamilyInstance(tagPlacementPoint, familySymbol, doc.ActiveView); //Rotate the new tag instance ElementTransformUtils.RotateElement(doc, newTag.Id, axisLine, rotationAngle); } createLinesTransaction.Commit(); } //If there is more than one line segment, an operation must be performed on the start and end of the start and end lines, respectively else { List <Line> linesToDraw = new List <Line>(); // Get the normalized value for 8" relative to the lengths of the start and end lines double firstLineLength = firstLine.Length; double fractionOfFirstLine = 0.6666666667 / firstLineLength; double lastLineLength = lastLine.Length; double fractionOfLastLine = 0.666666667 / lastLineLength; //Checking fractions to ensure they are not greater than 1 for the normalization if (fractionOfFirstLine > 1) { fractionOfFirstLine = 0.25d; } if (fractionOfLastLine > 1) { fractionOfLastLine = 0.25d; } //Shift the ends of the start and end lines by finding the point along the line relative to the normalized 8" value XYZ shiftedStartPoint = firstLine.Evaluate(fractionOfFirstLine, true); XYZ shiftedEndPoint = lastLine.Evaluate(1 - fractionOfLastLine, true); //Reset the start and end lines with the new shifted points firstLine = Line.CreateBound(shiftedStartPoint, firstLine.GetEndPoint(1)); lastLine = Line.CreateBound(lastLine.GetEndPoint(0), shiftedEndPoint); linesToDraw.Add(firstLine); //If there are only 3 offset lines, there will be just one middle segment if (offsetLines.Count == 3) { linesToDraw.Add(offsetLines[1]); } //If there are more than three offset lines, there will be more than one middle line segment else { List <Line> middleLines = offsetLines.GetRange(1, offsetLines.Count - 2); foreach (Line middleLine in middleLines) { linesToDraw.Add(middleLine); } } linesToDraw.Add(lastLine); //For the lines to draw, intersect them with the next line in the list and reset their start and end points to be the intersection for (int i = 0; i < linesToDraw.Count - 1; i++) { Line line1 = linesToDraw[i]; Line scaledLine1 = Line.CreateUnbound(line1.GetEndPoint(1), line1.Direction); Line line2 = linesToDraw[i + 1]; Line scaledLine2 = Line.CreateUnbound(line2.GetEndPoint(0), line2.Direction.Negate()); SetComparisonResult intersectionResult = scaledLine1.Intersect(scaledLine2, out IntersectionResultArray results); if (intersectionResult == SetComparisonResult.Overlap) { IntersectionResult result = results.get_Item(0); Line newLine1 = Line.CreateBound(line1.GetEndPoint(0), result.XYZPoint); Line newLine2 = Line.CreateBound(result.XYZPoint, line2.GetEndPoint(1)); linesToDraw[i] = newLine1; linesToDraw[i + 1] = newLine2; } } //Create the angled corner lines at the start and end of the line chain Line firstCornerLine = Line.CreateBound(firstPoint, firstLine.GetEndPoint(0)); Line lastCornerLine = Line.CreateBound(lastPoint, lastLine.GetEndPoint(1)); linesToDraw.Add(firstCornerLine); linesToDraw.Add(lastCornerLine); //Create each line as a detail line foreach (Line apiLine in linesToDraw) { DetailCurve newAccentLine = doc.Create.NewDetailCurve(doc.ActiveView, apiLine); newAccentLine.LineStyle = lineStyle; } //Declare some stuff for use in the symbol placement Line firstMiddleLine = linesToDraw[0]; Line lastMiddleLine = linesToDraw[linesToDraw.Count - 3]; XYZ firstTagPoint = firstMiddleLine.Evaluate(0.5d, true); XYZ lastTagPoint = lastMiddleLine.Evaluate(0.5d, true); XYZ firstDirection = firstMiddleLine.Direction; XYZ lastDirection = lastMiddleLine.Direction; Line firstAxisLine = Line.CreateUnbound(firstTagPoint, XYZ.BasisZ); Line lastAxisLine = Line.CreateUnbound(lastTagPoint, XYZ.BasisZ); double firstRotation = firstDirection.AngleTo(XYZ.BasisX); double lastRotation = lastDirection.AngleTo(XYZ.BasisX); if (familySymbol != null) { //Create tag at the beginning of the middle lines FamilyInstance firstTag = doc.Create.NewFamilyInstance(firstTagPoint, familySymbol, doc.ActiveView); ElementTransformUtils.RotateElement(doc, firstTag.Id, firstAxisLine, firstRotation); //Create a tag at the end of the middle lines if there are more than 2 middle lines if (linesToDraw.Count > 4) { FamilyInstance lastTag = doc.Create.NewFamilyInstance(lastTagPoint, familySymbol, doc.ActiveView); ElementTransformUtils.RotateElement(doc, lastTag.Id, lastAxisLine, lastRotation); } } createLinesTransaction.Commit(); } } catch (Exception e) { //Suppose the user closed the palette too soon. This will remind them to keep it open. if (BARevitTools.Application.thisApp.newMainUi.materialsAMLPalette == null) { MessageBox.Show("AML Picker was closed prematurely. Please keep the picker open until the lines are drawn."); } else { //Otherwise, if some other error occurred, show the exception MessageBox.Show(e.ToString()); } createLinesTransaction.RollBack(); } } else { ; } } }
public RoomsCDRTRequest(UIApplication uiApp, String text) { RVTDocument doc = uiApp.ActiveUIDocument.Document; Autodesk.Revit.DB.View activeView = doc.ActiveView; //Verify the active view is a floor plan view if (activeView.ViewType != ViewType.FloorPlan) { MessageBox.Show("Please run from a demo floor plan view."); } else { //Get the current phase of the active view Phase currentPhase = doc.GetElement(activeView.get_Parameter(BuiltInParameter.VIEW_PHASE).AsElementId()) as Phase; ElementId currentPhaseId = currentPhase.Id; ElementId previousPhaseId = null; //Collect the phases of the document PhaseArray phaseArray = doc.Phases; //Cycle through the phases in the project to get the previous phase for (int i = 0; i < phaseArray.Size; i++) { //By finding the index of the current phase, which must not be the first phase, the phase in the previous index can be obtained if (phaseArray.get_Item(i).ToString() == currentPhase.ToString() && i != 0) { previousPhaseId = phaseArray.get_Item(i - 1).Id; } i++; } //Collect the rooms in the current view where their phase is equal to the active view's phase List <Room> currentVisibleRooms = new FilteredElementCollector(doc, activeView.Id).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements().Cast <Room>().Where(r => r.get_Parameter(BuiltInParameter.ROOM_PHASE).AsElementId() == currentPhaseId).ToList(); List <string> currentVisibleRoomNumbers = new List <string>(); //Get the list of currently visible rooms' numbers foreach (Room room in currentVisibleRooms) { currentVisibleRoomNumbers.Add(room.Number); } //Only continue if the previous phase was found if (previousPhaseId != null) { List <Room> previousRoomsToTag = new List <Room>(); Outline outline = null; try { //This portion will require a new outline from the view's bounding box BoundingBoxXYZ viewBBox = activeView.get_BoundingBox(activeView); //Get the active view as a plan view so the view range can be obtained for the height of the outline ViewPlan viewPlan = activeView as ViewPlan; PlanViewRange planViewRange = viewPlan.GetViewRange(); double minX = viewBBox.Min.X; double minY = viewBBox.Min.Y; //The bottom Z point of the outline will be the elevation of the view's level plus the bottom offset double minZ = activeView.GenLevel.Elevation + planViewRange.GetOffset(PlanViewPlane.BottomClipPlane); double maxX = viewBBox.Max.X; double maxY = viewBBox.Max.Y; //The top Z point of the outline will be the elevation of the view's level plust the top offset double maxZ = activeView.GenLevel.Elevation + planViewRange.GetOffset(PlanViewPlane.TopClipPlane); //Generate the minimum and maximum points XYZ minPoint = new XYZ(minX, minY, minZ); XYZ maxPoint = new XYZ(maxX, maxY, maxZ); //Make a new outline from the points outline = new Outline(minPoint, maxPoint); //Establish a new bounding box filter using the outline BoundingBoxIntersectsFilter bboxFilter = new BoundingBoxIntersectsFilter(outline); //The previous rooms will be those that pass the bounding box intersects filter (their bounding boxes intersect the view bounding box) and they belong to the previous phase var previousNonVisibleRooms = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().WherePasses(bboxFilter).ToElements().Where(r => r.get_Parameter(BuiltInParameter.ROOM_PHASE).AsElementId() == previousPhaseId); foreach (Element elem in previousNonVisibleRooms) { //Get the rooms and their numbers Room room = elem as Room; string roomNumber = room.Number; //Verify the room number is not in the current view's list of visible room numbers if (!currentVisibleRoomNumbers.Contains(roomNumber)) { previousRoomsToTag.Add(room); } } } catch (Exception e) { //If something went wrong in getting the demoed rooms, report an error MessageBox.Show(e.ToString(), "Getting Demo Rooms Error"); } //Start a transaction to make the new tags Transaction t = new Transaction(doc, "Create Demo Room Tags"); t.Start(); FamilySymbol symbol = null; //Create a new instance of the load options IFamilyLoadOptions loadOptions = new RVTFamilyLoadOptions(); try { //Get the versioned symbol family to use as a "tag" string roomTagSymbolPath = RVTOperations.GetVersionedFamilyFilePath(uiApp, Properties.Settings.Default.RevitRoomTagSymbol); try { //Load only the particular type of tag doc.LoadFamilySymbol(roomTagSymbolPath, Properties.Settings.Default.RevitRoomTagSymbolType, loadOptions, out FamilySymbol symb); symbol = symb; } catch { //If it could not be loaded, let the user know it needs added to the family for the script to work MessageBox.Show(String.Format("The family type {0} could not be found in {1}. Please add it for this tool to work.", Properties.Settings.Default.RevitRoomTagSymbolType, Properties.Settings.Default.RevitRoomTagSymbol)); } } catch { //If the family itself could not be loaded, let the user know where the family was expected to be found. MessageBox.Show(String.Format("The {0} family could not be found at {1}. Please place the {0} family in the {1} folder for this tool to work.", Path.GetFileNameWithoutExtension(Properties.Settings.Default.RevitRoomTagSymbol), Path.GetDirectoryName(Properties.Settings.Default.RevitRoomTagSymbol))); } try { //Verify there are rooms to tag and the family symbol to use is not null if (previousRoomsToTag.Count > 0 && symbol != null) { //Cycle through the demoed rooms foreach (Room demoRoom in previousRoomsToTag) { //Get the location point of the demo room as a point LocationPoint roomLocationPoint = demoRoom.Location as LocationPoint; //Make a new symbol at the locatoin FamilyInstance newSymbol = doc.Create.NewFamilyInstance(roomLocationPoint.Point, symbol, activeView); //Update the parameter values for room Name and Number in the symbol newSymbol.GetParameters("Name").First().Set(demoRoom.get_Parameter(BuiltInParameter.ROOM_NAME).AsString()); newSymbol.GetParameters("Number").First().Set(demoRoom.get_Parameter(BuiltInParameter.ROOM_NUMBER).AsString()); } } t.Commit(); } catch (Exception f) { //Well, crap, the symbol didn't place in the view MessageBox.Show(f.ToString(), "Placement Error"); t.RollBack(); } } else { //If the previous phase was null, then the current phase of the view is the first phase, so let the user know MessageBox.Show("The currently viewed phase is the earliest phase in the project. Please verify you are viewing a new construction phase, but showing previous and demoed elements."); } } }