/
test_uralcp
/
columns_test
Обзор
Документация
Войти
/
test_uralcp
/
columns_test
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
master
ColumnDraft/DrawColumnDrafts.cs
961 строка
53 KB
aburavov
commit 1
28 ноя 2024, 15:20
28 ноя 2024, 15:20
8e3b255
Код
Авторство
О чём код?
using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.ExtensibleStorage; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using STP.ColumnDraft; using System; using System.Resources; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using System.IO; using System.Diagnostics; namespace ColumnDraft { [Transaction(TransactionMode.Manual)] public sealed partial class DrawColumnDrafts : IExternalCommand { public ElementType viewportNameType; //Функция для определения положения вутов public List<string> DetermineVutSides(FamilyInstance column) { // Получаем геометрию колонны GeometryElement geometry = column.get_Geometry(new Options()); if (geometry == null) return new List<string> { "Geometry not found" }; // Получаем точку основания колонны для дальнейших вычислений LocationPoint columnLocation = column.Location as LocationPoint; XYZ columnBasePoint = columnLocation.Point; // Переменные для хранения ширины основания колонны по X и Y double baseMinX = double.MaxValue; double baseMaxX = double.MinValue; double baseMinY = double.MaxValue; double baseMaxY = double.MinValue; // Список сторон, на которых находятся вуты HashSet<string> vutSides = new HashSet<string>(); // Ищем нижнюю грань (основание) и определяем габариты колонны по осям X и Y foreach (GeometryObject geomObj in geometry) { if (geomObj is Solid solid && solid.Volume > 0) { foreach (Face face in solid.Faces) { if (IsBottomFace(face)) // Проверяем, является ли грань основанием { Mesh mesh = face.Triangulate(); foreach (XYZ vertex in mesh.Vertices) { baseMinX = Math.Min(baseMinX, vertex.X); baseMaxX = Math.Max(baseMaxX, vertex.X); baseMinY = Math.Min(baseMinY, vertex.Y); baseMaxY = Math.Max(baseMaxY, vertex.Y); } break; // Основание найдено, можно завершить поиск } } } } // Проверяем, что габариты основания были корректно вычислены if (baseMinX == double.MaxValue || baseMaxX == double.MinValue || baseMinY == double.MaxValue || baseMaxY == double.MinValue) { return new List<string> { "Base dimensions not found" }; } // Теперь ищем грани, которые выходят за габариты основания и определяют вуты foreach (GeometryObject geomObj in geometry) { if (geomObj is Solid solid && solid.Volume > 0) { foreach (Face face in solid.Faces) { Mesh mesh = face.Triangulate(); foreach (XYZ vertex in mesh.Vertices) { // Проверяем, выходит ли вершина за габариты основания if (vertex.X > baseMaxX + 0.01) vutSides.Add("Right"); if (vertex.X < baseMinX - 0.01) vutSides.Add("Left"); if (vertex.Y > baseMaxY + 0.01) vutSides.Add("Front"); if (vertex.Y < baseMinY - 0.01) vutSides.Add("Back"); } } } } return vutSides.ToList(); } private bool IsBottomFace(Face face) { // Проверяем, что это PlanarFace if (face is PlanarFace planarFace) { // Получаем нормаль грани XYZ normal = planarFace.FaceNormal; // Проверяем, что нормаль направлена вниз (Z < 0) if (normal.Z < 0) { return true; // Это нижняя грань } } // Если это не PlanarFace или нормаль не направлена вниз, возвращаем false return false; } private (double minWidthX, double minWidthY, double maxWidthX, double maxWidthY) CalculateBaseWidths(IList<Face> faces) { double minWidthX = double.MaxValue; double minWidthY = double.MaxValue; double maxWidthX = 0; double maxWidthY = 0; PlanarFace bottomFace = null; // Итерируемся по всем граням Solid foreach (Face face in faces) { if (IsBottomFace(face)) { bottomFace = face as PlanarFace; if (bottomFace != null) { // Получаем BoundingBox плоскости BoundingBoxUV bb = bottomFace.GetBoundingBox(); if (bb != null) { // Вычисляем ширину по оси X и по оси Y double widthX = bb.Max.U - bb.Min.U; double widthY = bb.Max.V - bb.Min.V; double widthXUnit = UnitUtils.ConvertFromInternalUnits(widthX, UnitTypeId.Millimeters); Console.WriteLine(widthXUnit); double widthYUnit = UnitUtils.ConvertFromInternalUnits(widthY, UnitTypeId.Millimeters); Console.WriteLine(widthYUnit); // Находим минимальные ширины по каждой оси minWidthX = Math.Min(minWidthX, widthX); minWidthY = Math.Min(minWidthY, widthY); // Находим максимальные ширины по каждой оси maxWidthX = Math.Max(maxWidthX, widthX); maxWidthY = Math.Max(maxWidthY, widthY); } } } } // Если ни одна нижняя грань не найдена, возвращаем 0 по обеим осям if (minWidthX == double.MaxValue || minWidthY == double.MaxValue || maxWidthX == 0 || maxWidthY == 0) { return (0, 0, 0, 0); } return (minWidthX, minWidthY, maxWidthX, maxWidthY); } private void ExtractCurves(GeometryElement geomElement, List<XYZ> points) { foreach (GeometryObject geomObj in geomElement) { if (geomObj is Curve curve) { points.Add(curve.GetEndPoint(0)); points.Add(curve.GetEndPoint(1)); } else if (geomObj is GeometryElement childGeom) { ExtractCurves(childGeom, points); // рекурсивный вызов для вложенных элементов } } } Result IExternalCommand.Execute(Autodesk.Revit.UI.ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; Reference reference = uidoc.Selection.PickObject(ObjectType.Element); Element element = uidoc.Document.GetElement(reference); SizeData.Scale = 50; // Получение нужного типа видового экрана FilteredElementCollector vpCollector = new FilteredElementCollector(doc); List<ElementType> viewportTypes = vpCollector .OfClass(typeof(ElementType)) .OfType<ElementType>() .ToList(); viewportNameType = viewportTypes.Where(vp => vp.FamilyName == "Видовой экран" && vp.Name == "Имя вида").First(); ColumnData column = new ColumnData(); column.column = element; column.name = element.Name; if (element.get_Parameter(BuiltInParameter.ALL_MODEL_MARK).AsString().Contains('а')) { throw new Exception("Неверная марка"); } else { column.mark = element.get_Parameter(BuiltInParameter.ALL_MODEL_MARK).AsString(); } column.mark = element.get_Parameter(BuiltInParameter.ALL_MODEL_MARK).AsString().Replace('а', '\0'); string username = doc.Application.Username; //Получение пользовательской формы листа string SheetFormat = "А1А"; string TitleBlockName = "ОН_Форма 3_Пользовательская"; //Штамп FilteredElementCollector TypeCollector = new FilteredElementCollector(doc); ElementCategoryFilter tbCatFilter = new ElementCategoryFilter(BuiltInCategory.OST_TitleBlocks); List<Element> titleBlocks = TypeCollector.WherePasses(tbCatFilter).WhereElementIsElementType().ToElements().ToList(); Element TitleBlockType = titleBlocks.FirstOrDefault(t => t.Name == SheetFormat && (t as ElementType).FamilyName == TitleBlockName); //Ведомость деталей FilteredElementCollector collectorViewSchedule = new FilteredElementCollector(doc); ElementClassFilter catfilterViewSchedule = new ElementClassFilter(typeof(ViewSchedule)); List<Element> schedules = collectorViewSchedule.WherePasses(catfilterViewSchedule).WhereElementIsNotElementType().ToElements().ToList(); Element vd = schedules.FirstOrDefault(s => s.Name == "С_ - _ - Ведомость деталей"); //ВРС FilteredElementCollector collectorSteelViewSchedule = new FilteredElementCollector(doc); ElementClassFilter catfilterSteelViewSchedule = new ElementClassFilter(typeof(ViewSchedule)); List<Element> steelSchedules = collectorSteelViewSchedule.WherePasses(catfilterSteelViewSchedule).WhereElementIsNotElementType().ToElements().ToList(); Element vrs = steelSchedules.FirstOrDefault(s => s.Name == "С_ - _ - ВРС"); //Сборочные единицы FilteredElementCollector collectorAssemblyUnitsViewSchedule = new FilteredElementCollector(doc); ElementClassFilter catfilterAssemblyUnitsViewSchedule = new ElementClassFilter(typeof(ViewSchedule)); List<Element> assemblyUnitsSchedules = collectorAssemblyUnitsViewSchedule.WherePasses(catfilterAssemblyUnitsViewSchedule).WhereElementIsNotElementType().ToElements().ToList(); Element assemblyUnits = assemblyUnitsSchedules.FirstOrDefault(s => s.Name == "С_ - _ - Закладные"); //Арматура FilteredElementCollector collectorRebarViewSchedule = new FilteredElementCollector(doc); ElementClassFilter catfilterRebarViewSchedule = new ElementClassFilter(typeof(ViewSchedule)); List<Element> rebarSchedules = collectorRebarViewSchedule.WherePasses(catfilterRebarViewSchedule).WhereElementIsNotElementType().ToElements().ToList(); Element rebar = rebarSchedules.FirstOrDefault(s => s.Name == "С_ - _ - Арматура"); //Материалы FilteredElementCollector collectorMaterialViewSchedule = new FilteredElementCollector(doc); ElementClassFilter catfilterMaterialViewSchedule = new ElementClassFilter(typeof(ViewSchedule)); List<Element> materialSchedules = collectorMaterialViewSchedule.WherePasses(catfilterMaterialViewSchedule).WhereElementIsNotElementType().ToElements().ToList(); Element material = materialSchedules.FirstOrDefault(s => s.Name == "С_ - _ - Материалы"); //Подготовка данных для текстового примечания FilteredElementCollector textTypeCollector = new FilteredElementCollector(doc); List<Element> textTypes = textTypeCollector.OfClass(typeof(TextNoteType)).ToList(); TextNoteType textNoteType = textTypes.FirstOrDefault(fs => fs.Name == "ГОСТ 2.304_2.5_Без фона") as TextNoteType; //Получение таблиц FilteredElementCollector fec = new FilteredElementCollector(doc); List<string> schedulesNames = fec.OfClass(typeof(ViewSchedule)).Select(e => e.Name).ToList(); using (Transaction TR = new Transaction(doc, "Создание пустого листа")) { TR.Start(); #region Создание листа со штампом ViewSheet newSheet = ViewSheet.Create(doc, TitleBlockType.Id); newSheet.Name = "Колонна монолитная " + column.mark; double startingPointX = -SizeData.SheetA1.Height + SizeData.Stamp.LeftBorder + SizeData.Stamp.StampBorderWidth; double startingPointY = SizeData.SheetA1.Width; XYZ startingPoint = new XYZ(startingPointX, startingPointY, 0); #endregion # region Изменение формата даты Parameter date = newSheet.get_Parameter(BuiltInParameter.SHEET_ISSUE_DATE); string strDate = date.AsString(); strDate = strDate.Substring(0, 2) + "." + strDate.Substring(6, 2); date.Set(strDate); #endregion #region Добавление фамилии редактируещего Parameter editorSurname = newSheet.get_Parameter(new Guid("1c5b8392-2703-425d-ad99-d13798b6fbb6")); editorSurname.Set(username); #endregion #region Создание текстового примечания double noteOffsetY = UnitUtils.ConvertToInternalUnits(5, UnitTypeId.Millimeters) + UnitUtils.ConvertToInternalUnits(55, UnitTypeId.Millimeters) + UnitUtils.ConvertToInternalUnits(50, UnitTypeId.Millimeters) * 2; double noteOffsetX = -UnitUtils.ConvertToInternalUnits(5, UnitTypeId.Millimeters) - UnitUtils.ConvertToInternalUnits(185, UnitTypeId.Millimeters); string text = "1.\tОбщие указания представлены на листе 1. \r\n\r\n2.\tСпецификация, ведомость расхода стали и ведомость деталей представлены для одной колонны.\r\n\r\n3.\tСхема расположения колонн представлена на листе 2.\r\n\r\n4.\tНа чертежах указаны расстояния от оси стержней до грани бетона. \r\n\r\n5.\tВсе пересечения продольных и поперечных стержней, кроме оговоренных, вязаные. Вязку стержней выполнять в соответствии с требованиями ГОСТ 10922-2012.\r\n\r\n6.\tСоединения арматурных стержней позиций 1, 2 производить с использованием сварки согласно ГОСТ 14098-2014 или механических соединений согласно ГОСТ 34278-2019. Общее количество стыков - 20 шт."; XYZ textNotePoint = new XYZ( noteOffsetX, noteOffsetY, 0 ); TextNoteOptions textNoteOptions = new TextNoteOptions(textNoteType.Id); TextNote textNote = TextNote.Create( doc, newSheet.Id, textNotePoint, UnitUtils.ConvertToInternalUnits(185, UnitTypeId.Millimeters), text, textNoteOptions); #endregion TR.Commit(); #region Добавление ведомости расхода стали Transaction TRVRS = new Transaction(doc, "Размещение ВРС"); new VRSCreator().CreateVRS(doc, newSheet, column, vrs, TRVRS); #endregion TR.Start(); #region Добавление ведомости деталей ViewSchedule vdVS = vd as ViewSchedule; ElementId scheduleId = vdVS.Duplicate(ViewDuplicateOption.Duplicate); ViewSchedule detailSchedule = doc.GetElement(scheduleId) as ViewSchedule; ScheduleFieldId filterField = null; int n = 0; string basisName = String.Format("{0} - Ведомость деталей", column.mark); while (schedulesNames.Contains(basisName)) { if (n == 0) { basisName = String.Format("{0} - Ведомость деталей(дубл.)", column.mark); } else { basisName = String.Format("{0} - Ведомость деталей(дубл.{1})", column.mark, n); } if (n > 10) break; n++; } detailSchedule.Name = basisName; for (int i = 0; i < detailSchedule.Definition.GetFieldCount(); i++) { if (detailSchedule.Definition.GetField(i).GetName() == "Р.З._Метка основы") { filterField = detailSchedule.Definition.GetFieldId(i); } } ScheduleFilter filter = new ScheduleFilter(filterField, ScheduleFilterType.Equal, column.mark); //Поиск фильтра int filterIndex = -1; for (int i = 0; i < detailSchedule.Definition.GetFilterCount(); i++) { if (detailSchedule.Definition.GetFilter(i).FieldId.IntegerValue == filterField.IntegerValue) { filterIndex = i; } } if (filterIndex >= 0) { detailSchedule.Definition.SetFilter(filterIndex, filter); } else detailSchedule.Definition.AddFilter(filter); ScheduleSheetInstance DetailScheduleInstance = ScheduleSheetInstance.Create(doc, newSheet.Id, detailSchedule.Id, XYZ.Zero); BoundingBoxXYZ detailBB = DetailScheduleInstance.get_BoundingBox(newSheet); double detailWidth = detailBB.Max.X - detailBB.Min.X; XYZ vdPoint = new XYZ( -(SizeData.Stamp.StampWidth + SizeData.Margins.HorizontalMargin + detailWidth), (SizeData.SheetA1.Height - SizeData.Stamp.StampBorderWidth - (SizeData.VRSHeight) - SizeData.Margins.VerticalMargin), 0 ); DetailScheduleInstance.Point = vdPoint; #endregion # region Добавление Спецификации CreateSpecification createSpecification = new CreateSpecification(); createSpecification.CreateSpecificationSchedule(doc, newSheet, column, assemblyUnits as ViewSchedule, rebar as ViewSchedule, material as ViewSchedule, schedulesNames, textNoteType); #endregion //тестовый срез //Получение готового разреза Вид FilteredElementCollector collectorViewSlice = new FilteredElementCollector(doc); ElementCategoryFilter catfilterViewSlice = new ElementCategoryFilter(BuiltInCategory.OST_Views); List<Element> ViewSlices = collectorViewSlice.WherePasses(catfilterViewSlice).WhereElementIsNotElementType().ToElements().ToList(); ViewSection viewSlice = ViewSlices.FirstOrDefault(s => s.Name == column.mark + " - Вид копия 1") as ViewSection; //Получение шаблона вида Схема-Разрез FilteredElementCollector collectorViewTemplates = new FilteredElementCollector(doc); ElementClassFilter sectViewFilter = new ElementClassFilter(typeof(ViewSection)); List<ViewSection> sections = (from v in collectorViewTemplates.WherePasses(sectViewFilter).WhereElementIsNotElementType().ToElements() select v as ViewSection).ToList(); ViewSection templateSlice = sections.Where(s => s.Name == "К - Схема - Разрез").FirstOrDefault(); Console.WriteLine(templateSlice); //Применение шаблона вида Схема-Разрез viewSlice.ViewTemplateId = templateSlice.Id; Viewport firstSliceViewport = Viewport.Create(doc, newSheet.Id, viewSlice.Id, XYZ.Zero); BoundingBoxXYZ fsvpBB = firstSliceViewport.get_BoundingBox(newSheet); double fsvpWidth = fsvpBB.Max.X - fsvpBB.Min.X; double fsvpHeight = fsvpBB.Max.Y - fsvpBB.Min.Y; XYZ fsvpPoint = new XYZ( -SizeData.SheetA1.Width + SizeData.Stamp.LeftBorder + fsvpWidth / 2, SizeData.SheetA1.Height - SizeData.Stamp.StampBorderWidth - fsvpHeight / 2, 0 ); firstSliceViewport.SetBoxCenter(fsvpPoint); #region Линии разрыва //Поиск колонны FilteredElementCollector columnCol = new FilteredElementCollector(doc, viewSlice.Id); ElementCategoryFilter columnFilter = new ElementCategoryFilter(BuiltInCategory.OST_StructuralColumns); List<Element> columns = columnCol.WherePasses(columnFilter).WhereElementIsNotElementType().ToElements().ToList(); Element columnEl = columns[0]; BoundingBoxXYZ columnBB = columnEl.get_BoundingBox(newSheet); double minYColumn = columnBB.Min.Y; double maxYColumn = columnBB.Max.Y; double minXColumn = columnBB.Min.X; double maxXColumn = columnBB.Max.X; double minZColumn = columnBB.Min.Z; double maxZColumn = columnBB.Max.Z; double widthX = maxXColumn - minXColumn; double widthY = maxYColumn - minYColumn; //"Трассировочный луч" от левого до правого разрыва, но выше XYZ startPoint = new XYZ( UnitUtils.ConvertToInternalUnits(10 , UnitTypeId.Millimeters), minYColumn - UnitUtils.ConvertToInternalUnits(10, UnitTypeId.Millimeters), minZColumn + UnitUtils.ConvertToInternalUnits(10, UnitTypeId.Millimeters) ); XYZ endPoint = new XYZ( UnitUtils.ConvertToInternalUnits(10, UnitTypeId.Millimeters), columnBB.Max.Y + UnitUtils.ConvertToInternalUnits(10, UnitTypeId.Millimeters), minZColumn + (UnitUtils.ConvertToInternalUnits(10, UnitTypeId.Millimeters)) ); Line trace = Line.CreateBound(startPoint, endPoint); GeometryElement geomElement = columnEl.get_Geometry(new Options()); IList<Face> columnFaces = new List<Face>(); foreach (GeometryObject geomObj in geomElement) { if (geomObj is Solid solid) { foreach (Face face in solid.Faces) { if (IsBottomFace(face)) { columnFaces.Add(face); } } } } (double columnBottomWidthX, double columnBottomWidthY, double columnTopWidthX, double columnTopWidthY) = CalculateBaseWidths(columnFaces); Console.WriteLine(columnBottomWidthX); Console.WriteLine(columnBottomWidthY); //Поиск фундамента FilteredElementCollector foundationCol = new FilteredElementCollector(doc, viewSlice.Id); ElementCategoryFilter foundationFilter = new ElementCategoryFilter(BuiltInCategory.OST_StructuralFoundation); List<Element> foundations = foundationCol.WherePasses(foundationFilter).WhereElementIsNotElementType().ToElements().ToList(); Element foundation = foundations[0]; BoundingBoxXYZ foundationBB = foundation.get_BoundingBox(newSheet); Console.WriteLine(foundationBB); //Поиск линии разрыва FilteredElementCollector fsCollector = new FilteredElementCollector(doc); List<Element> FamilySymbols = fsCollector.OfClass(typeof(FamilySymbol)).ToElements().ToList(); FamilySymbol gapElement = FamilySymbols.FirstOrDefault(el => el.Name == "ОбластьМаскировки") as FamilySymbol; Console.WriteLine(gapElement); double xCoordBottomGap = 0; double yCoordBottomGap = 0; double yCoordLeftGap = 0; double yCoordRightGap = 0; double yCoordLeftTopGap = 0; double yCoordRightTopGap = 0; double curWidth; if (viewSlice.ViewDirection.X > 0) { curWidth = columnBottomWidthX; } else { curWidth = columnTopWidthY; } List<string> wootSides = DetermineVutSides(column.column as FamilyInstance); //Нижняя линия разрыва foreach (string woot in wootSides) { if (woot == "Right") { xCoordBottomGap = minXColumn; } if (woot == "Left") { xCoordBottomGap = maxXColumn; } if (woot == "Front") { yCoordBottomGap = minYColumn + curWidth / 2; yCoordLeftTopGap = minYColumn - UnitUtils.ConvertToInternalUnits(3 * SizeData.Scale, UnitTypeId.Millimeters); yCoordRightTopGap = maxYColumn + UnitUtils.ConvertToInternalUnits(3 * SizeData.Scale, UnitTypeId.Millimeters); yCoordLeftGap = minYColumn - UnitUtils.ConvertToInternalUnits(10 * SizeData.Scale, UnitTypeId.Millimeters); yCoordRightGap = minYColumn + curWidth + UnitUtils.ConvertToInternalUnits(10 * SizeData.Scale, UnitTypeId.Millimeters); } if (woot == "Back") { yCoordBottomGap = maxYColumn - curWidth / 2; yCoordLeftTopGap = minYColumn - UnitUtils.ConvertToInternalUnits(3 * SizeData.Scale, UnitTypeId.Millimeters); yCoordRightTopGap = maxYColumn + UnitUtils.ConvertToInternalUnits(3 * SizeData.Scale, UnitTypeId.Millimeters); yCoordRightGap = maxYColumn + UnitUtils.ConvertToInternalUnits(10 * SizeData.Scale, UnitTypeId.Millimeters); yCoordLeftGap = maxYColumn - curWidth - UnitUtils.ConvertToInternalUnits(10 * SizeData.Scale, UnitTypeId.Millimeters); } } XYZ gapBottomLoc = new XYZ( 0, yCoordBottomGap, minZColumn - UnitUtils.ConvertToInternalUnits(16*SizeData.Scale, UnitTypeId.Millimeters) ); FamilyInstance gapBottomLine = doc.Create.NewFamilyInstance(gapBottomLoc, gapElement, viewSlice); gapBottomLine.Location.Rotate(Line.CreateUnbound(gapBottomLoc, viewSlice.ViewDirection) , Math.PI); gapBottomLine.LookupParameter("Длина").Set(curWidth + 20 * UnitUtils.ConvertToInternalUnits(SizeData.Scale, UnitTypeId.Millimeters)); gapBottomLine.LookupParameter("Глубина маскирования").Set(UnitUtils.ConvertToInternalUnits(1000, UnitTypeId.Millimeters)); //Левая нижняя линия разрыва XYZ gapLeftLoc = new XYZ( 0, yCoordLeftGap, minZColumn - UnitUtils.ConvertToInternalUnits(8 * SizeData.Scale, UnitTypeId.Millimeters) ); double leftGapAngle; double rightGapAngle; if (viewSlice.ViewDirection.X > 0) { leftGapAngle = Math.PI / 2; rightGapAngle = -Math.PI / 2; } else { leftGapAngle = -Math.PI / 2; rightGapAngle = Math.PI / 2; } FamilyInstance gapLeftLine = doc.Create.NewFamilyInstance(gapLeftLoc, gapElement, viewSlice); gapLeftLine.Location.Rotate(Line.CreateUnbound(gapLeftLoc, viewSlice.ViewDirection), leftGapAngle); gapLeftLine.LookupParameter("Длина").Set(16 * UnitUtils.ConvertToInternalUnits(SizeData.Scale, UnitTypeId.Millimeters)); gapLeftLine.LookupParameter("Глубина маскирования").Set(UnitUtils.ConvertToInternalUnits(1000, UnitTypeId.Millimeters)); //Правая нижняя линия разрыва XYZ gapRightLoc = new XYZ( 0, yCoordRightGap, minZColumn - UnitUtils.ConvertToInternalUnits(8 * SizeData.Scale, UnitTypeId.Millimeters) ); FamilyInstance gapRightLine = doc.Create.NewFamilyInstance(gapRightLoc, gapElement, viewSlice); gapRightLine.Location.Rotate(Line.CreateUnbound(gapRightLoc, viewSlice.ViewDirection), rightGapAngle); gapRightLine.LookupParameter("Длина").Set(16 * UnitUtils.ConvertToInternalUnits(SizeData.Scale, UnitTypeId.Millimeters)); gapRightLine.LookupParameter("Глубина маскирования").Set(UnitUtils.ConvertToInternalUnits(1000, UnitTypeId.Millimeters)); //Левая верхняя линия разрыва XYZ gapLeftTopLoc = new XYZ( 0, minYColumn - 3 * UnitUtils.ConvertToInternalUnits(SizeData.Scale, UnitTypeId.Millimeters), maxZColumn + 20 * UnitUtils.ConvertToInternalUnits(SizeData.Scale, UnitTypeId.Millimeters) ); FamilyInstance gapLeftTopLine = doc.Create.NewFamilyInstance(gapLeftTopLoc, gapElement, viewSlice); gapLeftTopLine.Location.Rotate(Line.CreateUnbound(gapLeftTopLoc, viewSlice.ViewDirection), leftGapAngle); gapLeftTopLine.LookupParameter("Длина").Set(UnitUtils.ConvertToInternalUnits(1800, UnitTypeId.Millimeters)); gapLeftTopLine.LookupParameter("Глубина маскирования").Set(UnitUtils.ConvertToInternalUnits(5000, UnitTypeId.Millimeters)); //Правая верхняя линия разрыва XYZ gapRightTopLoc = new XYZ( 0, maxYColumn + 3 * UnitUtils.ConvertToInternalUnits(SizeData.Scale, UnitTypeId.Millimeters), maxZColumn + 20 * UnitUtils.ConvertToInternalUnits(SizeData.Scale, UnitTypeId.Millimeters) ); Console.WriteLine(viewSlice.ViewDirection); FamilyInstance gapRightTopLine = doc.Create.NewFamilyInstance(gapRightTopLoc, gapElement, viewSlice); gapRightTopLine.Location.Rotate(Line.CreateUnbound(gapRightTopLoc, viewSlice.ViewDirection), rightGapAngle); gapRightTopLine.LookupParameter("Длина").Set(UnitUtils.ConvertToInternalUnits(1800, UnitTypeId.Millimeters)); gapRightTopLine.LookupParameter("Глубина маскирования").Set(UnitUtils.ConvertToInternalUnits(5000, UnitTypeId.Millimeters)); #endregion //Получение готового разреза 1-1 ViewSection viewSlice11 = ViewSlices.FirstOrDefault(s => s.Name == column.mark + " - 1-1 копия 1") as ViewSection; //Получение шаблона вида Схема-Разрез ViewSection templateSlice11 = sections.Where(s => s.Name == "К - Разрез - Армирование").FirstOrDefault(); //Применение шаблона вида Схема-Разрез viewSlice11.ViewTemplateId = templateSlice11.Id; Viewport firstSliceViewport11 = Viewport.Create(doc, newSheet.Id, viewSlice11.Id, XYZ.Zero); BoundingBoxXYZ fsvpBB11 = firstSliceViewport11.get_BoundingBox(newSheet); double fsvpWidth11 = fsvpBB11.Max.X - fsvpBB11.Min.X; double fsvpHeight11 = fsvpBB11.Max.Y - fsvpBB11.Min.Y; XYZ fsvpPoint11 = new XYZ( fsvpPoint.X + SizeData.Margins.VerticalMargin + fsvpWidth11, SizeData.SheetA1.Height - SizeData.Stamp.StampBorderWidth - fsvpHeight11 / 2, 0 ); firstSliceViewport11.SetBoxCenter(fsvpPoint11); #region Марки арматуры //Сбор марок //FilteredElementCollector rebarTagsCol = new FilteredElementCollector(doc); //ElementCategoryFilter rebarTagsFilter = new ElementCategoryFilter(BuiltInCategory.OST_RebarTags); //List<Element> rebarTags = rebarTagsCol.WherePasses(rebarTagsFilter).WhereElementIsNotElementType().ToElements().ToList(); //Element markaZasechka = rebarTags.Find(tag => tag.Name == "Mарка_Засечка"); FilteredElementCollector fsymbCollector = new FilteredElementCollector(doc); List<Element> fSymbs = fsymbCollector.OfClass(typeof(FamilySymbol)).ToElements().ToList(); FamilySymbol rebarTagSymbolTick = fSymbs[0] as FamilySymbol; FamilySymbol rebarTagSymbolStep = fSymbs[0] as FamilySymbol; // пока вперемешку новые и старые названия семейств foreach (Element fSymbol in fSymbs) { if (fSymbol.Name == "Mарка_Засечка" && (fSymbol as FamilySymbol).FamilyName == "КР_Марка_Несущая арматура") rebarTagSymbolTick = fSymbol as FamilySymbol; if (fSymbol.Name == "Марка + Кол-во / Шаг50_Засечка" && (fSymbol as FamilySymbol).FamilyName == "КР_Марка_Несущая арматура") rebarTagSymbolStep = fSymbol as FamilySymbol; } //Сбор арматуры FilteredElementCollector rebarCol = new FilteredElementCollector(doc, viewSlice11.Id); ElementCategoryFilter rebarFilter = new ElementCategoryFilter(BuiltInCategory.OST_Rebar); List<Element> rebars = rebarCol.WherePasses(rebarFilter).WhereElementIsNotElementType().ToElements().ToList(); Console.WriteLine(rebars); List<string> rebarBMarks = new List<string>(); double rebarYWithMinY = 99999; double rebarYWithMaxY = 0; Rebar minBRebar = rebars[0] as Rebar; Rebar maxBRebar = rebars[0] as Rebar; FamilySymbol detailSymbol = null; FilteredElementCollector collector = new FilteredElementCollector(doc) .OfClass(typeof(FamilySymbol)) .OfCategory(BuiltInCategory.OST_DetailComponents) .WhereElementIsElementType(); Rebar rebarMark1MaxY = null; Rebar rebarMark2MaxY = null; foreach (FamilySymbol fs in collector) { Console.WriteLine(fs); if (fs.Name.Equals("ОбластьМаскировки")) // Укажите имя вашего семейства деталей { detailSymbol = fs; break; } } foreach (Element rebarlEl in rebars) { Rebar curRebar = rebarlEl as Rebar; BoundingBoxXYZ bbCurRebar = curRebar.get_BoundingBox(viewSlice11); if (curRebar.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() == "Г2") { IndependentTag tagG2 = IndependentTag.Create(doc, rebarTagSymbolTick.Id, viewSlice11.Id, new Reference(curRebar), true, TagOrientation.Horizontal, XYZ.Zero); tagG2.TagHeadPosition = new XYZ(0, 25, bbCurRebar.Max.Z - 1); } if (curRebar.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() == "Г1") { IndependentTag tagG1 = IndependentTag.Create(doc, rebarTagSymbolTick.Id, viewSlice11.Id, new Reference(curRebar), true, TagOrientation.Horizontal, XYZ.Zero); tagG1.TagHeadPosition = new XYZ(0, 25, bbCurRebar.Max.Z); } if (curRebar.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() == "Х2") { IndependentTag tagX2 = IndependentTag.Create(doc, rebarTagSymbolTick.Id, viewSlice11.Id, new Reference(curRebar), true, TagOrientation.Horizontal, new XYZ(0, bbCurRebar.Min.Y + 0.5, bbCurRebar.Min.Z)); tagX2.TagHeadPosition = new XYZ(0, bbCurRebar.Min.Y - 1.5, bbCurRebar.Min.Z - 1); tagX2.LeaderElbow = new XYZ(0, bbCurRebar.Min.Y - 0.5, bbCurRebar.Min.Z - 1); } if (curRebar.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() == "Х3") { IndependentTag tagX3 = IndependentTag.Create(doc, rebarTagSymbolStep.Id, viewSlice11.Id, new Reference(curRebar), true, TagOrientation.Horizontal, new XYZ(0, bbCurRebar.Min.Y + 0.5, bbCurRebar.Max.Z)); tagX3.TagHeadPosition = new XYZ(0, bbCurRebar.Min.Y - 3.5, bbCurRebar.Max.Z - 1.5); tagX3.LeaderElbow = new XYZ(0, bbCurRebar.Min.Y + 0.5, bbCurRebar.Max.Z - 1.5); IndependentTag tagX3double = IndependentTag.Create(doc, rebarTagSymbolStep.Id, viewSlice11.Id, new Reference(curRebar), true, TagOrientation.Horizontal, XYZ.Zero); //tagX3double.get_Parameter(BuiltInParameter.TAG_LEADER_TYPE).SetValueString("Со свободным концом"); tagX3double.TagHeadPosition = new XYZ(0, bbCurRebar.Min.Y - 3.5, bbCurRebar.Max.Z - 1.5); tagX3double.LeaderElbow = new XYZ(0, bbCurRebar.Min.Y + 0.5, bbCurRebar.Max.Z - 1.5); tagX3double.LeaderEndCondition = LeaderEndCondition.Free; tagX3double.LeaderEnd = new XYZ(0, bbCurRebar.Min.Y + 0.5, bbCurRebar.Max.Z - 3); } if (curRebar.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() == "2") { IndependentTag tag2 = IndependentTag.Create(doc, rebarTagSymbolTick.Id, viewSlice11.Id, new Reference(curRebar), true, TagOrientation.Horizontal, XYZ.Zero); tag2.TagHeadPosition = new XYZ(0, 26, bbCurRebar.Min.Z + 1.5); if (bbCurRebar.Min.Z > gapBottomLoc.Z) { double curRebarMiddleY = (bbCurRebar.Min.Y + bbCurRebar.Max.Y) / 2; XYZ p1 = new XYZ(0, curRebarMiddleY - 0.1, bbCurRebar.Min.Z + 0.25); XYZ p2 = new XYZ(0, curRebarMiddleY + 0.1, bbCurRebar.Min.Z + 0.25); XYZ p3 = new XYZ(0, curRebarMiddleY + 0.1, bbCurRebar.Min.Z - 0.25); XYZ p4 = new XYZ(0, curRebarMiddleY - 0.1, bbCurRebar.Min.Z - 0.25); List<Curve> curves = new List<Curve> { Line.CreateBound(p1, p2), Line.CreateBound(p2, p3), Line.CreateBound(p3, p4), Line.CreateBound(p4, p1) }; CurveLoop curveLoop = CurveLoop.Create(curves); FilledRegionType filledRegionType = new FilteredElementCollector(doc) .OfClass(typeof(FilledRegionType)) .FirstOrDefault() as FilledRegionType; FilledRegion filledRegion = FilledRegion.Create(doc, filledRegionType.Id, viewSlice11.Id, new List<CurveLoop> { curveLoop }); if (rebarMark2MaxY == null) { rebarMark2MaxY = curRebar; } else if (rebarMark2MaxY.get_BoundingBox(viewSlice11).Max.Y < bbCurRebar.Max.Y) { rebarMark2MaxY = curRebar; } } } if (curRebar.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() == "1") { IndependentTag tag1 = IndependentTag.Create(doc, rebarTagSymbolTick.Id, viewSlice11.Id, new Reference(curRebar), true, TagOrientation.Horizontal, XYZ.Zero); tag1.TagHeadPosition = new XYZ(0, 26, bbCurRebar.Min.Z + 3.5); if (bbCurRebar.Min.Z > gapBottomLoc.Z) { double curRebarMiddleY = (bbCurRebar.Min.Y + bbCurRebar.Max.Y) / 2; XYZ p1 = new XYZ(0, curRebarMiddleY - 0.1, bbCurRebar.Min.Z + 0.25); XYZ p2 = new XYZ(0, curRebarMiddleY + 0.1, bbCurRebar.Min.Z + 0.25); XYZ p3 = new XYZ(0, curRebarMiddleY + 0.1, bbCurRebar.Min.Z - 0.25); XYZ p4 = new XYZ(0, curRebarMiddleY - 0.1, bbCurRebar.Min.Z - 0.25); List<Curve> curves = new List<Curve> { Line.CreateBound(p1, p2), Line.CreateBound(p2, p3), Line.CreateBound(p3, p4), Line.CreateBound(p4, p1) }; CurveLoop curveLoop = CurveLoop.Create(curves); FilledRegionType filledRegionType = new FilteredElementCollector(doc) .OfClass(typeof(FilledRegionType)) .FirstOrDefault() as FilledRegionType; FilledRegion filledRegion = FilledRegion.Create(doc, filledRegionType.Id, viewSlice11.Id, new List<CurveLoop> { curveLoop }); if (rebarMark1MaxY == null) { rebarMark1MaxY = curRebar; } else if (rebarMark1MaxY.get_BoundingBox(viewSlice11).Max.Y < bbCurRebar.Max.Y) { rebarMark1MaxY = curRebar; } } } if (curRebar.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString().Contains('В')) { if (bbCurRebar.Min.Y < rebarYWithMinY && gapBottomLoc.Y < bbCurRebar.Min.Y) { minBRebar = curRebar; rebarYWithMinY = bbCurRebar.Min.Y; } if (bbCurRebar.Max.Y > rebarYWithMaxY && gapBottomLoc.Y > bbCurRebar.Max.Y) { maxBRebar = curRebar; rebarYWithMaxY = bbCurRebar.Max.Y; } } } #region "Размеры" // foreach (var curRebar in rebars) // { // // Получение местоположения арматуры // LocationCurve locationCurve = curRebar.Location as LocationCurve; // if (locationCurve != null) // { // // Получение начальной и конечной точки арматуры // XYZ startPointCurve = locationCurve.Curve.GetEndPoint(0); // XYZ endPointCurve = locationCurve.Curve.GetEndPoint(1); // // // Определение точки для размещения размеров (например, смещение по оси Y) // XYZ dimensionStartPoint = new XYZ(startPointCurve.X, startPointCurve.Y - 3, startPointCurve.Z); // смещение вниз // XYZ dimensionEndPoint = new XYZ(endPointCurve.X, endPointCurve.Y - 3, endPointCurve.Z); // смещение вниз // // // Получение плоскости для размеров // ReferenceArray refArray = new ReferenceArray(); // refArray.Append(new Reference(curRebar)); // // // Создание размера // Line dimensionLine = Line.CreateBound(dimensionStartPoint, dimensionEndPoint); // // Dimension dimension = doc.Create.NewDimension(viewSlice11, dimensionLine, refArray); // if (dimension != null) // { // dimension.DimensionType = doc.GetElement(dimension.DimensionType.Id) as DimensionType; // } // } // } #endregion //поиск выносок FilteredElementCollector vsymbCollector = new FilteredElementCollector(doc); List<Element> vSymbs = vsymbCollector.OfClass(typeof(FamilySymbol)).ToElements().ToList(); FamilySymbol rebarVinoskaSymbolTick = null; FamilySymbol rebarVinoskaSymbol = null; foreach (Element vSymbol in vSymbs) { if (vSymbol.Name == "Выноска_Засечка" && (vSymbol as FamilySymbol).FamilyName == "ТА_Выноска") rebarVinoskaSymbolTick = vSymbol as FamilySymbol; if (vSymbol.Name == "Выноска" && (vSymbol as FamilySymbol).FamilyName == "ТА_Выноска") rebarVinoskaSymbol = vSymbol as FamilySymbol; } //расстановка аннотаций для узлов IndependentTag tagAnnotation1 = IndependentTag.Create(doc, rebarTagSymbolTick.Id, viewSlice11.Id, new Reference(rebarMark1MaxY), true, TagOrientation.Horizontal, XYZ.Zero); tagAnnotation1.LeaderEndCondition = LeaderEndCondition.Free; tagAnnotation1.LeaderEnd = new XYZ(0, rebarMark1MaxY.get_BoundingBox(viewSlice11).Max.Y, rebarMark1MaxY.get_BoundingBox(viewSlice11).Min.Z); tagAnnotation1.LeaderElbow = new XYZ(0, gapBottomLoc.Y + 2.5, rebarMark1MaxY.get_BoundingBox(viewSlice11).Min.Z + 0.5); tagAnnotation1.TagHeadPosition = new XYZ(0, gapBottomLoc.Y + 3.5, rebarMark1MaxY.get_BoundingBox(viewSlice11).Min.Z + 0.5); FamilyInstance vinoskaAnnot1 = doc.Create.NewFamilyInstance(new XYZ(0, gapBottomLoc.Y + 3.5, rebarMark1MaxY.get_BoundingBox(viewSlice11).Min.Z + 0.5), rebarVinoskaSymbol, viewSlice11); vinoskaAnnot1.LookupParameter("Текст_верх").Set("см. п.п. 6"); vinoskaAnnot1.LookupParameter("Ширина выноски").Set(UnitUtils.ConvertToInternalUnits(12, UnitTypeId.Millimeters)); IndependentTag tagAnnotation2 = IndependentTag.Create(doc, rebarTagSymbolTick.Id, viewSlice11.Id, new Reference(rebarMark2MaxY), true, TagOrientation.Horizontal, XYZ.Zero); tagAnnotation2.LeaderEndCondition = LeaderEndCondition.Free; tagAnnotation2.LeaderEnd = new XYZ(0, rebarMark2MaxY.get_BoundingBox(viewSlice11).Max.Y, rebarMark2MaxY.get_BoundingBox(viewSlice11).Min.Z); tagAnnotation2.LeaderElbow = new XYZ(0, gapBottomLoc.Y + 2.5, rebarMark2MaxY.get_BoundingBox(viewSlice11).Min.Z + 0.5); tagAnnotation2.TagHeadPosition = new XYZ(0, gapBottomLoc.Y + 3.5, rebarMark2MaxY.get_BoundingBox(viewSlice11).Min.Z + 0.5); FamilyInstance vinoskaAnnot2 = doc.Create.NewFamilyInstance(new XYZ(0, gapBottomLoc.Y + 3.5, rebarMark2MaxY.get_BoundingBox(viewSlice11).Min.Z + 0.5), rebarVinoskaSymbol, viewSlice11); vinoskaAnnot2.LookupParameter("Текст_верх").Set("см. п.п. 6"); vinoskaAnnot2.LookupParameter("Ширина выноски").Set(UnitUtils.ConvertToInternalUnits(12, UnitTypeId.Millimeters)); BoundingBoxXYZ rebarBMinYBB = minBRebar.get_BoundingBox(viewSlice11); BoundingBoxXYZ rebarBMaxYBB = maxBRebar.get_BoundingBox(viewSlice11); IndependentTag tagB1 = IndependentTag.Create(doc, rebarTagSymbolTick.Id, viewSlice11.Id, new Reference(minBRebar), true, TagOrientation.Horizontal, XYZ.Zero); tagB1.TagHeadPosition = new XYZ(0, rebarBMinYBB.Min.Y + 2, -2); tagB1.LeaderEndCondition = LeaderEndCondition.Free; tagB1.LeaderEnd = new XYZ(0, rebarBMinYBB.Min.Y + 1.3, -2); IndependentTag tagB2 = IndependentTag.Create(doc, rebarTagSymbolTick.Id, viewSlice11.Id, new Reference(maxBRebar), true, TagOrientation.Horizontal, XYZ.Zero); tagB2.TagHeadPosition = new XYZ(0, rebarBMinYBB.Min.Y + 2, -2); tagB2.LeaderEndCondition = LeaderEndCondition.Free; tagB2.LeaderEnd = new XYZ(0, rebarBMaxYBB.Min.Y + 1.3, -2); FamilyInstance vinoska1 = doc.Create.NewFamilyInstance(new XYZ(0, rebarBMinYBB.Min.Y + 2, -2), rebarVinoskaSymbolTick, viewSlice11); vinoska1.LookupParameter("Текст_верх").Set("Выпуски"); vinoska1.LookupParameter("Текст_низ_1").Set("см. КЖ1"); vinoska1.LookupParameter("Ширина выноски").Set(UnitUtils.ConvertToInternalUnits(12, UnitTypeId.Millimeters)); //tagB2.LookupParameter("Текст_верх").Set("Выпуски"); //tagB2.LookupParameter("Текст_низ_1").Set("см. КЖ1"); #endregion TaskDialog.Show("Создание листа", "Колонна монолитная " + column.mark); TR.Commit(); } return Result.Succeeded; } } }