/// <summary> /// 线 参数设置 /// </summary> public static void UpdateLineParameters(this CSAModel model, FamilyInstance line, double lineHeight, double lineWidth, double space, int textCount) { line.GetParameters(TagProperty.线高度1.ToString()).First().Set(lineHeight); line.GetParameters(TagProperty.线宽度.ToString()).First().Set(lineWidth); line.GetParameters(TagProperty.间距.ToString()).First().Set(space); line.GetParameters(TagProperty.文字行数.ToString()).First().Set(textCount); }
/// <summary> /// Create a Revit Curve from a vertical column /// </summary> /// <param name="inst">The vertical column instance</param> /// <returns>The created Revit Line</returns> public Line CreateVerticalColumnCurve(FamilyInstance inst) { var lp = inst.Location != null ? (LocationPoint)inst.Location : null; var pt = lp != null ? lp.Point : null; var baseLevelParam = inst.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM); var baseLevel = baseLevelParam != null?a_doc.GetElement(baseLevelParam.AsElementId()) as Level : null; var topLevelParam = inst.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM); var topLevel = topLevelParam != null?a_doc.GetElement(topLevelParam.AsElementId()) as Level : null; Line retLine = null; if (pt != null && baseLevel != null && topLevel != null) { var baseOffset = inst.GetParameters("Base Offset"); var baseOffsetVal = baseOffset != null && baseOffset.Count > 0 ? UnitUtils.ConvertFromInternalUnits(baseOffset[0].AsDouble(), DisplayUnitType.DUT_DECIMAL_FEET) : 0.0; var topOffset = inst.GetParameters("Top Offset"); var topOffsetVal = topOffset != null && topOffset.Count > 0 ? UnitUtils.ConvertFromInternalUnits(topOffset[0].AsDouble(), DisplayUnitType.DUT_DECIMAL_FEET) : 0.0; var strPt = new XYZ(pt.X, pt.Y, baseLevel.Elevation + baseOffsetVal); var endPt = new XYZ(pt.X, pt.Y, topLevel.Elevation + topOffsetVal); double length = strPt.DistanceTo(endPt); if (length >= a_doc.Application.ShortCurveTolerance) { retLine = Line.CreateBound(strPt, endPt); } } return(retLine); }
/// <summary> /// 线 参数设置 /// </summary> /// <param name="nodePoints"></param> /// <param name="line"></param> private void UpdateLineParameters(PAAModel model, List <ElementAndNodePoint> nodePoints, FamilyInstance line, XYZ verticalVector) { double deepLength = Math.Abs((nodePoints.Last().NodePoint - nodePoints.First().NodePoint).DotProduct(verticalVector)); line.GetParameters(TagProperty.线高度1.ToString()).First().Set(model.LineHeight); line.GetParameters(TagProperty.线宽度.ToString()).First().Set(model.LineWidth); line.GetParameters(TagProperty.线下探长度.ToString()).First().Set(deepLength); line.GetParameters(TagProperty.间距.ToString()).First().Set(model.CurrentFontHeight); 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.NodePoint - first.NodePoint).DotProduct(verticalVector))); } else { //line.GetParameters(string.Format("节点{0}可见性", i)).First().Set(0); line.GetParameters(string.Format("节点{0}距离", i)).First().Set(0); } } }
/// <summary> /// Returns a reference to the FAMILY parameter (as a simple Parameter data type) on the given instance /// for the parameter with the given name. Will return the parameter /// whether it is an instance or type parameter. /// Returns null if no parameter on the instance was found. /// </summary> /// <param name="nestedFamilyInstance">An instance of a nested family file</param> /// <param name="parameterName">The name of the desired parameter to get a reference to</param> /// <remarks> /// Even though the data type returned is the more generic Parameter type, it will /// actually be for the data of the internal FamilyParameter object. /// </remarks> /// <returns></returns> public static Parameter GetFamilyParameter( FamilyInstance nestedFamilyInstance, string parameterName) { // Following good SOA practices, verify the // incoming parameters before attempting to proceed. if (nestedFamilyInstance == null) { throw new ArgumentNullException( "nestedFamilyInstance"); } if (string.IsNullOrEmpty(parameterName)) { throw new ArgumentNullException( "parameterName"); } Parameter oResult = null; // See if the parameter is an Instance parameter //oResult = nestedFamilyInstance.get_Parameter( parameterName ); // 2014 Debug.Assert(2 > nestedFamilyInstance.GetParameters(parameterName).Count, "ascertain that there are not more than one parameter of the given name"); oResult = nestedFamilyInstance.LookupParameter(parameterName); // 2015 // No? See if it's a Type parameter if (oResult == null) { //oResult = nestedFamilyInstance.Symbol.get_Parameter( parameterName ); // 2014 Debug.Assert(2 > nestedFamilyInstance.Symbol.GetParameters(parameterName).Count, "ascertain that there are not more than one parameter of the given name"); oResult = nestedFamilyInstance.Symbol.LookupParameter(parameterName); // 2015 } return(oResult); }
/// <summary> /// Returns a reference to the FAMILY parameter (as a simple Parameter data type) on the given instance /// for the parameter with the given name. Will return the parameter /// whether it is an instance or type parameter. /// Returns null if no parameter on the instance was found. /// </summary> /// <param name="nestedFamilyInstance">An instance of a nested family file</param> /// <param name="parameterName">The name of the desired parameter to get a reference to</param> /// <remarks> /// Even though the data type returned is the more generic Parameter type, it will /// actually be for the data of the internal FamilyParameter object. /// </remarks> /// <returns></returns> public static Parameter GetFamilyParameter( FamilyInstance nestedFamilyInstance, string parameterName) { // Following good SOA practices, verify the // incoming parameters before attempting to proceed. if( nestedFamilyInstance == null ) { throw new ArgumentNullException( "nestedFamilyInstance" ); } if( string.IsNullOrEmpty( parameterName ) ) { throw new ArgumentNullException( "parameterName" ); } Parameter oResult = null; // See if the parameter is an Instance parameter //oResult = nestedFamilyInstance.get_Parameter( parameterName ); // 2014 Debug.Assert( 2 > nestedFamilyInstance.GetParameters( parameterName ).Count, "ascertain that there are not more than one parameter of the given name" ); oResult = nestedFamilyInstance.LookupParameter( parameterName ); // 2015 // No? See if it's a Type parameter if( oResult == null ) { //oResult = nestedFamilyInstance.Symbol.get_Parameter( parameterName ); // 2014 Debug.Assert( 2 > nestedFamilyInstance.Symbol.GetParameters( parameterName ).Count, "ascertain that there are not more than one parameter of the given name" ); oResult = nestedFamilyInstance.Symbol.LookupParameter( parameterName ); // 2015 } return oResult; }
//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)); } }
public static void SetParams(FamilyInstance _fi, Dictionary <string, ParameterEditRecorder> _params) { if (_params == null) { return; } foreach (var key in _params.Keys) { var p = _fi.GetParameterByUniqueIdOrByName(key); if (p != null) { var refP = _params[key]; if (refP.StorageType == p.StorageType) { if (p.IsReadOnly && p.Definition.Name == "洞口宽度") { //for a WIP version of envi fam p = _fi.GetParameters("实际洞口宽度").First(); } p.SetValue(refP.Value); } } } }
/// <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); } } }
/// <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); } } }
//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 }
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); }
public static void Draw(Document doc, Element elem, String Section_Name, double LeftOffset, double RightOffset, double TopOffset, double BottomOffset, double NearClipOffset, double FarClipOffset) { ElementId elemid = elem.Id; //= refe.ElementId; XYZ Cen_pt = ((LocationPoint)elem.Location).Point; XYZ Y_Plane = new XYZ(0, -1, 0); ViewFamilyType view = KJU.Filter.ElementFiltering(doc, typeof(ViewFamilyType), "Section", Section_Name, null) as ViewFamilyType; FamilyInstance inst = elem as FamilyInstance; Transform tr = inst.GetTransform(); Parameter Elec_PanelName = inst.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_NAME); string Elec_Equipment_Name = null; Room room = inst.Room; if (null != room) { Elec_Equipment_Name = room.Name.Substring(0, room.Name.Length - room.Number.Length - 1) + "-" + inst.get_Parameter(BuiltInParameter.ALL_MODEL_MARK).AsString(); } else { Elec_Equipment_Name = "Exterior" + "-" + inst.get_Parameter(BuiltInParameter.ALL_MODEL_MARK).AsString(); } double Half_Width = inst.GetParameters("##Width")[0].AsDouble() / 2.0, Half_Height = inst.GetParameters("##Height")[0].AsDouble() / 2.0; XYZ Right_Dir = tr.BasisX; XYZ St_Pt = tr.Origin - Right_Dir * Half_Width, End_Pt = tr.Origin + Right_Dir * Half_Width; XYZ v = St_Pt - End_Pt; double X_Angle = (End_Pt - St_Pt).AngleOnPlaneTo(XYZ.BasisX, XYZ.BasisZ); //TaskDialog.Show("Angle","Angle = " + Math.Round(X_Angle * 180 / Math.PI,5).ToString() // + " --- " + Elec_Equipment_Name); XYZ Min = new XYZ(-(Half_Width + LeftOffset), -(Half_Height + BottomOffset), NearClipOffset); XYZ Max = new XYZ(Half_Width + RightOffset, Half_Height + TopOffset, FarClipOffset); XYZ Orgin = End_Pt + 0.5 * v; XYZ X_Dir = v.Normalize(); XYZ Up_Dir = XYZ.BasisZ; XYZ View_Dir = X_Dir.CrossProduct(Up_Dir); Transform Sec_Tr = Transform.Identity; Sec_Tr.Origin = Orgin; Sec_Tr.BasisX = X_Dir; Sec_Tr.BasisY = Up_Dir; Sec_Tr.BasisZ = View_Dir; BoundingBoxXYZ sectionBox = new BoundingBoxXYZ(); sectionBox.Transform = Sec_Tr; sectionBox.Min = Min; sectionBox.Max = Max; ViewSection vs = null; using (Transaction tn = new Transaction(doc)) { tn.Start("Section"); try { vs = ViewSection.CreateSection(doc, view.Id, sectionBox); Elec_PanelName.Set(Elec_Equipment_Name); vs.Name = inst.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_NAME).AsString(); tn.Commit(); } catch (Exception) { return; } } }
public RoomsCDRTRequest(UIApplication uiApp, String text) { RVTDocument doc = uiApp.ActiveUIDocument.Document; Autodesk.Revit.DB.View activeView = doc.ActiveView; //Verify the active view is a floor plan view if (activeView.ViewType != ViewType.FloorPlan) { MessageBox.Show("Please run from a demo floor plan view."); } else { //Get the current phase of the active view Phase currentPhase = doc.GetElement(activeView.get_Parameter(BuiltInParameter.VIEW_PHASE).AsElementId()) as Phase; ElementId currentPhaseId = currentPhase.Id; ElementId previousPhaseId = null; //Collect the phases of the document PhaseArray phaseArray = doc.Phases; //Cycle through the phases in the project to get the previous phase for (int i = 0; i < phaseArray.Size; i++) { //By finding the index of the current phase, which must not be the first phase, the phase in the previous index can be obtained if (phaseArray.get_Item(i).ToString() == currentPhase.ToString() && i != 0) { previousPhaseId = phaseArray.get_Item(i - 1).Id; } i++; } //Collect the rooms in the current view where their phase is equal to the active view's phase List <Room> currentVisibleRooms = new FilteredElementCollector(doc, activeView.Id).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements().Cast <Room>().Where(r => r.get_Parameter(BuiltInParameter.ROOM_PHASE).AsElementId() == currentPhaseId).ToList(); List <string> currentVisibleRoomNumbers = new List <string>(); //Get the list of currently visible rooms' numbers foreach (Room room in currentVisibleRooms) { currentVisibleRoomNumbers.Add(room.Number); } //Only continue if the previous phase was found if (previousPhaseId != null) { List <Room> previousRoomsToTag = new List <Room>(); Outline outline = null; try { //This portion will require a new outline from the view's bounding box BoundingBoxXYZ viewBBox = activeView.get_BoundingBox(activeView); //Get the active view as a plan view so the view range can be obtained for the height of the outline ViewPlan viewPlan = activeView as ViewPlan; PlanViewRange planViewRange = viewPlan.GetViewRange(); double minX = viewBBox.Min.X; double minY = viewBBox.Min.Y; //The bottom Z point of the outline will be the elevation of the view's level plus the bottom offset double minZ = activeView.GenLevel.Elevation + planViewRange.GetOffset(PlanViewPlane.BottomClipPlane); double maxX = viewBBox.Max.X; double maxY = viewBBox.Max.Y; //The top Z point of the outline will be the elevation of the view's level plust the top offset double maxZ = activeView.GenLevel.Elevation + planViewRange.GetOffset(PlanViewPlane.TopClipPlane); //Generate the minimum and maximum points XYZ minPoint = new XYZ(minX, minY, minZ); XYZ maxPoint = new XYZ(maxX, maxY, maxZ); //Make a new outline from the points outline = new Outline(minPoint, maxPoint); //Establish a new bounding box filter using the outline BoundingBoxIntersectsFilter bboxFilter = new BoundingBoxIntersectsFilter(outline); //The previous rooms will be those that pass the bounding box intersects filter (their bounding boxes intersect the view bounding box) and they belong to the previous phase var previousNonVisibleRooms = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().WherePasses(bboxFilter).ToElements().Where(r => r.get_Parameter(BuiltInParameter.ROOM_PHASE).AsElementId() == previousPhaseId); foreach (Element elem in previousNonVisibleRooms) { //Get the rooms and their numbers Room room = elem as Room; string roomNumber = room.Number; //Verify the room number is not in the current view's list of visible room numbers if (!currentVisibleRoomNumbers.Contains(roomNumber)) { previousRoomsToTag.Add(room); } } } catch (Exception e) { //If something went wrong in getting the demoed rooms, report an error MessageBox.Show(e.ToString(), "Getting Demo Rooms Error"); } //Start a transaction to make the new tags Transaction t = new Transaction(doc, "Create Demo Room Tags"); t.Start(); FamilySymbol symbol = null; //Create a new instance of the load options IFamilyLoadOptions loadOptions = new RVTFamilyLoadOptions(); try { //Get the versioned symbol family to use as a "tag" string roomTagSymbolPath = RVTOperations.GetVersionedFamilyFilePath(uiApp, Properties.Settings.Default.RevitRoomTagSymbol); try { //Load only the particular type of tag doc.LoadFamilySymbol(roomTagSymbolPath, Properties.Settings.Default.RevitRoomTagSymbolType, loadOptions, out FamilySymbol symb); symbol = symb; } catch { //If it could not be loaded, let the user know it needs added to the family for the script to work MessageBox.Show(String.Format("The family type {0} could not be found in {1}. Please add it for this tool to work.", Properties.Settings.Default.RevitRoomTagSymbolType, Properties.Settings.Default.RevitRoomTagSymbol)); } } catch { //If the family itself could not be loaded, let the user know where the family was expected to be found. MessageBox.Show(String.Format("The {0} family could not be found at {1}. Please place the {0} family in the {1} folder for this tool to work.", Path.GetFileNameWithoutExtension(Properties.Settings.Default.RevitRoomTagSymbol), Path.GetDirectoryName(Properties.Settings.Default.RevitRoomTagSymbol))); } try { //Verify there are rooms to tag and the family symbol to use is not null if (previousRoomsToTag.Count > 0 && symbol != null) { //Cycle through the demoed rooms foreach (Room demoRoom in previousRoomsToTag) { //Get the location point of the demo room as a point LocationPoint roomLocationPoint = demoRoom.Location as LocationPoint; //Make a new symbol at the locatoin FamilyInstance newSymbol = doc.Create.NewFamilyInstance(roomLocationPoint.Point, symbol, activeView); //Update the parameter values for room Name and Number in the symbol newSymbol.GetParameters("Name").First().Set(demoRoom.get_Parameter(BuiltInParameter.ROOM_NAME).AsString()); newSymbol.GetParameters("Number").First().Set(demoRoom.get_Parameter(BuiltInParameter.ROOM_NUMBER).AsString()); } } t.Commit(); } catch (Exception f) { //Well, crap, the symbol didn't place in the view MessageBox.Show(f.ToString(), "Placement Error"); t.RollBack(); } } else { //If the previous phase was null, then the current phase of the view is the first phase, so let the user know MessageBox.Show("The currently viewed phase is the earliest phase in the project. Please verify you are viewing a new construction phase, but showing previous and demoed elements."); } } }