我正在使用HelixToolkit3D作为一个小型学校项目,它需要根据现有列表与对象(自定义创建对象)生成3D对象(立方体),并且每个立方体的面应该是能够拥有自己的图像,它将作为字符串属性(图像的路径)到我之前提到的列表上的对象(例如front_image,back_image等)。我正在使用Wpf,我想使用绑定来生成3D元素。搜索后,我发现这个链接https://github.com/helix-toolkit/helix-toolkit/tree/develop/Source/Examples/WPF/ExampleBrowser/Examples/DataTemplate正是我所需要的,我能够使它工作,但只有立方体具有纯色。我试图从图像设置材质,但它不起作用。此外,我想为每个立方体添加像线框一样的边线。HelixToolkit 3D WPF每个立方体侧面的自定义图像
这是到目前为止我的代码:
3D视图XAML文件
<Controls:MetroWindow x:Class="Project1._3DView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Planom"
xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:h="http://helix-toolkit.org/wpf"
Closing="Window_Closing"
Icon="Images/meIcon.ico"
mc:Ignorable="d"
PreviewKeyDown="MetroWindow_PreviewKeyDown"
WindowStartupLocation="CenterScreen" WindowState="Maximized"
Title="Pamja 3-Dimensionale" Height="768" Width="1024">
<Window.Resources>
<local:ColorConverter3D x:Key="colorConverter"/>
<local:DataTemplate3D x:Key="{x:Type local:CubeElement}">
<local:GenericUIElement3D widthX="{Binding Depth}" Material="{Binding Material}" heightZ="{Binding Height}" depthY="{Binding Width}" Color="{Binding color}">
<local:GenericUIElement3D.Transform>
<TranslateTransform3D OffsetX="{Binding Position.X}" OffsetY="{Binding Position.Y}" OffsetZ="{Binding Position.Z}" />
</local:GenericUIElement3D.Transform>
</local:GenericUIElement3D>
</local:DataTemplate3D>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="71*"/>
<RowDefinition Height="666*"/>
</Grid.RowDefinitions>
<h:HelixViewport3D ShowCoordinateSystem="True" ZoomExtentsWhenLoaded="True" ShowFrameRate="True" ShowCameraTarget="True" Grid.RowSpan="2">
<h:SunLight>
<h:SunLight.Transform>
<TranslateTransform3D OffsetX="200" OffsetY="-200" OffsetZ="200" />
</h:SunLight.Transform>
</h:SunLight>
<h:GridLinesVisual3D Center="0,0,0" Width="400" Length="400" MinorDistance="10" MajorDistance="10" Thickness="0.1" Fill="Black"/>
<local:ItemsVisual3D ItemsSource="{Binding ObservableElements}" RefreshChildrenOnChange="True"/>
</h:HelixViewport3D>
</Grid>
3D视图.cs文件
public partial class _3DView : MahApps.Metro.Controls.MetroWindow
{
Shelf currentShelf;
public ObservableCollection<Article> ObservableElements { get; set; }
public _3DView(Shelf currentShelf)
{
InitializeComponent();
this.ObservableElements = new ObservableCollection<CubeElement>();
this.DataContext = this;
this.currentShelf = currentShelf;
foreach (CubeElement a in currentShelf.books)
{
a.Position = new Point3D((a.Depth/2) - (a.Depth * a.depthF) + currentShelf.Depth/2 + 1, (a.Width/2) + a.leftPush - currentShelf.Width/2, 20);
ObservableElements.Add(a);
}
currentShelf.items3D = ObservableElements;
}
}
CubeElement.cs
public partial class CubeElement : INotifyPropertyChanged
{
public CubeElement()
{
fSize = 12;
changeTracking = false;
drawRatio = 1;
isSelectable = true;
}
public string Id { get; set; }
public string Name { get; set; }
public string left_image { get; set; }
public string front_image { get; set; }
public string back_image { get; set; }
public string right_image { get; set; }
public string top_image { get; set; }
public Shelf shelf{ get; set; }
private double _width { get; set; }
public virtual double Width
{
get { return _width; }
set
{
_width = value;
widthDraw = _width * mainDraw;
OnPropertyChanged("Width");
}
}
private double _height { get; set; }
public virtual double Height
{
get { return _height; }
set
{
_height = value;
heightDraw = _height * mainDraw;
OnPropertyChanged(nameof(Height));
}
}
public virtual double Depth { get; set; }
public double Weight { get; set; }
public string Color
{
get { return _Color; }
set
{
_Color = value;
color = (Color)ColorConverter.ConvertFromString(_Color);
OnPropertyChanged("Color");
}
}
private string _Color { get; set; }
public int _depthF { get; set; }
public int depthF
{
get { return _depthF; }
set
{
_depthF = value;
if (shelf!= null)
{
Position = new Point3D((Depth/2) - (Depth * _depthF) + shelf.Depth/2 + 1, (Width/2) + leftPush - (shelf.Width/2), 20);
}
OnPropertyChanged("depthF");
}
}
private double _leftPush { get; set; }
public double leftPush
{
get { return _leftPush; }
set
{
_leftPush = value;
leftPushP = value * drawRatioW;
OnPropertyChanged("leftPush");
Position = new Point3D((Depth/2) - (Depth * depthF) + shelf.Depth/2 + 1, (Width/2) + (_leftPush/mainDraw) - (shelf.Width/2), 20);
}
}
private string _imagePath { get; set; }
[System.ComponentModel.DataAnnotations.Schema.NotMapped]
public string imagePath
{
get { return _imagePath; }
set
{
_imagePath = value; OnPropertyChanged("imagePath");
if(_imagePath != null)
{
Material = MaterialHelper.CreateEmissiveImageMaterial(_imagePath, Brushes.Red, UriKind.Absolute);
}
else
{
Material = MaterialHelper.CreateMaterial(color);
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public object this[string propertyName]
{
get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }
set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }
}
public Model3D Model { get; set; }
public Material Material { get; set; }
public Point3D _position;
public Point3D Position
{
get { return _position; }
set
{
_position = value;
OnPropertyChanged("Position");
}
}
public double Radius { get; set; }
private bool isVisible = true;
public bool IsVisible
{
get { return isVisible; }
set
{
if (IsVisible != value)
{
isVisible = value;
OnPropertyChanged("IsVisible");
}
}
}
private Color _color { get; set; }
public Color color
{
get { return _color; }
set
{
_color = value;
OnPropertyChanged("color");
}
}
}
Shelf.cs
public partial class Shelf
{
public string Id { get; set; }
public string Name { get; set; }
private double _width { get; set; }
public virtual double Width
{
get { return _width; }
set
{
_width = value;
OnPropertyChanged("Width");
}
}
private double _height { get; set; }
public virtual double Height
{
get { return _height; }
set
{
_height = value;
OnPropertyChanged("Height");
}
}
public double Depth { get; set; }
public double Weight { get; set; }
public ObservableCollection<CubeElement> books{ get; set; }
}
GenericUIElement3D.cs
public class GenericUIElement3D : UIElement3D
{
protected GeometryModel3D Model { get; set; }
public static readonly DependencyProperty ColorProperty = DependencyProperty.Register(
nameof(Color), typeof(Color), typeof(GenericUIElement3D), new UIPropertyMetadata((s, e) => ((GenericUIElement3D)s).ColorChanged()));
public static readonly DependencyProperty MaterialProperty = DependencyProperty.Register(
nameof(Material), typeof(Material), typeof(GenericUIElement3D), new PropertyMetadata(null));
public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(
nameof(widthX), typeof(double), typeof(GenericUIElement3D), new UIPropertyMetadata((s, e) => ((GenericUIElement3D)s).DimensionsChanged()));
public static readonly DependencyProperty HeightProperty = DependencyProperty.Register(
nameof(heightZ), typeof(double), typeof(GenericUIElement3D), new UIPropertyMetadata((s, e) => ((GenericUIElement3D)s).DimensionsChanged()));
public static readonly DependencyProperty DepthProperty = DependencyProperty.Register(
nameof(depthY), typeof(double), typeof(GenericUIElement3D), new UIPropertyMetadata((s, e) => ((GenericUIElement3D)s).DimensionsChanged()));
public Color Color
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
public double widthX
{
get { return (double)GetValue(WidthProperty); }
set { SetValue(WidthProperty, value); }
}
protected override void OnMouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
//MessageBox.Show("OnMouseDown raised. " + e.OriginalSource);
}
public double heightZ
{
get { return (double)GetValue(HeightProperty); }
set { SetValue(HeightProperty, value); }
}
public double depthY
{
get { return (double)GetValue(DepthProperty); }
set { SetValue(DepthProperty, value); }
}
public Material Material
{
get { return (Material)GetValue(MaterialProperty); }
set { SetValue(MaterialProperty, value); }
}
public GenericUIElement3D()
{
Model = new GeometryModel3D();
BindingOperations.SetBinding(Model, GeometryModel3D.MaterialProperty, new Binding(nameof(Material)) { Source = this });
Visual3DModel = Model;
}
private void SetGeometry()
{
MeshBuilder meshBuilder = new MeshBuilder(false, false);
meshBuilder.AddBox(new Point3D(0, 0, heightZ/2), widthX, depthY, heightZ);
Model.Geometry = meshBuilder.ToMesh();
}
private void ColorChanged()
{
Material = MaterialHelper.CreateMaterial(Color);
}
private void DimensionsChanged()
{
SetGeometry();
}
private void DepthChanged()
{
SetGeometry();
}
}
该项目是关于学校图书馆所以会有书籍和书架。如果有人尝试实验,代码会变得更简单(我希望我没有删除任何重要的代码)。基本上,在开始时会有2D视图,用于创建书架和添加书籍,然后如果想要的用户可以在平行窗口中切换到3D视图。我无法真正理解3D“VisualTree”如此之好(迄今为止),这就是为什么我需要一些帮助。
你见过这个例子:http://www.helix-toolkit.org/demos/wpf/rubik – Isma
@IsmaC。是的,我在发布问题后才看到它。我尝试过了,但是效果很差,而且我在华硕Rog gl75vt上运行该应用程序,它产生了很多三角形,所以我必须检查解决方法或使代码 – ASTeam