//private static bool CheckCollision(Document document, View view, IEnumerable<ElementId> selectedPipeIds, FamilyInstance currentLine, List<Line> currentLines, Triangle currentTriangle, FamilySymbol 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 => GeometryHelper.IsCover(currentLines, currentTriangle, c) != GeometryHelper.VLCoverType.Disjoint).ToList(); // //TODO 标注避让 // var collector = new FilteredElementCollector(document).OfClass(typeof(FamilyInstance)).WhereElementIsNotElementType().Excluding(new List<ElementId>() { currentLine.Id }); // 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 (GeometryHelper.VL_IsRectangleCrossed(currentTriangle.A, currentTriangle.C, boundingBox.Min, boundingBox.Max)) // crossedBoundingBox.Add(boundingBox); // else // uncrossedBoundingBox.Add(boundingBox); // Utils.GraphicsDisplayerManager.Display(@"E:\WorkingSpace\Outputs\Images\0822标注避让1.png", currentTriangle, otherPipeLines, pipeCollisions, crossedBoundingBox, uncrossedBoundingBox); // return crossedBoundingBox.Count() > 0; //} //private static List<Triangle> GetTrianglesFromBoundingBox(BoundingBoxXYZ lineBoundingBox) //{ // return new List<Triangle>() // { // new Triangle(lineBoundingBox.Min,lineBoundingBox.Max,lineBoundingBox.Min+new XYZ(0,(lineBoundingBox.Max-lineBoundingBox.Min).Y,0)), // new Triangle(lineBoundingBox.Min,lineBoundingBox.Max,lineBoundingBox.Min+new XYZ(0,(lineBoundingBox.Max-lineBoundingBox.Min).X,0)), // }; //} //private static List<Line> GetLinesFromBoundingBox(BoundingBoxXYZ lineBoundingBox) //{ // return new List<Line>() // { // Line.CreateBound(lineBoundingBox.Min,lineBoundingBox.Min+new XYZ(0,(lineBoundingBox.Max-lineBoundingBox.Min).Y,0)), // Line.CreateBound(lineBoundingBox.Max,lineBoundingBox.Min+new XYZ(0,(lineBoundingBox.Max-lineBoundingBox.Min).Y,0)), // Line.CreateBound(lineBoundingBox.Max,lineBoundingBox.Max-new XYZ(0,(lineBoundingBox.Max-lineBoundingBox.Min).Y,0)), // Line.CreateBound(lineBoundingBox.Min,lineBoundingBox.Max-new XYZ(0,(lineBoundingBox.Max-lineBoundingBox.Min).Y,0)), // }; //} /// <summary> /// 根据线的移动,重定位内容 /// </summary> public bool RegenerateMultipleTagSymbolByEntity(Document document, PipeAnnotationEntity entity, XYZ skewVector) { Document = document; XYZ startPoint = null; View view = Document.ActiveView; FamilyInstance line = document.GetElement(new ElementId(entity.LineId)) as FamilyInstance; List <PipeAndNodePoint> pipeAndNodePoints = new List <PipeAndNodePoint>(); for (int i = 0; i < entity.PipeIds.Count(); i++) { var pipeId = entity.PipeIds[i]; var pipe = Document.GetElement(new ElementId(pipeId)); if (pipe == null) { return(false); } var tagId = entity.TagIds[i]; pipeAndNodePoints.Add(new PipeAndNodePoint(pipe as Pipe, Document.GetElement(new ElementId(tagId)) as IndependentTag)); } ////偏移量 //XYZ skew = (line.Location as LocationPoint).Point - entity.StartPoint; //管道 获取 //平行,垂直 向量 XYZ parallelVector = null; XYZ verticalVector = null; parallelVector = ((pipeAndNodePoints.First().Pipe.Location as LocationCurve).Curve as Line).Direction; verticalVector = new XYZ(parallelVector.Y, -parallelVector.X, 0); parallelVector = LocationHelper.GetVectorByQuadrant(parallelVector, QuadrantType.OneAndFour); verticalVector = LocationHelper.GetVectorByQuadrant(verticalVector, QuadrantType.OneAndTwo); if (parallelVector.Y == 1) { verticalVector = -verticalVector; } //原始线高度 var orientLineHeight = line.GetParameters(TagProperty.线高度1.ToString()).First().AsDouble(); ////原始对象清理 //Document.Delete(line.Id); //foreach (var tagId in entity.TagIds) // Document.Delete(new ElementId(tagId)); ////平行检测 //if (!CheckParallel(pipes, verticalVector)) //{ // return AnnotationBuildResult.NotParallel; //} //节点计算 //TODO entity.StartPoint 不以记录为准 以其他点位的信息来计算 GetNodePoints(pipeAndNodePoints, entity.StartPoint + skewVector); pipeAndNodePoints = pipeAndNodePoints.OrderByDescending(c => c.NodePoint.Y).ToList(); List <XYZ> nodePoints = pipeAndNodePoints.Select(c => c.NodePoint).ToList(); List <Pipe> pipes = pipeAndNodePoints.Select(c => c.Pipe).ToList(); List <IndependentTag> tags = pipeAndNodePoints.Select(c => c.Tag).ToList(); //if (nodePoints.Count() == 0) //{ // return AnnotationBuildResult.NoOverlap; //} //起始点 startPoint = nodePoints.First(); //线 创建 var multipleTagSymbol = PAContext.GetMultipleTagSymbol(document); if (!multipleTagSymbol.IsActive) { multipleTagSymbol.Activate(); } //line = Document.Create.NewFamilyInstance(startPoint, MultipleTagSymbol, view); (line.Location as LocationPoint).Point = startPoint; ////线 旋转处理 //if (verticalVector.Y != 1)//TODO 判断是否相同方向 //{ // LocationPoint locationPoint = line.Location as LocationPoint; // if (locationPoint != null) // locationPoint.RotateByXY(startPoint, verticalVector); //} //偏移计算 var verticalSkew = LocationHelper.GetLengthBySide(skewVector, verticalVector); var parallelSkew = LocationHelper.GetLengthBySide(skewVector, parallelVector); //线参数 UpdateLineParameters(nodePoints, line, verticalVector); //标注 创建 var nodesHeight = UnitHelper.ConvertToFoot((nodePoints.Count() - 1) * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType); var lineHeight = orientLineHeight + verticalSkew > nodesHeight ? orientLineHeight + verticalSkew : nodesHeight; var tagHeight = lineHeight + nodesHeight; line.GetParameters(TagProperty.线高度1.ToString()).First().Set(lineHeight); var textSize = PAContext.TextSize; var widthScale = PAContext.WidthScale; switch (entity.LocationType) { case MultiPipeTagLocation.OnLineEdge: //添加对应的单管直径标注 line.GetParameters(TagProperty.线宽度.ToString()).First().Set(UnitHelper.ConvertToFoot(200, AnnotationConstaints.UnitType)); var skewLength = AnnotationConstaints.SkewLengthForOffLine; for (int i = 0; i < pipes.Count(); i++) { //var subTag = Document.Create.NewTag(view, pipes[i], false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, startPoint); var subTag = tags[i]; var text = subTag.TagText; var textLength = System.Windows.Forms.TextRenderer.MeasureText(text, AnnotationConstaints.Font).Width; var actualLength = textLength / (textSize * widthScale); subTag.TagHeadPosition = startPoint + skewLength * parallelVector + actualLength / 25.4 * parallelVector + (tagHeight + UnitHelper.ConvertToFoot(-i * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType)) * verticalVector; tags.Add(subTag); } break; case MultiPipeTagLocation.OnLine: //添加对应的单管直径标注 line.GetParameters(TagProperty.线宽度.ToString()).First().Set(UnitHelper.ConvertToFoot(800, AnnotationConstaints.UnitType)); skewLength = AnnotationConstaints.SkewLengthForOnLine; for (int i = 0; i < pipes.Count(); i++) { //var subTag = Document.Create.NewTag(view, pipes[i], false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, startPoint); var subTag = tags[i]; var text = subTag.TagText; var textLength = System.Windows.Forms.TextRenderer.MeasureText(text, AnnotationConstaints.Font).Width; var actualLength = textLength / (textSize * widthScale); subTag.TagHeadPosition = startPoint + skewLength * parallelVector + actualLength / 25.4 * parallelVector + (tagHeight + UnitHelper.ConvertToFoot(-i * AnnotationConstaints.TextHeight + 0.5 * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType)) * verticalVector; tags.Add(subTag); } break; default: return(false); } entity.ViewId = view.Id.IntegerValue; entity.StartPoint = startPoint; //entity.LineId = line.Id.IntegerValue; //entity.PipeIds.Clear(); //entity.PipeIds.AddRange(pipes.Select(c => c.Id.IntegerValue)); //entity.TagIds.Clear(); //entity.TagIds.AddRange(tags.Select(c => c.Id.IntegerValue)); return(true); }
/// <summary> /// 多管一键标注 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_AllMulltiplePipe_Click(object sender, EventArgs e) { if (!CheckInputsOfMultiple()) { return; } if (!CheckInputsOfSingle()) { return; } if (!CheckInputsOfCommon()) { return; } //先删除后新增 var lines = new FilteredElementCollector(Doc, View.Id) .OfClass(typeof(FamilyInstance)) .WherePasses(new FamilyInstanceFilter(Doc, PAContext.GetMultipleTagSymbol(Doc).Id)); var pipeTags = new FilteredElementCollector(Doc, View.Id) .OfCategory(BuiltInCategory.OST_PipeTags) .WhereElementIsNotElementType(); if (pipeTags.Count() > 0 || lines.Count() > 0) { if (PMMessageBox.ShowQuestion("已存在标注,继续将重新生成所有管道标注", MessageBoxButtons.OKCancel) != DialogResult.OK) { return; } } DelegateHelper.DelegateTransaction(Doc, "清空已有标注", () => { //清空模型对象 var lineIds = lines.Select(c => c.Id).ToList(); foreach (var lineId in lineIds) { Doc.Delete(lineId); } var pipeTagIds = pipeTags.Select(c => c.Id).ToList(); foreach (var pipeTagId in pipeTagIds) { Doc.Delete(pipeTagId); } //删除存储的关联 var storageCollection = PAContext.GetCollection(Doc); storageCollection.RemoveAll(c => c.ViewId == View.Id.IntegerValue); storageCollection.Save(Doc); var creator = new AnnotationCreater(); //生成处理 var pipes = new FilteredElementCollector(Doc, View.Id) .OfCategory(BuiltInCategory.OST_PipeCurves) .WhereElementIsNotElementType(); PipeCollection collection = new PipeCollection(); foreach (Pipe pipe in pipes) { if (CheckFilter(pipe)) { collection.Add(pipe); } } collection.SortBySkew(); List <PipeGroup> slopedPipeGroups = null; try { slopedPipeGroups = collection.GetPipeGroups(PipeAnnotationCmd.PipeAnnotationUIData.SettingForMultiple.LengthBetweenPipe_Inch); } catch (Exception ex)//特定情况暂时以提示处理,比如连续超过7个,比如 { TaskDialog.Show("警告", ex.Message); return(false); } foreach (var pipeGroup in slopedPipeGroups) { if (pipeGroup.Count > 1) { creator.GenerateMultipleTagSymbol(Doc, pipeGroup.Select(c => c.Id), PipeAnnotationCmd.PipeAnnotationUIData.SettingForMultiple, false); } else { var pipe = Doc.GetElement(pipeGroup.First().Id) as Pipe; var setting = PipeAnnotationCmd.PipeAnnotationUIData.SettingForSingle; var headerPoint = setting.GetHeaderPoint(pipe); var tag = Doc.Create.NewTag(View, pipe, setting.NeedLeader, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, headerPoint); tag.TagHeadPosition = headerPoint; } } creator.FinishMultipleGenerate(Doc); return(true); }); }
/// <summary> /// 生成标注 /// </summary> /// <param name="selectedIds"></param> /// <param name="entity"></param> /// <param name="view"></param> /// <returns></returns> AnnotationBuildResult GenerateMultipleTagSymbol(Document document, IEnumerable <ElementId> selectedIds, PipeAnnotationEntity entity, MultiPipeAnnotationSettings setting) { View view = document.ActiveView; XYZ startPoint = null; FamilyInstance line = null; List <PipeAndNodePoint> pipeAndNodePoints = new List <PipeAndNodePoint>(); var tags = new List <IndependentTag>(); //管道 获取 foreach (var selectedId in selectedIds) { pipeAndNodePoints.Add(new PipeAndNodePoint(Document.GetElement(selectedId) as Pipe)); } //平行,垂直 向量 XYZ parallelVector = null; XYZ verticalVector = null; parallelVector = ((pipeAndNodePoints.First().Pipe.Location as LocationCurve).Curve as Line).Direction; verticalVector = new XYZ(parallelVector.Y, -parallelVector.X, 0); parallelVector = LocationHelper.GetVectorByQuadrant(parallelVector, QuadrantType.OneAndFour); verticalVector = LocationHelper.GetVectorByQuadrant(verticalVector, QuadrantType.OneAndTwo); if (parallelVector.Y == 1) { verticalVector = -verticalVector; } //平行检测 if (!CheckParallel(pipeAndNodePoints.Select(c => c.Pipe), verticalVector)) { return(AnnotationBuildResult.NotParallel); } XYZ rightOfLefts; //左侧点的右边界 XYZ leftOfRights; //右侧点的左边界 //节点计算 if (!GetNodePoints(pipeAndNodePoints, out rightOfLefts, out leftOfRights)) { return(AnnotationBuildResult.NoOverlap); } pipeAndNodePoints = pipeAndNodePoints.OrderByDescending(c => c.NodePoint.Y).ToList(); var pipes = pipeAndNodePoints.Select(c => c.Pipe).ToList(); var orderedNodePoints = pipeAndNodePoints.Select(c => c.NodePoint).ToList(); //起始点 startPoint = orderedNodePoints.First(); //线 创建 var multipleTagSymbol = PAContext.GetMultipleTagSymbol(document); if (!multipleTagSymbol.IsActive) { multipleTagSymbol.Activate(); } line = Document.Create.NewFamilyInstance(startPoint, multipleTagSymbol, view); //线 旋转处理 LocationPoint locationPoint = line.Location as LocationPoint; if (locationPoint != null) { locationPoint.RotateByXY(startPoint, verticalVector); } //线 参数设置 UpdateLineParameters(orderedNodePoints, line, verticalVector); //标注 创建 var textSize = PAContext.TextSize; var widthScale = PAContext.WidthScale; //碰撞检测区域点 XYZ avoidP1_Line1 = orderedNodePoints.Last(); XYZ avoidP2_Line2 = null; XYZ avoidP3_Annotation1 = null; switch (entity.LocationType) { case MultiPipeTagLocation.OnLineEdge: //添加对应的单管直径标注 line.GetParameters(TagProperty.线宽度.ToString()).First().Set(UnitHelper.ConvertToFoot(200, AnnotationConstaints.UnitType)); var height = Convert.ToDouble(line.GetParameters(TagProperty.线高度1.ToString()).First().AsValueString()) + (orderedNodePoints.Count() - 1) * AnnotationConstaints.TextHeight; avoidP2_Line2 = avoidP1_Line1 + UnitHelper.ConvertToFoot(height, AnnotationConstaints.UnitType) * verticalVector; var skewLength = AnnotationConstaints.SkewLengthForOffLine; for (int i = 0; i < pipes.Count(); i++) { var subTag = Document.Create.NewTag(view, pipes[i], false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, startPoint); var text = subTag.TagText; var textLength = System.Windows.Forms.TextRenderer.MeasureText(text, AnnotationConstaints.Font).Width; var actualLength = textLength / (textSize * widthScale); subTag.TagHeadPosition = startPoint + skewLength * parallelVector + UnitHelper.ConvertToInch(actualLength, VLUnitType.millimeter) * parallelVector + UnitHelper.ConvertToFoot(height - i * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType) * verticalVector; tags.Add(subTag); if (i == 0) { avoidP3_Annotation1 = subTag.TagHeadPosition + skewLength * parallelVector + UnitHelper.ConvertToInch(actualLength, VLUnitType.millimeter) * parallelVector + UnitHelper.ConvertToFoot(0.5 * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType) * verticalVector; } } break; case MultiPipeTagLocation.OnLine: //添加对应的单管直径标注 line.GetParameters(TagProperty.线宽度.ToString()).First().Set(UnitHelper.ConvertToFoot(800, AnnotationConstaints.UnitType)); height = Convert.ToDouble(line.GetParameters(TagProperty.线高度1.ToString()).First().AsValueString()) + (orderedNodePoints.Count() - 1) * AnnotationConstaints.TextHeight; avoidP2_Line2 = avoidP1_Line1 + UnitHelper.ConvertToFoot(height, AnnotationConstaints.UnitType) * verticalVector; skewLength = AnnotationConstaints.SkewLengthForOnLine; for (int i = 0; i < pipes.Count(); i++) { var subTag = Document.Create.NewTag(view, pipes[i], false, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, startPoint); var text = subTag.TagText; var textLength = System.Windows.Forms.TextRenderer.MeasureText(text, AnnotationConstaints.Font).Width; var actualLength = textLength / (textSize * widthScale); subTag.TagHeadPosition = startPoint + skewLength * parallelVector + UnitHelper.ConvertToInch(actualLength, VLUnitType.millimeter) * parallelVector + UnitHelper.ConvertToFoot(height - i * AnnotationConstaints.TextHeight + 0.5 * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType) * verticalVector; tags.Add(subTag); if (i == 0) { avoidP3_Annotation1 = subTag.TagHeadPosition + skewLength * parallelVector + UnitHelper.ConvertToInch(actualLength, VLUnitType.millimeter) * parallelVector + UnitHelper.ConvertToFoot(AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType) * verticalVector; } } break; default: return(AnnotationBuildResult.NoLocationType); } entity.ViewId = view.Id.IntegerValue; entity.LineId = line.Id.IntegerValue; foreach (var pipe in pipes) { entity.PipeIds.Add(pipe.Id.IntegerValue); } foreach (var tag in tags) { entity.TagIds.Add(tag.Id.IntegerValue); } entity.StartPoint = startPoint; //碰撞检测 VLTriangle triangle = new VLTriangle(avoidP1_Line1, avoidP2_Line2, avoidP3_Annotation1); List <Line> lines = triangle.GetLines(); AvoidData data = new AvoidData(document, selectedIds, entity, lines, triangle, multipleTagSymbol, parallelVector, rightOfLefts.GetLength(), leftOfRights.GetLength()); AvoidStrategy strategty = AvoidStrategy.MoveLeft; var strategyEntity = AvoidStrategyFactory.GetAvoidStrategyEntity(strategty); strategyEntity.Data = data; while (strategyEntity.CheckCollision(strategyEntity.Data)) { if (strategyEntity.TryAvoid()) { strategyEntity.Apply(data); break; } else { strategyEntity = strategyEntity.GetNextStratetyEntity(); } } return(AnnotationBuildResult.Success); #region old //if (CheckCollision(document, view, selectedIds, line, lines, triangle, multipleTagSymbol)) //{ // int offsetLength = 10; // XYZ offset = null; // if (rightOfLefts.GetLength() > offsetLength) // offset = parallelVector * offsetLength; // else if (leftOfRights.GetLength() > offsetLength) // offset = -parallelVector * offsetLength; // else // return AnnotationBuildResult.Success; // avoidP1_Line1 += offset; // avoidP2_Line2 += offset; // avoidP3_Annotation1 += offset; // lines = GetLines(avoidP1_Line1, avoidP2_Line2, avoidP3_Annotation1); // triangle = new Triangle(avoidP1_Line1, avoidP2_Line2, avoidP3_Annotation1); // if (!CheckCollision(document, view, selectedIds, line, lines, triangle, multipleTagSymbol)) // { // //TODO 偏移处理 // Autodesk.Revit.DB.ElementTransformUtils.MoveElement(document, new ElementId(entity.LineId), offset); // foreach (var tagId in entity.TagIds) // { // Autodesk.Revit.DB.ElementTransformUtils.MoveElement(document, new ElementId(tagId), offset); // } // } //} //return AnnotationBuildResult.Success; #endregion }