2025-02-10 20:53:40 +08:00
|
|
|
|
using System.Text;
|
2024-09-22 11:05:41 +08:00
|
|
|
|
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;
|
2025-02-10 20:53:40 +08:00
|
|
|
|
|
2026-02-22 20:03:42 +08:00
|
|
|
|
using ShrlAlgoToolkit.RevitAddins.RvCommon;
|
|
|
|
|
|
using ShrlAlgoToolkit;
|
|
|
|
|
|
using ShrlAlgoToolkit.RevitAddins;
|
|
|
|
|
|
|
|
|
|
|
|
namespace ShrlAlgoToolkit.RevitAddins.Modeling;
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
|
|
|
|
|
public partial class PipesCreatorViewModel : ObservableObject
|
|
|
|
|
|
{
|
|
|
|
|
|
public PipesCreatorViewModel(Document document)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.document = document;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private readonly ActionEventHandler createHandler = new();
|
|
|
|
|
|
private readonly Document document;
|
|
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
2026-02-22 20:03:42 +08:00
|
|
|
|
[NotifyCanExecuteChangedFor(nameof(Modeling.PipesCreatorViewModel.CreateCommand))]
|
2025-10-04 08:52:23 +08:00
|
|
|
|
public partial PipeType SelectedPipeType { get; set; }
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
2026-02-22 20:03:42 +08:00
|
|
|
|
[NotifyCanExecuteChangedFor(nameof(Modeling.PipesCreatorViewModel.CreateCommand))]
|
2025-10-04 08:52:23 +08:00
|
|
|
|
public partial PipingSystemType SelectedPipingSystemType { get; set; }
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
});
|
2024-10-27 00:19:48 +08:00
|
|
|
|
var path = dwg.GetFilePath();
|
2024-09-22 11:05:41 +08:00
|
|
|
|
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()
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
2025-07-11 09:20:23 +08:00
|
|
|
|
var connectors = ConnectorExtensions.GetNearestConnectors(mep, mep1);
|
2024-09-22 11:05:41 +08:00
|
|
|
|
if (connectors.Count == 2 && connectors[0].Origin.IsAlmostEqualTo(connectors[1].Origin))
|
|
|
|
|
|
{
|
|
|
|
|
|
connectors[0].ConnectByFitting(connectors[1]);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (sb.Length > 0)
|
|
|
|
|
|
{
|
2025-02-10 20:53:40 +08:00
|
|
|
|
//var filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\问题管线.txt";
|
|
|
|
|
|
//File.WriteAllText(filePath, sb.ToString());
|
2026-01-01 10:02:59 +08:00
|
|
|
|
//WinDialogAssist.OpenFolderAndSelectFile(filePath);
|
2026-02-21 16:31:24 +08:00
|
|
|
|
Common.Assists.LogAssist.WriteTextFile("问题管线", sb.ToString());
|
2024-09-22 11:05:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//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();
|
|
|
|
|
|
//}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|