添加项目文件。
This commit is contained in:
403
Sai.RvKits/ModelManager/CorrectReferLevelExecutes.cs
Normal file
403
Sai.RvKits/ModelManager/CorrectReferLevelExecutes.cs
Normal file
@@ -0,0 +1,403 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Electrical;
|
||||
using Autodesk.Revit.DB.Mechanical;
|
||||
using Autodesk.Revit.DB.Plumbing;
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
using Sai.RvKits.Windows;
|
||||
|
||||
|
||||
namespace Sai.RvKits.RvFamily;
|
||||
|
||||
public class CorrectReferLevelExecutes
|
||||
{
|
||||
public CorrectReferLevelExecutes(UIApplication uiapp)
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
doc = uidoc.Document;
|
||||
view = uidoc.ActiveView;
|
||||
levels =doc.OfClass<Level>()
|
||||
.OfCategory(BuiltInCategory.OST_Levels)
|
||||
.Cast<Level>()
|
||||
.OrderBy(l => l.Elevation)
|
||||
.ToList();
|
||||
levelOutlines = GetRegions(levels);
|
||||
}
|
||||
|
||||
private readonly Document doc;
|
||||
private readonly Dictionary<Level, Outline> levelOutlines;
|
||||
|
||||
private readonly List<Level> levels;
|
||||
|
||||
//private uiApplication uiApplication;
|
||||
private readonly View view;
|
||||
/// <summary>
|
||||
/// 设置族实例
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<MessageModel> SetInstances()
|
||||
{
|
||||
List<MessageModel> errors = [];
|
||||
doc.Invoke(ts =>
|
||||
{
|
||||
//对比标高,得到实际分层位置
|
||||
foreach (var keyPair in levelOutlines)
|
||||
{
|
||||
//得到在标高范围内的元素
|
||||
BoundingBoxIsInsideFilter insideFilter = new(keyPair.Value);
|
||||
var level = keyPair.Key;
|
||||
var insideCollector = new FilteredElementCollector(doc).WherePasses(insideFilter).Where(elem => elem is FamilyInstance && (elem.LevelId != level.Id || elem.get_BoundingBox(view) != null)).ToList();
|
||||
|
||||
foreach (var elem in insideCollector)
|
||||
{
|
||||
try
|
||||
{
|
||||
//获取构件定位方式,基于标高,基于主体(基于面,基于线,基于主体构件:墙板等),基于点
|
||||
if (elem is not FamilyInstance familyInstance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var placementType = familyInstance.Symbol.Family.FamilyPlacementType;
|
||||
|
||||
switch (placementType)
|
||||
{
|
||||
case FamilyPlacementType.OneLevelBased:
|
||||
ModifyOneLevelBasedFamily(doc, level, familyInstance);
|
||||
break;
|
||||
case FamilyPlacementType.OneLevelBasedHosted:
|
||||
break;
|
||||
case FamilyPlacementType.TwoLevelsBased:
|
||||
ModifyTwoLevelBasedFamily(doc, levels, level, familyInstance);
|
||||
break;
|
||||
case FamilyPlacementType.ViewBased:
|
||||
break;
|
||||
case FamilyPlacementType.WorkPlaneBased:
|
||||
ModifyWorkPlaneBasedFamily(doc, level, familyInstance);
|
||||
break;
|
||||
case FamilyPlacementType.CurveBased:
|
||||
ModifyCurveBasedFamily(doc, level, familyInstance);
|
||||
break;
|
||||
case FamilyPlacementType.CurveBasedDetail:
|
||||
break;
|
||||
case FamilyPlacementType.CurveDrivenStructural:
|
||||
break;
|
||||
case FamilyPlacementType.Adaptive:
|
||||
break;
|
||||
case FamilyPlacementType.Invalid:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(new MessageModel(elem, ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "校正族实例标高");
|
||||
return errors;
|
||||
//if (errors.Any())
|
||||
//{
|
||||
// var processorViewModel = new ErrorResolveViewModel(UiDocument, errors);
|
||||
// var errorResolveWin = new ErrorResolveWin(processorViewModel);
|
||||
// WinDialogHelper.ShowAhead(errorResolveWin);
|
||||
//}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置管线
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<MessageModel> SetMEPCurves()
|
||||
{
|
||||
List<MessageModel> errors = [];
|
||||
doc.Invoke(ts =>
|
||||
{
|
||||
//对比标高,得到实际分层位置
|
||||
foreach (var keyPair in levelOutlines)
|
||||
{
|
||||
//得到在标高范围内的元素
|
||||
BoundingBoxIsInsideFilter insideFilter = new(keyPair.Value);
|
||||
var level = keyPair.Key;
|
||||
var insideCollector = new FilteredElementCollector(doc).WherePasses(insideFilter).Where(elem => elem.LevelId != level.Id || elem.get_BoundingBox(view) != null).ToList();
|
||||
|
||||
foreach (var elem in insideCollector)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (elem is Pipe or Duct or CableTray or Conduit)
|
||||
{
|
||||
elem.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM).Set(level.Id);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(new MessageModel(elem, ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "校正管线标高");
|
||||
return errors;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置墙
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<MessageModel> SetWalls()
|
||||
{
|
||||
List<MessageModel> errors = [];
|
||||
doc.Invoke(_ =>
|
||||
{
|
||||
//对比标高,得到实际分层位置
|
||||
foreach (var keyPair in levelOutlines)
|
||||
{
|
||||
//得到在标高范围内的元素
|
||||
BoundingBoxIsInsideFilter insideFilter = new(keyPair.Value);
|
||||
var level = keyPair.Key;
|
||||
var insideCollector = new FilteredElementCollector(doc).WherePasses(insideFilter).Where(elem => elem.LevelId != level.Id || elem.get_BoundingBox(view) != null).ToList();
|
||||
foreach (var elem in insideCollector)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (elem is Wall)
|
||||
{
|
||||
ModifyWall(view, levels, level, elem);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(new MessageModel(elem, ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "校正墙体标高");
|
||||
return errors;
|
||||
//if (errors.Any())
|
||||
//{
|
||||
// var processorViewModel = new ErrorResolveViewModel(UiDocument, errors);
|
||||
// var errorResolveWin = new ErrorResolveWin(processorViewModel);
|
||||
// WinDialogHelper.ShowAhead(errorResolveWin);
|
||||
//}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取基于标高的边界
|
||||
/// </summary>
|
||||
/// <param name="levels"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<Level, Outline> GetRegions(IEnumerable<Level> levels)
|
||||
{
|
||||
Dictionary<Level, Outline> levelOutlines = [];
|
||||
|
||||
////获取标高范围
|
||||
for (var i = 0; i < levels.Count() - 1; i++)
|
||||
{
|
||||
var baseLevel = levels.ElementAt(i);
|
||||
var topLevel = levels.ElementAt(i + 1);
|
||||
XYZ min = new(double.MinValue, double.MinValue, baseLevel.Elevation);
|
||||
XYZ max = new(double.MaxValue, double.MaxValue, topLevel.Elevation);
|
||||
Outline outline = new(min, max);
|
||||
levelOutlines.Add(baseLevel, outline);
|
||||
}
|
||||
|
||||
return levelOutlines;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改基于线的族
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="familyInstance"></param>
|
||||
private static void ModifyCurveBasedFamily(Document doc, Level level, FamilyInstance familyInstance)
|
||||
{
|
||||
var originOffset = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).AsDouble();
|
||||
if (familyInstance.Host is not Level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!familyInstance.Symbol.IsActive)
|
||||
{
|
||||
familyInstance.Symbol.Activate();
|
||||
}
|
||||
|
||||
var hostLevel = familyInstance.Host as Level;
|
||||
var offset = hostLevel.Elevation + originOffset - level.Elevation;
|
||||
var loc = familyInstance.Location as LocationCurve;
|
||||
var p1 = loc.Curve.GetEndPoint(0);
|
||||
var p2 = loc.Curve.GetEndPoint(1);
|
||||
var line = Line.CreateBound(p1.Add(XYZ.BasisZ * level.Elevation), p2.Add(XYZ.BasisZ * level.Elevation));
|
||||
|
||||
var newFamilyInstance = doc.Create.NewFamilyInstance(level.GetPlaneReference(), line, familyInstance.Symbol);
|
||||
var offsetParam = newFamilyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
|
||||
offsetParam.Set(offset);
|
||||
foreach (Parameter param in familyInstance.Parameters)
|
||||
{
|
||||
if (param.IsReadOnly || param.Definition.Name == offsetParam.Definition.Name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (param.StorageType)
|
||||
{
|
||||
case StorageType.None:
|
||||
break;
|
||||
case StorageType.Integer:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsInteger());
|
||||
break;
|
||||
case StorageType.Double:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsDouble());
|
||||
break;
|
||||
case StorageType.String:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsString());
|
||||
break;
|
||||
case StorageType.ElementId:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsElementId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
doc.Delete(familyInstance.Id);
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改基于标高的族
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="familyInstance"></param>
|
||||
private static void ModifyOneLevelBasedFamily(Document doc, Level level, FamilyInstance familyInstance)
|
||||
{
|
||||
var baseLevelParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM);
|
||||
var originLevel = doc.GetElement(baseLevelParam.AsElementId()) as Level;
|
||||
baseLevelParam.Set(level.Id);
|
||||
|
||||
var param = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
|
||||
if (param == null || param.IsReadOnly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var value = param.AsDouble();
|
||||
param.Set(originLevel.Elevation + value - level.Elevation);
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改基于两个标高的族
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
/// <param name="levels"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="familyInstance"></param>
|
||||
private static void ModifyTwoLevelBasedFamily(Document doc, List<Level> levels, Level level, FamilyInstance familyInstance)
|
||||
{
|
||||
var n = levels.FindIndex(l => l.Id == level.Id);
|
||||
|
||||
var baseLevelParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM);
|
||||
var originLevel = doc.GetElement(baseLevelParam.AsElementId()) as Level;
|
||||
baseLevelParam.Set(level.Id);
|
||||
|
||||
var baseOffsetParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM);
|
||||
|
||||
var baseOffsetValue = baseOffsetParam.AsDouble();
|
||||
baseOffsetParam.Set(baseOffsetValue + originLevel.Elevation - level.Elevation);
|
||||
|
||||
var topLevelParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);
|
||||
originLevel = doc.GetElement(topLevelParam.AsElementId()) as Level;
|
||||
topLevelParam.Set(levels[n + 1].Id);
|
||||
|
||||
var topOffsetParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM);
|
||||
|
||||
var topOffsetValue = topOffsetParam.AsDouble();
|
||||
|
||||
familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(originLevel.Elevation + topOffsetValue - levels[n + 1].Elevation);
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改基于墙
|
||||
/// </summary>
|
||||
/// <param name="view"></param>
|
||||
/// <param name="levels"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="elem"></param>
|
||||
private static void ModifyWall(View view, List<Level> levels, Level level, Element elem)
|
||||
{
|
||||
var wall = (Wall)elem;
|
||||
var doc = elem.Document;
|
||||
var isExist = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).Cast<FamilyInstance>().Any(fi => fi.Host?.Id == wall.Id);
|
||||
if (isExist)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var n = levels.FindIndex(l => l.Id == level.Id);
|
||||
var wallBox = wall.get_BoundingBox(view);
|
||||
var minZ = wallBox.Min.Z;
|
||||
var maxZ = wallBox.Max.Z;
|
||||
|
||||
wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).Set(level.Id);
|
||||
wall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).Set(minZ - level.Elevation);
|
||||
wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).Set(levels[n + 1].Id);
|
||||
wall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(maxZ - levels[n + 1].Elevation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改基于工作平面的族
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="familyInstance"></param>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
private static void ModifyWorkPlaneBasedFamily(Document doc, Level level, FamilyInstance familyInstance)
|
||||
{
|
||||
var baseLevelParam = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM);
|
||||
|
||||
//var originLevel = doc.GetElement(baseLevelParam.AsElementId()) as Level;
|
||||
//var hostParam = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_PARAM);
|
||||
//var hostParamValue = doc.GetElement(hostParam.AsElementId());
|
||||
|
||||
if (familyInstance.Host is Level)
|
||||
{
|
||||
if (!familyInstance.Symbol.IsActive)
|
||||
{
|
||||
familyInstance.Symbol.Activate();
|
||||
}
|
||||
|
||||
var lop = familyInstance.Location as LocationPoint;
|
||||
var newFamilyInstance = doc.Create.NewFamilyInstance(level.GetPlaneReference(), lop?.Point, familyInstance.HandOrientation, familyInstance.Symbol);
|
||||
var p = newFamilyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).Definition;
|
||||
foreach (Parameter param in familyInstance.Parameters)
|
||||
{
|
||||
if (param.IsReadOnly || param.Definition.Name == p.Name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (param.StorageType)
|
||||
{
|
||||
case StorageType.None:
|
||||
break;
|
||||
case StorageType.Integer:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsInteger());
|
||||
break;
|
||||
case StorageType.Double:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsDouble());
|
||||
break;
|
||||
case StorageType.String:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsString());
|
||||
break;
|
||||
case StorageType.ElementId:
|
||||
newFamilyInstance.get_Parameter(param.Definition).Set(param.AsElementId());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
doc.Delete(familyInstance.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (baseLevelParam.IsReadOnly == false)
|
||||
{
|
||||
baseLevelParam.Set(level.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user