Files
Shrlalgo.RvKits/ShrlAlgoToolkit.RevitAddins/RvCommon/PipesCreatorViewModel.cs
2026-01-01 10:02:59 +08:00

272 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Text;
using ACadSharp.Entities;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI.Selection;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Nice3point.Revit.Toolkit.External.Handlers;
using ShrlAlgoToolkit.Core.Assists;
namespace ShrlAlgoToolkit.RevitAddins.RvCommon;
public partial class PipesCreatorViewModel : ObservableObject
{
public PipesCreatorViewModel(Document document)
{
this.document = document;
}
private readonly ActionEventHandler createHandler = new();
private readonly Document document;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvCommon.PipesCreatorViewModel.CreateCommand))]
public partial PipeType SelectedPipeType { get; set; }
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvCommon.PipesCreatorViewModel.CreateCommand))]
public partial PipingSystemType SelectedPipingSystemType { get; set; }
public IList<PipeType> PipeTypes => document.OfClass<PipeType>().Cast<PipeType>().ToList();
public IList<PipingSystemType> PipingSystemTypes => document.OfClass<PipingSystemType>().Cast<PipingSystemType>().ToList();
private bool CanCreate()
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
return SelectedPipeType != null && SelectedPipingSystemType != null;
}
[RelayCommand(CanExecute = nameof(CanCreate))]
private void Create()
{
createHandler.Raise(uiapp =>
{
var application = uiapp.Application;
var uiDocument = uiapp.ActiveUIDocument;
var doc = uiDocument.Document;
Reference reference;
Reference textRefer;
try
{
reference = uiDocument.Selection.PickObject(
ObjectType.PointOnElement,
new FuncFilter(e => e is ImportInstance import && import.IsLinked && doc.GetElement(e.GetTypeId()) is CADLinkType),
"请选择dwg管线图层"
);
//图层ID
textRefer = uiDocument.Selection.PickObject(ObjectType.PointOnElement, new FuncFilter(e => e is ImportInstance import && import.IsLinked && doc.GetElement(e.GetTypeId()) is CADLinkType), "请选择管线标注文字");
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return;
}
var dwg = doc.GetElement(reference) as ImportInstance;
var pipeLayerName = dwg.GetLayerName(reference);
var textLayerName = dwg.GetLayerName(textRefer);
//SketchPlane sketchPlane = SketchPlane.Create(Document, Plane.CreateByNormalAndOrigin(XYZ.BasisZ, XYZ.Zero));
doc.Invoke(_ =>
{
var curve = dwg!.GetGeometryObjectFromReference(reference);
var text = dwg.GetGeometryObjectFromReference(textRefer);
doc.ActiveView.SetCategoryHidden(curve.GraphicsStyleId, false);
doc.ActiveView.SetCategoryHidden(text.GraphicsStyleId, false);
});
var path = dwg.GetFilePath();
using ACadSharp.IO.DwgReader reader = new(path);
var cadDocument = reader.Read();
//var blocks = cadDocument.Entities.OfType<ACadSharp.Entities.Insert>().Where(e => e.Layer.Name == layerName).ToList();
var textEntities = cadDocument.Entities.OfType<TextEntity>().Where(e => e.Layer.Name == textLayerName).ToList();
var lwPolyLines = cadDocument.Entities.OfType<LwPolyline>().Where(e => e.Layer.Name == pipeLayerName).ToList();
var dwgTransform = dwg!.GetTransform();
StringBuilder sb = new();
doc.InvokeGroup(_ =>
{
foreach (var lwPolyline in lwPolyLines)
{
//if (n % 500 == 0)
//{
// var result = TaskDialog.Show("提示", $"已创建{n},是否继续?", TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No);
// if (result == TaskDialogResult.No)
// {
// break;
// }
//}
var v = lwPolyline.Vertices;
if (v.Count == 2)
{
var p1 = new XYZ(v[0].Location.X, v[0].Location.Y, 0) / 304.8;
var p2 = new XYZ(v[1].Location.X, v[1].Location.Y, 0) / 304.8;
if (p1.DistanceTo(p2) < application.ShortCurveTolerance)
{
continue;
}
var di = double.MaxValue;
TextEntity text = null;
var l = Autodesk.Revit.DB.Line.CreateBound(p1, p2);
foreach (var entity in textEntities)
{
try
{
var transform = Transform.CreateRotation(XYZ.BasisZ, entity.Rotation);
var rotationVector = transform.OfPoint(XYZ.BasisX);
if (entity.Value.StartsWith("DN") || entity.Value.StartsWith("De"))
{
var crossProduct = l.Direction.CrossProduct(rotationVector);
if (crossProduct.GetLength() < 0.05)
{
var xyz = new XYZ(entity.InsertPoint.X, entity.InsertPoint.Y, entity.InsertPoint.Z) / 304.8;
var ofPoint = dwgTransform.OfPoint(xyz);
//同一平面
var point = new XYZ(ofPoint.X, ofPoint.Y, 0);
var d = l.Distance(point);
if (d < di)
{
di = d;
text = entity;
}
}
}
}
catch (Exception)
{
// ignored
}
}
doc.Invoke(
_ =>
{
//var pipeDiameter = Regex.Match(text.Value, @"(?<=DN)\d+");
//if (pipeDiameter.Length > 0)
//{
// var diameter = Convert.ToDouble(pipeDiameter.Value) / 304.8;
// pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).Set(diameter);
//}
//var elevation = Regex.Match(text.Value, @"(?<=\+)(\d|\.)+");
//if (elevation.Length > 0)
//{
// var h = Convert.ToDouble(elevation.Value) * 1000 / 304.8;
// pipe.get_Parameter(BuiltInParameter.RBS_OFFSET_PARAM).Set(h);
//}
p1 = dwgTransform.OfPoint(p1);
p2 = dwgTransform.OfPoint(p2);
var newPipe = Pipe.Create(doc, SelectedPipingSystemType.Id, SelectedPipeType.Id, doc.ActiveView.GenLevel.Id, p1, p2);
doc.Regenerate();
if (text != null)
{
var diameter = string.Empty;
//string slope = string.Empty;
//var splitStrings = text.Value.Split(' ');
//foreach (var str in splitStrings)
//{
// var str1 = str.Trim();
// if (str1.Contains("DN"))
// {
// diameter = str.TrimStart("DN".ToCharArray());
// }
// else if (str1.Contains("De"))
// {
// diameter = str.TrimStart("De".ToCharArray());
// }
// if (str1.Contains("i="))
// {
// slope = str.TrimStart("i=".ToCharArray());
// }
//}
if (double.TryParse(diameter, out var d))
{
newPipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).Set(d / 304.8);
}
//if (double.TryParse(slope, out var s))
//{
// newPipe.get_Parameter(BuiltInParameter.RBS_PIPE_SLOPE).Set(s);
//}
}
else
{
sb.AppendLine($"{newPipe.Id}");
}
// ElementTransformUtils.MoveElement(Document, newPipe.Id, move);
//n++;
},
"创建管线"
);
doc.Invoke(_ =>
{
var mepCurves = doc.OfClass<MEPCurve>()
.Where(p => p is not InsulationLiningBase and not FlexPipe and not FlexDuct)
.ToList();
foreach (var mep in mepCurves)
{
foreach (var mep1 in mepCurves)
{
if (
mep.Id != mep1.Id
&& !mep.GetConnectors(true).IsEmpty
&& !mep1.GetConnectors(true).IsEmpty
&& mep.GetType() == mep1.GetType()
)
{
var connectors = ConnectorExtensions.GetNearestConnectors(mep, mep1);
if (connectors.Count == 2 && connectors[0].Origin.IsAlmostEqualTo(connectors[1].Origin))
{
connectors[0].ConnectByFitting(connectors[1]);
}
}
}
}
});
}
}
});
if (sb.Length > 0)
{
//var filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\问题管线.txt";
//File.WriteAllText(filePath, sb.ToString());
//WinDialogAssist.OpenFolderAndSelectFile(filePath);
IOAssist.WriteTxtFile("问题管线", sb.ToString());
}
//UiDocument.Selection.SetElementIds(ids);
//using (Transaction name = new Transaction(Document, "tsname"))
//{
// name.Start();
// for (int i = 0; i < 20; i++)
// {
// var block = blocks[i];
// var loc = new XYZ(block.InsertPoint.X / 304.8, block.InsertPoint.Y / 304.8, 0);
// //var loc = dwg.GetTransform().Origin;
// if (!instance.Symbol.IsActive)
// {
// instance.Symbol.Activate();
// }
// var fi = Document.Create.NewFamilyInstance(loc, instance.Symbol, view.GenLevel, StructuralType.NonStructural);
// Document.Regenerate();
// ElementTransformUtils.MoveElement(Document,fi.Id,move);
// }
// name.Commit();
//}
});
}
}