调整代码
This commit is contained in:
311
ShrlAlgoToolkit.RevitAddins/ArchStru/WallFinishesViewModel.cs
Normal file
311
ShrlAlgoToolkit.RevitAddins/ArchStru/WallFinishesViewModel.cs
Normal file
@@ -0,0 +1,311 @@
|
||||
using System.Windows;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Architecture;
|
||||
using Autodesk.Revit.UI.Selection;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.RvCivil;
|
||||
|
||||
public partial class WallFinishesViewModel(List<WallType> wallTypes) : ObservableObject
|
||||
{
|
||||
private readonly ActionEventHandler wallFinishHandler = new ();
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvCivil.WallFinishesViewModel.PlaceWallCommand))]
|
||||
public partial double WallBaseOffset { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvCivil.WallFinishesViewModel.PlaceWallCommand))]
|
||||
private double wallHeight;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial List<WallType> WallTypes { get; set; } = wallTypes;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvCivil.WallFinishesViewModel.PlaceWallCommand))]
|
||||
private WallType selectedWallType;
|
||||
|
||||
public PlacementType PlaceType { get; set; }
|
||||
|
||||
private bool CanPlaceWallFinish()
|
||||
{
|
||||
return SelectedWallType != null && WallHeight > 0 && WallHeight > WallBaseOffset;
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanPlaceWallFinish))]
|
||||
private void PlaceWall()
|
||||
{
|
||||
wallFinishHandler.Raise(uiapp =>
|
||||
{
|
||||
var uidoc = uiapp.ActiveUIDocument;
|
||||
var doc = uidoc.Document;
|
||||
var wallWidth = SelectedWallType.Width;
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
switch (PlaceType)
|
||||
{
|
||||
case PlacementType.ByFace:
|
||||
|
||||
/* 项目“ShrlAlgoToolkit.RevitAddins (net48)”的未合并的更改
|
||||
在此之前:
|
||||
PlaceWallFinishesByFace(uiapp, SelectedWallType, wallWidth, WallHeight, WallBaseOffset);
|
||||
break;
|
||||
在此之后:
|
||||
PlaceWallFinishesByFace(uiapp, SelectedWallType, wallWidth, WallHeight, WallBaseOffset);
|
||||
break;
|
||||
*/
|
||||
WallFinishesViewModel.PlaceWallFinishesByFace(uidoc, SelectedWallType, wallWidth, WallHeight, WallBaseOffset);
|
||||
break;
|
||||
case PlacementType.ByWall:
|
||||
PlaceWallFinishesByWall(uidoc, SelectedWallType, wallWidth, WallHeight, WallBaseOffset);
|
||||
break;
|
||||
case PlacementType.ByRoom:
|
||||
var rooms = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms);
|
||||
if (!rooms.Any())
|
||||
{
|
||||
MessageBox.Show("项目中当前没有房间", "温馨提示");
|
||||
//message = "项目中当前没有房间";
|
||||
}
|
||||
|
||||
PlaceWallFinishesByRoom(uidoc, SelectedWallType, wallWidth, WallHeight, WallBaseOffset);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
|
||||
});
|
||||
}
|
||||
|
||||
private static void PlaceWallFinishesByFace(UIDocument uidoc, WallType wallType, double wallWidth, double height, double baseOffset)
|
||||
{
|
||||
var doc = uidoc.Document;
|
||||
var referFace = uidoc.Selection.PickObject(ObjectType.Face, new GenericFilter<Wall>(), "请选择布置的墙面");
|
||||
var wall = doc.GetElement(referFace) as Wall;
|
||||
var face = wall.GetGeometryObjectFromReference(referFace) as Face;
|
||||
|
||||
var bottomFace = wall.GetAllGeometryObjects<Face>().FirstOrDefault(f => f.ComputeNormal(new UV()).IsAlmostEqualTo(-XYZ.BasisZ));
|
||||
if (bottomFace == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var baseLevel = doc.GetElement(wall.LevelId) as Level;
|
||||
|
||||
face.Intersect(bottomFace, out var intersectCurve);
|
||||
doc.Invoke(
|
||||
_ =>
|
||||
{
|
||||
var curve = intersectCurve.CreateOffset(wallWidth / 2, XYZ.BasisZ).CreateReversed();
|
||||
|
||||
var wallCreated = Wall.Create(doc, curve, wallType.Id, baseLevel.Id, height / 304.8, baseOffset / 304.8, false, false);
|
||||
doc.Regenerate();
|
||||
try
|
||||
{
|
||||
if (wallCreated.WallType.Kind == WallKind.Stacked)
|
||||
{
|
||||
foreach (var wallid in wallCreated.GetStackedWallMemberIds())
|
||||
{
|
||||
var stackedWall = doc.GetElement(wallid) as Wall;
|
||||
JoinGeometryUtils.JoinGeometry(doc, wall, stackedWall);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JoinGeometryUtils.JoinGeometry(doc, wall, wallCreated);
|
||||
}
|
||||
//JoinGeometryUtils.JoinGeometry(doc, wall, wallCreated);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Common.Assists.LogAssist.ToLog(ex.Message);
|
||||
}
|
||||
},
|
||||
"创建墙面饰面"
|
||||
);
|
||||
}
|
||||
|
||||
private static void PlaceWallFinishesByRoom(UIDocument uidoc, WallType wallType, double wallWidth, double wallHeight, double wallBaseOffset)
|
||||
{
|
||||
var doc = uidoc.Document;
|
||||
var refer = uidoc.Selection.PickObject(ObjectType.Element, new GenericFilter<Room>(), "请选择布置的房间");
|
||||
var room = uidoc.Document.GetElement(refer) as Room;
|
||||
var baseLevel = doc.GetElement(room.LevelId) as Level;
|
||||
List<CurveLoop> curveLoops =[];
|
||||
List<ElementId> walltojoin = [];
|
||||
List<List<ElementId>> wallToJoinList = [];
|
||||
var opts = new SpatialElementBoundaryOptions();
|
||||
//{
|
||||
// SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish
|
||||
//};
|
||||
|
||||
//BuiltInCategory builtInCategory = (BuiltInCategory)walltype.Category.ViewId.IntegerValue;
|
||||
//if (walltype.Kind == WallKind.Stacked)
|
||||
//{
|
||||
// var li = walltype.GetSubelements();
|
||||
// walltype.get
|
||||
//}
|
||||
//if (walltype.Kind == WallKind.Basic)
|
||||
//{
|
||||
// var compounds = walltype.GetCompoundStructure();
|
||||
// for (int i = 0; i < compounds.LayerCount; i++)
|
||||
// {
|
||||
// offest += compounds.GetWidth();
|
||||
// }
|
||||
//}
|
||||
|
||||
var segementsList = room.GetBoundarySegments(opts);
|
||||
|
||||
if (segementsList != null)
|
||||
{
|
||||
foreach (var boundarySegments in segementsList)
|
||||
{
|
||||
CurveLoop curveLoop = new();
|
||||
foreach (var boundarySegment in boundarySegments)
|
||||
{
|
||||
curveLoop.Append(boundarySegment.GetCurve());
|
||||
walltojoin.Add(boundarySegment.ElementId);
|
||||
}
|
||||
|
||||
wallToJoinList.Add(walltojoin);
|
||||
curveLoops.Add(curveLoop);
|
||||
}
|
||||
}
|
||||
|
||||
doc.Invoke(
|
||||
ts =>
|
||||
{
|
||||
var options = ts.GetFailureHandlingOptions();
|
||||
FailuresPreProcessor failuresProcessor = new();
|
||||
options.SetFailuresPreprocessor(failuresProcessor);
|
||||
ts.SetFailureHandlingOptions(options);
|
||||
//Plane plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, new XYZ());
|
||||
//var mc = doc.Create.NewModelCurveArray(array, SketchPlane.Create(doc, plane));
|
||||
for (var i = 0; i < curveLoops.Count; i++)
|
||||
{
|
||||
//切线方向叉乘参数中的向量,内侧叉乘-z
|
||||
var curveLoopOffset = CurveLoop.CreateViaOffset(curveLoops[i], wallWidth / 2, -XYZ.BasisZ);
|
||||
for (var j = 0; j < curveLoopOffset.Count(); j++)
|
||||
{
|
||||
var curve = curveLoopOffset.ElementAt(j);
|
||||
////c的方向叉乘参数中的向量,内侧叉乘-z
|
||||
//var lc = c.CreateOffset(100 / 304.8, -XYZ.BasisZ);
|
||||
|
||||
//var x = curve.ComputeDerivatives(0.5, true).BasisX.CrossProduct(-XYZ.BasisZ).Normalize() * 100 / 304.8;
|
||||
//var mc = doc.Create.NewModelCurve(lc, SketchPlane.Create(doc, plane));
|
||||
//var mc = doc.Create.NewModelCurve(c, SketchPlane.Create(doc, plane));
|
||||
var wallCreated = Wall.Create(
|
||||
doc,
|
||||
curve,
|
||||
wallType.Id,
|
||||
baseLevel.Id,
|
||||
wallHeight / 304.8,
|
||||
wallBaseOffset / 304.8,
|
||||
false,
|
||||
false
|
||||
);
|
||||
wallCreated.get_Parameter(BuiltInParameter.WALL_ATTR_ROOM_BOUNDING).Set(1);
|
||||
doc.Regenerate();
|
||||
//连接墙体让门窗可以剪切出来
|
||||
#if REVIT2018 || REVIT2020
|
||||
if (wallToJoinList[i][j].IntegerValue > 0)
|
||||
#elif REVIT2025
|
||||
if (wallToJoinList[i][j].Value > 0)
|
||||
#endif
|
||||
{
|
||||
var elemToJoin = doc.GetElement(wallToJoinList[i][j]);
|
||||
try
|
||||
{
|
||||
if (wallCreated.WallType.Kind == WallKind.Stacked)
|
||||
{
|
||||
foreach (var wallid in wallCreated.GetStackedWallMemberIds())
|
||||
{
|
||||
var stackedWall = doc.GetElement(wallid) as Wall;
|
||||
JoinGeometryUtils.JoinGeometry(doc, elemToJoin, stackedWall);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JoinGeometryUtils.JoinGeometry(doc, elemToJoin, wallCreated);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Common.Assists.LogAssist.ToLog(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
//WallUtils.AllowWallJoinAtEnd(w, 0);
|
||||
//offsetCurves.Add(lc);
|
||||
}
|
||||
}
|
||||
},
|
||||
"创建房间墙饰面"
|
||||
);
|
||||
}
|
||||
|
||||
private static void PlaceWallFinishesByWall(UIDocument uidoc, WallType wallType, double wallWidth, double wallHeight, double wallBaseOffset)
|
||||
{
|
||||
var doc = uidoc.Document;
|
||||
var refer = uidoc.Selection.PickObject(ObjectType.Element, new GenericFilter<Wall>(), "请选择布置的墙体");
|
||||
var wall = uidoc.Document.GetElement(refer) as Wall;
|
||||
var baselevel = doc.GetElement(wall.LevelId) as Level;
|
||||
|
||||
var bottomFace = wall.GetAllGeometryObjects<Face>().FirstOrDefault(f => f.ComputeNormal(new UV()).IsAlmostEqualTo(-XYZ.BasisZ));
|
||||
var sideFaces = wall.GetAllGeometryObjects<Face>().Where(f => f.ComputeNormal(new UV()).DotProduct(XYZ.BasisZ) < 1.0e-09);
|
||||
//CurveLoop loop = new CurveLoop();
|
||||
List<Curve> curs = [];
|
||||
foreach (var sideFace in sideFaces)
|
||||
{
|
||||
bottomFace.Intersect(sideFace, out var intersectCurve);
|
||||
curs.Add(intersectCurve);
|
||||
//ModelCurve ml = doc.Create.NewModelCurve(cur, doc.ActiveView.SketchPlane);
|
||||
|
||||
//loop.Append(cur);
|
||||
}
|
||||
|
||||
//var loop = CurveLoop.Create(curs);
|
||||
//var offestcurveloop = CurveLoop.CreateViaOffset(loop, wallwidth / 2, XYZ.BasisZ);
|
||||
doc.Invoke(
|
||||
_ =>
|
||||
{
|
||||
for (var i = 0; i < curs.Count; i++)
|
||||
{
|
||||
var curve = curs.ElementAt(i).CreateOffset(wallWidth / 2, -XYZ.BasisZ);
|
||||
var wallCreated = Wall.Create(doc, curve, wallType.Id, baselevel.Id, wallHeight / 304.8, wallBaseOffset / 304.8, false, false);
|
||||
|
||||
doc.Regenerate();
|
||||
try
|
||||
{
|
||||
if (wallCreated.WallType.Kind == WallKind.Stacked)
|
||||
{
|
||||
foreach (var wallid in wallCreated.GetStackedWallMemberIds())
|
||||
{
|
||||
var stackedwall = doc.GetElement(wallid) as Wall;
|
||||
JoinGeometryUtils.JoinGeometry(doc, wall, stackedwall);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JoinGeometryUtils.JoinGeometry(doc, wall, wallCreated);
|
||||
}
|
||||
//JoinGeometryUtils.JoinGeometry(doc, wall, wallCreated);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Common.Assists.LogAssist.ToLog(ex.Message);
|
||||
}
|
||||
|
||||
//WallUtils.AllowWallJoinAtEnd(w, 0);
|
||||
//offestcurves.Add(lc);
|
||||
}
|
||||
},
|
||||
"创建墙体饰面"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user