Skip to content

Commit

Permalink
RevitOpeningPlacement: Обновление статусов заданий для Навигатора ВИС (
Browse files Browse the repository at this point in the history
  • Loading branch information
vlastroG authored Oct 31, 2024
1 parent c5b5bf9 commit 30f299f
Show file tree
Hide file tree
Showing 20 changed files with 1,423 additions and 401 deletions.
36 changes: 32 additions & 4 deletions src/RevitOpeningPlacement/GetOpeningTasksCmd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ namespace RevitOpeningPlacement {
/// </summary>
[Transaction(TransactionMode.Manual)]
public class GetOpeningTasksCmd : BasePluginCommand {
private const int _progressBarStepLarge = 100;
private const int _progressBarStepSmall = 25;


public GetOpeningTasksCmd() {
PluginName = "Навигатор по заданиям";
}
Expand Down Expand Up @@ -197,6 +193,11 @@ private void GetOpeningsTaskInDocumentKR(IKernel kernel) {
}

private void GetOpeningsTaskInDocumentMEP(IKernel kernel) {
kernel.Bind<OpeningConfig>()
.ToMethod(c => {
var repo = c.Kernel.Get<RevitRepository>();
return OpeningConfig.GetOpeningConfig(repo.Doc);
});
kernel.Bind<IConstantsProvider>()
.To<ConstantsProvider>()
.InSingletonScope();
Expand All @@ -206,6 +207,33 @@ private void GetOpeningsTaskInDocumentMEP(IKernel kernel) {
kernel.Bind<IOpeningInfoUpdater<OpeningMepTaskOutcoming>>()
.To<MepTaskOutcomingInfoUpdater>()
.InTransientScope();
kernel.Bind<ILengthConverter>()
.To<LengthConverterService>()
.InSingletonScope();
kernel.Bind<OutcomingTaskGeometryProvider>()
.ToSelf()
.InSingletonScope();
kernel.Bind<GeometryUtils>()
.ToSelf()
.InSingletonScope();
kernel.Bind<PipeOffsetFinder>()
.ToSelf()
.InTransientScope();
kernel.Bind<DuctOffsetFinder>()
.ToSelf()
.InTransientScope();
kernel.Bind<ConduitOffsetFinder>()
.ToSelf()
.InTransientScope();
kernel.Bind<CableTrayOffsetFinder>()
.ToSelf()
.InTransientScope();
kernel.Bind<FamilyInstanceOffsetFinder>()
.ToSelf()
.InTransientScope();
kernel.Bind<IOutcomingTaskOffsetFinder>()
.To<ElementOffsetFinder>()
.InTransientScope();

kernel.Bind<MepNavigatorForOutcomingTasksViewModel>()
.ToSelf()
Expand Down
5 changes: 5 additions & 0 deletions src/RevitOpeningPlacement/Models/Configs/OpeningConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ internal class OpeningConfig : ProjectConfig {
/// </summary>
public bool ShowPlacingErrors { get; set; } = false;

/// <summary>
/// Название настроек
/// </summary>
public string Name { get; set; } = "по умолчанию";

public static OpeningConfig GetOpeningConfig(Document document) {
if(document is null) { throw new ArgumentNullException(nameof(document)); }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.ComponentModel;
using System.ComponentModel;

namespace RevitOpeningPlacement.OpeningModels.Enums {
/// <summary>
Expand Down Expand Up @@ -41,6 +41,11 @@ internal enum OpeningTaskOutcomingStatus {
/// Задание на отверстие размещено вручную
/// </summary>
[Description("Размещено вручную")]
ManuallyPlaced
ManuallyPlaced,
/// <summary>
/// Задание на отверстие - объединенное
/// </summary>
[Description("Объединенное")]
United
}
}
54 changes: 54 additions & 0 deletions src/RevitOpeningPlacement/Services/CableTrayOffsetFinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Linq;

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;

using RevitClashDetective.Models.Extensions;

using RevitOpeningPlacement.Models.Configs;

namespace RevitOpeningPlacement.Services {
internal class CableTrayOffsetFinder : OutcomingTaskOffsetFinder<CableTray> {
private MepCategory _category;

public CableTrayOffsetFinder(
OpeningConfig openingConfig,
OutcomingTaskGeometryProvider geometryProvider,
GeometryUtils geometryUtils,
ILengthConverter lengthConverter) : base(openingConfig, geometryProvider, geometryUtils, lengthConverter) {

TessellationCount = 1; // кабельный лоток - прямоугольный, вообще не должно быть изогнутых линий
}


protected override int TessellationCount { get; }


protected override double GetHeight(CableTray mepElement) {
return mepElement.Height;
}

protected override double GetWidth(CableTray mepElement) {
return mepElement.Width;
}

protected override MepCategory GetCategory(CableTray mepElement) {
_category = _category ?? OpeningConfig.Categories[Models.MepCategoryEnum.CableTray];
return _category;
}

protected override Solid GetMepSolid(CableTray cableTray) {
// нужен именно средний уровень детализации, на котором геометрия лотка - это параллелепипед
var options = new Options() {
ComputeReferences = true,
IncludeNonVisibleObjects = false,
DetailLevel = ViewDetailLevel.Medium
};
var solids = cableTray.get_Geometry(options)
.SelectMany(item => item.GetSolids())
.GetUnitedSolids()
.ToList();
return ElementExtensions.UniteSolids(solids);
}
}
}
42 changes: 42 additions & 0 deletions src/RevitOpeningPlacement/Services/ConduitOffsetFinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;

using RevitClashDetective.Models.Extensions;

using RevitOpeningPlacement.Models.Configs;

namespace RevitOpeningPlacement.Services {
internal class ConduitOffsetFinder : OutcomingTaskOffsetFinder<Conduit> {
private MepCategory _category;

public ConduitOffsetFinder(
OpeningConfig openingConfig,
OutcomingTaskGeometryProvider geometryProvider,
GeometryUtils geometryUtils,
ILengthConverter lengthConverter) : base(openingConfig, geometryProvider, geometryUtils, lengthConverter) {

TessellationCount = 10;
}


protected override int TessellationCount { get; }


protected override double GetHeight(Conduit mepElement) {
return mepElement.Diameter;
}

protected override double GetWidth(Conduit mepElement) {
return mepElement.Diameter;
}

protected override MepCategory GetCategory(Conduit mepElement) {
_category = _category ?? OpeningConfig.Categories[Models.MepCategoryEnum.Conduit];
return _category;
}

protected override Solid GetMepSolid(Conduit mepElement) {
return mepElement.GetSolid();
}
}
}
58 changes: 58 additions & 0 deletions src/RevitOpeningPlacement/Services/DuctOffsetFinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;

using RevitClashDetective.Models.Extensions;

using RevitOpeningPlacement.Models.Configs;

namespace RevitOpeningPlacement.Services {
internal class DuctOffsetFinder : OutcomingTaskOffsetFinder<Duct> {
private MepCategory _roundCategory;
private MepCategory _rectangleCategory;

public DuctOffsetFinder(
OpeningConfig openingConfig,
OutcomingTaskGeometryProvider geometryProvider,
GeometryUtils geometryUtils,
ILengthConverter lengthConverter) : base(openingConfig, geometryProvider, geometryUtils, lengthConverter) {

TessellationCount = 10;
}


protected override int TessellationCount { get; }


protected override MepCategory GetCategory(Duct mepElement) {
if(mepElement.DuctType.Shape == ConnectorProfileType.Round) {
_roundCategory = _roundCategory
?? OpeningConfig.Categories[Models.MepCategoryEnum.RoundDuct];
return _roundCategory;
} else {
_rectangleCategory = _rectangleCategory
?? OpeningConfig.Categories[Models.MepCategoryEnum.RectangleDuct];
return _rectangleCategory;
}
}

protected override double GetHeight(Duct mepElement) {
if(mepElement.DuctType.Shape == ConnectorProfileType.Round) {
return mepElement.Diameter;
} else {
return mepElement.Height;
}
}

protected override double GetWidth(Duct mepElement) {
if(mepElement.DuctType.Shape == ConnectorProfileType.Round) {
return mepElement.Diameter;
} else {
return mepElement.Width;
}
}

protected override Solid GetMepSolid(Duct mepElement) {
return mepElement.GetSolid();
}
}
}
79 changes: 79 additions & 0 deletions src/RevitOpeningPlacement/Services/ElementOffsetFinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System;

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;

using RevitOpeningPlacement.OpeningModels;

namespace RevitOpeningPlacement.Services {
internal class ElementOffsetFinder : IOutcomingTaskOffsetFinder {
private readonly PipeOffsetFinder _pipeFinder;
private readonly DuctOffsetFinder _ductFinder;
private readonly ConduitOffsetFinder _conduitFinder;
private readonly CableTrayOffsetFinder _cableTrayFinder;
private readonly FamilyInstanceOffsetFinder _familyInstanceFinder;


public ElementOffsetFinder(
PipeOffsetFinder pipeFinder,
DuctOffsetFinder ductFinder,
ConduitOffsetFinder conduitFinder,
CableTrayOffsetFinder cableTrayFinder,
FamilyInstanceOffsetFinder familyInstanceFinder) {

_pipeFinder = pipeFinder
?? throw new ArgumentNullException(nameof(pipeFinder));
_ductFinder = ductFinder
?? throw new ArgumentNullException(nameof(ductFinder));
_conduitFinder = conduitFinder
?? throw new ArgumentNullException(nameof(conduitFinder));
_cableTrayFinder = cableTrayFinder
?? throw new ArgumentNullException(nameof(cableTrayFinder));
_familyInstanceFinder = familyInstanceFinder
?? throw new ArgumentNullException(nameof(familyInstanceFinder));
}


public double FindHorizontalOffsetsSum(OpeningMepTaskOutcoming opening, Element mepElement) {
return GetOffsetFinder(mepElement).FindHorizontalOffsetsSum(opening, mepElement);
}

public double FindVerticalOffsetsSum(OpeningMepTaskOutcoming opening, Element mepElement) {
return GetOffsetFinder(mepElement).FindVerticalOffsetsSum(opening, mepElement);
}

public double GetMaxHorizontalOffsetSum(Element mepElement) {
return GetOffsetFinder(mepElement).GetMaxHorizontalOffsetSum(mepElement);
}

public double GetMinHorizontalOffsetSum(Element mepElement) {
return GetOffsetFinder(mepElement).GetMinHorizontalOffsetSum(mepElement);
}

public double GetMaxVerticalOffsetSum(Element mepElement) {
return GetOffsetFinder(mepElement).GetMaxVerticalOffsetSum(mepElement);
}

public double GetMinVerticalOffsetSum(Element mepElement) {
return GetOffsetFinder(mepElement).GetMinVerticalOffsetSum(mepElement);
}

private IOutcomingTaskOffsetFinder GetOffsetFinder(Element mepElement) {
if(mepElement is Pipe) {
return _pipeFinder;
} else if(mepElement is Duct) {
return _ductFinder;
} else if(mepElement is Conduit) {
return _conduitFinder;
} else if(mepElement is CableTray) {
return _cableTrayFinder;
} else if(mepElement is FamilyInstance) {
return _familyInstanceFinder;
} else {
throw new InvalidOperationException($"Type doesn't support: {mepElement.GetType().FullName}");
}
}
}
}
64 changes: 64 additions & 0 deletions src/RevitOpeningPlacement/Services/FamilyInstanceOffsetFinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Linq;

using Autodesk.Revit.DB;

using dosymep.Revit;

using RevitClashDetective.Models.Extensions;

using RevitOpeningPlacement.Models.Configs;

namespace RevitOpeningPlacement.Services {
internal class FamilyInstanceOffsetFinder : OutcomingTaskOffsetFinder<FamilyInstance> {
public FamilyInstanceOffsetFinder(
OpeningConfig openingConfig,
OutcomingTaskGeometryProvider geometryProvider,
GeometryUtils geometryUtils,
ILengthConverter lengthConverter) : base(openingConfig, geometryProvider, geometryUtils, lengthConverter) {

TessellationCount = 10;
}


protected override int TessellationCount { get; }


protected override MepCategory GetCategory(FamilyInstance mepElement) {
switch(mepElement.Category.GetBuiltInCategory()) {
case BuiltInCategory.OST_PipeFitting:
return OpeningConfig.Categories[Models.MepCategoryEnum.Pipe];
case BuiltInCategory.OST_DuctFitting:
case BuiltInCategory.OST_DuctAccessory:
if(mepElement.MEPModel.ConnectorManager.Connectors
.OfType<Connector>()
.All(c => c.Shape == ConnectorProfileType.Round)) {
return OpeningConfig.Categories[Models.MepCategoryEnum.RoundDuct];
} else {
return OpeningConfig.Categories[Models.MepCategoryEnum.RectangleDuct];
}
case BuiltInCategory.OST_CableTrayFitting:
return OpeningConfig.Categories[Models.MepCategoryEnum.CableTray];
case BuiltInCategory.OST_ConduitFitting:
return OpeningConfig.Categories[Models.MepCategoryEnum.Conduit];
default:
throw new InvalidOperationException();
}
}

protected override double GetHeight(FamilyInstance mepElement) {
var box = mepElement.GetBoundingBox();
// будем брать наибольшее расстояние по осям OY и OZ. Такой точности сейчас хватает.
return Math.Max(box.Max.Z - box.Min.Z, box.Max.Y - box.Min.Y);
}

protected override double GetWidth(FamilyInstance mepElement) {
var box = mepElement.GetBoundingBox();
return box.Max.X - box.Min.X;
}

protected override Solid GetMepSolid(FamilyInstance mepElement) {
return mepElement.GetSolid();
}
}
}
Loading

0 comments on commit 30f299f

Please sign in to comment.