葡京网上娱乐场WPF自定义Window样式(1)

【题外话】

目录:

近日实验室要我修改C3D(The 3D Biomechanics Data
Standard)文件,即使从网上找到了一个叫c3d4sharp的类库,那么些类库单纯读取C3D文件的话仍是可以够,但是假设要兑现修改或者成立C3D文件就相比困苦了。同时c3d4sharp实现得相比较简单,很多C3D文件里一些数据都不襄助。好在C3D文件总体不是很复杂,于是自己就起来重新写了一个C3D文件读写的库,现在在codeplex上创办了个品种叫C3D.NET

WPF自定义Window样式(1)

 

WPF自定义Window样式(2)

【小说索引】

 

  1. C3D文件格式的构造
  2. C3D文件头的社团
  3. C3D文件参数集合的结构
  4. C3D文件数量区域的构造
  5. 动用C3D.NET读写文件示例

1. 引言

 

    WPF是打造界面的一大利器。近日在做一个类型,用的就是WPF。既然使用了WPF了,那么自然的,需要自定义窗体样式。所利用的代码是在网上查到的:初稿链接

【一、C3D文件格式的结构】

     
首先上原始源码

先是说C3D文件全体不是很复杂,也尚无过多错综复杂的定义,C3D的文档格式可以从其官网下载或在线阅读。首先C3D文件是以Section为单位存储的,每一个Section固定为512字节。Section一定是按顺序存储的,可是有意思的是,Section的序号是从1起头的,而不是0。C3D文件分为三局部,分别是Section
ID = 1的C3D文件头(固定为一个Section,512字节),Section
ID一般等于2(在文书头内会提交)的C3D参数集合以及Section
ID不晓得等于几(在文书头和参数集合中都会交到)的C3D数据部分。

2. 开立项目

但是C3D也有很复杂的地点,一个是关于整型的运用,可以行使应用有号子的(Int16),也足以动用无符号的(UInt16),只然而后者能积存的数据量要多一些罢了,既然这样,不知为什么当初还要采纳有标志的整型。而且最要紧的是,文档内没有其它标识能指出文档使用的是何种整型。官方给出的化解模式是,可以遵照例如帧总数、帧索引等判断,假若读出负数,则采纳无符号的,否则采取有标志的。

     
 创立空白项目stonemqy.CustomWindow,添加WPF项目stonemqy.CustomWindow.Main。在stonemqy.CustomWindow.Main中添加文(加文)件夹Themes,并在内部添加资源字典Generic.xaml,注意那里的Themes文件夹和Generic.xaml资源字典的名字不可变更。并在档次下依次添加类VisualStates、TransitioningContentControl和CustomWindow。

另一个是C3D文件能在不同系列的CPU上转移,这表现于不同CPU可能利用的字节序(Endian)和浮点数字不同,比如我们用的CPU都是拔取Little-Endian以及IEEE754的浮点数标准。从网上查还发现有DEC
(VAX)以及IBM等CPU采纳不同的浮点数标准,详见我前边一篇作品:http://www.cnblogs.com/mayswind/p/3365594.html。而C3D则是永葆3类CPU,AMDCPU选拔Little-Endian以及IEEE754标准的浮点数,DEC
(VAX)拔取的Little-Endian以及故意的浮点数,MIPS
(SGI)拔取的Big-Endian以及IEEE754标准的浮点数,所以在读取文档的时候恐怕需要至极开展处理,在第三节会详细表达。

3. VisualStates

 

using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Media;

namespace stonemqy.CustomWindow.Main
{
    public static class VisualStates
    {  /// <summary>
        /// This method tries to get the named VisualStateGroup for the 
        /// dependency object. The provided object's ImplementationRoot will be 
        /// looked up in this call.
        /// </summary>
        /// <param name="dependencyObject">The dependency object.</param>
        /// <param name="groupName">The visual state group's name.</param>
        /// <returns>Returns null or the VisualStateGroup object.</returns>
        public static VisualStateGroup TryGetVisualStateGroup(DependencyObject dependencyObject, string groupName)
        {
            FrameworkElement root = GetImplementationRoot(dependencyObject);
            if (root == null)
            {
                return null;
            }

            return VisualStateManager.GetVisualStateGroups(root)
                .OfType<VisualStateGroup>()
                .Where(group => string.CompareOrdinal(groupName, group.Name) == 0)
                .FirstOrDefault();
        }

        /// <summary>
        /// Gets the implementation root of the Control.
        /// </summary>
        /// <param name="dependencyObject">The DependencyObject.</param>
        /// <remarks>
        /// Implements Silverlight's corresponding internal property on Control.
        /// </remarks>
        /// <returns>Returns the implementation root or null.</returns>
        public static FrameworkElement GetImplementationRoot(DependencyObject dependencyObject)
        {
            Debug.Assert(dependencyObject != null, "DependencyObject should not be null.");
            return (1 == VisualTreeHelper.GetChildrenCount(dependencyObject)) ?
                VisualTreeHelper.GetChild(dependencyObject, 0) as FrameworkElement :
                null;
        }
    }
}

【二、C3D文件头的协会】

4. TransitioningContentControl

先是来说第一片段,也就是C3D的文件头,C3D的文件头一定只占1个Section,即定位的512字节,所以一旦读取前512字节就足以把任何头数据获得到了。即便各类Section有512字节之多,然而对于C3D的文书头只占了很少的一有些,在文件头中有雅量空白的区域。其中第一有的是文本头参数部分,内容如下:

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace stonemqy.CustomWindow.Main
{
    /// <summary>
    /// Represents a control with a single piece of content and when that content 
    /// changes performs a transition animation. 
    /// </summary>
    /// <QualityBand>Experimental</QualityBand>
    /// <remarks>The API for this control will change considerably in the future.</remarks>
    [TemplateVisualState(GroupName = PresentationGroup, Name = NormalState)]
    [TemplateVisualState(GroupName = PresentationGroup, Name = DefaultTransitionState)]
    [TemplatePart(Name = PreviousContentPresentationSitePartName, Type = typeof(ContentControl))]
    [TemplatePart(Name = CurrentContentPresentationSitePartName, Type = typeof(ContentControl))]
    public class TransitioningContentControl : ContentControl
    {
        #region Visual state names
        /// <summary>
        /// The name of the group that holds the presentation states.
        /// </summary>
        private const string PresentationGroup = "PresentationStates";

        /// <summary>
        /// The name of the state that represents a normal situation where no
        /// transition is currently being used.
        /// </summary>
        private const string NormalState = "Normal";

        /// <summary>
        /// The name of the state that represents the default transition.
        /// </summary>
        public const string DefaultTransitionState = "DefaultTransition";
        #endregion Visual state names

        #region Template part names
        /// <summary>
        /// The name of the control that will display the previous content.
        /// </summary>
        internal const string PreviousContentPresentationSitePartName = "PreviousContentPresentationSite";

        /// <summary>
        /// The name of the control that will display the current content.
        /// </summary>
        internal const string CurrentContentPresentationSitePartName = "CurrentContentPresentationSite";

        #endregion Template part names

        #region TemplateParts
        /// <summary>
        /// Gets or sets the current content presentation site.
        /// </summary>
        /// <value>The current content presentation site.</value>
        private ContentPresenter CurrentContentPresentationSite { get; set; }

        /// <summary>
        /// Gets or sets the previous content presentation site.
        /// </summary>
        /// <value>The previous content presentation site.</value>
        private ContentPresenter PreviousContentPresentationSite { get; set; }
        #endregion TemplateParts

        #region public bool IsTransitioning

        /// <summary>
        /// Indicates whether the control allows writing IsTransitioning.
        /// </summary>
        private bool _allowIsTransitioningWrite;

        /// <summary>
        /// Gets a value indicating whether this instance is currently performing
        /// a transition.
        /// </summary>
        public bool IsTransitioning
        {
            get { return (bool)GetValue(IsTransitioningProperty); }
            private set
            {
                _allowIsTransitioningWrite = true;
                SetValue(IsTransitioningProperty, value);
                _allowIsTransitioningWrite = false;
            }
        }

        /// <summary>
        /// Identifies the IsTransitioning dependency property.
        /// </summary>
        public static readonly DependencyProperty IsTransitioningProperty =
            DependencyProperty.Register(
                "IsTransitioning",
                typeof(bool),
                typeof(TransitioningContentControl),
                new PropertyMetadata(OnIsTransitioningPropertyChanged));

        /// <summary>
        /// IsTransitioningProperty property changed handler.
        /// </summary>
        /// <param name="d">TransitioningContentControl that changed its IsTransitioning.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnIsTransitioningPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TransitioningContentControl source = (TransitioningContentControl)d;

            if (!source._allowIsTransitioningWrite)
            {
                source.IsTransitioning = (bool)e.OldValue;
                throw new InvalidOperationException("TransitiotioningContentControl_IsTransitioningReadOnly");
            }
        }
        #endregion public bool IsTransitioning

        /// <summary>
        /// The storyboard that is used to transition old and new content.
        /// </summary>
        private Storyboard _currentTransition;

        /// <summary>
        /// Gets or sets the storyboard that is used to transition old and new content.
        /// </summary>
        private Storyboard CurrentTransition
        {
            get { return _currentTransition; }
            set
            {
                // decouple event
                if (_currentTransition != null)
                {
                    _currentTransition.Completed -= OnTransitionCompleted;
                }

                _currentTransition = value;

                if (_currentTransition != null)
                {
                    _currentTransition.Completed += OnTransitionCompleted;
                }
            }
        }

        #region public string Transition
        /// <summary>
        /// Gets or sets the name of the transition to use. These correspond
        /// directly to the VisualStates inside the PresentationStates group.
        /// </summary>
        public string Transition
        {
            get { return GetValue(TransitionProperty) as string; }
            set { SetValue(TransitionProperty, value); }
        }

        /// <summary>
        /// Identifies the Transition dependency property.
        /// </summary>
        public static readonly DependencyProperty TransitionProperty =
            DependencyProperty.Register(
                "Transition",
                typeof(string),
                typeof(TransitioningContentControl),
                new PropertyMetadata(DefaultTransitionState, OnTransitionPropertyChanged));

        /// <summary>
        /// TransitionProperty property changed handler.
        /// </summary>
        /// <param name="d">TransitioningContentControl that changed its Transition.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnTransitionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TransitioningContentControl source = (TransitioningContentControl)d;
            string oldTransition = e.OldValue as string;
            string newTransition = e.NewValue as string;

            if (source.IsTransitioning)
            {
                source.AbortTransition();
            }

            // find new transition
            Storyboard newStoryboard = source.GetStoryboard(newTransition);

            // unable to find the transition.
            if (newStoryboard == null)
            {
                // could be during initialization of xaml that presentationgroups was not yet defined
                if (VisualStates.TryGetVisualStateGroup(source, PresentationGroup) == null)
                {
                    // will delay check
                    source.CurrentTransition = null;
                }
                else
                {
                    // revert to old value
                    source.SetValue(TransitionProperty, oldTransition);

                    throw new ArgumentException(
                       "TransitioningContentControl_TransitionNotFound");
                }
            }
            else
            {
                source.CurrentTransition = newStoryboard;
            }
        }
        #endregion public string Transition

        #region public bool RestartTransitionOnContentChange
        /// <summary>
        /// Gets or sets a value indicating whether the current transition
        /// will be aborted when setting new content during a transition.
        /// </summary>
        public bool RestartTransitionOnContentChange
        {
            get { return (bool)GetValue(RestartTransitionOnContentChangeProperty); }
            set { SetValue(RestartTransitionOnContentChangeProperty, value); }
        }

        /// <summary>
        /// Identifies the RestartTransitionOnContentChange dependency property.
        /// </summary>
        public static readonly DependencyProperty RestartTransitionOnContentChangeProperty =
            DependencyProperty.Register(
                "RestartTransitionOnContentChange",
                typeof(bool),
                typeof(TransitioningContentControl),
                new PropertyMetadata(false, OnRestartTransitionOnContentChangePropertyChanged));

        /// <summary>
        /// RestartTransitionOnContentChangeProperty property changed handler.
        /// </summary>
        /// <param name="d">TransitioningContentControl that changed its RestartTransitionOnContentChange.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnRestartTransitionOnContentChangePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((TransitioningContentControl)d).OnRestartTransitionOnContentChangeChanged((bool)e.OldValue, (bool)e.NewValue);
        }

        /// <summary>
        /// Called when the RestartTransitionOnContentChangeProperty changes.
        /// </summary>
        /// <param name="oldValue">The old value of RestartTransitionOnContentChange.</param>
        /// <param name="newValue">The new value of RestartTransitionOnContentChange.</param>
        protected virtual void OnRestartTransitionOnContentChangeChanged(bool oldValue, bool newValue)
        {
        }
        #endregion public bool RestartTransitionOnContentChange

        #region Events
        /// <summary>
        /// Occurs when the current transition has completed.
        /// </summary>
        public event RoutedEventHandler TransitionCompleted;
        #endregion Events

        /// <summary>
        /// Initializes a new instance of the <see cref="TransitioningContentControl"/> class.
        /// </summary>
        public TransitioningContentControl()
        {
            DefaultStyleKey = typeof(TransitioningContentControl);
        }

        /// <summary>
        /// Builds the visual tree for the TransitioningContentControl control 
        /// when a new template is applied.
        /// </summary>
        public override void OnApplyTemplate()
        {
            if (IsTransitioning)
            {
                AbortTransition();
            }

            base.OnApplyTemplate();

            PreviousContentPresentationSite = GetTemplateChild(PreviousContentPresentationSitePartName) as ContentPresenter;
            CurrentContentPresentationSite = GetTemplateChild(CurrentContentPresentationSitePartName) as ContentPresenter;

            if (CurrentContentPresentationSite != null)
            {
                CurrentContentPresentationSite.Content = Content;
            }

            // hookup currenttransition
            Storyboard transition = GetStoryboard(Transition);
            CurrentTransition = transition;
            if (transition == null)
            {
                string invalidTransition = Transition;
                // revert to default
                Transition = DefaultTransitionState;

                throw new ArgumentException(
                    "TransitioningContentControl_TransitionNotFound");
            }

            VisualStateManager.GoToState(this, NormalState, false);
            VisualStateManager.GoToState(this, Transition, true);
        }

        /// <summary>
        /// Called when the value of the <see cref="P:System.Windows.Controls.ContentControl.Content"/> property changes.
        /// </summary>
        /// <param name="oldContent">The old value of the <see cref="P:System.Windows.Controls.ContentControl.Content"/> property.</param>
        /// <param name="newContent">The new value of the <see cref="P:System.Windows.Controls.ContentControl.Content"/> property.</param>
        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);

            StartTransition(oldContent, newContent);
        }

        /// <summary>
        /// Starts the transition.
        /// </summary>
        /// <param name="oldContent">The old content.</param>
        /// <param name="newContent">The new content.</param>
        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "newContent", Justification = "Should be used in the future.")]
        private void StartTransition(object oldContent, object newContent)
        {
            // both presenters must be available, otherwise a transition is useless.
            if (CurrentContentPresentationSite != null && PreviousContentPresentationSite != null)
            {
                CurrentContentPresentationSite.Content = newContent;

                PreviousContentPresentationSite.Content = oldContent;

                // and start a new transition
                if (!IsTransitioning || RestartTransitionOnContentChange)
                {
                    IsTransitioning = true;
                    VisualStateManager.GoToState(this, NormalState, false);
                    VisualStateManager.GoToState(this, Transition, true);
                }
            }
        }

        /// <summary>
        /// Handles the Completed event of the transition storyboard.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void OnTransitionCompleted(object sender, EventArgs e)
        {
            AbortTransition();

            RoutedEventHandler handler = TransitionCompleted;
            if (handler != null)
            {
                handler(this, new RoutedEventArgs());
            }
        }

        /// <summary>
        /// Aborts the transition and releases the previous content.
        /// </summary>
        public void AbortTransition()
        {
            // go to normal state and release our hold on the old content.
            VisualStateManager.GoToState(this, NormalState, false);
            IsTransitioning = false;
            if (PreviousContentPresentationSite != null)
            {
                PreviousContentPresentationSite.Content = null;
            }
        }

        /// <summary>
        /// Attempts to find a storyboard that matches the newTransition name.
        /// </summary>
        /// <param name="newTransition">The new transition.</param>
        /// <returns>A storyboard or null, if no storyboard was found.</returns>
        private Storyboard GetStoryboard(string newTransition)
        {
            VisualStateGroup presentationGroup = VisualStates.TryGetVisualStateGroup(this, PresentationGroup);
            Storyboard newStoryboard = null;
            if (presentationGroup != null)
            {
                newStoryboard = presentationGroup.States
                    .OfType<VisualState>()
                    .Where(state => state.Name == newTransition)
                    .Select(state => state.Storyboard)
                    .FirstOrDefault();
            }
            return newStoryboard;
        }


    }
}

葡京网上娱乐场 1

 

字节 类型 说明
00H Byte 参数集合开始的Section ID(通常为0x02,但也不一定)
01H Byte 文件标识(固定为0x50)
02H-03H Int16 每帧里3D坐标点的个数
04H-05H Int16 每帧里模拟测量的个数
06H-07H Int16 第1帧的序号(最小为1)
08H-09H Int16 最后1帧的序号
0AH-0BH Int16 最大插值差距
0CH-0FH Single 比例因子(正数表示存储的帧为整数帧,负数为浮点帧)
10H-11H Int16  数据区域开始的Section ID
12H-13H Int16 每帧模拟采样个数
14H-17H Single 帧率

 5. CustomWindow

在此之后的第二部分,也就是储存的风波,听上去应该占很多字节,不过出于限制了轩然大波数量最多不可以领先18个,同时事件名称最长为4字节,所以事件部分也只占很少的半空中。由于C3D重假若为着记录运动的数目,可能在其间有成千上万相比较首要的地点,事件就是用来标记出这个地点的。一个轩然大波包括五个内容,分别是最长四字节的事件名称、一字节的事件是否应当显得的图景以及一个四字节的单精度浮点数表示事件现身的光阴。

   
 此处原来关于于CustomWindow的有的诠释,可是经验证,注释有误,故贴代码时将注释删除了。

字节 类型 说明
12AH-12BH Int16 事件名是否支持4字节(支持为0x3039,不支持为0)
12CH-12DH Int16 事件数量(最大为18)
130H-176H Single[] 按事件顺序存储的每个事件发生的时间(第1个帧为0.0s)
178H-188H Byte[] 按事件顺序存储的每个事件是否应该显示(1为显示,0为不显示)
18CH-1D2H Char[] 按事件顺序存储的每个事件的名称(每个事件占4字节)
using System; 
using System.Windows; 
using System.Windows.Input; 

namespace stonemqy.CustomWindow.Main
{
    public class CustomWindow : Window
    {
        public CustomWindow()
        {
            DefaultStyleKey = typeof(CustomWindow);
            CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, CloseWindow));
            CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, MaximizeWindow, CanResizeWindow));
            CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, MinimizeWindow, CanMinimizeWindow));
            CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, RestoreWindow, CanResizeWindow));
            CommandBindings.Add(new CommandBinding(SystemCommands.ShowSystemMenuCommand, ShowSystemMenu));
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            if (e.ButtonState == MouseButtonState.Pressed)
                DragMove();
        }

        protected override void OnContentRendered(EventArgs e)
        {
            base.OnContentRendered(e);
            if (SizeToContent == SizeToContent.WidthAndHeight)
                InvalidateMeasure();
        }

        #region Window Commands

        private void CanResizeWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ResizeMode == ResizeMode.CanResize || ResizeMode == ResizeMode.CanResizeWithGrip;
        }

        private void CanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ResizeMode != ResizeMode.NoResize;
        }

        private void CloseWindow(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
            //SystemCommands.CloseWindow(this);
        }

        private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e)
        {
            SystemCommands.MaximizeWindow(this);
        }

        private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)
        {
            SystemCommands.MinimizeWindow(this);
        }

        private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
        {
            SystemCommands.RestoreWindow(this);
        }


        private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e)
        {
            var element = e.OriginalSource as FrameworkElement;
            if (element == null)
                return;

            var point = WindowState == WindowState.Maximized ? new Point(0, element.ActualHeight)
                : new Point(Left + BorderThickness.Left, element.ActualHeight + Top + BorderThickness.Top);
            point = element.TransformToAncestor(this).Transform(point);
            SystemCommands.ShowSystemMenu(this, point);
        }

        #endregion
    }
}

 

6. Generic.xaml

【三、C3D文件参数集合的协会】 

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:stonemqy.CustomWindow.Main"
                    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">


    <DataTemplate x:Key="RestoreWhite">
        <Grid UseLayoutRounding="True"
              RenderTransform="1,0,0,1,.5,.5">
            <Path Data="M2,0 L8,0 L8,6 M0,3 L6,3 M0,2 L6,2 L6,8 L0,8 Z"
                  Width="8"
                  Height="8"
                  VerticalAlignment="Center"
                  HorizontalAlignment="Center"
                  Stroke="White"
                  StrokeThickness="1" />
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="CloseWhite">
        <Grid Margin="1,0,0,0">

            <Rectangle Stroke="White"
                       Height="2"
                       RenderTransformOrigin="0.5,0.5"
                       Width="11"
                       UseLayoutRounding="True">
                <Rectangle.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform />
                        <SkewTransform />
                        <RotateTransform Angle="45" />
                        <TranslateTransform />
                    </TransformGroup>
                </Rectangle.RenderTransform>
            </Rectangle>
            <Rectangle Stroke="White"
                       Height="2"
                       RenderTransformOrigin="0.5,0.5"
                       Width="11"
                       UseLayoutRounding="True">
                <Rectangle.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform />
                        <SkewTransform />
                        <RotateTransform Angle="-45" />
                        <TranslateTransform />
                    </TransformGroup>
                </Rectangle.RenderTransform>
            </Rectangle>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="MaximizeWhite">
        <Grid>
            <Path Data="M0,1 L9,1 L9,8 L0,8 Z"
                  Width="9"
                  Height="8"
                  Margin="0,2,0,0"
                  VerticalAlignment="Center"
                  HorizontalAlignment="Center"
                  Stroke="White"
                  StrokeThickness="2" />
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="MinimizeWhite">
        <Grid>
            <Path Data="M0,6 L8,6 Z"
                  Width="8"
                  Height="7"
                  VerticalAlignment="Center"
                  HorizontalAlignment="Center"
                  Stroke="White"
                  StrokeThickness="2" />
        </Grid>
    </DataTemplate>



    <Style x:Key="TitleBarButtonFocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="2"
                               SnapsToDevicePixels="True"
                               Stroke="Transparent"
                               StrokeDashArray="1 2"
                               StrokeThickness="1" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="TitleBarButtonStyle"
           TargetType="{x:Type Button}">
        <Setter Property="Focusable"
                Value="False" />
        <Setter Property="Background"
                Value="Transparent" />
        <Setter Property="BorderBrush"
                Value="Transparent" />
        <Setter Property="BorderThickness"
                Value="1" />
        <Setter Property="HorizontalContentAlignment"
                Value="Center" />
        <Setter Property="VerticalContentAlignment"
                Value="Center" />
        <Setter Property="Padding"
                Value="1" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid x:Name="LayoutRoot">
                        <Rectangle x:Name="ButtonBackground"
                                   Width="28"
                                   Height="28"
                                   Fill="#FFFFFFFF"
                                   Opacity="0" />
                        <Border x:Name="ButtonBorder"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}"
                                SnapsToDevicePixels="true">
                            <ContentPresenter x:Name="TitleBarButtonContentPresenter"
                                              Focusable="False"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              Margin="{TemplateBinding Padding}"
                                              RecognizesAccessKey="True"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                        </Border>
                    </Grid>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver"
                                 Value="true">
                            <Setter Property="Opacity"
                                    Value="0.2"
                                    TargetName="ButtonBackground" />
                        </Trigger>
                        <Trigger Property="IsPressed"
                                 Value="True">
                            <Setter Property="Opacity"
                                    Value="0.4"
                                    TargetName="ButtonBackground" />
                        </Trigger>
                        <Trigger Property="IsEnabled"
                                 Value="false">
                            <Setter TargetName="TitleBarButtonContentPresenter"
                                    Property="Opacity"
                                    Value=".5" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <!--<Style TargetType="{x:Type local:OmecWindow}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:OmecWindow}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>-->



    <Style TargetType="{x:Type local:CustomWindow}">
        <Setter Property="Foreground"
                Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
        <Setter Property="Background"
                Value="#FFF1F1F1" />
        <Setter Property="BorderBrush"
                Value="#FF0874AA" />
        <Setter Property="BorderThickness"
                Value="1" />
        <Setter Property="IsTabStop"
                Value="False" />
        <Setter Property="ResizeMode"
                Value="CanResizeWithGrip" />
        <Setter Property="UseLayoutRounding"
                Value="True" />
        <Setter Property="TextOptions.TextFormattingMode"
                Value="Display" />
        <Setter Property="WindowStyle"
                Value="SingleBorderWindow" />
        <Setter Property="FontFamily"
                Value="Segoe UI" />
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome CornerRadius="0"
                              GlassFrameThickness="1"
                              UseAeroCaptionButtons="False"
                              NonClientFrameEdges="None" />
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:CustomWindow}">


                    <Border BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            x:Name="WindowBorder">
                        <Grid x:Name="LayoutRoot"
                              Background="{TemplateBinding Background}">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>

                            <Grid x:Name="PART_WindowTitleGrid"
                                  Grid.Row="0"
                                  Height="26.4"
                                  Background="{TemplateBinding BorderBrush}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <StackPanel Orientation="Horizontal">
                                    <!--<Image Source="{TemplateBinding Icon}"
                                           Margin="7,0,5,0"
                                           VerticalAlignment="Center"
                                          />-->
                                    <Button VerticalAlignment="Center"
                                            Margin="7,0,5,0"
                                            Content="{TemplateBinding Icon}"
                                            Height="{x:Static SystemParameters.SmallIconHeight}"
                                            Width="{x:Static SystemParameters.SmallIconWidth}"
                                            WindowChrome.IsHitTestVisibleInChrome="True"
                                            IsTabStop="False">
                                        <Button.Template>
                                            <ControlTemplate TargetType="{x:Type Button}">
                                                <Image Source="{TemplateBinding Content}" />
                                            </ControlTemplate>
                                        </Button.Template>
                                        <i:Interaction.Triggers>
                                            <i:EventTrigger EventName="Click">
                                                <i:InvokeCommandAction Command="{x:Static SystemCommands.ShowSystemMenuCommand}" />
                                            </i:EventTrigger>
                                            <i:EventTrigger EventName="MouseDoubleClick">
                                                <i:InvokeCommandAction Command="{x:Static SystemCommands.CloseWindowCommand}" />
                                            </i:EventTrigger>
                                        </i:Interaction.Triggers>
                                    </Button>
                                    <ContentControl IsTabStop="False"
                                                    Foreground="White"
                                                    HorizontalAlignment="Center"
                                                    VerticalAlignment="Center"
                                                    FontSize="{DynamicResource {x:Static SystemFonts.CaptionFontSize}}"
                                                    Content="{TemplateBinding Title}" />
                                </StackPanel>
                                <StackPanel x:Name="WindowCommandButtonsStackPanel"
                                            Grid.Column="1"
                                            HorizontalAlignment="Right"
                                            VerticalAlignment="Top"
                                            Background="Transparent"
                                            Orientation="Horizontal"
                                            WindowChrome.IsHitTestVisibleInChrome="True">
                                    <Button x:Name="Minimize"
                                            ToolTip="Minimize"
                                            WindowChrome.IsHitTestVisibleInChrome="True"
                                            Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}"
                                            ContentTemplate="{StaticResource MinimizeWhite}"
                                            Style="{StaticResource TitleBarButtonStyle}"
                                            IsTabStop="False" />
                                    <Grid Margin="1,0,1,0">
                                        <Button x:Name="Restore"
                                                ToolTip="Restore"
                                                WindowChrome.IsHitTestVisibleInChrome="True"
                                                Command="{Binding Source={x:Static SystemCommands.RestoreWindowCommand}}"
                                                ContentTemplate="{StaticResource RestoreWhite}"
                                                Style="{StaticResource TitleBarButtonStyle}"
                                                Visibility="Collapsed"
                                                IsTabStop="False" />
                                        <Button x:Name="Maximize"
                                                ToolTip="Maximize"
                                                WindowChrome.IsHitTestVisibleInChrome="True"
                                                Command="{Binding Source={x:Static SystemCommands.MaximizeWindowCommand}}"
                                                ContentTemplate="{StaticResource MaximizeWhite}"
                                                Style="{StaticResource TitleBarButtonStyle}"
                                                IsTabStop="False" />
                                    </Grid>
                                    <Button x:Name="Close"
                                            ToolTip="Close"
                                            WindowChrome.IsHitTestVisibleInChrome="True"
                                            Command="{Binding Source={x:Static SystemCommands.CloseWindowCommand}}"
                                            ContentTemplate="{StaticResource CloseWhite}"
                                            Style="{StaticResource TitleBarButtonStyle}"
                                            IsTabStop="False" />
                                </StackPanel>
                            </Grid>
                            <AdornerDecorator Grid.Row="1" KeyboardNavigation.IsTabStop="False">
                                <!--<ContentPresenter x:Name="MainContentPresenter"
                                                  KeyboardNavigation.TabNavigation="Cycle" />-->
                                <local:TransitioningContentControl Content="{TemplateBinding Content}"
                                                                   x:Name="MainContentPresenter"

                                                                   KeyboardNavigation.TabNavigation="Cycle" />
                            </AdornerDecorator>
                            <ResizeGrip x:Name="ResizeGrip"
                                        HorizontalAlignment="Right"
                                        VerticalAlignment="Bottom"
                                        Grid.Row="1"
                                        IsTabStop="False"
                                        Visibility="Hidden"
                                        WindowChrome.ResizeGripDirection="BottomRight" />
                        </Grid>
                    </Border>


                    <ControlTemplate.Triggers>
                        <Trigger Property="IsActive"
                                 Value="False">
                            <Setter Property="BorderBrush"
                                    Value="#FF6F7785" />
                        </Trigger>
                        <Trigger Property="WindowState"
                                 Value="Maximized">
                            <Setter TargetName="Maximize"
                                    Property="Visibility"
                                    Value="Collapsed" />
                            <Setter TargetName="Restore"
                                    Property="Visibility"
                                    Value="Visible" />
                            <Setter TargetName="LayoutRoot"
                                    Property="Margin"
                                    Value="7" />
                        </Trigger>
                        <Trigger Property="WindowState"
                                 Value="Normal">
                            <Setter TargetName="Maximize"
                                    Property="Visibility"
                                    Value="Visible" />
                            <Setter TargetName="Restore"
                                    Property="Visibility"
                                    Value="Collapsed" />
                        </Trigger>
                        <Trigger Property="ResizeMode"
                                 Value="NoResize">
                            <Setter TargetName="Minimize"
                                    Property="Visibility"
                                    Value="Collapsed" />
                            <Setter TargetName="Maximize"
                                    Property="Visibility"
                                    Value="Collapsed" />
                            <Setter TargetName="Restore"
                                    Property="Visibility"
                                    Value="Collapsed" />
                        </Trigger>

                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="ResizeMode"
                                           Value="CanResizeWithGrip" />
                                <Condition Property="WindowState"
                                           Value="Normal" />
                            </MultiTrigger.Conditions>
                            <Setter TargetName="ResizeGrip"
                                    Property="Visibility"
                                    Value="Visible" />
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

    </Style>



    <Style TargetType="local:TransitioningContentControl">
        <Setter Property="IsTabStop"
                Value="False" />
        <Setter Property="HorizontalContentAlignment"
                Value="Stretch" />
        <Setter Property="VerticalContentAlignment"
                Value="Stretch" />
        <Setter Property="Transition"
                Value="DefaultTransition" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:TransitioningContentControl">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius="2">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="PresentationStates">
                                <VisualState x:Name="DefaultTransition">
                                    <Storyboard>
                                        <!--<DoubleAnimationUsingKeyFrames 
                                            BeginTime="00:00:00" 
                                            Storyboard.TargetName="CurrentContentPresentationSite"
                                            Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="1"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                            BeginTime="00:00:00" 
                                            Storyboard.TargetName="PreviousContentPresentationSite" 
                                            Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="0"/>
                                        </DoubleAnimationUsingKeyFrames>-->
                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="CurrentContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="0" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.400"
                                                                  Value="1" />
                                        </DoubleAnimationUsingKeyFrames>

                                        <DoubleAnimation BeginTime="00:00:00"
                                                         Duration="00:00:00.500"
                                                         Storyboard.TargetName="CurrentContentPresentationSite"
                                                         Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"
                                                         From="50"
                                                         To="0">
                                            <DoubleAnimation.EasingFunction>
                                                <CubicEase EasingMode="EaseOut" />
                                            </DoubleAnimation.EasingFunction>
                                        </DoubleAnimation>

                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="PreviousContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="1" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.100"
                                                                  Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="PreviousContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.Visibility)">
                                            <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Collapsed</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>

                                <VisualState x:Name="UpTransition">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="CurrentContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="0" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                  Value="1" />
                                        </DoubleAnimationUsingKeyFrames>

                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="CurrentContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="30" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                  Value="0" />
                                        </DoubleAnimationUsingKeyFrames>

                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="PreviousContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="1" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                  Value="0" />
                                        </DoubleAnimationUsingKeyFrames>

                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="PreviousContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="0" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                  Value="-30" />
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>

                                <VisualState x:Name="DownTransition">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="CurrentContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="0" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                  Value="1" />
                                        </DoubleAnimationUsingKeyFrames>

                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="CurrentContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="-40" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                  Value="0" />
                                        </DoubleAnimationUsingKeyFrames>

                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="PreviousContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="1" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                  Value="0" />
                                        </DoubleAnimationUsingKeyFrames>

                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                       Storyboard.TargetName="PreviousContentPresentationSite"
                                                                       Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00"
                                                                  Value="0" />
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.300"
                                                                  Value="40" />
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>

                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Grid>
                            <ContentPresenter x:Name="PreviousContentPresentationSite"
                                              Content="{x:Null}"
                                              ContentTemplate="{TemplateBinding ContentTemplate}"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                <ContentPresenter.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform />
                                        <SkewTransform />
                                        <RotateTransform />
                                        <TranslateTransform />
                                    </TransformGroup>
                                </ContentPresenter.RenderTransform>
                            </ContentPresenter>

                            <ContentPresenter x:Name="CurrentContentPresentationSite"
                                              Content="{x:Null}"
                                              ContentTemplate="{TemplateBinding ContentTemplate}"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                <ContentPresenter.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform />
                                        <SkewTransform />
                                        <RotateTransform />
                                        <TranslateTransform />
                                    </TransformGroup>
                                </ContentPresenter.RenderTransform>
                            </ContentPresenter>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

C3D文件存储了汪洋的参数,其使用了近似目录的不二法门存储了参数,然而还好只有一级。即参数部分只有参数组和参数,并且每个参数组里只可以有参数无法再包含参数组,每个参数必须在一个参数组内。参数集合起初于文件头中的首个字节表示的Section
ID,常常为2,可是也不必然,有的文件会在文书头后留出空白,然后参数集合开始的Section
ID就滞缓了。所以判断是否为C3D文件千万不要一开端读进去个Int16然后判断是不是0x5002,而迟早要咬定第二个字节是不是0x50,确定参数集合的岗位也终将要按照文件的率先字节来。

  1. MainWindow.xaml

         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:stonemqy.CustomWindow.Main"
         Title="MainWindow" Height="350" Width="525">
     <Grid>
    
     </Grid>
    

    /local:CustomWindow

  2. MainWindow.cs

    namespace stonemqy.CustomWindow.Main
    {

     /// <summary>
     /// MainWindow.xaml 的交互逻辑
     /// </summary>
     public partial class MainWindow : CustomWindow
     {
         public MainWindow()
         {
             InitializeComponent();
         }
     }
    

    }

  3. 运转效果

而对此参数集合,最先的4字节概念如下:

葡京网上娱乐场 2

字节 类型 说明
00H Byte 第一个参数所在的Section在整个参数集合中的位置(通常为0x01,说明开头4字节之后就是第一个参数)
01H Byte 参数集合部分标识(固定为0x50)
02H Byte 参数集合所占Section数量
03H Byte 生成文件的CPU类型(0x54为Intel,0x55为DEC (VAX, PDP-11),0x56为MIPS (SGI/MIPS))
  1. 连串代码

里头前2个字节官方说一向忽略就行,不过为了配合在写入的时候仍然要写进去的。第3字节其实我们按梯次读到头也不需要以此数量。这其间重要的是CPU类型,由于不同CPU类型拔取的字节序以及存储的浮点数字有所不同,所以我们还索要按照CPU类型举行相应的处理。

源码

对于AMD和DEC生成的文档,都是使用Little-Endian字节序存储的文档,所以自然要动用Little-Endian来读取Int16、Single等序列;而MIPS则利用的Big-Endian字节序存储文档,所以在读取的时候肯定要咬定当前电脑默认的字节序以及文档接纳的字节序。

而对此Intel和MIPS生成的文档,对于浮点数字的积存都是利用正式的IEEE754浮点数字,对于.NET而言不需要开展此外处理;而DEC生成的文档则运用特有浮点数,需要将4个字节全体读取未来再拓展出格的更换,转换方法见自己事先的篇章:http://www.cnblogs.com/mayswind/p/3365594.html

在此之下就存储着独具的参数了,参数分为两类,分别是参数组和参数。

对此参数组,要存储以下6个内容:

字节 类型 说明
00H SByte 参数组名称长度(如果为负数则表示该参数组锁定请不要修改,而长度为绝对值)
01H SByte 参数组ID的负数
02H – … Char[] 参数组名称(仅包含大写字母、0-9以及下划线_)
… + 1 – … + 2 Int16 下一参数组/参数的偏移(包含本内容的2字节)
… + 3 Byte 参数组描述长度
… + 4 –  Char[] 参数组描述内容(ASCII码)

C3D文件没有规定一个参数组后面跟另一个参数组依然跟该参数组里的享有参数,所以读取的时候要注意下。而参数的始末则与参数组基本均等,只是在下一参数组/参数的舞狮与参数组描述长度之间存放着该参数的实在多少罢了,由于地点描述起来太难为了,这里就不写了。

字节

类型

说明

事先的始末

 

Int16

下一参数组/参数的撼动(包含本内容的2字节)

 

Byte

参数存放内容的品种(-1 Char,1 Byte,2
Int16,4 Single),相对值即为长度

 

Byte

参数内容维数(0-3)

 

Byte[]

参数每一维大小(倘诺维数为0,就从不此部分)

 

Byte[] 

参数实际内容

 

Byte

参数组描述长度

自此的始末

此地需要验证的就是,由于参数可以存放数组,所以增添了维数的标识,即当维数为0时,存放的始末为Char、Byte、Int16、Single等转移出的字节数组;而当维数为1时,存放的为Char[]、Byte[]、Int16[]、Single[]等转移出的字节数组,以此类推。而对数组的蕴藏,其实就是数组每个元素依次展开仓储,而对此多维数组,则是按行优先开展仓储的,比如三维数组,先存储Data[0,0,1]再存储Data[0,0,2],依次类推。

不过需要阐明的是,对于Char[]以及Char[,]这二种,要是表示的话实际应该相应的是String以及String[]。

 

【四、C3D文件数量区域的结构】

C3D数据区域以帧为单位寄放的,其实一定于这个区域就是一个帧的汇集。而C3D帧其实分为两种,一种是整数帧,而另一种是浮点帧。这两边的区别在于,前者存储的具备内容都是Int16,而后人则为Single,除此之外,前者的3D坐标点(X、Y、Z)还亟需倍加比(加比(Gaby))例因子才得以,而后者存储的内容相当于已经乘以了百分比因子了。

数码区域初始于参数集合中的”POINT”参数组中的”DATA_START”参数,其代表数据区域先导的Section
ID,除此之外,在文件头中也有一份副本。可是遵照合法的说教,假如文件头和参数集合中都一些内容,优先读取参数集合中的数据。

对此每个帧,又含有四个部分,第一局部为3D坐标点部分,第二片段为模拟采样部分。

  • 对此每帧的3D坐标点部分,存储着该帧所有3D坐标点的数码,每个3D坐标点包括4个Int16或Single数据,分别是X坐标、Y坐标、Z坐标以及Residual和Camera
    Mask,其中Residual和Camera
    Mask共占一个Int16。比较有趣的是,对于浮点帧,Residual和Camera
    Mask仍旧也仍旧一个Int16,只可是存储的时候要将相应的数值转换为Single再举行仓储。

    • 对此浮点帧,存储的X、Y、Z坐标就是其实的坐标;而对于整数帧,存储的X、Y、Z的坐标还索要倍加比(加比(Gaby))例因子才可以,比例因子存储于参数集合中的”POINT”参数组中的”SCALE”参数。
    • Residual和Camera
      Mask共占一个Int16,将其更换为字节数组之后,高位字节(第1个字节)的最高位代表Residual的标记,即表示该坐标点是否可行,假如为0则意味着有效,假如为1则意味无效,而剩余的7个字节则为Camera
      Mask,每一位代表一个录像机,从没有到高位分别表示7个录像机是否接纳(为1为运用,为0为未选拔)。而Residual的真实数据则为字节数组的第0字节乘以比例因子(浮点帧则为比例因子的相对值)。
  • 而仿照采样部分,则存储着该帧所有的模仿采样的多少,可是每个帧可能包含三个模拟采样,同时每个模仿采样可能又富含五个channel,存储的数据即为该channel下记录的数量。不过存储的数目与实际的数目还需要依照下述公式举行折算,其中data
    value为存储的数额,real world value为实际的数额。

    • zero
      offset可以从”ANALOG”参数组中的”OFFSET”中取得,该多少为Int16的数组,第i位指的就是第i个channel的zero
      offset。
    • channel
      scale可以从”ANALOG”参数组中的”SCALE”中收获,该数据为Single的数组,第i位指的就是dii个channel的scale。
    • general
      scale是兼备模拟采样都亟待倍加的比重,该数据足以从”ANALOG”参数组中的”GEN_SCALE”中获取,为Single。

    real world value = (data value – zero offset) channel scale general scale

 

【五、使用C3D.NET读写文件示例】

前边说了这样多,其实假诺用C3D.NET来分析的话实际是非凡简单的。我们可以从https://c3d.codeplex.com/下载C3D.NET的二进制文件或者源码,引用后首要的类都在C3D这么些命名空间下。

对于遍历所有的3D坐标可以应用以下的点子,首先可以从文件或者从流中创立C3D文件,然后从文件头中读取存储的第1帧的序号,然后读取采样点的多寡就能够了,当然也足以不从参数组中读取,直接运用file.AllFrames[i].Point3Ds.Length也可以:

 1 C3DFile file = C3DFile.LoadFromFile("文件路径");
 2 Int16 firstFrameIndex = file.Header.FirstFrameIndex;
 3 Int16 pointCount = file.Parameters["POINT:USED"].GetData<Int16>();
 4 
 5 for (Int16 i = 0; i < file.AllFrames.Count; i++)
 6 {
 7     for (Int16 j = 0; j < pointCount; j++)
 8     {
 9         Console.WriteLine("Frame {0} : X = {1}, Y = {2}, Z = {3}",
10             firstFrameIndex + i,
11             file.AllFrames[i].Point3Ds[j].X,
12             file.AllFrames[i].Point3Ds[j].Y ,
13             file.AllFrames[i].Point3Ds[j].Z);
14     }
15 }

而读取模拟采样的话,采纳的格局也接近:

 1 Single frameRate = file.Parameters["POINT", "RATE"].GetData<Single>();
 2 Int16 analogChannelCount = file.Parameters["ANALOG", "USED"].GetData<Int16>();
 3 Int16 analogSamplesPerFrame = (Int16)(file.Parameters["ANALOG", "RATE"].GetData<Int16>() / frameRate);
 4 
 5 for (Int16 i = 0; i < file.AllFrames.Count; i++)
 6 {
 7     for (Int16 j = 0; j < analogChannelCount; j++)
 8     {
 9         for (Int16 k = 0; k < analogSamplesPerFrame; k++)
10         {
11             Console.WriteLine("Frame {0}, Sample {1} : {2}",
12                 firstFrameIndex + i, j + 1,
13                 file.AllFrames[i].AnalogSamples[j][k]);
14         }
15     }
16 }

除此之外一遍性将C3D文件内容总体读取出来的这种方法以外,还足以运用C3DReader来一帧一帧的读取。

 1 using (FileStream fs = new FileStream("文件路径", FileMode.Open, FileAccess.Read))
 2 {
 3     C3DReader reader = new C3DReader(fs);
 4     C3DHeader header = reader.ReadHeader();
 5     C3DParameterDictionary dictionary = reader.ReadParameters();
 6     Int32 index = header.FirstFrameIndex;
 7 
 8     while (true)
 9     {
10         C3DFrame frame = reader.ReadNextFrame(dictionary);
11 
12         if (frame == null)
13         {
14             break;
15         }
16 
17         for (Int16 j = 0; j < frame.Point3Ds.Length; j++)
18         {
19             Console.WriteLine("Frame {0} : X = {1}, Y = {2}, Z = {3}",
20                 index++,
21                 frame.Point3Ds[j].X,
22                 frame.Point3Ds[j].Y,
23                 frame.Point3Ds[j].Z);
24         }
25     }
26 }

对此开创一个C3D文件,只需要选拔C3DFile.Create()就可以成立一个空的C3D文件的,不带有其他的参数集合。而保存C3D文件则直接行使file.SaveTo(“文件路径”)就足以了。

对此增长参数集合可以行使以下的代码:

1 //首先需要添加参数集合,ID为正数
2 file.Parameters.AddGroup(1, "POINT", "");
3 //然后往指定ID的参数集合中添加参数即可
4 file.Parameters[1].Add("USED", "").SetData<Int16>(5);

添加帧能够选择如下的代码:

1 file.AllFrames.Add(new C3DFrame(new C3DPoint3DData[] {
2     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask},
3     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask},
4     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask},
5     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask},
6     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask} }));

自然,也足以将C3DPoint3DData数组换成C3DAnalog山姆ples数组,或者双方同时充裕也可以。

 

【相关链接】

  1. C3D.ORG:http://www.c3d.org/
  2. c3d4sharp – C3D File reading/writing tools written in
    C#:http://code.google.com/p/c3d4sharp/
  3. C3D.NET:https://c3d.codeplex.com/