public static void LoadTextHeight(Document doc) { if (double.IsNaN(TextHeight)) { var familyDoc = doc.EditFamily(SingleTagSymbol.Family); var textElement = new FilteredElementCollector(familyDoc).OfClass(typeof(TextElement)).First(c => c.Name == "2.5") as TextElement; var textSizeStr = textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_SIZE).AsValueString(); var textSize = double.Parse(textSizeStr.Substring(0, textSizeStr.IndexOf(" mm"))); TextHeight = UnitHelper.ConvertToFoot(48, VLUnitType.millimeter) * textSize;//48是字体大小1mm在Revit中对应的高度 var textWidth = textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsValueString(); } }
//public void CalculateLocations(Element element, XYZ offset) //{ // var scale = 1 / VLConstraints.OrientFontSizeScale * VLConstraints.CurrentFontSizeScale; // var width = CSALocationType.GetLineWidth() * scale; // var height = 400 * scale; // var widthFoot = UnitHelper.ConvertToFoot(width, VLUnitType.millimeter); // var heightFoot = UnitHelper.ConvertToFoot(height, VLUnitType.millimeter); // var verticalFix = UnitHelper.ConvertToFoot(100, VLUnitType.millimeter) * scale; // var locationCurve = TargetType.GetLine(element); // UpdateVectors(locationCurve); // //线起始点 (中点) // LineStartLocation = (locationCurve.GetEndPoint(0) + locationCurve.GetEndPoint(1)) / 2; // //文本位置 start:(附着元素中点+线基本高度+文本高度*(文本个数-1)) end: start+宽 // //高度,宽度 取决于文本 // ParallelLinesLocations = new List<TextLocation>(); // TextLocations = new List<XYZ>(); // for (int i = Texts.Count() - 1; i >= 0; i--) // { // var start = LineStartLocation + (heightFoot + i * VLConstraints.CurrentFontHeight) * VerticalVector; // var end = start + widthFoot * ParallelVector; // ParallelLinesLocations.Add(new TextLocation(start, end)); // TextLocations.Add(CSALocationType.GetTextLocation(verticalFix, VerticalVector, start, end)); // } // //线终点 (最高的文本位置) // LineEndLocation = ParallelLinesLocations[0].Start; //} //public void CalculateLocations(Element element) //{ // CalculateLocations(element, new XYZ(0, 0, 0)); //} #endregion #region 线族的计算方案 public void CalculateLocations(Element element, FamilyInstance line, XYZ offset) { //数据准备 var locationCurve = TargetType.GetLine(element); var miniHeight = CurrentFontHeight * 2; UpdateVectors((locationCurve as Line)); //ParallelVector = VLLocationHelper.GetVectorByQuadrant((locationCurve as Line).Direction, QuadrantType.OneAndFour); //VerticalVector = VLLocationHelper.GetVectorByQuadrant(new XYZ(ParallelVector.Y, -ParallelVector.X, 0), QuadrantType.OneAndTwo); //计算线的定位位置 bool isRegenerate = offset != null; if (!isRegenerate) { LineLocation = (locationCurve.GetEndPoint(0) + locationCurve.GetEndPoint(1)) / 2; offset = new XYZ(0, 0, 0); LineHeight = UnitHelper.ConvertToFoot(1000, VLUnitType.millimeter); } else { LineLocation = locationCurve.Project(LineLocation + offset).XYZPoint; LineHeight = line.GetParameters(TagProperty.线高度1.ToString()).First().AsDouble() + VLLocationHelper.GetLengthBySide(offset, VerticalVector); LineHeight = LineHeight > miniHeight ? LineHeight : miniHeight;//确保最短长度有一个文字高度 } //高度,宽度 取决于文本 FontScale = 1 / VLConstraintsForCSA.OrientFontSizeScale * CurrentFontSizeScale; //LineWidth = UnitHelper.ConvertToFoot(CSALocationType.GetLineWidth() * FontScale, VLUnitType.millimeter); var verticalFix = CurrentFontHeight * VLConstraintsForCSA.TextSpace;; //偏移修正 为了显示更好 方便更改 var horizontalFix = UnitHelper.ConvertToFoot(50, VLUnitType.millimeter); //偏移修正 为了显示更好 方便更改 LineSpace = CurrentFontHeight * (1 + VLConstraintsForCSA.TextSpace); TextLocations = new List <XYZ>(); for (int i = Texts.Count() - 1; i >= 0; i--) { var start = LineLocation + (LineHeight + i * LineSpace) * VerticalVector; var end = start + LineWidth * ParallelVector; TextLocations.Add(CSALocationType.GetTextLocation(CurrentFontHeight, verticalFix, VerticalVector, horizontalFix, ParallelVector, start, end)); } }
/// <summary> /// 线 参数设置 /// </summary> /// <param name="nodePoints"></param> /// <param name="line"></param> void UpdateLineParameters(List <XYZ> nodePoints, FamilyInstance line, XYZ verticalVector) { double deepLength = Math.Abs((nodePoints.Last() - nodePoints.First()).DotProduct(verticalVector));//nodePoints.First().DistanceTo(nodePoints.Last()) line.GetParameters(TagProperty.线下探长度.ToString()).First().Set(deepLength); line.GetParameters(TagProperty.间距.ToString()).First().Set(UnitHelper.ConvertToFoot(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(Math.Abs((cur - first).DotProduct(verticalVector)));//cur.DistanceTo(first) } else { line.GetParameters(string.Format("节点{0}可见性", i)).First().Set(0); line.GetParameters(string.Format("节点{0}距离", i)).First().Set(0); } } }
public override void Execute() { var viewType = (CSAViewType)Enum.Parse(typeof(CSAViewType), ViewType.ToString()); switch (viewType) { case CSAViewType.Idle: View = new CompoundStructureAnnotationWindow(this); IntPtr rvtPtr = Autodesk.Windows.ComponentManager.ApplicationWindow; WindowInteropHelper helper = new WindowInteropHelper(View); helper.Owner = rvtPtr; View.ShowDialog(); break; case CSAViewType.Select: if (View.IsActive) { View.Close(); } using (PmSoft.Common.RevitClass.PickObjectsMouseHook MouseHook = new PmSoft.Common.RevitClass.PickObjectsMouseHook()) { MouseHook.InstallHook(PmSoft.Common.RevitClass.PickObjectsMouseHook.OKModeENUM.Objects); try { Model.TargetId = UIDocument.Selection.PickObject(ObjectType.Element , new VLClassesFilter(false, typeof(Wall), typeof(Floor), typeof(ExtrusionRoof), typeof(FootPrintRoof))).ElementId; MouseHook.UninstallHook(); ViewType = (int)CSAViewType.Generate; } catch (Exception ex) { MouseHook.UninstallHook(); ViewType = (int)CSAViewType.Idle; } } break; case CSAViewType.Generate: var doc = UIDocument.Document; if (VLTransactionHelper.DelegateTransaction(doc, "生成结构标注", () => { var element = doc.GetElement(Model.TargetId); var Collection = CSAContext.GetCollection(doc); //避免重复生成 由于一个对象可能在不同的视图中进行标注设置 所以还是需要重复生成的 var existedModel = Collection.Data.FirstOrDefault(c => c.TargetId.IntegerValue == Model.TargetId.IntegerValue); if (existedModel != null) { Collection.Data.Remove(existedModel); CSAContext.Creator.Clear(doc, existedModel); } var fontScale = 1 / VLConstraintsForCSA.OrientFontSizeScale * Model.CurrentFontSizeScale; Model.LineWidth = UnitHelper.ConvertToFoot(Model.CSALocationType.GetLineWidth() * fontScale, VLUnitType.millimeter); CSAContext.Creator.Generate(doc, Model, element); Collection.Data.Add(Model); Collection.Save(doc); return(true); })) { ViewType = (int)CSAViewType.Select; } else { ViewType = (int)CSAViewType.Idle; } break; case CSAViewType.Close: View.Close(); break; case CSAViewType.Closing: default: break; } }
//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="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 }
public bool CalculateLocations() { switch (ModelType) { case PAAModelType.SinglePipe: #region single var target = Document.GetElement(TargetId); var locationCurve = TargetType.GetLine(target); UpdateVectors(locationCurve); //干线起始点 var lineBound = Line.CreateBound(BodyStartPoint, BodyEndPoint); if (lineBound.VL_IsIntersect(locationCurve)) { var intersectionPoints = lineBound.VL_GetIntersectedOrContainedPoints(locationCurve); if (intersectionPoints.Count == 1) { BodyStartPoint = intersectionPoints.FirstOrDefault().ToSameZ(BodyEndPoint); //.ToSameZ(BodyStartPoint); } } else { } //否则不改变原始坐标,仅重置 //支线终点 if (TextType == PAATextType.Option2) { if (!IsRegenerate) { LeafEndPoint = BodyEndPoint + LineWidth * ParallelVector; } //文本位置 start:(附着元素中点+线基本高度+文本高度*(文本个数-1)) end: start+宽 //高度,宽度 取决于文本 AnnotationLocation = TextType.GetTextLocation(CurrentFontHeight, VerticalVector, BodyEndPoint, LeafEndPoint); } else { if (!IsRegenerate) { LeafEndPoint = BodyEndPoint + (IsReversed ? -LineWidth * ParallelVector : LineWidth * ParallelVector); } var bb = BodyEndPoint - BodyStartPoint; var lb = (LeafEndPoint - BodyEndPoint); if (lb.CrossProductByCoordinateType(bb, VLCoordinateType.XY) < 0) { var temp = LeafEndPoint; LeafEndPoint = BodyEndPoint; BodyEndPoint = temp; } //文本位置 start:(附着元素中点+线基本高度+文本高度*(文本个数-1)) end: start+宽 //高度,宽度 取决于文本 if (bb.CrossProductByCoordinateType(ParallelVector, VLCoordinateType.XY) < 0) { AnnotationLocation = TextType.GetTextLocation(CurrentFontHeight, VerticalVector, LeafEndPoint, BodyEndPoint); } else { AnnotationLocation = TextType.GetTextLocation(CurrentFontHeight, VerticalVector, BodyEndPoint, LeafEndPoint); } } return(true); #endregion case PAAModelType.MultiplePipe: #region multiple PipeAndNodePoints = new List <ElementAndNodePoint>(); if (IsRegenerate) { for (int i = 0; i < TargetIds.Count; i++) { target = Document.GetElement(TargetIds[i]); var annotationId = AnnotationIds[i]; var annotation = Document.GetElement(annotationId); if (annotation == null) { return(false); } PipeAndNodePoints.Add(new ElementAndNodePoint(target, annotation as IndependentTag)); } } else { foreach (var selectedId in TargetIds) { PipeAndNodePoints.Add(new ElementAndNodePoint(Document.GetElement(selectedId))); } } //平行,垂直 向量 UpdateVectors(PipeAndNodePoints.First().Line); //重叠区间 XYZ rightOfLefts; XYZ leftOfRights; XYZ startPoint = TargetLocation; List <XYZ> lefts = new List <XYZ>(); List <XYZ> rights = new List <XYZ>(); if (!IsRegenerate) { bool usingX = GetLeftsAndRights(PipeAndNodePoints, lefts, rights); rightOfLefts = usingX ? lefts.First(c => c.X == lefts.Max(p => p.X)) : lefts.First(c => c.Y == lefts.Max(p => p.Y)); leftOfRights = usingX ? rights.First(c => c.X == rights.Min(p => p.X)) : rights.First(c => c.Y == rights.Min(p => p.Y)); if ((usingX && rightOfLefts.X > leftOfRights.X) || (!usingX && rightOfLefts.Y > leftOfRights.Y)) { //TODO 提示无重叠区间 return(false); } } else { rightOfLefts = leftOfRights = null; } //节点计算 XYZ firstNode; if (!IsRegenerate) { firstNode = (rightOfLefts + leftOfRights) / 2; } else { locationCurve = PipeAndNodePoints[0].Line; firstNode = locationCurve.Project(startPoint).XYZPoint; } PipeAndNodePoints[0].NodePoint = firstNode; //节点位置 for (int i = 1; i < PipeAndNodePoints.Count(); i++) { PipeAndNodePoints[i].NodePoint = PipeAndNodePoints[i].Line.Project(PipeAndNodePoints[0].NodePoint).XYZPoint; } //排序 if (PipeAndNodePoints.Count() > 1) { if (Math.Abs(PipeAndNodePoints[0].NodePoint.Y - PipeAndNodePoints[1].NodePoint.Y) < 0.01) { PipeAndNodePoints = PipeAndNodePoints.OrderBy(c => c.NodePoint.X).ToList(); } else { PipeAndNodePoints = PipeAndNodePoints.OrderByDescending(c => c.NodePoint.Y).ToList(); } } TargetIds = PipeAndNodePoints.Select(c => c.Target.Id).ToList(); //标注定位计算 XYZ offset = GetOffSet(); bool overMoved = false;//位移是否超过的最低限制 double parallelSkew = offset.GetLengthBySide(ParallelVector); foreach (var PipeAndNodePoint in PipeAndNodePoints) { PipeAndNodePoint.NodePoint += parallelSkew * ParallelVector; } TargetLocation = PipeAndNodePoints.First().NodePoint; if (IsRegenerate) // && regenerateType != RegenerateType.RegenerateByPipe) { //原始线高度+偏移数据 var line = Document.GetElement(LineId); var orientLineHeight = IsRegenerate ? line.GetParameters(TagProperty.线高度1.ToString()).First().AsDouble() : 0; var verticalSkew = RegenerateType == RegenerateType.ByMultipleTarget ? 0 : VLLocationHelper.GetLengthBySide(offset, VerticalVector); //if (Math.Abs(VerticalVector.X) > 1 - UnitHelper.MiniValueForXYZ) // verticalSkew = -verticalSkew; var nodesHeight = UnitHelper.ConvertToFoot((PipeAndNodePoints.Count() - 1) * CurrentFontHeight, VLUnitType.millimeter); overMoved = orientLineHeight + verticalSkew < nodesHeight; var lineHeight = orientLineHeight + verticalSkew; if (overMoved) { lineHeight = nodesHeight; verticalSkew = nodesHeight - orientLineHeight; } LineHeight = lineHeight; } else { LineHeight = CurrentFontHeight; } LineSpace = CurrentFontHeight; UpdateLineWidth(Document.GetElement(TargetIds.First())); //string text = GetFullTextForLine(Document.GetElement(TargetIds.First())); //var textWidth = TextRenderer.MeasureText(text, PAAContext.FontManagement.OrientFont).Width; //LineWidth = textWidth * PAAContext.FontManagement.CurrentFontWidthSize; //标注位置 for (int i = 0; i < PipeAndNodePoints.Count(); i++) { var start = TargetLocation + (LineHeight + i * LineSpace) * VerticalVector; var end = start + LineWidth * ParallelVector; PipeAndNodePoints[PipeAndNodePoints.Count() - 1 - i].AnnotationPoint = TextType.GetTextLocation(CurrentFontHeight, VerticalVector, start, end); } #endregion return(true); default: throw new NotImplementedException("未支持该类型的生成"); } }
public void Execute(UpdaterData updateData) { try { var document = updateData.GetDocument(); var edits = updateData.GetModifiedElementIds(); var collection = CSAContext.GetCollection(document); if (CSAContext.IsEditing == true) { CSAContext.IsEditing = false; return; } List <int> movedEntities = new List <int>(); foreach (var changeId in edits) { CSAModel model = null; if (VLConstraintsForCSA.Doc == null) { VLConstraintsForCSA.Doc = document; } #region 根据Target重新生成 var targetMoved = collection.Data.FirstOrDefault(c => c.TargetId.IntegerValue == changeId.IntegerValue); if (targetMoved != null) { model = targetMoved; if (movedEntities.Contains(model.TargetId.IntegerValue)) { continue; } var creater = CSAContext.Creator; var target = document.GetElement(model.TargetId);//标注主体失效时删除 if (target == null) { collection.Data.Remove(model); continue; } CSAContext.Creator.Regenerate(document, model, target, new XYZ(0, 0, 0)); movedEntities.Add(model.TargetId.IntegerValue); CSAContext.IsEditing = true; } #endregion #region 根据Text重新生成 var textMoved = collection.Data.FirstOrDefault(c => c.TextNoteIds.FirstOrDefault(p => p.IntegerValue == changeId.IntegerValue) != null); if (textMoved != null) { model = textMoved; if (movedEntities.Contains(model.TargetId.IntegerValue)) { continue; } var creater = CSAContext.Creator; var target = document.GetElement(model.TargetId);//标注主体失效时删除 if (target == null) { collection.Data.Remove(model); continue; } //文本更改处理 var index = model.TextNoteIds.IndexOf(changeId); var newText = (document.GetElement(changeId) as TextNote).Text; if (model.Texts[index] != newText) { CompoundStructure compoundStructure = null; HostObjAttributes hoster = null; if (target is Wall) { hoster = (HostObjAttributes)((target as Wall).WallType); compoundStructure = hoster.GetCompoundStructure(); } if (target is Floor) { hoster = (HostObjAttributes)((target as Floor).FloorType); compoundStructure = hoster.GetCompoundStructure(); } if (target is RoofBase)//屋顶有多种类型 { hoster = (HostObjAttributes)((target as RoofBase).RoofType); compoundStructure = hoster.GetCompoundStructure(); } if (compoundStructure == null) { throw new NotImplementedException("关联更新失败,未获取有效的CompoundStructure类型"); } var layers = compoundStructure.GetLayers(); string pattern = @"([\d+\.]+)厚(.+)[\r]?"; Regex regex = new Regex(pattern); var match = regex.Match(newText); if (!match.Success) { PMMessageBox.ShowError("关联更新失败,文本不符合规范"); return; } var length = match.Groups[1].Value; var lengthFoot = UnitHelper.ConvertToFoot(Convert.ToDouble(length), VLUnitType.millimeter); var materialName = match.Groups[2].Value; var material = new FilteredElementCollector(document).OfClass(typeof(Material)) .FirstOrDefault(c => c.Name == materialName); if (material == null) { PMMessageBox.ShowError("关联更新失败,未获取到对应名称的材质"); return; } //更新 layers[index].Width = lengthFoot; layers[index].MaterialId = material.Id; compoundStructure.SetLayers(layers); IDictionary <int, CompoundStructureError> report = null; IDictionary <int, int> errorMap; try { compoundStructure.IsValid(document, out report, out errorMap); hoster.SetCompoundStructure(compoundStructure); } catch (Exception ex) { PMMessageBox.ShowError("材质设置失败,错误详情:" + (report != null ? string.Join(",", report.Select(c => c.Value)) : "")); throw ex; } ////报错This operation is valid only for non-vertically compound structures //layer = layers[index]; //layer.MaterialId = material.Id; ////compoundStructure.SetLayer(index, layer); } else { var textNote = document.GetElement(changeId) as TextNote; if (model.TextNoteTypeElementId.IntegerValue != textNote.TextNoteType.Id.IntegerValue) { model.TextNoteTypeElementId = textNote.TextNoteType.Id; CSAContext.Creator.Regenerate(document, model, target, new XYZ(0, 0, 0)); } else { //文本偏移处理 //var index = model.TextNoteIds.IndexOf(changeId); //var offset = (document.GetElement(changeId) as TextNote).Coord - model.TextLocations[index]; //CompoundStructureAnnotationContext.Creater.Regenerate(document, model, target, offset); //CSAContext.IsEditing = true;//移动会导致偏移 从而二次触发 } } movedEntities.Add(model.TargetId.IntegerValue); } #endregion #region 根据Line重新生成 var lineMoved = collection.Data.FirstOrDefault(c => c.LineId.IntegerValue == changeId.IntegerValue); if (lineMoved != null) { model = lineMoved; if (movedEntities.Contains(model.TargetId.IntegerValue)) { continue; } var creater = CSAContext.Creator; var target = document.GetElement(model.TargetId); if (target == null) { collection.Data.Remove(model); continue; } CSAContext.Creator.Regenerate(document, model, target); movedEntities.Add(model.TargetId.IntegerValue); CSAContext.IsEditing = true; } #endregion } CSAContext.Save(document); } catch (Exception ex) { VLLogHelper.Error(ex); } }