public override bool TryAvoid()
        {
            if (UnitHelper.ConvertToInch(Data.LeftSpace, VLUnitType.millimeter) < OffsetLength)
            {
                return(false);
            }

            Data.TemporaryTriangle = new VLTriangle(Data.CurrentTriangle, GetSideVector());
            Data.TemporaryLines    = Data.TemporaryTriangle.GetLines();
            return(!CheckCollision(Data, true));
        }
Exemple #2
0
        /// <summary>
        /// 线 参数设置
        /// </summary>
        /// <param name="nodePoints"></param>
        /// <param name="line"></param>
        private void UpdateLineParameters(List <XYZ> nodePoints, FamilyInstance line)
        {
            double deepLength = nodePoints.First().DistanceTo(nodePoints.Last());

            line.GetParameters(TagProperty.线下探长度.ToString()).First().Set(deepLength);
            line.GetParameters(TagProperty.间距.ToString()).First().Set(UnitHelper.ConvertToInch(AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType));
            line.GetParameters(TagProperty.文字行数.ToString()).First().Set(nodePoints.Count());
            for (int i = 2; i <= 8; i++)
            {
                var first = nodePoints.First();
                if (nodePoints.Count() >= i)
                {
                    var cur = nodePoints[i - 1];
                    line.GetParameters(string.Format("节点{0}可见性", i)).First().Set(1);
                    line.GetParameters(string.Format("节点{0}距离", i)).First().Set(cur.DistanceTo(first));
                }
                else
                {
                    line.GetParameters(string.Format("节点{0}可见性", i)).First().Set(0);
                    line.GetParameters(string.Format("节点{0}距离", i)).First().Set(0);
                }
            }
        }
Exemple #3
0
        public void Execute(UpdaterData updateData)
        {
            var document   = updateData.GetDocument();
            var edits      = updateData.GetModifiedElementIds();
            var collection = PipeAnnotationContext.GetCollection(document);

            if (PipeAnnotationContext.IsEditing == true)
            {
                PipeAnnotationContext.IsEditing = false;
                return;
            }
            List <int> movedEntities = new List <int>();

            foreach (var editId in edits)
            {
                var element = document.GetElement(editId);
                PipeAnnotationEntity entity = null;
                var lineMoved = collection.FirstOrDefault(c => c.LineId == editId.IntegerValue);
                if (lineMoved != null)
                {
                    TaskDialog.Show("警告", "线移动了");
                    entity = lineMoved;
                    var            creater    = PipeAnnotationContext.Creater;
                    FamilyInstance line       = document.GetElement(new ElementId(entity.LineId)) as FamilyInstance;
                    XYZ            skewVector = (line.Location as LocationPoint).Point - entity.StartPoint;
                    creater.RegenerateMultipleTagSymbolByEntity(document, entity, skewVector);
                    movedEntities.Add(entity.LineId);
                    PipeAnnotationContext.IsEditing = true;
                }
                var pipeMoved = collection.FirstOrDefault(c => c.PipeIds.Contains(editId.IntegerValue));
                if (pipeMoved != null)
                {
                    TaskDialog.Show("警告", "管道移动了");
                    entity = pipeMoved;
                    if (movedEntities.Contains(entity.LineId))
                    {
                        continue;
                    }
                    var creater        = PipeAnnotationContext.Creater;
                    XYZ parallelVector = null;
                    XYZ verticalVector = null;
                    parallelVector = ((document.GetElement(new ElementId(entity.PipeIds.First())).Location as LocationCurve).Curve as Line).Direction;
                    verticalVector = new XYZ(parallelVector.Y, -parallelVector.X, 0);
                    parallelVector = VLLocationHelper.GetVectorByQuadrant(parallelVector, QuadrantType.OneAndFour, VLCoordinateType.XY);
                    verticalVector = VLLocationHelper.GetVectorByQuadrant(verticalVector, QuadrantType.OneAndTwo, VLCoordinateType.XY);
                    int indexOfPipe = entity.PipeIds.IndexOf(editId.IntegerValue);
                    var startPoint  = entity.StartPoint;
                    var movedPipe   = document.GetElement(new ElementId(editId.IntegerValue)) as Pipe;
                    var pipeLine    = (movedPipe.Location as LocationCurve).Curve;
                    pipeLine.MakeUnbound();
                    var    projectionPoint = pipeLine.Project(startPoint).XYZPoint;
                    var    line            = document.GetElement(new ElementId(entity.LineId)) as FamilyInstance;
                    double preHeight       = 0;
                    if (indexOfPipe > 0)
                    {
                        preHeight   = line.GetParameters(string.Format("节点{0}距离", indexOfPipe + 1)).First().AsDouble();
                        startPoint -= preHeight * verticalVector;
                    }
                    creater.RegenerateMultipleTagSymbolByEntity(document, entity, startPoint - projectionPoint);
                    movedEntities.Add(entity.LineId);
                    PipeAnnotationContext.IsEditing = true;
                }
                var tagMoved = collection.FirstOrDefault(c => c.TagIds.Contains(editId.IntegerValue));
                if (tagMoved != null)
                {
                    TaskDialog.Show("警告", "标注移动了");
                    entity = tagMoved;
                    if (movedEntities.Contains(entity.LineId))
                    {
                        continue;
                    }
                    var creater        = PipeAnnotationContext.Creater;
                    var index          = entity.TagIds.IndexOf(editId.IntegerValue);
                    var subTag         = document.GetElement(new ElementId(editId.IntegerValue)) as IndependentTag;
                    var text           = subTag.TagText;
                    var textLength     = System.Windows.Forms.TextRenderer.MeasureText(text, AnnotationConstaints.Font).Width;
                    var actualLength   = textLength / (creater.TextSize * creater.WidthScale);
                    XYZ parallelVector = null;
                    XYZ verticalVector = null;
                    parallelVector = ((document.GetElement(new ElementId(entity.PipeIds.First())).Location as LocationCurve).Curve as Line).Direction;
                    verticalVector = new XYZ(parallelVector.Y, -parallelVector.X, 0);
                    parallelVector = VLLocationHelper.GetVectorByQuadrant(parallelVector, QuadrantType.OneAndFour, VLCoordinateType.XY);
                    verticalVector = VLLocationHelper.GetVectorByQuadrant(verticalVector, QuadrantType.OneAndTwo, VLCoordinateType.XY);
                    var    height     = Convert.ToDouble(document.GetElement(new ElementId(entity.LineId)).GetParameters(TagProperty.线高度1.ToString()).First().AsValueString()) + (entity.PipeIds.Count() - 1) * AnnotationConstaints.TextHeight;
                    double skewLength = 0;
                    XYZ    startPoint = null;
                    switch (entity.LocationType)
                    {
                    case MultiPipeTagLocation.OnLineEdge:
                        skewLength = AnnotationConstaints.SkewLengthForOffLine;
                        startPoint = subTag.TagHeadPosition - skewLength * parallelVector - actualLength / 25.4 * parallelVector
                                     - UnitHelper.ConvertToInch(height - index * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType) * verticalVector;
                        break;

                    case MultiPipeTagLocation.OnLine:
                        skewLength = AnnotationConstaints.SkewLengthForOffLine;
                        startPoint = subTag.TagHeadPosition - skewLength * parallelVector - actualLength / 25.4 * parallelVector
                                     - UnitHelper.ConvertToInch(height - index * AnnotationConstaints.TextHeight + 0.5 * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType) * verticalVector;
                        break;
                    }
                    XYZ skewVector = startPoint - entity.StartPoint;
                    creater.RegenerateMultipleTagSymbolByEntity(document, entity, skewVector);
                    movedEntities.Add(entity.LineId);
                    PipeAnnotationContext.IsEditing = true;
                }
            }
            PipeAnnotationContext.SaveCollection(document);
        }
Exemple #4
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
        }
Exemple #5
0
        /// <summary>
        /// 位于线端,标注定位计算
        /// </summary>
        private XYZ GetHeadPositionForOnLineEdge(XYZ parallelVector, XYZ verticalVector, XYZ startPoint, double height, double skewLength, int i, IndependentTag subTag)
        {
            var text         = subTag.TagText;
            var textLength   = System.Windows.Forms.TextRenderer.MeasureText(text, AnnotationConstaints.Font).Width;
            var actualLength = textLength / (TextSize * WidthScale);

            return(startPoint + skewLength * parallelVector + actualLength / 25.4 * parallelVector + UnitHelper.ConvertToInch(height - i * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType) * verticalVector);
        }
Exemple #6
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 <Pipe>    pipes      = new List <Pipe>();

            foreach (var pipeId in entity.PipeIds)
            {
                pipes.Add(Document.GetElement(new ElementId(pipeId)) as Pipe);
            }
            List <IndependentTag> tags = new List <IndependentTag>();

            foreach (var tagId in entity.TagIds)
            {
                tags.Add(Document.GetElement(new ElementId(tagId)) as IndependentTag);
            }
            ////偏移量
            //XYZ skew = (line.Location as LocationPoint).Point - entity.StartPoint;
            //管道 获取
            //平行,垂直 向量
            XYZ parallelVector = null;
            XYZ verticalVector = null;

            parallelVector = ((pipes.First().Location as LocationCurve).Curve as Line).Direction;
            verticalVector = new XYZ(parallelVector.Y, -parallelVector.X, 0);
            parallelVector = VLLocationHelper.GetVectorByQuadrant(parallelVector, QuadrantType.OneAndFour, VLCoordinateType.XY);
            verticalVector = VLLocationHelper.GetVectorByQuadrant(verticalVector, QuadrantType.OneAndTwo, VLCoordinateType.XY);
            //原始线高度
            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 不以记录为准 以其他点位的信息来计算
            List <XYZ> nodePoints = GetNodePoints(pipes, entity.StartPoint + skewVector).OrderByDescending(c => c.Y).ToList();

            //if (nodePoints.Count() == 0)
            //{
            //    return AnnotationBuildResult.NoOverlap;
            //}
            //起始点
            startPoint = nodePoints.First();
            //线 创建
            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 = VLLocationHelper.GetLengthBySide(skewVector, verticalVector);
            var parallelSkew = VLLocationHelper.GetLengthBySide(skewVector, parallelVector);

            //线参数
            UpdateLineParameters(nodePoints, line);
            //标注 创建
            var nodesHeight = UnitHelper.ConvertToInch((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);
            switch (entity.LocationType)
            {
            case MultiPipeTagLocation.OnLineEdge:
                //添加对应的单管直径标注
                line.GetParameters(TagProperty.线宽度.ToString()).First().Set(UnitHelper.ConvertToInch(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.ConvertToInch(-i * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType)) * verticalVector;
                    tags.Add(subTag);
                }
                break;

            case MultiPipeTagLocation.OnLine:
                //添加对应的单管直径标注
                line.GetParameters(TagProperty.线宽度.ToString()).First().Set(UnitHelper.ConvertToInch(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.ConvertToInch(-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);
        }
Exemple #7
0
        private AnnotationBuildResult GenerateMultipleTagSymbol(IEnumerable <ElementId> selectedIds, PipeAnnotationEntity entity, View view)
        {
            XYZ            startPoint = null;
            FamilyInstance line       = null;
            var            pipes      = new List <Pipe>();
            var            tags       = new List <IndependentTag>();

            //管道 获取
            foreach (var selectedId in selectedIds)
            {
                pipes.Add(Document.GetElement(selectedId) as Pipe);
            }
            //平行,垂直 向量
            XYZ parallelVector = null;
            XYZ verticalVector = null;

            parallelVector = ((pipes.First().Location as LocationCurve).Curve as Line).Direction;
            verticalVector = new XYZ(parallelVector.Y, -parallelVector.X, 0);
            parallelVector = VLLocationHelper.GetVectorByQuadrant(parallelVector, QuadrantType.OneAndFour, VLCoordinateType.XY);
            verticalVector = VLLocationHelper.GetVectorByQuadrant(verticalVector, QuadrantType.OneAndTwo, VLCoordinateType.XY);
            //平行检测
            if (!CheckParallel(pipes, verticalVector))
            {
                return(AnnotationBuildResult.NotParallel);
            }
            //节点计算
            List <XYZ> nodePoints = GetNodePoints(pipes).OrderByDescending(c => c.Y).ToList();

            if (nodePoints.Count() == 0)
            {
                return(AnnotationBuildResult.NoOverlap);
            }
            //起始点
            startPoint = nodePoints.First();
            //线 创建
            if (!MultipleTagSymbol.IsActive)
            {
                MultipleTagSymbol.Activate();
            }
            line = Document.Create.NewFamilyInstance(startPoint, MultipleTagSymbol, view);
            //线 旋转处理
            if (verticalVector.Y != 1)
            {
                LocationPoint locationPoint = line.Location as LocationPoint;
                if (locationPoint != null)
                {
                    locationPoint.RotateByXY(startPoint, verticalVector);
                }
            }
            //线 参数设置
            UpdateLineParameters(nodePoints, line);
            //标注 创建
            switch (entity.LocationType)
            {
            case MultiPipeTagLocation.OnLineEdge:
                //添加对应的单管直径标注
                line.GetParameters(TagProperty.线宽度.ToString()).First().Set(UnitHelper.ConvertToInch(200, AnnotationConstaints.UnitType));
                var height     = Convert.ToDouble(line.GetParameters(TagProperty.线高度1.ToString()).First().AsValueString()) + (nodePoints.Count() - 1) * AnnotationConstaints.TextHeight;
                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 + actualLength / 25.4 * parallelVector
                                             + UnitHelper.ConvertToInch(height - i * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType) * verticalVector;
                    tags.Add(subTag);
                }
                break;

            case MultiPipeTagLocation.OnLine:
                //添加对应的单管直径标注
                line.GetParameters(TagProperty.线宽度.ToString()).First().Set(UnitHelper.ConvertToInch(800, AnnotationConstaints.UnitType));
                height = Convert.ToDouble(line.GetParameters(TagProperty.线高度1.ToString()).First().AsValueString()) +
                         (nodePoints.Count() - 1) * AnnotationConstaints.TextHeight;
                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 + actualLength / 25.4 * parallelVector
                                             + UnitHelper.ConvertToInch(height - i * AnnotationConstaints.TextHeight + 0.5 * AnnotationConstaints.TextHeight, AnnotationConstaints.UnitType) * verticalVector;
                    tags.Add(subTag);
                }
                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;
            return(AnnotationBuildResult.Success);
        }