Example #1
0
        /// <summary>
        /// 生成标注
        /// </summary>
        public AnnotationBuildResult GenerateMultipleTagSymbol(Document document, IEnumerable <ElementId> selectedIds, MultiPipeAnnotationSettings setting, bool generateSingleOne)
        {
            if (selectedIds.Count() > AnnotationConstaints.PipeCountMax)
            {
                throw new NotImplementedException("暂不支持8根以上及管道的多管直径标注生成");
            }
            Document   = document;
            Collection = PAContext.GetCollection(Document);
            PipeAnnotationEntity entity = new PipeAnnotationEntity();

            entity.LocationType = setting.Location;
            View view = Document.ActiveView;
            AnnotationBuildResult result = GenerateMultipleTagSymbol(document, selectedIds, entity, setting);

            if (generateSingleOne && result == AnnotationBuildResult.Success)
            {
                Collection.Add(entity);
                Collection.Save(Document);
            }
            else if (result == AnnotationBuildResult.Success)
            {
                Collection.Add(entity);
            }
            return(result);
        }
Example #2
0
 public void FinishMultipleGenerate(Document document)
 {
     if (Collection == null)
     {
         Collection = PAContext.GetCollection(Document);
     }
     Collection.Save(Document);
 }
Example #3
0
        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 view  = doc.ActiveView;

            if (view.ViewType != ViewType.FloorPlan &&
                view.ViewType != ViewType.Elevation)
            {
                PmSoft.Common.Controls.PMMessageBox.Show("需选择二维视图或者图纸");
                return(Result.Cancelled);
            }
            //TODO0817 增加功能面板启动时获取字体高度
            VLTransactionHelper.DelegateTransaction(doc, "获取字体高度", () =>
            {
                PAContext.LoadFamilySymbols(doc);
                return(true);
            });
            PAContext.LoadTextHeight(doc);

            PipeAnnotationForm form = new PipeAnnotationForm(new PipeAnnotationCmd(uiApp));

            System.Windows.Forms.DialogResult result = System.Windows.Forms.DialogResult.Retry;
            while ((result = form.ShowDialog()) == System.Windows.Forms.DialogResult.Retry)
            {
                switch (form.ActionType)
                {
                case ActionType.SelectSinglePipe:
                    var selectedId = uiDoc.Selection.PickObject(ObjectType.Element, new PipeFramingFilter()).ElementId;
                    form.SelectedElementIds.Clear();
                    form.SelectedElementIds.Add(selectedId);
                    form.FinishSelection();
                    break;

                case ActionType.SelectMultiplePipe:
                    var selectedIds = uiDoc.Selection.PickObjects(ObjectType.Element, new PipeFramingFilter()).Select(c => c.ElementId);
                    form.SelectedElementIds.Clear();
                    form.SelectedElementIds.AddRange(selectedIds);
                    form.FinishSelection();
                    break;

                default:
                    break;
                }
            }
            return(Result.Succeeded);
        }
Example #4
0
 public override void SaveConfig(Document doc)
 {
     DelegateHelper.DelegateTransaction(doc, "加载配置记忆", (Func <bool>)(() =>
     {
         List <string> values = new List <string>();
         values.Add((string)SettingForSingle.LengthFromLine_Milimeter.ToString());
         values.Add(SettingForSingle.Location.ToString());
         values.Add(SettingForSingle.NeedLeader.ToString());
         values.Add(SettingForMultiple.LengthBetweenPipe_Milimeter.ToString());
         values.Add(SettingForMultiple.Location.ToString());
         values.Add(SettingForCommon.IncludeLinkPipe.ToString());
         values.Add(SettingForCommon.AutoPreventCollision.ToString());
         //0728长度过滤
         values.Add(SettingForCommon.MinLength_Milimeter.ToString());
         values.Add(SettingForCommon.FilterVertical.ToString());
         PAContext.SaveSetting(doc, string.Join(Splitter, values));
         return(true);
     }));
 }
Example #5
0
 public override void LoadConfig(Document doc)
 {
     IsSuccess = DelegateHelper.DelegateTransaction(doc, "标注族加载", () =>
     {
         return(PAContext.LoadFamilySymbols(doc));
     });// && PipeAnnotationContext.LoadParameterOfSymbols(doc);
     if (!IsSuccess)
     {
         TaskDialog.Show("错误", "加载必要的族时失败");
         return;
     }
     //PipeAnnotationContext.LoadParameterOfSymbols(doc);
     DelegateHelper.DelegateTransaction(doc, "加载配置记忆", () =>
     {
         SettingForSingle   = new SinglePipeAnnotationSettings(this);
         SettingForMultiple = new MultiPipeAnnotationSettings(this);
         SettingForCommon   = new CommonAnnotationSettings();
         var data           = PAContext.GetSetting(doc);
         var values         = data.Split(Splitter.ToCharArray().First());
         if (values.Count() >= 7)
         {
             SettingForSingle.LengthFromLine_Milimeter = Convert.ToInt32(values[0]);
             SettingForSingle.Location   = (SinglePipeTagLocation)Enum.Parse(typeof(SinglePipeTagLocation), values[1]);
             SettingForSingle.NeedLeader = Convert.ToBoolean(values[2]);
             SettingForMultiple.LengthBetweenPipe_Milimeter = Convert.ToInt32(values[3]);
             SettingForMultiple.Location           = (MultiPipeTagLocation)Enum.Parse(typeof(MultiPipeTagLocation), values[4]);
             SettingForCommon.IncludeLinkPipe      = Convert.ToBoolean(values[5]);
             SettingForCommon.AutoPreventCollision = Convert.ToBoolean(values[6]);
             //0728长度过滤
             if (values.Count() > 7)
             {
                 SettingForCommon.MinLength_Milimeter = Convert.ToInt32(values[7]);
                 SettingForCommon.FilterVertical      = Convert.ToBoolean(values[8]);
             }
         }
         return(true);
     });
     IsSuccess = true;
 }
Example #6
0
        /// <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);
            });
        }
Example #7
0
        //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);
        }
Example #8
0
        /// <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
        }