Skip to content

Commit

Permalink
Add image example
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeyNefyodov committed Aug 27, 2024
1 parent 218624f commit 39cc6a0
Show file tree
Hide file tree
Showing 14 changed files with 450 additions and 0 deletions.
24 changes: 24 additions & 0 deletions ImageExportExample/Commands/ImageExportCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Autodesk.Revit.Attributes;
using ImageExportExample.ViewModels;
using ImageExportExample.Views;
using Nice3point.Revit.Toolkit.External;

namespace ImageExportExample.Commands
{
/// <summary>
/// External command entry point invoked from the Revit interface
/// </summary>
[UsedImplicitly]
[Transaction(TransactionMode.Manual)]
public class ImageExportCommand : ExternalCommand
{
public override void Execute()
{
var viewModel = new ImageExportExampleViewModel();
var view = new ImageExportExampleView(viewModel);
viewModel.HideRequest += (s, e) => view.Hide();
viewModel.ShowRequest += (s, e) => view.ShowDialog();
view.ShowDialog();
}
}
}
46 changes: 46 additions & 0 deletions ImageExportExample/ImageExportExample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<UseWPF>true</UseWPF>
<LangVersion>latest</LangVersion>
<PlatformTarget>x64</PlatformTarget>
<ImplicitUsings>true</ImplicitUsings>
<Configurations>Debug R20;Debug R21;Debug R22;Debug R23;Debug R24;Debug R25</Configurations>
<Configurations>$(Configurations);Release R20;Release R21;Release R22;Release R23;Release R24;Release R25</Configurations>
</PropertyGroup>

<PropertyGroup Condition="$(Configuration.Contains('R20'))">
<RevitVersion>2020</RevitVersion>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('R21'))">
<RevitVersion>2021</RevitVersion>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('R22'))">
<RevitVersion>2022</RevitVersion>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('R23'))">
<RevitVersion>2023</RevitVersion>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('R24'))">
<RevitVersion>2024</RevitVersion>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration.Contains('R25'))">
<RevitVersion>2025</RevitVersion>
<TargetFramework>net8.0-windows</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Nice3point.Revit.Build.Tasks" Version="1.*" />
<PackageReference Include="Nice3point.Revit.Toolkit" Version="$(RevitVersion).*" />
<PackageReference Include="Nice3point.Revit.Extensions" Version="$(RevitVersion).*" />
<PackageReference Include="Nice3point.Revit.Api.RevitAPI" Version="$(RevitVersion).*" />
<PackageReference Include="Nice3point.Revit.Api.RevitAPIUI" Version="$(RevitVersion).*" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.*" />
</ItemGroup>

</Project>
16 changes: 16 additions & 0 deletions ImageExportExample/Models/ElementDescriptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ImageExportExample.Models
{
public class ElementDescriptor
{
public Bitmap Image { get; set; }
public string Id { get; set; }
public string Name { get; set; }
}
}
80 changes: 80 additions & 0 deletions ImageExportExample/ViewModels/ImageExportExampleViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using Autodesk.Revit.UI.Selection;
using ImageExportExample.Models;
using System.Collections.ObjectModel;
using System.Drawing;
using System.IO;

namespace ImageExportExample.ViewModels
{
public sealed partial class ImageExportExampleViewModel : ObservableObject
{
[ObservableProperty] private ObservableCollection<ElementDescriptor> _elements = [];

[RelayCommand]
private void AddImage()
{
RaiseHideRequest();
var reference = Context.UiDocument.Selection.PickObject(ObjectType.Element);
var element = Context.Document.GetElement(reference);

var bitmap = ExportImage(element);
var descriptor = new ElementDescriptor
{
Image = bitmap,
Name = element.Name,
Id = element.Id.ToString()
};

Elements.Add(descriptor);
RaiseShowRequest();
}
public static Bitmap ExportImage(Element element)
{
var viewType = Context.Document.EnumerateTypes<ViewFamilyType>()
.FirstOrDefault(view => view.ViewFamily == ViewFamily.ThreeDimensional);
using var transaction = new Transaction(Context.Document, "New image");
transaction.Start();
var newView = View3D.CreateIsometric(Context.Document, viewType.Id);
newView.IsolateElementTemporary(element.Id);
newView.ConvertTemporaryHideIsolateToPermanent();
newView.DisplayStyle = DisplayStyle.Realistic;

var filePath = Path.Combine(Path.GetTempPath(), $"{element.Id}.png");

var options = new ImageExportOptions
{
PixelSize = 1200,
ExportRange = ExportRange.SetOfViews,
FilePath = filePath,
ShadowViewsFileType = ImageFileType.PNG
};
options.SetViewsAndSheets([newView.Id]);
Context.Document.ExportImage(options);
transaction.RollBack();

var directoryPath = Path.GetDirectoryName(filePath);
var files = Directory.GetFiles(directoryPath);
foreach ( var file in files )
{
if (file.Contains($"{element.Id}") && file.EndsWith(".png"))
{
return new Bitmap(file);
}
}
return null;
}
public event EventHandler HideRequest;

private void RaiseHideRequest()
{
HideRequest?.Invoke(this, EventArgs.Empty);
}

public event EventHandler ShowRequest;

private void RaiseShowRequest()
{
ShowRequest?.Invoke(this, EventArgs.Empty);
}
}
}
25 changes: 25 additions & 0 deletions ImageExportExample/Views/Converters/BoolVisibilityConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
using Visibility = System.Windows.Visibility;

namespace ImageExportExample.Views.Converters
{
public class BoolVisibilityConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value! ? Visibility.Visible : Visibility.Hidden;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (Visibility)value! == Visibility.Visible;
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
35 changes: 35 additions & 0 deletions ImageExportExample/Views/Converters/EnumVisibilityConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
using Visibility = System.Windows.Visibility;

namespace ImageExportExample.Views.Converters
{
public class EnumVisibilityConverter<TEnum> : MarkupExtension, IValueConverter where TEnum : Enum
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not TEnum valueEnum)
{
throw new ArgumentException($"{nameof(value)} is not type: {typeof(TEnum)}");
}

if (parameter is not TEnum parameterEnum)
{
throw new ArgumentException($"{nameof(parameter)} is not type: {typeof(TEnum)}");
}

return EqualityComparer<TEnum>.Default.Equals(valueEnum, parameterEnum) ? Visibility.Visible : Visibility.Hidden;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
46 changes: 46 additions & 0 deletions ImageExportExample/Views/Converters/ImageBitmapConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Markup;
using System.Windows.Media.Imaging;

namespace ImageExportExample.Views.Converters
{
public class ImageBitmapConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is null) return System.Windows.Data.Binding.DoNothing;
if (value is not Bitmap bitmap) return System.Windows.Data.Binding.DoNothing;

using var memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Png);

var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = memoryStream;
image.EndInit();

return image;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}

}
}
24 changes: 24 additions & 0 deletions ImageExportExample/Views/Converters/InverseBoolConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;

namespace ImageExportExample.Views.Converters
{
public class InverseBoolConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return !(bool)value!;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return !(bool)value!;
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
using Visibility = System.Windows.Visibility;

namespace ImageExportExample.Views.Converters
{
public class InverseBoolVisibilityConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value! == false ? Visibility.Visible : Visibility.Hidden;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (Visibility)value! != Visibility.Visible;
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
42 changes: 42 additions & 0 deletions ImageExportExample/Views/ImageExportExampleView.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<Window
x:Class="ImageExportExample.Views.ImageExportExampleView"
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:viewModel="clr-namespace:ImageExportExample.ViewModels"
xmlns:converters="clr-namespace:ImageExportExample.Views.Converters"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance viewModel:ImageExportExampleViewModel}"
WindowStartupLocation="CenterScreen"
Title="ImageExportExample"
Height="850"
Width="400">
<StackPanel>
<Button Content="Add image" Margin="5" Command="{Binding AddImageCommand}"/>
<ListView ItemsSource="{Binding Elements}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="2">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image
Width="200" Height="200" Source="{Binding Path=Image, Converter={converters:ImageBitmapConverter}}"/>
<StackPanel Grid.Column="1">
<TextBlock Margin="5">
<Run> Element Id</Run>
<Run Text="{Binding Id}"/>
</TextBlock>
<TextBlock Margin="5">
<Run> Element Name</Run>
<Run Text="{Binding Name}"/>
</TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Window>
13 changes: 13 additions & 0 deletions ImageExportExample/Views/ImageExportExampleView.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using ImageExportExample.ViewModels;

namespace ImageExportExample.Views
{
public sealed partial class ImageExportExampleView
{
public ImageExportExampleView(ImageExportExampleViewModel viewModel)
{
DataContext = viewModel;
InitializeComponent();
}
}
}
Loading

0 comments on commit 39cc6a0

Please sign in to comment.