832 lines
39 KiB
C#
832 lines
39 KiB
C#
using Autodesk.Revit.DB;
|
||
using Autodesk.Revit.UI;
|
||
using RookieStation.ProjectConfig;
|
||
using RookieStation.Utils;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Collections.ObjectModel;
|
||
using System.Linq;
|
||
using RookieStation.ParcelAreaModule.Models;
|
||
using RookieStation.ParcelAreaModule.Views;
|
||
using Autodesk.Revit.DB.Electrical;
|
||
using Autodesk.Revit.Creation;
|
||
using System.IO;
|
||
using RookieStation.ParcelAreaModule.ViewModels;
|
||
|
||
namespace RookieStation.ParcelAreaModule.ExecuteCmd
|
||
{
|
||
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
||
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
|
||
internal class PlaceShelves : IExternalCommand
|
||
{
|
||
/// <summary>
|
||
/// 编号
|
||
/// </summary>
|
||
private int currentnum = 1;
|
||
|
||
/// <summary>
|
||
/// 选择一次后停止
|
||
/// </summary>
|
||
//private static bool PlaceSingleInstanceAbort = true;
|
||
|
||
/// <summary>
|
||
/// revit窗口句柄
|
||
/// </summary>
|
||
private IntPtr revitWindow;
|
||
|
||
/// <summary>
|
||
/// 添加的元素
|
||
/// </summary>
|
||
private List<ElementId> eleIdsAdded = new List<ElementId>();
|
||
|
||
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
|
||
{
|
||
UIApplication uiapp = commandData.Application;
|
||
UIDocument uidoc = uiapp.ActiveUIDocument;
|
||
Autodesk.Revit.DB.Document doc = uidoc.Document;
|
||
revitWindow = uiapp.MainWindowHandle;
|
||
WpfShelvesLayout placement = CommonUtils.ShowDialog<WpfShelvesLayout>();
|
||
|
||
if (placement.DialogResult != true)
|
||
{
|
||
return Result.Cancelled;
|
||
}
|
||
ShelvesPlacementViewModel vm = placement.vm;
|
||
ObservableCollection<Shelf> shelves = vm.Data;
|
||
Level level = uidoc.ActiveView.GenLevel;
|
||
if (level == null)
|
||
{
|
||
return Result.Failed;
|
||
}
|
||
FamilySymbol guideSymbol = RsRevitUtils.GetGuideSymbol(doc);
|
||
if (guideSymbol == null)
|
||
{
|
||
message = "定位族丢失";
|
||
//TaskDialog.Show("错误", "定位族丢失");
|
||
return Result.Failed;
|
||
}
|
||
return doc.InvokeGroup(tg =>
|
||
{
|
||
try
|
||
{
|
||
//定位线
|
||
|
||
eleIdsAdded.Clear();
|
||
uiapp.Application.DocumentChanged += Application_DocumentChanged;
|
||
uidoc.PromptForFamilyInstancePlacement(guideSymbol);
|
||
uiapp.Application.DocumentChanged -= Application_DocumentChanged;
|
||
}
|
||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||
{
|
||
uiapp.Application.DocumentChanged -= Application_DocumentChanged;
|
||
if (eleIdsAdded.Count == 0)
|
||
{
|
||
return Result.Failed;
|
||
}
|
||
Line referline = RsRevitUtils.GetGuideGeometryAndDeleteGuide(doc, eleIdsAdded);
|
||
|
||
Family shelfFamily = null;
|
||
FamilySymbol shelfSymbol = null;
|
||
double shelfSpacing = vm.ShelfSpacing / 304.8;
|
||
//通道宽度
|
||
double passageWidth = vm.PassageWidth / 304.8;
|
||
//参考线起点平行于参考线的偏移量
|
||
double parallelReferlineOffest = vm.ParallelReferlineOffest / 304.8;
|
||
//参考线起点垂直于参考线的偏移量
|
||
double verticalReferlineOffest = vm.VerticalReferlineOffest / 304.8;
|
||
doc.Invoke(ts =>
|
||
{
|
||
shelfFamily = RsRevitUtils.GetLoadedFamily(doc, UserConstant.FamilyLibraryDirectory + "货架\\仓储货架.rfa");
|
||
}, "加载仓储货架族");
|
||
|
||
for (int i = 0; i < shelves.Count; i++)
|
||
{
|
||
Shelf shelf = shelves[i];
|
||
double shelfWidth = shelf.Width / 304.8;
|
||
List<XYZ> referlinePoints = GetReferlineShelfSplitPoints(referline, shelfSpacing, parallelReferlineOffest, shelfWidth);
|
||
double l = shelf.Length / 304.8;
|
||
shelfSymbol = GetShelfSymbol(doc, shelfFamily, shelfSymbol, shelf);
|
||
//偏移单位向量
|
||
XYZ direction = XYZ.BasisZ.CrossProduct(referline.Direction).Normalize();
|
||
List<FamilyInstance> ShelfInstances = new List<FamilyInstance>();
|
||
XYZ finalPoint = XYZ.Zero;
|
||
switch (shelf.NumOfGroup)
|
||
{
|
||
case NumOfGroup.Single:
|
||
|
||
for (int j = 0; j < referlinePoints.Count; j++)
|
||
{
|
||
XYZ offestVector = direction * (verticalReferlineOffest + l / 2);
|
||
//垂直基准线平移 平行基准线平移
|
||
finalPoint = referlinePoints[j] + offestVector + referline.Direction * shelfWidth / 2;
|
||
//附加通道和(单联、多联)货架长度的偏移
|
||
if (i > 0)
|
||
{
|
||
double totalLength = GetTotalFrontShelvesLength(shelves, i);
|
||
//附加排在前面通道和所有货架的长度
|
||
XYZ additionalVector = direction * (i * passageWidth + totalLength);
|
||
finalPoint += additionalVector;
|
||
}
|
||
FamilyInstance instance = null;
|
||
doc.Invoke(ts =>
|
||
{
|
||
instance = doc.Create.NewFamilyInstance(finalPoint, shelfSymbol, level, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
||
ShelfInstances.Add(instance);
|
||
}, "创建货架");
|
||
FlipHandShelfInstance(doc, parallelReferlineOffest, j, instance);
|
||
}
|
||
|
||
break;
|
||
|
||
case NumOfGroup.Double:
|
||
|
||
for (int j = 0; j < referlinePoints.Count; j++)
|
||
{
|
||
XYZ tempPoint = referlinePoints[j];
|
||
//偏移距离
|
||
XYZ offestVector = direction * (verticalReferlineOffest + l);
|
||
//基础偏移距离,移动半个长度到直线的一侧,垂直基准线平移 平行基准线平移
|
||
finalPoint = tempPoint + offestVector + referline.Direction * shelfWidth / 2;
|
||
//附加通道和(单联、多联)货架长度的偏移
|
||
if (i > 0)
|
||
{
|
||
double totallength = GetTotalFrontShelvesLength(shelves, i);
|
||
|
||
XYZ additionaldir = direction * (i * passageWidth + totallength);
|
||
finalPoint += additionaldir;
|
||
}
|
||
FamilyInstance endInstance = null;
|
||
FamilyInstance startInstance = null;
|
||
doc.Invoke(ts =>
|
||
{
|
||
endInstance = doc.Create.NewFamilyInstance(finalPoint + l / 2 * direction, shelfSymbol, level, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
||
|
||
startInstance = doc.Create.NewFamilyInstance(finalPoint - l / 2 * direction, shelfSymbol, level, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
||
|
||
ShelfInstances.Add(startInstance);
|
||
|
||
ShelfInstances.Add(endInstance);
|
||
}, "创建货架");
|
||
FlipHandShelfInstance(doc, parallelReferlineOffest, j, startInstance, endInstance);
|
||
}
|
||
break;
|
||
|
||
case NumOfGroup.Three:
|
||
|
||
for (int j = 0; j < referlinePoints.Count; j++)
|
||
{
|
||
XYZ tempPoint = referlinePoints[j];
|
||
XYZ offestVector = direction * (verticalReferlineOffest + l * 3 / 2);
|
||
//垂直基准线平移 平行基准线平移
|
||
finalPoint = tempPoint + offestVector + referline.Direction * shelfWidth / 2;
|
||
//附加通道和(单联、多联)货架长度的偏移
|
||
if (i > 0)
|
||
{
|
||
double totallength = GetTotalFrontShelvesLength(shelves, i);
|
||
XYZ additionaldir = direction * (i * passageWidth + totallength);
|
||
finalPoint += additionaldir;
|
||
}
|
||
FamilyInstance endInstance = null;
|
||
FamilyInstance centerInstance = null;
|
||
FamilyInstance startInstance = null;
|
||
doc.Invoke(ts =>
|
||
{
|
||
centerInstance = doc.Create.NewFamilyInstance(finalPoint, shelfSymbol, level, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
||
endInstance = doc.Create.NewFamilyInstance(finalPoint + l * direction, shelfSymbol, level, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
||
startInstance = doc.Create.NewFamilyInstance(finalPoint - l * direction, shelfSymbol, level, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
||
ShelfInstances.Add(centerInstance);
|
||
ShelfInstances.Add(endInstance);
|
||
ShelfInstances.Add(startInstance);
|
||
}, "创建货架");
|
||
FlipHandShelfInstance(doc, parallelReferlineOffest, j, startInstance, centerInstance, endInstance);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
doc.Invoke(ts =>
|
||
{
|
||
for (int j = 0; j < ShelfInstances.Count; j++)
|
||
{
|
||
XYZ veroffestdir = XYZ.BasisZ.CrossProduct(referline.Direction).Normalize();
|
||
//旋转角度
|
||
double angle = XYZ.BasisY.AngleTo(veroffestdir);
|
||
//判断相对于Y轴是正向角度(逆时针)还是逆向角度(顺时针)
|
||
var z = veroffestdir.CrossProduct(XYZ.BasisY).Normalize();
|
||
if (z.IsAlmostEqualTo(XYZ.BasisZ))
|
||
{
|
||
//逆向旋转,角度取负值
|
||
angle = -angle;
|
||
}
|
||
FamilyInstance shelfInstance = ShelfInstances[j];
|
||
var loc = RsRevitUtils.GetLocationPointByElement(shelfInstance);
|
||
|
||
Line zline = Line.CreateUnbound(loc, XYZ.BasisZ);
|
||
//旋转,移动
|
||
ElementTransformUtils.RotateElement(doc, shelfInstance.Id, zline, angle);
|
||
//旋转后的
|
||
var handOrientationd = shelfInstance.HandOrientation;
|
||
//货架左右切换时
|
||
if (shelfInstance.HandFlipped)
|
||
{
|
||
handOrientationd = -handOrientationd;
|
||
}
|
||
////垂直基准线平移
|
||
//ElementTransformUtils.MoveElement(doc, fi.Id, offestdir);
|
||
|
||
////平行基准线平移
|
||
//ElementTransformUtils.MoveElement(doc, fi.Id, line.Direction * w / 2);
|
||
//if (i >= 1)
|
||
//{
|
||
// XYZ additionaldir = zdir.CrossProduct(line.Direction).Normalize() * i * (passagewidth + l);
|
||
// ElementTransformUtils.MoveElement(doc, fi.Id, additionaldir);
|
||
//}
|
||
}
|
||
}, "调整货架位置");
|
||
if (vm.IsPlaceShelfCards == true)
|
||
{
|
||
var cardInstances = CreateAndNumberCards(doc, referline, shelf, ShelfInstances);
|
||
doc.Invoke(ts =>
|
||
{
|
||
RsRevitUtils.DeleteOverlapFamilyInstance(doc, cardInstances);
|
||
}, "删除重合端牌");
|
||
}
|
||
}
|
||
if (vm.IsPlaceCableTray == true)
|
||
{
|
||
CreateCableTrays(doc, vm, referline, shelfSpacing, passageWidth, parallelReferlineOffest);
|
||
}
|
||
if (vm.IsPlaceLight == true)
|
||
{
|
||
var locs = new List<XYZ>();
|
||
CreateLights(doc, vm, referline, shelfSpacing, passageWidth, parallelReferlineOffest, out locs);
|
||
CreateMessengerWire(doc, vm, locs);
|
||
}
|
||
}
|
||
return Result.Succeeded;
|
||
}, "取件区布置");
|
||
}
|
||
|
||
private static void FlipHandShelfInstance(Autodesk.Revit.DB.Document doc, double parallelReferlineOffest, int i, params FamilyInstance[] familyInstances)
|
||
{
|
||
doc.Invoke(ts =>
|
||
{
|
||
if (parallelReferlineOffest < 0.001)//起始水平偏移量为0时
|
||
{
|
||
if (i % 2 != 0)
|
||
{
|
||
for (int j = 0; j < familyInstances.Count(); j++)
|
||
{
|
||
if (familyInstances[j].CanFlipHand)
|
||
{
|
||
familyInstances[j].flipHand();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (i % 2 == 0)
|
||
{
|
||
for (int j = 0; j < familyInstances.Count(); j++)
|
||
{
|
||
if (familyInstances[j].CanFlipHand)
|
||
{
|
||
familyInstances[j].flipHand();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}, "翻转货架");
|
||
}
|
||
|
||
private static FamilySymbol GetShelfSymbol(Autodesk.Revit.DB.Document doc, Family shelfFamily, FamilySymbol shelfSymbol, Shelf shelf)
|
||
{
|
||
doc.Invoke(ts =>
|
||
{
|
||
if (shelfFamily != null)
|
||
{
|
||
var shelfSymbolIds = shelfFamily.GetFamilySymbolIds();
|
||
foreach (var id in shelfSymbolIds)
|
||
{
|
||
FamilySymbol tempSymbol = doc.GetElement(id) as FamilySymbol;
|
||
if (tempSymbol.Name == shelf.SymbolName)
|
||
{
|
||
shelfSymbol = tempSymbol;
|
||
break;
|
||
}
|
||
}
|
||
if (!shelfSymbol.IsActive)
|
||
{
|
||
shelfSymbol.Activate();
|
||
}
|
||
}
|
||
}, "加载货架,激活类型");
|
||
return shelfSymbol;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建吊线
|
||
/// </summary>
|
||
/// <param name="locs"></param>
|
||
private void CreateMessengerWire(Autodesk.Revit.DB.Document doc, ShelvesPlacementViewModel vm, List<XYZ> locs)
|
||
{
|
||
doc.Invoke(ts =>
|
||
{
|
||
string file = UserConstant.FamilyLibraryDirectory + "其他\\吊线.rfa";
|
||
FamilySymbol symbol = RsRevitUtils.GetAndActiveDefaultFamilySymbol(doc, file);
|
||
try
|
||
{
|
||
for (int i = 0; i < locs.Count; i++)
|
||
{
|
||
var instance = doc.Create.NewFamilyInstance(locs[i] + XYZ.BasisZ * (vm.LightHeight + 100) / 304.8, symbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
||
double length = (UserConstant.Height - vm.LightHeight - 100) / 304.8;
|
||
if (length > 0)
|
||
{
|
||
instance.GetParameters("吊线长度").FirstOrDefault().Set(length);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.WriteLog(ex.Message);
|
||
}
|
||
}, "布置吊线");
|
||
}
|
||
|
||
private void CreateCableTrays(Autodesk.Revit.DB.Document doc, ShelvesPlacementViewModel vm, Line referline, double shelfSpacing, double passageWidth, double parallelReferlineOffest)
|
||
{
|
||
Level level = doc.ActiveView.GenLevel;
|
||
List<CableTray> cts = new List<CableTray>();
|
||
ObservableCollection<Shelf> shelves = vm.Data;
|
||
var referlinePoints = GetReferlineCableTrayStartPoint(referline, shelfSpacing, parallelReferlineOffest, shelves.First().Width / 304.8);
|
||
XYZ offestVector = XYZ.BasisZ.CrossProduct(referline.Direction).Normalize();
|
||
var firstRowPoints = referlinePoints.ConvertAll(p => p - (offestVector * 400 / 304.8));
|
||
var totalLength = GetTotalFrontShelvesLength(shelves, shelves.Count) + passageWidth * (shelves.Count - 1);
|
||
var lastRowPoints = referlinePoints.ConvertAll(p => p + offestVector * (400 / 304.8 + totalLength));
|
||
doc.Invoke(ts =>
|
||
{
|
||
//var lastpoints = GetCableTrayStartPoint(referline, shelfSpacing, parallelReferlineOffest, shelves.Last().Width / 304.8);
|
||
var ctTypeId = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_CableTray).OfClass(typeof(CableTrayType)).WhereElementIsElementType().FirstElementId();
|
||
for (int j = 0; j < referlinePoints.Count; j++)
|
||
{
|
||
var ct = CableTray.Create(doc, ctTypeId, firstRowPoints[j], lastRowPoints[j], level.Id);
|
||
cts.Add(ct);
|
||
}
|
||
for (int i = 0; i < firstRowPoints.Count() - 1; i++)
|
||
{
|
||
var frontct = CableTray.Create(doc, ctTypeId, firstRowPoints[i], firstRowPoints[i + 1], level.Id);
|
||
cts.Add(frontct);
|
||
}
|
||
for (int i = 0; i < lastRowPoints.Count() - 1; i++)
|
||
{
|
||
var backct = CableTray.Create(doc, ctTypeId, lastRowPoints[i], lastRowPoints[i + 1], level.Id);
|
||
cts.Add(backct);
|
||
}
|
||
foreach (var ct in cts)
|
||
{
|
||
ct.get_Parameter(BuiltInParameter.RBS_CABLETRAY_WIDTH_PARAM).Set(100 / 304.8);
|
||
ct.get_Parameter(BuiltInParameter.RBS_CABLETRAY_HEIGHT_PARAM).Set(50 / 304.8);
|
||
ct.get_Parameter(BuiltInParameter.RBS_CTC_BOTTOM_ELEVATION).Set((vm.LightHeight + 100) / 304.8);
|
||
}
|
||
doc.Regenerate();
|
||
List<Connector> connectors = new List<Connector>();
|
||
connectors.AddRange(cts.ConvertAll(ct => ct.ConnectorManager.Lookup(0)));
|
||
connectors.AddRange(cts.ConvertAll(ct => ct.ConnectorManager.Lookup(1)));
|
||
var connectorGropy = connectors.GroupBy(con => new { con.Origin.X, con.Origin.Y });
|
||
//生成弯头三通后,会修改connector的原点,造成分组问题,所以将其重新组合成list
|
||
List<List<Connector>> connectorsList = new List<List<Connector>>();
|
||
for (int i = 0; i < connectorGropy.Count(); i++)
|
||
{
|
||
var g = connectorGropy.ElementAt(i).ToList();
|
||
connectorsList.Add(g);
|
||
}
|
||
|
||
for (int i = 0; i < connectorsList.Count(); i++)
|
||
{
|
||
var g = connectorsList[i];
|
||
try
|
||
{
|
||
if (g.Count() == 2)
|
||
{
|
||
//g.ElementAt(0).ConnectTo(g.ElementAt(1));
|
||
doc.Create.NewElbowFitting(g.ElementAt(0), g.ElementAt(1));
|
||
}
|
||
|
||
if (g.Count() == 3)
|
||
{
|
||
var line = RsRevitUtils.GetLocationCurveByElement(g.ElementAt(0).Owner) as Line;
|
||
var line1 = RsRevitUtils.GetLocationCurveByElement(g.ElementAt(1).Owner) as Line;
|
||
var line2 = RsRevitUtils.GetLocationCurveByElement(g.ElementAt(2).Owner) as Line;
|
||
if (line.Direction.CrossProduct(line1.Direction).IsZeroLength())
|
||
{
|
||
doc.Create.NewTeeFitting(g.ElementAt(0), g.ElementAt(1), g.ElementAt(2));
|
||
}
|
||
else if (line.Direction.CrossProduct(line2.Direction).IsZeroLength())
|
||
{
|
||
doc.Create.NewTeeFitting(g.ElementAt(0), g.ElementAt(2), g.ElementAt(1));
|
||
}
|
||
else
|
||
{
|
||
doc.Create.NewTeeFitting(g.ElementAt(1), g.ElementAt(2), g.ElementAt(0));
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.WriteLog(ex.Message);
|
||
continue;
|
||
}
|
||
}
|
||
}, "桥架创建");
|
||
}
|
||
|
||
private void CreateLights(Autodesk.Revit.DB.Document doc, ShelvesPlacementViewModel vm, Line referline, double shelfSpacing, double passageWidth, double parallelReferlineOffest, out List<XYZ> Locations)
|
||
{
|
||
ObservableCollection<Shelf> shelves = vm.Data;
|
||
var referlinePoints = GetReferlineCableTrayStartPoint(referline, shelfSpacing, parallelReferlineOffest, shelves.First().Width / 304.8);
|
||
XYZ offestVector = XYZ.BasisZ.CrossProduct(referline.Direction).Normalize();
|
||
//第一排
|
||
var firstRowPoints = referlinePoints.ConvertAll(p => p - (offestVector * 400 / 304.8));
|
||
var totalLength = GetTotalFrontShelvesLength(shelves, shelves.Count) + passageWidth * (shelves.Count - 1);
|
||
//最后一排
|
||
var lastRowPoints = referlinePoints.ConvertAll(p => p + offestVector * (400 / 304.8 + totalLength));
|
||
List<XYZ> locs = new List<XYZ>();
|
||
Locations = locs;
|
||
|
||
string file = UserConstant.FamilyLibraryDirectory + "灯具\\明装筒灯.rfa";
|
||
List<FamilyInstanceCreationData> instanceCreationDatas = new List<FamilyInstanceCreationData>();
|
||
|
||
for (int i = 0; i < firstRowPoints.Count; i++)
|
||
{
|
||
Line line = Line.CreateBound(firstRowPoints[i], lastRowPoints[i]);
|
||
|
||
int n = 1000;
|
||
double param = 2000 / 304.8;
|
||
for (int j = 0; j < n; j++)
|
||
{
|
||
if (!line.IsInside(param * j))
|
||
{
|
||
locs.Add(line.GetEndPoint(1));
|
||
break;
|
||
}
|
||
XYZ po = line.Evaluate(param * j, false);
|
||
locs.Add(po);
|
||
}
|
||
}
|
||
doc.Invoke(ts =>
|
||
{
|
||
FamilySymbol symbol = RsRevitUtils.GetAndActiveDefaultFamilySymbol(doc, file);
|
||
try
|
||
{
|
||
foreach (XYZ p in locs)
|
||
{
|
||
FamilyInstanceCreationData instanceCreationData = new FamilyInstanceCreationData(p + XYZ.BasisZ * vm.LightHeight / 304.8, symbol, doc.ActiveView.GenLevel, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
||
instanceCreationDatas.Add(instanceCreationData);
|
||
}
|
||
doc.Create.NewFamilyInstances2(instanceCreationDatas);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.WriteLog(ex.Message);
|
||
}
|
||
}, "创建灯具");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建货架并编号
|
||
/// </summary>
|
||
/// <param name="doc"></param>
|
||
/// <param name="referline"></param>
|
||
/// <param name="shelf"></param>
|
||
/// <param name="shelfInstances"></param>
|
||
private List<FamilyInstance> CreateAndNumberCards(Autodesk.Revit.DB.Document doc, Line referline, Shelf shelf, List<FamilyInstance> shelfInstances)
|
||
{
|
||
List<FamilyInstance> cardInstances = new List<FamilyInstance>();
|
||
|
||
doc.Invoke(ts =>
|
||
{
|
||
for (int j = 0; j < shelfInstances.Count; j++)
|
||
{
|
||
FamilyInstance instance = shelfInstances[j];
|
||
var loc = RsRevitUtils.GetLocationPointByElement(instance);
|
||
|
||
Line zline = Line.CreateUnbound(loc, XYZ.BasisZ);
|
||
//旋转后的
|
||
var handOrientationd = instance.HandOrientation;
|
||
//货架左右切换时
|
||
if (instance.HandFlipped)
|
||
{
|
||
handOrientationd = -handOrientationd;
|
||
}
|
||
|
||
#region 布置端牌
|
||
|
||
FamilyInstance frontInstance = null;
|
||
|
||
Reference frontFace = instance.GetReferences(FamilyInstanceReferenceType.Front).FirstOrDefault();
|
||
PlaceCard(doc, loc, instance, handOrientationd, frontFace, out frontInstance);
|
||
if (frontInstance.CanFlipWorkPlane)
|
||
{
|
||
frontInstance.IsWorkPlaneFlipped = true;
|
||
}
|
||
cardInstances.Add(frontInstance);
|
||
|
||
FamilyInstance backInstance = null;
|
||
Reference backFace = instance.GetReferences(FamilyInstanceReferenceType.Back).FirstOrDefault();
|
||
PlaceCard(doc, loc, instance, -handOrientationd, backFace, out backInstance);
|
||
|
||
cardInstances.Add(backInstance);
|
||
NumberCards(shelf, shelfInstances, j, frontInstance, backInstance);
|
||
|
||
#endregion 布置端牌
|
||
|
||
//Reference backface = fi.GetReferences(FamilyInstanceReferenceType.Back).FirstOrDefault();
|
||
//if (a.Contains("606:SURFACE"))
|
||
//{
|
||
// hand = -fi.HandOrientation;
|
||
//}
|
||
}
|
||
}, "调整货架角度及布置端牌");
|
||
return cardInstances;
|
||
}
|
||
|
||
private void NumberCards(Shelf shelf, List<FamilyInstance> shelfInstances, int i, params FamilyInstance[] cardInstances)
|
||
{
|
||
switch (shelf.NumOfGroup)
|
||
{
|
||
case NumOfGroup.Single:
|
||
for (int j = 0; j < cardInstances.Count(); j++)
|
||
{
|
||
if (currentnum < 10)
|
||
{
|
||
cardInstances[j].GetParameters("货架号").FirstOrDefault().Set($"0{currentnum}");
|
||
}
|
||
else
|
||
{
|
||
cardInstances[j].GetParameters("货架号").FirstOrDefault().Set($"{currentnum}");
|
||
}
|
||
}
|
||
|
||
currentnum += 1;
|
||
break;
|
||
|
||
case NumOfGroup.Double:
|
||
//根据组合加上组合数
|
||
if (i % 2 == 0 && i != 0)
|
||
{
|
||
currentnum += 2;
|
||
}
|
||
for (int j = 0; j < cardInstances.Count(); j++)
|
||
{
|
||
if (currentnum < 9)
|
||
{
|
||
cardInstances[j].GetParameters("货架号").FirstOrDefault().Set($"0{currentnum}~0{currentnum + 1}");
|
||
}
|
||
else if (currentnum == 9)
|
||
{
|
||
cardInstances[j].GetParameters("货架号").FirstOrDefault().Set($"0{currentnum}~{currentnum + 1}");
|
||
}
|
||
else
|
||
{
|
||
cardInstances[j].GetParameters("货架号").FirstOrDefault().Set($"{currentnum}~{currentnum + 1}");
|
||
}
|
||
}
|
||
//最后一个需要加上组合数作为下一列的开始
|
||
if (i == shelfInstances.Count - 1)
|
||
{
|
||
currentnum += 2;
|
||
}
|
||
break;
|
||
|
||
case NumOfGroup.Three:
|
||
//根据组合加上组合数
|
||
if (i % 3 == 0 && i != 0)
|
||
{
|
||
currentnum += 3;
|
||
}
|
||
for (int j = 0; j < cardInstances.Count(); j++)
|
||
{
|
||
if (currentnum < 9)
|
||
{
|
||
cardInstances[j].GetParameters("货架号").FirstOrDefault().Set($"0{currentnum}~0{currentnum + 2}");
|
||
}
|
||
else
|
||
{
|
||
cardInstances[j].GetParameters("货架号").FirstOrDefault().Set($"{currentnum}~{currentnum + 2}");
|
||
}
|
||
}
|
||
//最后一个需要加上组合数作为下一列的开始
|
||
if (i == shelfInstances.Count - 1)
|
||
{
|
||
currentnum += 3;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 桥架起点
|
||
/// </summary>
|
||
/// <param name="referline"></param>
|
||
/// <param name="shelfSpacing"></param>
|
||
/// <param name="parallelReferlineOffest"></param>
|
||
/// <param name="shelfWidth"></param>
|
||
/// <returns></returns>
|
||
private static List<XYZ> GetReferlineCableTrayStartPoint(Line referline, double shelfSpacing, double parallelReferlineOffest, double shelfWidth)
|
||
{
|
||
int n = 100;
|
||
double lineParameter = 0.0;
|
||
List<XYZ> firstRowPoints = new List<XYZ>();
|
||
XYZ pointOnReferline = XYZ.Zero;
|
||
if (parallelReferlineOffest < 0.001)//起点无间距,起始点具有货架
|
||
{
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
if (!referline.IsInside(lineParameter + 2 * shelfWidth + shelfSpacing))
|
||
{
|
||
break;
|
||
}
|
||
lineParameter = (shelfSpacing * (i + 0.5)) + (((2 * i) + 1) * shelfWidth);
|
||
pointOnReferline = referline.Evaluate(lineParameter, false);
|
||
firstRowPoints.Add(pointOnReferline);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
if (!referline.IsInside(lineParameter + (2 * shelfWidth) + shelfSpacing))
|
||
{
|
||
break;
|
||
}
|
||
if (i == 0)
|
||
{
|
||
pointOnReferline = referline.Evaluate(parallelReferlineOffest / 2, false);
|
||
}
|
||
else
|
||
{
|
||
lineParameter = parallelReferlineOffest + (2 * i * shelfWidth) + shelfSpacing * (i - 0.5);
|
||
pointOnReferline = referline.Evaluate(lineParameter, false);
|
||
}
|
||
firstRowPoints.Add(pointOnReferline);
|
||
}
|
||
}
|
||
|
||
return firstRowPoints;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据货架布置参数,分割参考线(货架左下角点)
|
||
/// </summary>
|
||
/// <param name="referline"></param>
|
||
/// <param name="shelfSpacing">货架间距</param>
|
||
/// <param name="parallelReferlineOffest">参考线起点进行水平偏移距离</param>
|
||
/// <param name="shelfWidth">货架宽度</param>
|
||
/// <returns></returns>
|
||
private static List<XYZ> GetReferlineShelfSplitPoints(Line referline, double shelfSpacing, double parallelReferlineOffest, double shelfWidth)
|
||
{
|
||
int n = 100;//循环次数
|
||
List<XYZ> firstRowPoints = new List<XYZ>();
|
||
XYZ pointOnReferline = XYZ.Zero;
|
||
double lineParameter = 0.0;
|
||
if (parallelReferlineOffest < 0.001)//起点无间距,起始点具有货架
|
||
{
|
||
for (int j = 0; j < n; j++)
|
||
{
|
||
if (!referline.IsInside(lineParameter + shelfWidth))
|
||
{
|
||
break;
|
||
}
|
||
if (j % 2 == 0)
|
||
{
|
||
pointOnReferline = referline.Evaluate(lineParameter, false);
|
||
lineParameter += shelfSpacing + shelfWidth;//存在不同的间距,所以需分开增加
|
||
}
|
||
else
|
||
{
|
||
pointOnReferline = referline.Evaluate(lineParameter, false);
|
||
lineParameter += shelfWidth;//存在不同的间距,所以需分开增加
|
||
}
|
||
|
||
firstRowPoints.Add(pointOnReferline);
|
||
}
|
||
}
|
||
else//起点有距离,即起始点无货架
|
||
{
|
||
lineParameter = parallelReferlineOffest;
|
||
|
||
for (int j = 0; j < n; j++)
|
||
{
|
||
if (!referline.IsInside(lineParameter + shelfWidth))
|
||
{
|
||
break;
|
||
}
|
||
if (j % 2 == 0)
|
||
{
|
||
pointOnReferline = referline.Evaluate(lineParameter, false);
|
||
lineParameter += shelfWidth;//存在不同的间距,所以需分开增加
|
||
}
|
||
else
|
||
{
|
||
pointOnReferline = referline.Evaluate(lineParameter, false);
|
||
lineParameter += shelfSpacing + shelfWidth;//存在不同的间距,所以需分开增加
|
||
}
|
||
|
||
firstRowPoints.Add(pointOnReferline);
|
||
}
|
||
}
|
||
|
||
return firstRowPoints;
|
||
}
|
||
|
||
private void Application_DocumentChanged(object sender, Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
|
||
{
|
||
ICollection<ElementId> idsAdded = e.GetAddedElementIds();
|
||
int n = idsAdded.Count;
|
||
//List<Element> eles = new List<Element>();
|
||
//foreach (var id in idsAdded)
|
||
//{
|
||
// eles.Add(e.GetDocument().GetElement(id));
|
||
//}
|
||
eleIdsAdded.AddRange(idsAdded);
|
||
//if (PlaceSingleInstanceAbort && n == 1)
|
||
if (n == 1)
|
||
{
|
||
KeyPress.PostMessage(revitWindow, (uint)KeyPress.KEYBOARD_MSG.WM_KEYDOWN, (uint)System.Windows.Forms.Keys.Escape, 0);
|
||
KeyPress.PostMessage(revitWindow, (uint)KeyPress.KEYBOARD_MSG.WM_KEYDOWN, (uint)System.Windows.Forms.Keys.Escape, 0);
|
||
//KeyPress.OneKey(revitWindow, (char)System.Windows.Forms.Keys.Escape);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 布置端牌
|
||
/// </summary>
|
||
/// <param name="doc"></param>
|
||
/// <param name="p"></param>
|
||
/// <param name="fi"></param>
|
||
/// <param name="handOrientation">左右方向</param>
|
||
/// <param name="facereference"></param>
|
||
/// <param name="cardInstance"></param>
|
||
private void PlaceCard(Autodesk.Revit.DB.Document doc, XYZ p, FamilyInstance fi, XYZ handOrientation, Reference facereference, out FamilyInstance cardInstance)
|
||
{
|
||
var shelfwidth = fi.Symbol.GetParameters("宽度").FirstOrDefault().AsDouble();
|
||
|
||
Family card = RsRevitUtils.GetLoadedFamily(doc, UserConstant.FamilyLibraryDirectory + "货架\\货架端牌.rfa");
|
||
var cardsymbolIds = card.GetFamilySymbolIds();
|
||
|
||
FamilySymbol cardsymbol = null;
|
||
foreach (ElementId syid in cardsymbolIds)
|
||
{
|
||
var sy = doc.GetElement(syid) as FamilySymbol;
|
||
var cardwidth = sy.GetParameters("宽度").FirstOrDefault().AsDouble();
|
||
if (cardwidth == shelfwidth)
|
||
{
|
||
cardsymbol = sy;
|
||
}
|
||
}
|
||
if (!cardsymbol.IsActive)
|
||
{
|
||
cardsymbol.Activate();
|
||
}
|
||
cardInstance = doc.Create.NewFamilyInstance(facereference, p, handOrientation, cardsymbol);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取该行之前的所有货架长度总和(英制)
|
||
/// </summary>
|
||
/// <param name="shelves"></param>
|
||
/// <param name="i">行数大于1即i>0</param>
|
||
/// <returns></returns>
|
||
private double GetTotalFrontShelvesLength(ObservableCollection<Shelf> shelves, int i)
|
||
{
|
||
double totallength = 0.0;
|
||
for (int j = 0; j < i; j++)
|
||
{
|
||
switch (shelves[j].NumOfGroup)
|
||
{
|
||
case NumOfGroup.Single:
|
||
totallength += shelves[j].Length / 304.8;
|
||
break;
|
||
|
||
case NumOfGroup.Double:
|
||
totallength += shelves[j].Length * 2 / 304.8;
|
||
break;
|
||
|
||
case NumOfGroup.Three:
|
||
totallength += shelves[j].Length * 3 / 304.8;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
return totallength;
|
||
}
|
||
}
|
||
} |