void Init(EdgeArray edgeArray, BeamAlignToFloorModel model) { Edges = edgeArray; Points = VLGeometryHelper.GetPoints(Edges, model); PointZ0s = Points.Select(c => new XYZ(c.X, c.Y, 0)).ToList(); Lines = new List <Line>(); AddLinesFromPoints(ref Lines, Points); LineZ0s = new List <Line>(); AddLinesFromPoints(ref LineZ0s, PointZ0s); //TODO 某些轮廓是由多个面组成,需修正Triangle的分解算法,此处修正即支持非平面的轮廓集合的处理 Triangles = VLGeometryHelper.GetTriangles(Points); TriangleZ0s = VLGeometryHelper.GetTriangles(PointZ0s); IsSolid = true; }
/// <summary> /// 计算线面交点 /// 平行为null /// </summary> public XYZ GetConflictPoint(MEPCurve mepCurve) { var line = (MEPCurve.Location as LocationCurve).Curve as Line; var lineToAvoid = (mepCurve.Location as LocationCurve).Curve as Line; var lineDirection1 = line.Direction; var lineDirection2 = lineToAvoid.Direction; if ((Math.Abs(lineDirection1.DotProductByCoordinate(lineDirection2, VLCoordinateType.XY)) - lineDirection1.GetLengthByCoordinate(VLCoordinateType.XY) * lineDirection2.GetLengthByCoordinate(VLCoordinateType.XY)).IsMiniValue()) { return(null); } VLTriangle triangle = new VLTriangle(lineToAvoid.GetEndPoint(0), lineToAvoid.GetEndPoint(1), lineToAvoid.GetEndPoint(0) + new XYZ(0, 0, 1)); return(VLGeometryHelper.GetIntersection(triangle, line.GetEndPoint(0), line.Direction)); }
/// <summary> /// 避让测试 /// return true when collided /// return false when passed /// </summary> /// <returns></returns> public bool CheckCollision(AvoidData data, bool tryAvoid = false) { Document document = data.Document; View view = document.ActiveView; IEnumerable <ElementId> selectedPipeIds = data.SelectedPipeIds; ElementId currentLineId = new ElementId(data.Entity.LineId); List <Line> currentLines = tryAvoid ? data.TemporaryLines : data.CurrentLines; VLTriangle currentTriangle = tryAvoid ? data.TemporaryTriangle : data.CurrentTriangle; FamilySymbol multipleTagSymbol = data.MultipleTagSymbol; //管道避让 var otherPipeLines = new FilteredElementCollector(document).OfClass(typeof(Pipe)) .Select(c => Line.CreateBound((c.Location as LocationCurve).Curve.GetEndPoint(0), (c.Location as LocationCurve).Curve.GetEndPoint(1))).ToList(); var pipeCollisions = new FilteredElementCollector(document).OfClass(typeof(Pipe)).Excluding(selectedPipeIds.ToList()) .Select(c => Line.CreateBound((c.Location as LocationCurve).Curve.GetEndPoint(0), (c.Location as LocationCurve).Curve.GetEndPoint(1))).ToList() .Where(c => VLGeometryHelper.IsPlanarCover(currentLines, currentTriangle, c) != VLGeometryHelper.VLCoverType.Disjoint).ToList(); //标注避让 var collector = new FilteredElementCollector(document).OfClass(typeof(FamilyInstance)).WhereElementIsNotElementType().Excluding(new List <ElementId>() { currentLineId }); var otherLines = collector.Where(c => (c as FamilyInstance).Symbol.Id == multipleTagSymbol.Id); var boundingBoxes = otherLines.Select(c => c.get_BoundingBox(view)); List <BoundingBoxXYZ> crossedBoundingBox = new List <BoundingBoxXYZ>(); List <BoundingBoxXYZ> uncrossedBoundingBox = new List <BoundingBoxXYZ>(); foreach (var boundingBox in boundingBoxes.Where(c => c != null)) { if (VLGeometryHelper.VL_IsRectangleCrossed(currentTriangle.A, currentTriangle.C, boundingBox.Min, boundingBox.Max)) { crossedBoundingBox.Add(boundingBox); } else { uncrossedBoundingBox.Add(boundingBox); } } PmSoft.Optimization.DrawingProduction.Utils.GraphicsDisplayerManager.Display(@"E:\WorkingSpace\Outputs\Images\0822标注避让.png", tryAvoid ? data.TemporaryTriangle : data.CurrentTriangle, otherPipeLines, pipeCollisions, crossedBoundingBox, uncrossedBoundingBox); return(pipeCollisions.Count() > 0 || crossedBoundingBox.Count() > 0); }
///// <summary> ///// 检测轮廓是否相交或包含 有限线段 ///// </summary> ///// <param name="outLine"></param> ///// <returns></returns> //public bool IsCover(XYZ pointZ0) //{ // foreach (var subOutLine in OutLines) // { // if (subOutLine.GetContainer(pointZ0) != null) // { // return true; // } // } // return false; //} /// <summary> /// 获得拆分点 /// </summary> /// <returns></returns> public SeperatePoints GetFitLines(Line beamLineZ0) { SeperatePoints fitLines = new SeperatePoints(); var p0 = beamLineZ0.GetEndPoint(0); var p1 = beamLineZ0.GetEndPoint(1); foreach (var SubOutLine in OutLines) { var coverType = SubOutLine.IsCover(beamLineZ0); if (coverType != CoverType.Disjoint) { fitLines.AdvancedPoints.AddRange(SubOutLine.GetFitLines(beamLineZ0).AdvancedPoints); } //线的端点增加 注意检测是否已存在 var point = p0; if (fitLines.AdvancedPoints.FirstOrDefault(c => c.Point.VL_XYEqualTo(point)) == null) { var triangle = SubOutLine.GetContainer(point); if (triangle != null) { var directOutLine = SubOutLine.GetContainedOutLine(point); fitLines.AdvancedPoints.Add(new AdvancedPoint(VLGeometryHelper.GetIntersection(triangle, point, new XYZ(0, 0, 1)), beamLineZ0.Direction, directOutLine.IsSolid)); } } point = p1; if (fitLines.AdvancedPoints.FirstOrDefault(c => c.Point.VL_XYEqualTo(point)) == null) { var triangle = SubOutLine.GetContainer(point); if (triangle != null) { var directOutLine = SubOutLine.GetContainedOutLine(point); fitLines.AdvancedPoints.Add(new AdvancedPoint(VLGeometryHelper.GetIntersection(triangle, point, new XYZ(0, 0, 1)), beamLineZ0.Direction, directOutLine.IsSolid)); } } } return(fitLines); }
/// <summary> /// 处理逻辑: /// 首先获取板的分层嵌套轮廓 /// 然后检测线是否与上诉轮廓集合有相交 /// 如果相交则进行线的裁剪处理 /// ( /// 获取所有交点 /// 检测是否包含线的端点 /// 结合交点和端点进行梁的分段处理 /// 返回镂空区间的梁 /// ) /// 没有相交则返回完整的线,交于其他板进行裁剪处理 /// </summary> internal List <Line> Deal(Element beam, Line beamLineZ0, LevelFloor levelFloor) { var beamLine = (beam.Location as LocationCurve).Curve as Line; List <Line> undealedZ0 = new List <Line>(); LevelOutLines leveledOutLines = GetLeveledOutLines(levelFloor); if (leveledOutLines.IsCover(beamLineZ0)) { var seperatePoints = leveledOutLines.GetFitLines(beamLineZ0); var pBeamZ0 = beamLineZ0.GetEndPoint(0); var pBeamZ1 = beamLineZ0.GetEndPoint(1); if (seperatePoints.AdvancedPoints.FirstOrDefault(c => c.Point.VL_XYEqualTo(pBeamZ0)) == null) { seperatePoints.AdvancedPoints.Add(new AdvancedPoint(pBeamZ0, beamLine.Direction, false)); } if (seperatePoints.AdvancedPoints.FirstOrDefault(c => c.Point.VL_XYEqualTo(pBeamZ1)) == null) { seperatePoints.AdvancedPoints.Add(new AdvancedPoint(pBeamZ1, beamLine.Direction, false)); } seperatePoints.AdvancedPoints = new AdvancedPoints(seperatePoints.AdvancedPoints.OrderByDescending(c => c.Point.X).ThenBy(c => c.Point.Y).ToList()); bool isSolid = seperatePoints.AdvancedPoints.First().IsSolid;//点的IsSolid可能是其他分层的记录,需更新为当前分层的最新值 var beamSymbol = (beam as FamilyInstance).Symbol; var beamLevel = Document.GetElement(beam.LevelId) as Level; for (int i = 0; i < seperatePoints.AdvancedPoints.Count - 1; i++) { var sp0 = seperatePoints.AdvancedPoints[i].Point; var sp1 = seperatePoints.AdvancedPoints[i + 1].Point; if (isSolid) { var triangle = leveledOutLines.GetContainer(sp0); if (triangle == null) { throw new NotImplementedException("Container Not Found"); } var fixedSP0 = VLGeometryHelper.GetIntersection(triangle, sp0, new XYZ(0, 0, 1)); triangle = leveledOutLines.GetContainer(sp1); if (triangle == null) { throw new NotImplementedException("Container Not Found"); } var fixedSP1 = VLGeometryHelper.GetIntersection(triangle, sp1, new XYZ(0, 0, 1)); var sectionBeam = Document.Create.NewFamilyInstance(Line.CreateBound(fixedSP0, fixedSP1), beamSymbol, beamLevel, Autodesk.Revit.DB.Structure.StructuralType.Beam); CreatedBeams.Add(sectionBeam); } else { var fixedSP0 = VLGeometryHelper.VL_GetIntersectionOnLine(sp0, pBeamZ0, beamLineZ0.Direction); var fixedSP1 = VLGeometryHelper.VL_GetIntersectionOnLine(sp1, pBeamZ0, beamLineZ0.Direction); undealedZ0.Add(Line.CreateBound(fixedSP0, fixedSP1)); } isSolid = !isSolid; } //CARE23415 GraphicsDisplayerManager.Display(seperatePoints); } else { undealedZ0.Add(beamLineZ0); } return(undealedZ0); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { var uiApp = commandData.Application; var app = commandData.Application.Application; var uiDoc = commandData.Application.ActiveUIDocument; var doc = commandData.Application.ActiveUIDocument.Document; ////链接模板测试 //var linkFilter = new CategoryFilter(BuiltInCategory.OST_Floors, true); //Reference reference = uiDoc.Selection.PickObject(ObjectType.LinkedElement, linkFilter, "先选择一个链接文件"); //Element element = doc.GetElement(reference.ElementId); //if (element.Category.Name != "RVT 链接") // return Result.Cancelled; //var floors = uiDoc.Selection.PickObjects(ObjectType.LinkedElement, linkFilter, "在链接文件中选择板:").ToList(); ////194278 //element = doc.GetElement(new ElementId(194278)); //var linkInstance = doc.GetElement(reference.ElementId) as RevitLinkInstance; //if (linkInstance!=null) //{ // var linkDoc = linkInstance.GetLinkDocument(); // element = linkDoc.GetElement(new ElementId(194278)); //} //MessageHelper.TaskDialogShow("开始选择板"); //业务逻辑处理 VLTransactionHelper.DelegateTransaction(doc, "梁齐板", () => { Document linkDocument = null; IEnumerable <ElementId> floorIds = null; if (model.ContentType == ContentType.Document) { //基础板,OST_StructuralFoundation //结构楼板,OST_Floors floorIds = uiDoc.Selection.PickObjects(ObjectType.Element, new CategoryFilter(BuiltInCategory.OST_Floors), "选择楼板").Select(c => c.ElementId); if (floorIds == null || floorIds.Count() == 0) { return(false); } } else { var linkFilter = new CategoryFilter(BuiltInCategory.OST_Floors, true); Reference reference = uiDoc.Selection.PickObject(ObjectType.LinkedElement, linkFilter, "先选择一个链接文件"); Element element = doc.GetElement(reference.ElementId); if (element.Category.Name != "RVT 链接") { return(false); } linkDocument = (element as RevitLinkInstance).GetLinkDocument(); floorIds = uiDoc.Selection.PickObjects(ObjectType.LinkedElement, linkFilter, "在链接文件中选择板:").Select(c => c.LinkedElementId); model.Offset = (element as Instance).GetTotalTransform().Origin; ////链接元素测试 //foreach (var floor in floors) //{ // var f = doc.GetElement(floor.ElementId); // f = (element as RevitLinkInstance).GetLinkDocument().GetElement(floor.ElementId); //} } //MessageHelper.TaskDialogShow("开始选择梁"); var beamIds = uiDoc.Selection.PickObjects(ObjectType.Element, new CategoryFilter(BuiltInCategory.OST_StructuralFraming), "选择梁").Select(c => c.ElementId); if (beamIds == null || beamIds.Count() == 0) { return(false); } //ValidFaces collector = new ValidFaces(doc, model); ////对板按高程从高到底处理 //List<LevelFloor> levelFloors = new List<LevelFloor>(); //foreach (var floorId in floorIds) //{ // var floor = doc.GetElement(floorId) as Floor; // var level = doc.GetElement(floor.LevelId) as Level; // levelFloors.Add(new LevelFloor(level.Elevation, floor)); //} //List<Line> beamLines = collector.DealAll(null, new List<Line>(), levelFloors); //GraphicsDisplayerManager.Display(collector, levelFloors); #region 0803版本 OutLineManager0802 collector = new OutLineManager0802(doc, model); //对板按高程从高到底处理 List <LevelFloor> levelFloors = new List <LevelFloor>(); foreach (var floorId in floorIds) { if (model.ContentType == ContentType.Document) { var floor = doc.GetElement(floorId) as Floor; var level = doc.GetElement(floor.LevelId) as Level; levelFloors.Add(new LevelFloor(level.Elevation, floor)); } else { collector.LinkDocument = linkDocument; var floor = linkDocument.GetElement(floorId) as Floor; var level = linkDocument.GetElement(floor.LevelId) as Level; levelFloors.Add(new LevelFloor(level.Elevation, floor)); } } //依次对各个梁进行个板面的拆分处理 foreach (var beamId in beamIds) { var beam = doc.GetElement(beamId); var beamSymbol = (beam as FamilyInstance).Symbol; var beamLevel = doc.GetElement(beam.LevelId) as Level; var beamLine = (beam.Location as LocationCurve).Curve as Line; if (beamLine == null) { throw new NotImplementedException("暂不支持曲线梁"); } var start = new XYZ(beamLine.GetEndPoint(0).X, beamLine.GetEndPoint(0).Y, 0); var end = new XYZ(beamLine.GetEndPoint(1).X, beamLine.GetEndPoint(1).Y, 0); var beamLineZ0 = Line.CreateBound(start, end); GraphicsDisplayerManager.Display(collector, levelFloors); List <Line> beamLines = collector.DealAll(beam, new List <Line>() { beamLineZ0 }, levelFloors); //最终未贴合板的梁段生成 foreach (var ungenerateBeamLine in beamLines) { var sp0 = ungenerateBeamLine.GetEndPoint(0); var sp1 = ungenerateBeamLine.GetEndPoint(1); var fixedSP0 = VLGeometryHelper.VL_GetIntersectionOnLine(sp0, beamLine.GetEndPoint(0), beamLine.Direction); var fixedSP1 = VLGeometryHelper.VL_GetIntersectionOnLine(sp1, beamLine.GetEndPoint(0), beamLine.Direction); var sectionBeam = doc.Create.NewFamilyInstance(Line.CreateBound(fixedSP0, fixedSP1), beamSymbol, beamLevel, Autodesk.Revit.DB.Structure.StructuralType.Beam); collector.CreatedBeams.Add(sectionBeam); } collector.LinkBeamWithAngleGT180(beam); doc.Delete(beam.Id); } #endregion #region 0803前 ////添加板 //foreach (var floorId in floorIds) //{ // var floor = doc.GetElement(floorId) as Floor; // collector.Add(floor); //} ////计算梁的偏移处理 //foreach (var beamId in beamIds) //{ // var beam = doc.GetElement(beamId); // var fitLineCollection = collector.Fit(beam); // var seperatePoints = collector.Merge(fitLineCollection, new DirectionPoint((beam.Location as LocationCurve).Curve.GetEndPoint(0), ((beam.Location as LocationCurve).Curve as Line).Direction, false), new DirectionPoint((beam.Location as LocationCurve).Curve.GetEndPoint(1), ((beam.Location as LocationCurve).Curve as Line).Direction, false)); // collector.Adapt(doc, beam, seperatePoints.SeperatedLines); // //绘图分析 // GraphicsDisplayerManager.Display(@"E:\WorkingSpace\Outputs\Images\display2.png", seperatePoints, collector.LeveledOutLines); //} #endregion return(true); }); //model.ContentType = model.ContentType == ContentType.Document ? ContentType.LinkDocument : ContentType.Document; return(Result.Succeeded); }