/// <summary> /// Creates a new conduit. /// </summary> /// <param name="doc"></param> /// <param name="parm"></param> /// <param name="startPt"></param> /// <param name="endPt"></param> /// <returns></returns> public static Conduit CreateConduit(this Document doc, PipeParameter parm, XYZ startPt, XYZ endPt) { if (doc is null) { throw new ArgumentNullException(nameof(doc)); } if (parm is null) { throw new ArgumentNullException(nameof(parm)); } if (startPt is null) { throw new ArgumentNullException(nameof(startPt)); } if (endPt is null) { throw new ArgumentNullException(nameof(endPt)); } return(Conduit.Create(doc, parm.TypeId, startPt, endPt, parm.LevelId)); }
/// <summary> /// /// </summary> /// <returns></returns> private FamilyInstance Connect(Transaction docTrans, Connector conCabinet, Connector conConduit) { // 找到设备的底面 XYZ cabLocation = conCabinet.Origin; PlanarFace bottomFace = GeoHelper.GetBottomPlanarFace(_cabinet.MepInstance); double bottomZ = bottomFace.Origin.Z; // 根据线管的位置与方向,以及设备中连接件的位置,得到此线管发出的射线与设备连接件的某竖向平面的交点 XYZ rayPoint = GetRayPoint(conConduit.CoordinateSystem, conCabinet.CoordinateSystem); XYZ verticalConduitTop = new XYZ(rayPoint.X, rayPoint.Y, cabLocation.Z); XYZ verticalConduitBottom = new XYZ(rayPoint.X, rayPoint.Y, bottomZ); // 判断是否能够成功地生成弯头 // (因为如果不能成功生成,在API的代码中也不会报错,而只是在Transaction.Commit时弹出一个消息框) double?outDiamter = _conduit.GetConduitOuterDiameter(); if (outDiamter == null) { throw new NullReferenceException("在线管中未找到参数“外径”"); } // ------------------------------------------------ // 要生成弯头所需要的最小的弯曲半径,如果弯头的半径大于此值,则不能成功生成弯头。 // 在生成弯头时,两边的线管如果被截断,则其截断后的长度不能为负,也不能为零,至少还要剩3mm(2.5 mm都不行)。 double minLengthOfVerticalConduit = UnitUtils.ConvertToInternalUnits(5, DisplayUnitType.DUT_MILLIMETERS); // 弯头对象除了圆弧段以外,其两端还各有一个线管段,其长度 = 线管外径。 double allowableRadius = cabLocation.Z - conConduit.Origin.Z - outDiamter.Value - minLengthOfVerticalConduit; double allowableRatio = allowableRadius / outDiamter.Value; // ------------------------------------------------ double?ratioInFamily = GetElbowRadiusRatio(docTrans, _conduit.ConduitIns); if (ratioInFamily == null) { throw new NullReferenceException("在线管中没有找到匹配的弯头对象"); } if (allowableRatio < ratioInFamily) { throw new InvalidOperationException(message: "线管当前所使用的弯头中的弯曲半径值过大,不能正常地生成弯头。" + "请换用其他的弯头,或者将将弯头中的实例参数“弯曲半径”由“管件外径 * " + ratioInFamily + "”修改为“管件外径 * " + allowableRatio + "”或更小的值。"); } // 生成设备内部的竖向线管 Conduit cd = Conduit.Create(_doc, _conduit.ConduitIns.GetTypeId(), verticalConduitBottom, verticalConduitTop, ElementId.InvalidElementId); MEPConduit mepCd = new MEPConduit(cd); // 调整线管直径到与选择的线管直径相同 double?diameter = _conduit.GetConduitDiameter(); if (diameter == null) { throw new NullReferenceException("在线管中未找到参数“直径(公称尺寸)”"); } mepCd.SetConduitDiameter(diameter.Value); // Connector conn_vert = cd.ConnectorManager.Lookup(0); // 生成弯头 FamilyInstance elbow = _doc.Create.NewElbowFitting(conn_vert, conConduit); return(elbow); }
/// <summary> /// Adds the new conduit. /// </summary> /// <param name="doc"></param> /// <param name="typeId"></param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="lvlId"></param> /// <returns></returns> public static Conduit AddConduit(this Document doc, ElementId typeId, XYZ start, XYZ end, ElementId lvlId) { return(Conduit.Create(doc, typeId, start, end, lvlId)); }
/// <summary> /// Given a curve element, determine three parallel /// curves on the right, left and above, offset by /// a given radius or half diameter. /// </summary> void CreateConduitOffsets( Element conduit, double diameter, double distance) { Document doc = conduit.Document; // Given element location curve var obj = conduit.Location as LocationCurve; XYZ start = obj.Curve.GetEndPoint(0); XYZ end = obj.Curve.GetEndPoint(1); XYZ vx = end - start; // Offsets double radius = 0.5 * diameter; double offset_lr = radius; double offset_up = radius * Math.Sqrt(3); // Assume vx is horizontal to start with XYZ vz = XYZ.BasisZ; XYZ vy = vz.CrossProduct(vx); XYZ start1 = start + offset_lr * vy; XYZ start2 = start - offset_lr * vy; XYZ start3 = start + offset_up * vz; XYZ end1 = start1 + vx; XYZ end2 = start2 + vx; XYZ end3 = start3 + vx; // Confusing sample code from // https://forums.autodesk.com/t5/revit-api-forum/offset-conduit-only-by-z-axis/m-p/9972671 var L = Math.Sqrt((start.X - end.X) * (start.X - end.X) + (start.Y - end.Y) * (start.Y - end.Y)); double x1startO = start.X + distance * (end.Y - start.Y) / L; double x1endO = end.X + distance * (end.Y - start.Y) / L; double y1startO = start.Y + distance * (start.X - end.X) / L; double y1end0 = end.Y + distance * (start.X - end.X) / L; Conduit conduit1 = Conduit.Create(doc, conduit.GetTypeId(), new XYZ(x1startO, y1startO, start.Z), new XYZ(x1endO, y1end0, end.Z), conduit.LevelId); conduit1.get_Parameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).Set(diameter); double x2startO = start.X - distance * (end.Y - start.Y) / L; double x2endO = end.X - distance * (end.Y - start.Y) / L; double y2startO = start.Y - distance * (start.X - end.X) / L; double y2end0 = end.Y - distance * (start.X - end.X) / L; Conduit conduit2 = Conduit.Create(doc, conduit.GetTypeId(), new XYZ(x2startO, y2startO, start.Z), new XYZ(x2endO, y2end0, end.Z), conduit.LevelId); conduit2.get_Parameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).Set(diameter); XYZ p0 = new XYZ(start.X - (end.Y - start.Y) * (1 / obj.Curve.ApproximateLength), start.Y + (end.X - start.X) * (1 / obj.Curve.ApproximateLength), start.Z); XYZ p1 = new XYZ(start.X + (end.Y - start.Y) * (1 / obj.Curve.ApproximateLength), start.Y - (end.X - start.X) * (1 / obj.Curve.ApproximateLength), start.Z); Conduit conduit3; Curve copyCurve = obj.Curve.CreateOffset(-diameter * Math.Sqrt(3) / 2, Line.CreateBound(p0, p1).Direction); conduit3 = Conduit.Create(doc, conduit.GetTypeId(), copyCurve.GetEndPoint(0), copyCurve.GetEndPoint(1), conduit.LevelId); conduit3.get_Parameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).Set(diameter); }
public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements) { try { var document = revit.Application.ActiveUIDocument.Document; GetSomeShit(document, out string error); if (error != null) { TaskDialog.Show("Ошибка", error); return(Result.Succeeded); } var systemsByEquipmentIds = new Dictionary <ElementId, List <ElementId> >(); foreach (var system in ElectricalSystems) { var equipment = system.BaseEquipment; if (equipment == null) { continue; } if (!systemsByEquipmentIds.ContainsKey(equipment.Id)) { systemsByEquipmentIds.Add(equipment.Id, new List <ElementId>()); } systemsByEquipmentIds[equipment.Id].Add(system.Id); } var conduitTypes = new Dictionary <string, ElementId>(); foreach (ConduitType type in ConduitTypes) { conduitTypes.Add(type.FamilyName + ": " + type.Name, type.Id); } var gui = new UserForm(document, systemsByEquipmentIds, conduitTypes); if (gui.ShowDialog() != DialogResult.OK) { return(Result.Cancelled); } var conduitTypeId = gui.SelectedConduitType; var electricalCircuitsWithLevelId = new List <Tuple <ElementId, List <XYZ> > >(); foreach (var systemId in gui.SelectedCircuits) { var system = (ElectricalSystem)document.GetElement(systemId); var circuit = system.GetCircuitPath().ToList(); electricalCircuitsWithLevelId.Add(new Tuple <ElementId, List <XYZ> >(system.LevelId, circuit)); } Transaction tr = new Transaction(document, "Создание коробов по электрической цепи"); tr.Start(); foreach (var x in electricalCircuitsWithLevelId) { var createdConduits = new List <Conduit>(); for (var i = 0; i < x.Item2.Count() - 1; i++) { var startPoint = new XYZ( Math.Min(x.Item2[i].X, x.Item2[i + 1].X) - 0.01, Math.Min(x.Item2[i].Y, x.Item2[i + 1].Y) - 0.01, Math.Min(x.Item2[i].Z, x.Item2[i + 1].Z) - 0.01 ); var endPoint = new XYZ( Math.Max(x.Item2[i].X, x.Item2[i + 1].X) + 0.01, Math.Max(x.Item2[i].Y, x.Item2[i + 1].Y) + 0.01, Math.Max(x.Item2[i].Z, x.Item2[i + 1].Z) + 0.01 ); var myOutLn = new Outline(startPoint, endPoint); var conduits = new List <ElementId>(); if (!myOutLn.IsEmpty) { var filter = new BoundingBoxIsInsideFilter(myOutLn); var collector = new FilteredElementCollector(document); conduits = collector .WherePasses(filter) .OfClass(typeof(Conduit)) .Cast <Conduit>() .Select(a => a.Id) .ToList(); } document.Delete(conduits); var conduit = Conduit.Create(document, conduitTypeId, x.Item2.ElementAt(i), x.Item2.ElementAt(i + 1), x.Item1); createdConduits.Add(conduit); } //for (var i = 0; i < createdConduits.Count() - 1; i++) //{ // var connector1 = new Connector(); // var connector2; // foreach (Connector c in createdConduits.ElementAt(i).ConnectorManager.Connectors) // { // // моя тут сломался фмгня получается // connector1 = c; // break; // } // foreach (Connector c in createdConduits.ElementAt(i+1).ConnectorManager.Connectors) // { // // connector2 = c; // break; // } // document.Create.NewElbowFitting( // connector1, // connector2); //} } tr.Commit(); return(Result.Succeeded); } catch (Exception e) { TaskDialog.Show("Error", e.ToString()); return(Result.Failed); } return(Result.Succeeded); }