Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
using System.Windows.Media;

namespace RevitLookup.Abstractions.Models.Settings;
Expand All @@ -13,6 +13,7 @@ public sealed class VisualizationSettings
[JsonPropertyName("FaceSettings")] public required FaceVisualizationSettings FaceSettings { get; set; }
[JsonPropertyName("MeshSettings")] public required MeshVisualizationSettings MeshSettings { get; set; }
[JsonPropertyName("PolylineSettings")] public required PolylineVisualizationSettings PolylineSettings { get; set; }
[JsonPropertyName("CurveLoopSettings")] public required CurveLoopVisualizationSettings CurveLoopSettings { get; set; }
[JsonPropertyName("SolidSettings")] public required SolidVisualizationSettings SolidSettings { get; set; }
[JsonPropertyName("XyzSettings")] public required XyzVisualizationSettings XyzSettings { get; set; }
}
Expand Down Expand Up @@ -91,6 +92,25 @@ public class PolylineVisualizationSettings
[JsonPropertyName("ShowDirection")] public bool ShowDirection { get; set; }
}

/// <summary>
/// Schema for CurveLoop visualization settings.
/// </summary>
[Serializable]
public class CurveLoopVisualizationSettings
{
[JsonPropertyName("Transparency")] public double Transparency { get; set; }
[JsonPropertyName("Diameter")] public double Diameter { get; set; }
[JsonPropertyName("MinThickness")] public double MinThickness { get; set; }

[JsonPropertyName("SurfaceColor")] public Color SurfaceColor { get; set; }
[JsonPropertyName("CurveColor")] public Color CurveColor { get; set; }
[JsonPropertyName("DirectionColor")] public Color DirectionColor { get; set; }

[JsonPropertyName("ShowSurface")] public bool ShowSurface { get; set; }
[JsonPropertyName("ShowCurve")] public bool ShowCurve { get; set; }
[JsonPropertyName("ShowDirection")] public bool ShowDirection { get; set; }
}

/// <summary>
/// Schema for solid visualization settings.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RevitLookup.Abstractions/ViewModels/Visualization/ICurveLoopVisualizationViewModel.cs
using System.Windows.Media;

namespace RevitLookup.Abstractions.ViewModels.Visualization
{
public interface ICurveLoopVisualizationViewModel
{
double MinThickness { get; }
double Diameter { get; set; }
double Transparency { get; set; }
Color SurfaceColor { get; set; }
Color CurveColor { get; set; }
Color DirectionColor { get; set; }
bool ShowSurface { get; set; }
bool ShowCurve { get; set; }
bool ShowDirection { get; set; }

void RegisterServer(object curveLoop);
void UnregisterServer();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<ui:ContentDialog
x:Class="RevitLookup.UI.Framework.Views.Visualization.CurveLoopVisualizationDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="http://lookupengine.com/xaml"
xmlns:colorPicker="clr-namespace:RevitLookup.UI.Framework.Controls.ColorPicker"
xmlns:local="clr-namespace:RevitLookup.UI.Framework.Views.Visualization"
xmlns:visualization="clr-namespace:RevitLookup.Abstractions.ViewModels.Visualization;assembly=RevitLookup.Abstractions"
Title="Curve Loop Visualization settings"
DialogMaxWidth="470"
VerticalContentAlignment="Center"
mc:Ignorable="d"
d:DesignHeight="540"
d:DesignWidth="600"
d:DataContext="{d:DesignInstance visualization:ICurveLoopVisualizationViewModel}">

<ui:ContentDialog.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
<Style
BasedOn="{StaticResource DefaultContentDialogStyle}"
TargetType="{x:Type local:CurveLoopVisualizationDialog}" />
</ResourceDictionary>
</ui:ContentDialog.Resources>

<StackPanel>
<DockPanel>
<ui:SymbolIcon
DockPanel.Dock="Right"
Margin="8 0 0 0"
FontSize="20"
Symbol="Eyedropper20" />
<colorPicker:ColorPickerControl
DockPanel.Dock="Right"
SelectedColor="{Binding SurfaceColor}" />
<CheckBox
TabIndex="0"
IsChecked="{Binding ShowSurface}"
Content="Surface" />
</DockPanel>
<StackPanel
Margin="0 8 0 0">
<DockPanel>
<TextBlock
Text="Diameter" />
<TextBlock
HorizontalAlignment="Right"
Text="{Binding Diameter,
StringFormat={}{0:F1} inch,
Mode=OneWay,
FallbackValue='12 inch'}" />
</DockPanel>
<Slider
Margin="0 4 0 0"
Minimum="{Binding MinThickness, Mode=OneTime}"
Maximum="6"
TickFrequency="0.2"
IsSnapToTickEnabled="True"
TickPlacement="BottomRight"
Value="{Binding Diameter}" />
</StackPanel>
<StackPanel
Margin="0 8 0 0">
<DockPanel>
<TextBlock
Text="Transparency" />
<TextBlock
HorizontalAlignment="Right"
Text="{Binding Transparency,
StringFormat={}{0} %,
Mode=OneWay,
FallbackValue='12 %'}" />
</DockPanel>
<Slider
Margin="0 4 0 0"
Minimum="0"
Maximum="100"
TickFrequency="10"
IsSnapToTickEnabled="True"
TickPlacement="BottomRight"
Value="{Binding Transparency}" />
</StackPanel>
<DockPanel
Margin="0 8 0 0">
<ui:SymbolIcon
DockPanel.Dock="Right"
Margin="8 0 0 0"
FontSize="20"
Symbol="Eyedropper20" />
<colorPicker:ColorPickerControl
DockPanel.Dock="Right"
SelectedColor="{Binding CurveColor}" />
<CheckBox
TabIndex="1"
IsChecked="{Binding ShowCurve}"
Content="Curve Loop" />
</DockPanel>
<DockPanel
Margin="0 8 0 0">
<ui:SymbolIcon
DockPanel.Dock="Right"
Margin="8 0 0 0"
FontSize="20"
Symbol="Eyedropper20" />
<colorPicker:ColorPickerControl
DockPanel.Dock="Right"
SelectedColor="{Binding DirectionColor}" />
<CheckBox
TabIndex="2"
IsChecked="{Binding ShowDirection}"
Content="Direction" />
</DockPanel>
</StackPanel>
</ui:ContentDialog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// RevitLookup.UI.Framework/Views/Visualization/CurveLoopVisualizationDialog.xaml.cs
using RevitLookup.Abstractions.Services.Appearance;
using RevitLookup.Abstractions.ViewModels.Visualization;
using Wpf.Ui;

namespace RevitLookup.UI.Framework.Views.Visualization
{
public sealed partial class CurveLoopVisualizationDialog: Wpf.Ui.Controls.ContentDialog
{
private readonly ICurveLoopVisualizationViewModel _viewModel;

public CurveLoopVisualizationDialog(
IContentDialogService dialogService,
ICurveLoopVisualizationViewModel viewModel,
IThemeWatcherService themeWatcherService)
: base(dialogService.GetDialogHost())
{
_viewModel = viewModel;

DataContext = _viewModel;
InitializeComponent();

themeWatcherService.Watch(this);
}

public async Task ShowDialogAsync(object curveLoop)
{
_viewModel.RegisterServer(curveLoop);
MonitorServerConnection();

await ShowAsync();
}

private void MonitorServerConnection()
{
Unloaded += (_, _) => _viewModel.UnregisterServer();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.IO;
using System.IO;
using System.Text.Json;
using System.Windows.Media;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -198,6 +198,18 @@ public void ResetVisualizationSettings()
ShowCurve = true,
ShowDirection = true
},
CurveLoopSettings = new CurveLoopVisualizationSettings
{
Transparency = 20,
Diameter = 2,
MinThickness = 0.1,
SurfaceColor = Colors.DodgerBlue,
CurveColor = Color.FromArgb(255, 30, 81, 255),
DirectionColor = Color.FromArgb(255, 255, 89, 30),
ShowSurface = true,
ShowCurve = true,
ShowDirection = true
},
SolidSettings = new SolidVisualizationSettings
{
Transparency = 20,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright 2003-2024 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.

using System.Globalization;
using System.Reflection;
using System.Windows.Controls;
using System.Windows.Input;
using Autodesk.Revit.DB;
using LookupEngine.Abstractions.Configuration;
using LookupEngine.Abstractions.Decomposition;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using RevitLookup.Abstractions.Configuration;
using RevitLookup.Abstractions.Services.Presentation;
using RevitLookup.UI.Framework.Extensions;
using RevitLookup.UI.Framework.Views.Visualization;

namespace RevitLookup.Core.Decomposition.Descriptors;

public sealed class CurveLoopDescriptor : Descriptor, IDescriptorResolver, IContextMenuConnector
{
private readonly CurveLoop _curveloop;

public CurveLoopDescriptor(CurveLoop curveloop)
{
_curveloop = curveloop;
Name = $"{curveloop.GetExactLength().ToString(CultureInfo.InvariantCulture)} ft";
}

public Func<IVariant>? Resolve(string target, ParameterInfo[] parameters)
{
return target switch
{
nameof(CurveLoop.IsOpen) => ResolveIsOpen,
nameof(CurveLoop.GetPlane) => ResolveGetPlane,
nameof(CurveLoop.NumberOfCurves) => ResolveNumberOfCurves,
_ => null
};

IVariant ResolveNumberOfCurves()
{
var variants = Variants.Values<int>(1);

variants.Add(_curveloop.NumberOfCurves(), "number of curves in the curve loop");

return variants.Consume();
}

IVariant ResolveIsOpen()
{
return Variants.Values<bool>(1)
.Add(_curveloop.IsOpen(), "whether the curve loop is open or closed")
.Consume();
}

IVariant ResolveGetPlane()
{
return Variants.Values<Plane>(1)
.Add(_curveloop.GetPlane(), "Plane")
.Consume();
}
}

public void RegisterMenu(ContextMenu contextMenu, IServiceProvider serviceProvider)
{
#if REVIT2023_OR_GREATER
contextMenu.AddMenuItem("SelectMenuItem")
.SetCommand(_curveloop, SelectCurve)
.SetShortcut(Key.F6);

contextMenu.AddMenuItem("ShowMenuItem")
.SetCommand(_curveloop, ShowCurve)
.SetShortcut(Key.F7);
#endif
contextMenu.AddMenuItem("VisualizeMenuItem")
.SetAvailability(true && _curveloop.GetExactLength() > 1e-6)
.SetCommand(_curveloop, VisualizeCurve)
.SetShortcut(Key.F8);

async Task VisualizeCurve(CurveLoop curveloop)
{
if (Context.ActiveUiDocument is null) return;

try
{
var dialog = serviceProvider.GetRequiredService<CurveLoopVisualizationDialog>();
await dialog.ShowDialogAsync(curveloop);
}
catch (Exception exception)
{
var logger = serviceProvider.GetRequiredService<ILogger<CurveLoopDescriptor>>();
var notificationService = serviceProvider.GetRequiredService<INotificationService>();

logger.LogError(exception, "Visualize curveloop error");
notificationService.ShowError("Visualization error", exception);
}
}

#if REVIT2023_OR_GREATER
void SelectCurve(CurveLoop curveloop)
{
if (Context.ActiveUiDocument is null) return;
if (curveloop.Any(curve => curve.Reference is null)) return;

foreach (var curve in curveloop)
{
RevitShell.ActionEventHandler.Raise(_ => Context.ActiveUiDocument.Selection.SetReferences([curve.Reference]));
}
}

void ShowCurve(CurveLoop curveloop)
{
if (Context.ActiveUiDocument is null) return;
if (curveloop.Any(curve => curve.Reference is null)) return;

RevitShell.ActionEventHandler.Raise(application =>
{
var uiDocument = application.ActiveUIDocument;
if (uiDocument is null) return;

foreach (var curve in curveloop)
{
var element = curve.Reference.ElementId.ToElement(uiDocument.Document);
if (element is not null) uiDocument.ShowElements(element);

uiDocument.Selection.SetReferences([curve.Reference]);
}
});
}
#endif
}
}
Loading