private IEnumerable <AdvancedWall> FindIntersectionWalls(List <AdvancedWall> sideWalls, List <AdvancedWall> allWalls) { var intersectionWalls = new List <AdvancedWall>(); foreach (var wall in allWalls) { foreach (var sideWall in sideWalls) { if (wall.IsAdjoinToByLocationCurveEnds(sideWall) && !AdvancedHelpers.HasWallInListById(sideWalls, wall)) { intersectionWalls.Add(wall); } } } return(intersectionWalls); }
/// <summary>Фильтрация face'ов по условиям</summary> private IEnumerable <AdvancedPlanarFace> FilterFaces( ExtremeWallVariant extremeWallVariant, List <AdvancedWall> sideWalls, IEnumerable <AdvancedPlanarFace> selectedFaces) { var tolerance = 0.0001; // Нужно два списка так как разные фильтрации var faces = new List <AdvancedPlanarFace>(); // Удаляю фейсы, не пересекаемые секущей плоскостью foreach (var face in selectedFaces) { if (face.MinZ <= _cutPlanZ && face.MaxZ >= _cutPlanZ) { faces.Add(face); } } // Нужно удалить фейсы, которые совпадают по направлению var returnedFaces = new List <AdvancedPlanarFace>(); bool hasFaces; do { hasFaces = faces.Any(f => f != null); for (var i = 0; i < faces.Count; i++) { var face = faces[i]; if (face != null) { returnedFaces.Add(face); for (var j = 0; j < faces.Count; j++) { if (i == j) { continue; } if (faces[j] == null) { continue; } if (extremeWallVariant == ExtremeWallVariant.Left || extremeWallVariant == ExtremeWallVariant.Right) { // same Y if (Math.Abs(face.PlanarFace.Origin.Y - faces[j].PlanarFace.Origin.Y) < tolerance) { faces[j] = null; } } else if (extremeWallVariant == ExtremeWallVariant.Top || extremeWallVariant == ExtremeWallVariant.Bottom) { // same X if (Math.Abs(face.PlanarFace.Origin.X - faces[j].PlanarFace.Origin.X) < tolerance) { faces[j] = null; } } } faces[i] = null; } } }while (hasFaces); // Удаление по глубине проецирования // Глубину проецирования беру по наибольшей толщине стен в списке var depth = AdvancedHelpers.GetMaxWallWidthFromList(sideWalls) * 2; if (extremeWallVariant == ExtremeWallVariant.Bottom) { foreach (var wall in sideWalls.Where(w => w.Orientation == ElementOrientation.Horizontal)) { for (var i = returnedFaces.Count - 1; i >= 0; i--) { var face = returnedFaces[i]; if (face.MinX > wall.GetMinX() - wall.Wall.Width && face.MinX < wall.GetMaxX() + wall.Wall.Width) { if (face.MinY > wall.GetMinY() + depth) { returnedFaces.RemoveAt(i); } } } } } if (extremeWallVariant == ExtremeWallVariant.Top) { foreach (var wall in sideWalls.Where(w => w.Orientation == ElementOrientation.Horizontal)) { for (var i = returnedFaces.Count - 1; i >= 0; i--) { var face = returnedFaces[i]; if (face.MinX > wall.GetMinX() - wall.Wall.Width && face.MinX < wall.GetMaxX() + wall.Wall.Width) { if (face.MaxY < wall.GetMaxY() - depth) { returnedFaces.RemoveAt(i); } } } } } if (extremeWallVariant == ExtremeWallVariant.Left) { foreach (var wall in sideWalls.Where(w => w.Orientation == ElementOrientation.Vertical)) { for (var i = returnedFaces.Count - 1; i >= 0; i--) { var face = returnedFaces[i]; if (face.MinY > wall.GetMinY() - wall.Wall.Width && face.MinY < wall.GetMaxY() + wall.Wall.Width) { if (face.MinX > wall.GetMinX() + depth) { returnedFaces.RemoveAt(i); } } } } } if (extremeWallVariant == ExtremeWallVariant.Right) { foreach (var wall in sideWalls.Where(w => w.Orientation == ElementOrientation.Vertical)) { for (var i = returnedFaces.Count - 1; i >= 0; i--) { var face = returnedFaces[i]; if (face.MinY > wall.GetMinY() - wall.Wall.Width && face.MinY < wall.GetMaxY() + wall.Wall.Width) { if (face.MaxX < wall.GetMaxX() - depth) { returnedFaces.RemoveAt(i); } } } } } // Фильтрация ближайших граней: если расстояние между гранями меньше заданного в настройка, // то удалять из этой пары ту грань, которая указана в настройках (по длине грани) var minWidthSetting = int.TryParse( UserConfigFile.GetValue(LangItem, "ExteriorFaceMinWidthBetween"), out var m) ? m : 100; var minWidthBetween = minWidthSetting.MmToFt(); // Вариант удаления: 0 - наименьший, 1 - наибольший var removeVariant = int.TryParse( UserConfigFile.GetValue(LangItem, "ExteriorMinWidthFaceRemove"), out m) ? m : 0; if (extremeWallVariant == ExtremeWallVariant.Bottom || extremeWallVariant == ExtremeWallVariant.Top) { // Сначала нужно отсортировать returnedFaces.Sort((f1, f2) => f1.MinX.CompareTo(f2.MinX)); var wasRemoved = false; do { for (var i = 0; i < returnedFaces.Count - 1; i++) { var face1 = returnedFaces[i]; var face2 = returnedFaces[i + 1]; var distance = Math.Abs(face1.MinX - face2.MinX); if (distance < minWidthBetween) { wasRemoved = true; var face1Length = Math.Abs(face1.MaxY - face1.MinY); var face2Length = Math.Abs(face2.MaxY - face2.MinY); if (removeVariant == 0) { if (face1Length < face2Length) { returnedFaces.RemoveAt(i); } else { returnedFaces.RemoveAt(i + 1); } } else { if (face1Length > face2Length) { returnedFaces.RemoveAt(i); } else { returnedFaces.RemoveAt(i + 1); } } break; } wasRemoved = false; } }while (wasRemoved); } if (extremeWallVariant == ExtremeWallVariant.Left || extremeWallVariant == ExtremeWallVariant.Right) { // Сначала нужно отсортировать returnedFaces.Sort((f1, f2) => f1.MinY.CompareTo(f2.MinY)); var wasRemoved = false; do { for (var i = 0; i < returnedFaces.Count - 1; i++) { var face1 = returnedFaces[i]; var face2 = returnedFaces[i + 1]; var distance = Math.Abs(face1.MinY - face2.MinY); if (distance < minWidthBetween) { wasRemoved = true; var face1Lenght = Math.Abs(face1.MaxX - face1.MinX); var face2Lenght = Math.Abs(face2.MaxX - face2.MinX); if (removeVariant == 0) { if (face1Lenght < face2Lenght) { returnedFaces.RemoveAt(i); } else { returnedFaces.RemoveAt(i + 1); } } else { if (face1Lenght > face2Lenght) { returnedFaces.RemoveAt(i); } else { returnedFaces.RemoveAt(i + 1); } } break; } wasRemoved = false; } }while (wasRemoved); } return(returnedFaces); }
/// <summary>Проставить внешние размеры</summary> public void DoWork() { var doc = _uiApplication.ActiveUIDocument.Document; _cutPlanZ = GeometryHelpers.GetViewPlanCutPlaneElevation((ViewPlan)doc.ActiveView); // select var selectedElements = SelectElements(); if (selectedElements == null) { return; } // get list of advanced elements foreach (var element in selectedElements) { switch (element) { case Wall wall: var advancedWall = new AdvancedWall(wall); if (advancedWall.IsDefined) { _advancedWalls.Add(advancedWall); } break; case Grid grid: var advancedGrid = new AdvancedGrid(grid); if (advancedGrid.IsDefined) { _advancedGrids.Add(advancedGrid); } break; } } if (!_advancedWalls.Any()) { MessageBox.Show(Language.GetItem(LangItem, "msg7"), MessageBoxIcon.Close); return; } // Фильтрую стены по толщине AdvancedHelpers.FilterByWallWidth(_advancedWalls); if (!_advancedWalls.Any()) { MessageBox.Show(Language.GetItem(LangItem, "msg8"), MessageBoxIcon.Close); return; } // Фильтрую стены, оставляя которые пересекаются секущим диапазоном AdvancedHelpers.FilterByCutPlan(_advancedWalls, _uiApplication.ActiveUIDocument.Document); // Вдруг после этого не осталось стен! if (!_advancedWalls.Any()) { MessageBox.Show(Language.GetItem(LangItem, "msg9"), MessageBoxIcon.Close); return; } AdvancedHelpers.FindExtremes( _advancedWalls, out var leftExtreme, out var rightExtreme, out var topextreme, out var bottomExtreme); using (var transactionGroup = new TransactionGroup(doc, _transactionName)) { transactionGroup.Start(); var createdDimensions = new List <Dimension>(); if (_exteriorConfiguration.RightDimensions) { createdDimensions.AddRange(CreateSideDimensions(rightExtreme, _advancedWalls, ExtremeWallVariant.Right)); } if (_exteriorConfiguration.LeftDimensions) { createdDimensions.AddRange(CreateSideDimensions(leftExtreme, _advancedWalls, ExtremeWallVariant.Left)); } if (_exteriorConfiguration.TopDimensions) { createdDimensions.AddRange(CreateSideDimensions(topextreme, _advancedWalls, ExtremeWallVariant.Top)); } if (_exteriorConfiguration.BottomDimensions) { createdDimensions.AddRange(CreateSideDimensions(bottomExtreme, _advancedWalls, ExtremeWallVariant.Bottom)); } if (createdDimensions.Any(d => d != null)) { using (var tr = new Transaction(doc, "Remove zeroes")) { tr.Start(); foreach (var createdDimension in createdDimensions.Where(d => d != null)) { if (Dimensions.TryRemoveZeroes(createdDimension, out var referenceArray) && createdDimension.Curve is Line line) { doc.Delete(createdDimension.Id); doc.Create.NewDimension(doc.ActiveView, line, referenceArray); } } tr.Commit(); } } transactionGroup.Assimilate(); } }
private Dimension CreateDimensionByOverallWalls( Document doc, Line chainDimensionLine, IReadOnlyCollection <AdvancedWall> sideWalls, ExtremeWallVariant extremeWallVariant) { Dimension returnedDimension = null; var verticalWalls = sideWalls.Where(w => w.Orientation == ElementOrientation.Vertical).ToList(); var horizontalWalls = sideWalls.Where(w => w.Orientation == ElementOrientation.Horizontal).ToList(); // Если вдруг нет стен if (!verticalWalls.Any() && !horizontalWalls.Any()) { return(null); } var referenceArray = new ReferenceArray(); // То же самое, что и получить из стен, только взять крайние референсы if (extremeWallVariant == ExtremeWallVariant.Right || extremeWallVariant == ExtremeWallVariant.Left) { var faces = new List <AdvancedPlanarFace>(); // для каждой вертикальной стены нахожу соприкасающиеся горизонтальные стены foreach (var verticalWall in verticalWalls) { // Добавляю в список все фейсы самой стены foreach (var face in verticalWall.AdvancedPlanarFaces) { if (face.IsHorizontal) { faces.Add(face); } } var adjoinElements1 = ((LocationCurve)verticalWall.Wall.Location).get_ElementsAtJoin(0); var adjoinElements2 = ((LocationCurve)verticalWall.Wall.Location).get_ElementsAtJoin(1); var adjoinWalls = new List <AdvancedWall>(); foreach (Element element in adjoinElements1) { var w = AdvancedHelpers.GetAdvancedWallFromListById(horizontalWalls, element.Id.IntegerValue); if (w != null) { adjoinWalls.Add(w); } } foreach (Element element in adjoinElements2) { var w = AdvancedHelpers.GetAdvancedWallFromListById(horizontalWalls, element.Id.IntegerValue); if (w != null) { adjoinWalls.Add(w); } } // добавляю все фейсы соприкасающихся стен foreach (var wall in adjoinWalls) { foreach (var face in wall.AdvancedPlanarFaces) { if (face.IsHorizontal) { faces.Add(face); } } } } faces.Sort((f1, f2) => f1.MinY.CompareTo(f2.MinY)); referenceArray.Append(faces.First().PlanarFace.Reference); referenceArray.Append(faces.Last().PlanarFace.Reference); } if (extremeWallVariant == ExtremeWallVariant.Top || extremeWallVariant == ExtremeWallVariant.Bottom) { var faces = new List <AdvancedPlanarFace>(); // для каждой вертикальной стены нахожу соприкасающиеся горизонтальные стены foreach (var horizontalWall in horizontalWalls) { // Добавляю в список все фейсы самой стены foreach (var face in horizontalWall.AdvancedPlanarFaces) { if (face.IsVertical) { faces.Add(face); } } var adjoinElements1 = ((LocationCurve)horizontalWall.Wall.Location).get_ElementsAtJoin(0); var adjoinElements2 = ((LocationCurve)horizontalWall.Wall.Location).get_ElementsAtJoin(1); var adjoinWalls = new List <AdvancedWall>(); foreach (Element element in adjoinElements1) { var w = AdvancedHelpers.GetAdvancedWallFromListById(verticalWalls, element.Id.IntegerValue); if (w != null) { adjoinWalls.Add(w); } } foreach (Element element in adjoinElements2) { var w = AdvancedHelpers.GetAdvancedWallFromListById(verticalWalls, element.Id.IntegerValue); if (w != null) { adjoinWalls.Add(w); } } // добавляю все фейсы соприкасающихся стен foreach (var wall in adjoinWalls) { foreach (var face in wall.AdvancedPlanarFaces) { if (face.IsVertical) { faces.Add(face); } } } } faces.Sort((f1, f2) => f1.MinX.CompareTo(f2.MinX)); referenceArray.Append(faces.First().PlanarFace.Reference); referenceArray.Append(faces.Last().PlanarFace.Reference); } if (!referenceArray.IsEmpty) { using (var transaction = new Transaction(doc, _transactionName)) { transaction.Start(); returnedDimension = doc.Create.NewDimension(doc.ActiveView, chainDimensionLine, referenceArray); transaction.Commit(); } } return(returnedDimension); }
private IEnumerable <Dimension> CreateSideDimensions( List <AdvancedWall> sideAdvancedWalls, List <AdvancedWall> allWalls, ExtremeWallVariant extremeWallVariant) { var doc = _uiApplication.ActiveUIDocument.Document; // Сумма длин отступов от крайней стены var chainOffsetSumm = 0; // Делаю цикл по цепочкам foreach (var chain in _exteriorConfiguration.Chains) { // Суммирую отступы chainOffsetSumm += chain.ElementOffset; // Получаю линию для построения размера с учетом масштаба var chainDimensionLine = AdvancedHelpers.GetDimensionLineForChain( doc, sideAdvancedWalls, extremeWallVariant, chainOffsetSumm.MmToFt() * doc.ActiveView.Scale); if (chainDimensionLine == null) { MessageBox.Show(Language.GetItem(LangItem, "msg12"), MessageBoxIcon.Close); continue; } // Крайние оси if (chain.ExtremeGrids) { yield return(CreateDimensionByExtremeGrids(doc, chainDimensionLine, extremeWallVariant)); } else if (chain.Overall) { yield return(CreateDimensionByOverallWalls(doc, chainDimensionLine, sideAdvancedWalls, extremeWallVariant)); } // Так как вариант "крайние оси" или "габарит" перекрывает все остальные else { var referenceArray = new ReferenceArray(); // Собираю референсы для стен в зависимости от настроек цепочки if (chain.Walls) { GetWallsReferences(sideAdvancedWalls, allWalls, extremeWallVariant, chain, ref referenceArray); } // from grids if (chain.Grids) { GetGridsReferences(extremeWallVariant, ref referenceArray); } if (!referenceArray.IsEmpty) { using (var transaction = new Transaction(doc, _transactionName)) { transaction.Start(); var dimension = doc.Create.NewDimension(doc.ActiveView, chainDimensionLine, referenceArray); if (dimension != null) { yield return(dimension); } transaction.Commit(); } } } } }