Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media3D / Viewport2DVisual3D.cs / 1305600 / Viewport2DVisual3D.cs
//---------------------------------------------------------------------------- // //// Copyright (c) Microsoft Corporation. All rights reserved. // // // Description: // // History: // 4/12/2007: kurtb - Created // //--------------------------------------------------------------------------- using MS.Utility; using MS.Internal; using MS.Internal.Media; using MS.Internal.Media3D; using MS.Internal.PresentationCore; using MS.Internal.KnownBoxes; using System; using System.Collections.Generic; using System.Diagnostics; using System.Collections.Specialized; using System.ComponentModel; using System.Windows; using System.Windows.Media.Composition; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Documents; using System.Collections; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Media.Media3D { ////// The Viewport2DVisual3D class represents the link from 3D back to 2D, just as /// Viewport3DVisual represents the link from 2D in to 3D. /// [ContentProperty("Visual")] public sealed class Viewport2DVisual3D : Visual3D { ////// Constructs a new Viewport2DVisual3D /// public Viewport2DVisual3D() { _visualBrush = CreateVisualBrush(); _bitmapCacheBrush = CreateBitmapCacheBrush(); // create holders for the content // We don't want this model to set itself as the IC for Geometry and Material // so we set to to not be able to be an inheritance context. GeometryModel3D model = new GeometryModel3D(); model.CanBeInheritanceContext = false; Visual3DModel = model; } internal static bool Get3DPointFor2DCoordinate(Point point, out Point3D point3D, Point3DCollection positions, PointCollection textureCoords, Int32Collection triIndices) { point3D = new Point3D(); // walk through the triangles - and look for the triangles we care about Point3D[] p = new Point3D[3]; Point[] uv = new Point[3]; if (positions != null && textureCoords != null) { if (triIndices == null || triIndices.Count == 0) { int texCoordCount = textureCoords.Count; // in this case we have a non-indexed mesh int count = positions.Count; count = count - (count % 3); for (int i = 0; i < count; i+=3) { for (int j = 0; j < 3; j++) { p[j] = positions[i + j]; if (i + j < texCoordCount) { uv[j] = textureCoords[i + j]; } else { // In the case you have less texture coordinates than positions, MIL will set // missing ones to be 0,0. We do the same to stay consistent. // See CMILMesh3D::CopyTextureCoordinatesFromDoubles uv[j] = new Point(0, 0); } } if (M3DUtil.IsPointInTriangle(point, uv, p, out point3D)) { return true; } } } else { // in this case we have an indexed mesh int posLimit = positions.Count; int texCoordLimit = textureCoords.Count; for (int i = 2, count=triIndices.Count; i < count; i += 3) { bool validTextureCoordinates = true; for (int j = 0; j < 3; j++) { // subtract 2 to take in to account we start i // at the high range of indices int index = triIndices[(i-2) + j]; // if a point or texture coordinate is out of range, end early since this is an error if (index < 0 || index >= posLimit) { // no need to look anymore - see MeshGeometry3D RayHitTestIndexedList for // reasoning why we stop return false; } if (index < 0 || index >= texCoordLimit) { validTextureCoordinates = false; break; } p[j] = positions[index]; uv[j] = textureCoords[index]; } if (validTextureCoordinates) { if (M3DUtil.IsPointInTriangle(point, uv, p, out point3D)) { return true; } } } } } return false; } ////// Converts a point given in texture coordinates to the corresponding /// 2D point on the UIElement passed in. /// /// The texture coordinate to convert /// The UIElement whose coordinate system is to be used ////// The 2D point on the passed in UIElement cooresponding to the /// passed in texture coordinate. /// internal static Point TextureCoordsToVisualCoords(Point uv, Visual visual) { return TextureCoordsToVisualCoords(uv, visual.CalculateSubgraphRenderBoundsOuterSpace()); } // same as the above except we now take the rectangle giving the bounds of the visual // rather than the visual itself internal static Point TextureCoordsToVisualCoords(Point uv, Rect descBounds) { return new Point(uv.X * descBounds.Width + descBounds.Left, uv.Y * descBounds.Height + descBounds.Top); } ////// Returns true and the intersection point for the given rayHitResult if there is an intersection, /// and false otherwise. /// /// /// The output point if there was an intersection ////// Returns the point of intersection in outputPoint if there is one, and returns true /// to indicate this. /// internal static bool GetIntersectionInfo(RayHitTestResult rayHitResult, out Point outputPoint) { bool success = false; outputPoint = new Point(); // try to cast to a RaymeshGeometry3DHitTestResult RayMeshGeometry3DHitTestResult rayMeshResult = rayHitResult as RayMeshGeometry3DHitTestResult; if (rayMeshResult != null) { // we can now extract the mesh and visual for the object we hit MeshGeometry3D geom = rayMeshResult.MeshHit; // pull the barycentric coordinates of the intersection point double vertexWeight1 = rayMeshResult.VertexWeight1; double vertexWeight2 = rayMeshResult.VertexWeight2; double vertexWeight3 = rayMeshResult.VertexWeight3; // the indices in to where the actual intersection occurred int index1 = rayMeshResult.VertexIndex1; int index2 = rayMeshResult.VertexIndex2; int index3 = rayMeshResult.VertexIndex3; PointCollection textureCoordinates = geom.TextureCoordinates; // texture coordinates of the three vertices hit // in the case that no texture coordinates are supplied we will simply // treat it as if no intersection occurred if (textureCoordinates != null && index1 < textureCoordinates.Count && index2 < textureCoordinates.Count && index3 < textureCoordinates.Count) { Point texCoord1 = textureCoordinates[index1]; Point texCoord2 = textureCoordinates[index2]; Point texCoord3 = textureCoordinates[index3]; // get the final uv values based on the barycentric coordinates outputPoint = new Point(texCoord1.X * vertexWeight1 + texCoord2.X * vertexWeight2 + texCoord3.X * vertexWeight3, texCoord1.Y * vertexWeight1 + texCoord2.Y * vertexWeight2 + texCoord3.Y * vertexWeight3); success = true; } } return success; } ////// Converts a point on the passed in UIElement to the corresponding /// texture coordinate for that point. The function assumes (0, 0) /// is the upper-left texture coordinate and (1,1) is the lower-right. /// /// The 2D point on the passed in UIElement to convert /// The UIElement whose coordinate system is being used ////// The texture coordinate corresponding to the 2D point on the passed in UIElement /// internal static Point VisualCoordsToTextureCoords(Point pt, Visual visual) { return VisualCoordsToTextureCoords(pt, visual.CalculateSubgraphRenderBoundsOuterSpace()); } // same as the above except we now take the rectangle giving the bounds of the visual // rather than the visual itself internal static Point VisualCoordsToTextureCoords(Point pt, Rect descBounds) { return new Point((pt.X - descBounds.Left) / (descBounds.Right - descBounds.Left), (pt.Y - descBounds.Top) / (descBounds.Bottom - descBounds.Top)); } ////// GenerateMaterial creates the material for the InteractiveModelVisual3D. The /// material is composed of the Visual, which is displayed on a VisualBrush on a /// DiffuseMaterial, as well as any post materials which are also applied. /// private void GenerateMaterial() { Material material = Material; // We clone the material so that we can modify parts of it without affecting the // original material that it came from. if (material != null) { material = material.CloneCurrentValue(); } ((GeometryModel3D)Visual3DModel).Material = material; if (material != null) { SwapInCyclicBrush(material); } } ////// The visual applied to the VisualBrush, which is then used on the 3D object. /// /// We AddOwner this property to get the same special treatment as VisualBrush's VisualProperty /// gets in InheritanceContext linkups and because both properties are used to describe the /// Visual content of the owner. /// /// public static readonly DependencyProperty VisualProperty = VisualBrush.VisualProperty.AddOwner( typeof(Viewport2DVisual3D), new PropertyMetadata(null, new PropertyChangedCallback(OnVisualChanged))); ////// public Visual Visual { get { return (Visual)GetValue(VisualProperty); } set { SetValue(VisualProperty, value); } } ////// The visual brush that the internal visual is contained on. /// private VisualBrush InternalVisualBrush { get { return _visualBrush; } set { _visualBrush = value; } } private BitmapCacheBrush InternalBitmapCacheBrush { get { return _bitmapCacheBrush; } set { _bitmapCacheBrush = value; } } internal static void OnVisualChanged(Object sender, DependencyPropertyChangedEventArgs e) { Viewport2DVisual3D viewport2DVisual3D = ((Viewport2DVisual3D)sender); // remove the old parent, add on a new one Visual oldValue = (Visual)e.OldValue; Visual newValue = (Visual)e.NewValue; if (oldValue != newValue) { // // The following code deals with properly setting up the new child to have its inheritance context // only point towards this Viewport2DVisual3D. // // When we add the new visual as a child, if that visual is an FE (which most will be) we expect it to // clear the inheritance context (IC) since it has a visual parent. In the case of a non-FE they don't // deal with ICs anyway, so they should have a null IC. The Assert that follows then guards against // the child not having a null inheritance context. // // We then set the target Visual on the internal brush to be this new visual. Since when we created // the brush we set it to not be an inheritance context, the InheritanceContext should still be null. // // We become the IC after returning from this function, since the function that calls this change handler // will set us as the IC. // if (viewport2DVisual3D.CacheMode as BitmapCache != null) { viewport2DVisual3D.InternalBitmapCacheBrush.Target = newValue; Debug.Assert((newValue == null || newValue.InheritanceContext == null), "Expected BitmapCacheBrush to remove the InheritanceContext on newValue"); } else { // Add ourselves as the parent of the object viewport2DVisual3D.RemoveVisualChild(oldValue); viewport2DVisual3D.AddVisualChild(newValue); Debug.Assert((newValue == null || newValue.InheritanceContext == null), "Expected AddVisualChild to remove the InheritanceContext on newValue"); // Change the brush's target viewport2DVisual3D.InternalVisualBrush.Visual = newValue; // setting the visual brush to use this new child should not invalidate our previous condition Debug.Assert((newValue == null || newValue.InheritanceContext == null), "Expected the InternalVisualBrush not to set the InheritanceContext"); } } } ////// AttachChild /// /// This method is called to add a 2D Visual child to the Viewport2DVisual3D /// /// private void AddVisualChild(Visual child) { if (child == null) { return; } if (child._parent != null) { throw new ArgumentException(SR.Get(SRID.Visual_HasParent)); } // Set the parent pointer. child._parent = this; // NOTE: Since the 2D object is on a VisualBrush, it will allow it to handle // the dirtyness of the 2D object, realization information, as well as layout. See // Visual(3D).AddVisualChild for the things they propagate on adding a new child // Fire notifications this.OnVisualChildrenChanged(child, null /* no removed child */); child.FireOnVisualParentChanged(null); } ////// DisconnectChild /// /// This method is called to remove the 2D visual child of the Viewport2DVisual3D /// /// private void RemoveVisualChild(Visual child) { if (child == null || child._parent == null) { return; } if (child._parent != this) { throw new ArgumentException(SR.Get(SRID.Visual_NotChild)); } // NOTE: We'll let the VisualBrush handle final cleanup from the channel // child._parent = null; // NOTE: We also let the VisualBrush handle any flag propagation issues (so Visual(3D).RemoveVisualChild for // the things they propagate) as well as layout. // Fire notifications child.FireOnVisualParentChanged(this); OnVisualChildrenChanged(null /* no child added */, child); } ////// Creates the VisualBrush that will be used to hold the interactive /// 2D content. /// ///The VisualBrush to hold the interactive 2D content private VisualBrush CreateVisualBrush() { VisualBrush vb = new VisualBrush(); // We don't want the VisualBrush being the InheritanceContext for the Visual it contains. Rather we want // that to be the Viewport2DVisual3D itself. vb.CanBeInheritanceContext = false; vb.ViewportUnits = BrushMappingMode.Absolute; vb.TileMode = TileMode.None; // set any rendering options in the visual brush - we do this to still give access to these caching hints // without exposing the visual brush RenderOptions.SetCachingHint(vb, (CachingHint)GetValue(CachingHintProperty)); RenderOptions.SetCacheInvalidationThresholdMinimum(vb, (double)GetValue(CacheInvalidationThresholdMinimumProperty)); RenderOptions.SetCacheInvalidationThresholdMaximum(vb, (double)GetValue(CacheInvalidationThresholdMaximumProperty)); return vb; } ////// Creates the BitmapCacheBrush that will be used to hold the interactive /// 2D content. /// ///The BitmapCacheBrush to hold the interactive 2D content private BitmapCacheBrush CreateBitmapCacheBrush() { BitmapCacheBrush bcb = new BitmapCacheBrush(); // We don't want the cache brush being the InheritanceContext for the Visual it contains. Rather we want // that to be the Viewport2DVisual3D itself. bcb.CanBeInheritanceContext = false; // Ensure that the brush supports rendering all properties on the Visual to match VisualBrush behavior. bcb.AutoWrapTarget = true; bcb.BitmapCache = CacheMode as BitmapCache; return bcb; } ////// Replaces any instances of the sentinal brush with the internal brush /// /// The material to look through private void SwapInCyclicBrush(Material material) { int numMaterialsSwapped = 0; StackmaterialStack = new Stack (); materialStack.Push(material); Brush internalBrush = (CacheMode as BitmapCache != null) ? (Brush)InternalBitmapCacheBrush : (Brush)InternalVisualBrush; while (materialStack.Count > 0) { Material currMaterial = materialStack.Pop(); if (currMaterial is DiffuseMaterial) { DiffuseMaterial diffMaterial = (DiffuseMaterial)currMaterial; if ((Boolean)diffMaterial.GetValue(Viewport2DVisual3D.IsVisualHostMaterialProperty)) { diffMaterial.Brush = internalBrush; numMaterialsSwapped++; } } else if (currMaterial is EmissiveMaterial) { EmissiveMaterial emmMaterial = (EmissiveMaterial)currMaterial; if ((Boolean)emmMaterial.GetValue(Viewport2DVisual3D.IsVisualHostMaterialProperty)) { emmMaterial.Brush = internalBrush; numMaterialsSwapped++; } } else if (currMaterial is SpecularMaterial) { SpecularMaterial specMaterial = (SpecularMaterial)currMaterial; if ((Boolean)specMaterial.GetValue(Viewport2DVisual3D.IsVisualHostMaterialProperty)) { specMaterial.Brush = internalBrush; numMaterialsSwapped++; } } else if (currMaterial is MaterialGroup) { MaterialGroup matGroup = (MaterialGroup)currMaterial; // the IsVisualHostMaterialProperty should not be set on a MaterialGroup - verify that if ((Boolean)matGroup.GetValue(Viewport2DVisual3D.IsVisualHostMaterialProperty)) { throw new ArgumentException(SR.Get(SRID.Viewport2DVisual3D_MaterialGroupIsInteractiveMaterial), "material"); } // iterate over the children and put them on the stack of materials to modify MaterialCollection children = matGroup.Children; if (children != null) { for (int i=0, count = children.Count; i < count; i++) { Material m = children[i]; materialStack.Push(m); } } } else { Invariant.Assert(true, "Unexpected Material type encountered. V2DV3D handles DiffuseMaterial, EmissiveMaterial, SpecularMaterial, and MaterialGroup."); } } // throw if there is more than 1 interactive material if (numMaterialsSwapped > 1) { throw new ArgumentException(SR.Get(SRID.Viewport2DVisual3D_MultipleInteractiveMaterials), "material"); } } /// /// The 3D geometry that the InteractiveModelVisual3D represents /// public static readonly DependencyProperty GeometryProperty = DependencyProperty.Register( "Geometry", typeof(Geometry3D), typeof(Viewport2DVisual3D), new PropertyMetadata(null, new PropertyChangedCallback(OnGeometryChanged))); ////// public Geometry3D Geometry { get { return (Geometry3D)GetValue(GeometryProperty); } set { SetValue(GeometryProperty, value); } } internal static void OnGeometryChanged(Object sender, DependencyPropertyChangedEventArgs e) { Viewport2DVisual3D viewport2DVisual3D = ((Viewport2DVisual3D)sender); viewport2DVisual3D.InvalidateAllCachedValues(); if (!e.IsASubPropertyChange) { ((GeometryModel3D)viewport2DVisual3D.Visual3DModel).Geometry = viewport2DVisual3D.Geometry; } } private void InvalidateAllCachedValues() { // invalidate all of them InternalPositionsCache = null; InternalTextureCoordinatesCache = null; InternalTriangleIndicesCache = null; } // the cache of frozen positions for use with the various transforms internal Point3DCollection InternalPositionsCache { get { if (_positionsCache == null) { Debug.Assert(Geometry == null || Geometry is MeshGeometry3D); MeshGeometry3D geometry = Geometry as MeshGeometry3D; if (geometry != null) { _positionsCache = geometry.Positions; if (_positionsCache != null) { _positionsCache = (Point3DCollection)_positionsCache.GetCurrentValueAsFrozen(); } } } return _positionsCache; } set { _positionsCache = value; } } // the cache of frozen internal texture coordinates internal PointCollection InternalTextureCoordinatesCache { get { if (_textureCoordinatesCache == null) { Debug.Assert(Geometry == null || Geometry is MeshGeometry3D); MeshGeometry3D geometry = Geometry as MeshGeometry3D; if (geometry != null) { _textureCoordinatesCache= geometry.TextureCoordinates; if (_textureCoordinatesCache != null) { _textureCoordinatesCache = (PointCollection)_textureCoordinatesCache.GetCurrentValueAsFrozen(); } } } return _textureCoordinatesCache; } set { _textureCoordinatesCache = value; } } // the cache of frozen internal triangle indices internal Int32Collection InternalTriangleIndicesCache { get { if (_triangleIndicesCache== null) { Debug.Assert(Geometry == null || Geometry is MeshGeometry3D); MeshGeometry3D geometry = Geometry as MeshGeometry3D; if (geometry != null) { _triangleIndicesCache = geometry.TriangleIndices; if (_triangleIndicesCache != null) { _triangleIndicesCache = (Int32Collection)_triangleIndicesCache.GetCurrentValueAsFrozen(); } } } return _triangleIndicesCache; } set { _triangleIndicesCache = value; } } ////// The material used to visually represent the Viewport2DVisual3D /// public static readonly DependencyProperty MaterialProperty = DependencyProperty.Register("Material", typeof(Material), typeof(Viewport2DVisual3D), new PropertyMetadata(null, new PropertyChangedCallback(OnMaterialPropertyChanged))); ////// Material for this Viewport2DVisual3D. /// public Material Material { get { return (Material)GetValue(MaterialProperty); } set { SetValue(MaterialProperty, value); } } internal static void OnMaterialPropertyChanged(Object sender, DependencyPropertyChangedEventArgs e) { Viewport2DVisual3D viewport2DVisual3D = ((Viewport2DVisual3D)sender); viewport2DVisual3D.GenerateMaterial(); } ////// The attached dependency property used to indicate whether a material should be made /// interactive. /// public static readonly DependencyProperty IsVisualHostMaterialProperty = DependencyProperty.RegisterAttached( "IsVisualHostMaterial", typeof(Boolean), typeof(Viewport2DVisual3D), new PropertyMetadata(BooleanBoxes.FalseBox)); ////// Sets the attached property IsVisualHostMaterial for the given element. /// /// The element to which to write the IsVisualHostMaterial attached property. /// The value to set public static void SetIsVisualHostMaterial(Material element, Boolean value) { // [BreakingChange] Dev10 TFS Bug #453513 // We should throw ArgumentNullException if element is null. element.SetValue(IsVisualHostMaterialProperty, BooleanBoxes.Box(value)); } ////// Reads the attached property IsVisualHostMaterial from the given element. /// /// The element from which to read the IsVisualHostMaterial attached property. ///The property's value. public static Boolean GetIsVisualHostMaterial(Material element) { // [BreakingChange] Dev10 TFS Bug #453513 // We should throw ArgumentNullException if element is null. return (bool)element.GetValue(IsVisualHostMaterialProperty); } public static readonly DependencyProperty CacheModeProperty = DependencyProperty.Register( "CacheMode", typeof(CacheMode), typeof(Viewport2DVisual3D), new PropertyMetadata(null, new PropertyChangedCallback(OnCacheModeChanged))); public CacheMode CacheMode { get { return (CacheMode)GetValue(CacheModeProperty); } set { SetValue(CacheModeProperty, value); } } internal static void OnCacheModeChanged(Object sender, DependencyPropertyChangedEventArgs e) { Viewport2DVisual3D viewport2DVisual3D = ((Viewport2DVisual3D)sender); BitmapCache oldValue = (CacheMode)e.OldValue as BitmapCache; BitmapCache newValue = (CacheMode)e.NewValue as BitmapCache; if (oldValue != newValue) { viewport2DVisual3D.InternalBitmapCacheBrush.BitmapCache = newValue; // // The BitmapCacheBrush doesn't point directly at the Visual like the VisualBrush does, // since BitmapCacheBrush ignores most properties on a Visual by design. In order for // those properties to be respected to match the internal VisualBrush's behavior, we insert // a dummy Visual node between the V2DV3D and its 2D Visual. We then target the dummy // node with the brush instead. // if (oldValue == null) { // // If we are swapping from using the VisualBrush to using the BitmapCacheBrush... // // Remove the visual child from the V2DV3D and add the dummy child. viewport2DVisual3D.RemoveVisualChild(viewport2DVisual3D.Visual); viewport2DVisual3D.AddVisualChild(viewport2DVisual3D.InternalBitmapCacheBrush.InternalTarget); Debug.Assert( (viewport2DVisual3D.InternalBitmapCacheBrush.InternalTarget == null || viewport2DVisual3D.InternalBitmapCacheBrush.InternalTarget.InheritanceContext == null), "Expected AddVisualChild to remove the InheritanceContext on InternalTarget"); // Swap the brush pointing to the visual. The cache brush will re-parent the visual to the dummy. viewport2DVisual3D.InternalVisualBrush.Visual = null; viewport2DVisual3D.InternalBitmapCacheBrush.Target = viewport2DVisual3D.Visual; // setting the cache brush to use this new child should not invalidate our previous condition Debug.Assert( (viewport2DVisual3D.InternalBitmapCacheBrush.InternalTarget == null || viewport2DVisual3D.InternalBitmapCacheBrush.InternalTarget.InheritanceContext == null), "Expected the InternalBitmapCacheBrush not to set the InheritanceContext"); } if (newValue == null) { // // If we are swapping from using the BitmapCacheBrush to using the VisualBrush... // // Swap the brush pointing to the visual. The cache brush will remove the dummy as the parent // of the visual. viewport2DVisual3D.InternalBitmapCacheBrush.Target = null; viewport2DVisual3D.InternalVisualBrush.Visual = viewport2DVisual3D.Visual; // Remove the dummy child and re-add the visual as the V2DV3D's child. viewport2DVisual3D.RemoveVisualChild(viewport2DVisual3D.InternalBitmapCacheBrush.InternalTarget); viewport2DVisual3D.AddVisualChild(viewport2DVisual3D.Visual); Debug.Assert((viewport2DVisual3D.Visual == null || viewport2DVisual3D.Visual.InheritanceContext == null), "Expected AddVisualChild to remove the InheritanceContext on Visual"); } // If we changed from using one brush to the other we need to regenerate the Material. if (oldValue == null || newValue == null) { viewport2DVisual3D.GenerateMaterial(); } } } ////// Derived classes override this property to enable the Visual code to enumerate /// the Visual children. Derived classes need to return the number of children /// from this method. /// /// By default a Visual does not have any children. /// /// Remark: During this virtual method the Visual tree must not be modified. /// protected override int Visual3DChildrenCount { get { return 0; } } ////// Derived class must implement to support Visual children. The method must return /// the child at the specified index. Index must be between 0 and GetVisualChildrenCount-1. /// /// By default a Visual3D does not have any children. /// /// Remark: /// Need to lock down Visual tree during the callbacks. /// During this virtual call it is not valid to modify the Visual tree. /// /// It is okay to type this protected API to the 2D Visual. The only 2D Visual with /// 3D childern is the Viewport3DVisual which is sealed. -- [....] 01/17/06 /// protected override Visual3D GetVisual3DChild(int index) { throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange)); } ////// Returns the number of children of this object (in most cases this will be /// the number of Visuals, but it some cases, Viewport3DVisual for instance, /// this is the number of Visual3Ds). /// /// Used only by VisualTreeHelper. /// internal override int InternalVisual2DOr3DChildrenCount { get { // Call the right virtual method. return (Visual != null ? 1 : 0); } } ////// Returns the child at index "index" (in most cases this will be /// a Visual, but it some cases, Viewport3DVisual for instance, /// this is a Visual3D). /// /// Used only by VisualTreeHelper. /// internal override DependencyObject InternalGet2DOr3DVisualChild(int index) { Visual visualChild = Visual; if (index != 0 || visualChild == null) { throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange)); } return visualChild; } ////// CachingHintProperty - Hints the rendering engine that rendered content should be cached /// when possible. /// private static readonly DependencyProperty CachingHintProperty = RenderOptions.CachingHintProperty.AddOwner( typeof(Viewport2DVisual3D), new UIPropertyMetadata( new PropertyChangedCallback(OnCachingHintChanged))); private static void OnCachingHintChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Viewport2DVisual3D viewport2D = (Viewport2DVisual3D) d; RenderOptions.SetCachingHint(viewport2D._visualBrush, (CachingHint)e.NewValue); } ////// CacheInvalidationThresholdMinimum - /// private static readonly DependencyProperty CacheInvalidationThresholdMinimumProperty = RenderOptions.CacheInvalidationThresholdMinimumProperty.AddOwner( typeof(Viewport2DVisual3D), new UIPropertyMetadata( new PropertyChangedCallback(OnCacheInvalidationThresholdMinimumChanged))); private static void OnCacheInvalidationThresholdMinimumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Viewport2DVisual3D viewport2D = (Viewport2DVisual3D) d; RenderOptions.SetCacheInvalidationThresholdMinimum(viewport2D._visualBrush, (double)e.NewValue); } ////// CacheInvalidationThresholdMaximum - /// private static readonly DependencyProperty CacheInvalidationThresholdMaximumProperty = RenderOptions.CacheInvalidationThresholdMaximumProperty.AddOwner( typeof(Viewport2DVisual3D), new UIPropertyMetadata( new PropertyChangedCallback(OnCacheInvalidationThresholdMaximumChanged))); private static void OnCacheInvalidationThresholdMaximumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Viewport2DVisual3D viewport2D = (Viewport2DVisual3D) d; RenderOptions.SetCacheInvalidationThresholdMaximum(viewport2D._visualBrush, (double)e.NewValue); } //----------------------------------------------------------------------- // // PRIVATE DATA // //----------------------------------------------------------------------- // the actual visual that is created private VisualBrush _visualBrush; private BitmapCacheBrush _bitmapCacheBrush; private Point3DCollection _positionsCache = null; private PointCollection _textureCoordinatesCache = null; private Int32Collection _triangleIndicesCache = null; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebPartAddingEventArgs.cs
- ListViewItem.cs
- ReplyChannel.cs
- ApplicationGesture.cs
- PhoneCall.cs
- Splitter.cs
- WebBrowserSiteBase.cs
- HostExecutionContextManager.cs
- WebPartAddingEventArgs.cs
- SharedPersonalizationStateInfo.cs
- LineBreak.cs
- RefType.cs
- followingquery.cs
- ServiceConfigurationTraceRecord.cs
- SchemaEntity.cs
- InstalledFontCollection.cs
- Substitution.cs
- SafeArrayRankMismatchException.cs
- DataQuery.cs
- BinaryNode.cs
- SystemGatewayIPAddressInformation.cs
- StoragePropertyMapping.cs
- LinkButton.cs
- ExceptionUtil.cs
- TableLayoutStyleCollection.cs
- TdsParserStateObject.cs
- PartialTrustHelpers.cs
- OrderingExpression.cs
- WebPartDisplayModeCollection.cs
- ToolStripLabel.cs
- CompoundFileReference.cs
- VisualStyleInformation.cs
- OutOfMemoryException.cs
- FormViewRow.cs
- DiagnosticTrace.cs
- MessageFormatterConverter.cs
- PolicyFactory.cs
- BooleanStorage.cs
- SchemaAttDef.cs
- ErrorTableItemStyle.cs
- AppendHelper.cs
- Win32.cs
- AggregateNode.cs
- ConfigurationLocationCollection.cs
- ResourceManager.cs
- SafeBitVector32.cs
- KeyValueConfigurationCollection.cs
- StandardOleMarshalObject.cs
- LinqDataSourceView.cs
- ObsoleteAttribute.cs
- ProfileSettings.cs
- XpsS0ValidatingLoader.cs
- ComplexBindingPropertiesAttribute.cs
- AuthorizationRuleCollection.cs
- Walker.cs
- FileDialog_Vista.cs
- Panel.cs
- LeaseManager.cs
- BinaryKeyIdentifierClause.cs
- SiteMap.cs
- DbUpdateCommandTree.cs
- XmlILStorageConverter.cs
- SizeFConverter.cs
- CapabilitiesAssignment.cs
- TextEndOfLine.cs
- CompilerLocalReference.cs
- TracedNativeMethods.cs
- MetadataConversionError.cs
- StatusBar.cs
- WindowsEditBox.cs
- TypeForwardedToAttribute.cs
- StatusBar.cs
- CodeTypeDeclarationCollection.cs
- Int32EqualityComparer.cs
- BamlWriter.cs
- TextRangeSerialization.cs
- Stack.cs
- AsymmetricKeyExchangeFormatter.cs
- FilteredDataSetHelper.cs
- SerializableTypeCodeDomSerializer.cs
- Trigger.cs
- DataSourceDesigner.cs
- ScriptModule.cs
- ToolStripItemRenderEventArgs.cs
- StreamUpdate.cs
- StorageMappingFragment.cs
- FamilyMap.cs
- AppSettingsSection.cs
- GenerateHelper.cs
- RoleGroup.cs
- SignedInfo.cs
- ContractHandle.cs
- JsonReaderWriterFactory.cs
- XhtmlBasicLiteralTextAdapter.cs
- Types.cs
- brushes.cs
- QueryExpr.cs
- ObjectSecurity.cs
- CodeEventReferenceExpression.cs
- DataException.cs