2024-09-22 11:05:41 +08:00
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using Autodesk.Revit.DB;
|
|
|
|
|
|
using Autodesk.Revit.DB.Architecture;
|
|
|
|
|
|
using Autodesk.Revit.UI;
|
|
|
|
|
|
using Autodesk.Revit.UI.Selection;
|
|
|
|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
|
|
using Nice3point.Revit.Toolkit.External.Handlers;
|
|
|
|
|
|
|
2025-02-10 20:53:40 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace ShrlAlgo.RvKits.RvCivil;
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
|
|
|
|
|
public partial class WallFinishesViewModel(List<WallType> wallTypes) : ObservableObject
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly ActionEventHandler wallFinishHandler = new ();
|
|
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
|
[NotifyCanExecuteChangedFor(nameof(PlaceWallCommand))]
|
|
|
|
|
|
private double wallBaseOffset;
|
|
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
|
[NotifyCanExecuteChangedFor(nameof(PlaceWallCommand))]
|
|
|
|
|
|
private double wallHeight;
|
|
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
|
private List<WallType> wallTypes = wallTypes;
|
|
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
|
[NotifyCanExecuteChangedFor(nameof(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:
|
|
|
|
|
|
|
2025-02-10 20:53:40 +08:00
|
|
|
|
/* 项目“ShrlAlgo.RvKits (net48)”的未合并的更改
|
2024-09-22 11:05:41 +08:00
|
|
|
|
在此之前:
|
2024-12-22 10:26:12 +08:00
|
|
|
|
PlaceWallFinishesByFace(uiapp, SelectedWallType, wallWidth, WallHeight, WallBaseOffset);
|
2024-09-22 11:05:41 +08:00
|
|
|
|
break;
|
|
|
|
|
|
在此之后:
|
2024-12-22 10:26:12 +08:00
|
|
|
|
PlaceWallFinishesByFace(uiapp, SelectedWallType, wallWidth, WallHeight, WallBaseOffset);
|
2024-09-22 11:05:41 +08:00
|
|
|
|
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(
|
|
|
|
|
|
ts =>
|
|
|
|
|
|
{
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogHelper.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)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogHelper.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(
|
|
|
|
|
|
ts =>
|
|
|
|
|
|
{
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogHelper.ToLog(ex.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//WallUtils.AllowWallJoinAtEnd(w, 0);
|
|
|
|
|
|
//offestcurves.Add(lc);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
"创建墙体饰面"
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|