/// <summary> /// If this section has not yet been warped, then do so. /// This method is invoked by threads. /// </summary> public void Warp() { if (HasBeenWarped) return; lock (LockObj) { if (HasBeenWarped) return; if (VolumeTransform != null) Trace.WriteLine("Warping section " + VolumeTransform.ToString() +/*.Info.MappedSection + */ " to volume space", "VolumeModel"); Debug.Assert(this.VolumeTransform != null); bool LoadedFromCache = false; if (System.IO.File.Exists(this.CachedTransformsFileName)) { /*Check to make sure cache file is older than both .stos modified time and mapping modified time*/ DateTime CacheCreationTime = System.IO.File.GetLastWriteTimeUtc(this.CachedTransformsFileName); if (CacheCreationTime >= VolumeTransform.Info.LastModified && CacheCreationTime >= SourceMapping.LastModified) { try { this._TileTransforms = LoadFromCache(); } catch (Exception ) { //On any error, use the traditional path this._TileTransforms = null; LoadedFromCache = false; Trace.WriteLine("Deleting invalid cache file: " + this.CachedTransformsFileName); try { System.IO.File.Delete(this.CachedTransformsFileName); } catch (System.IO.IOException except) { Trace.WriteLine("Could not delete invalid cache file: " + this.CachedTransformsFileName); } } LoadedFromCache = this._TileTransforms != null; } else { //Remove the cache file, it is stale Trace.WriteLine("Deleting stale cache file: " + this.CachedTransformsFileName); try { System.IO.File.Delete(this.CachedTransformsFileName); } catch (System.IO.IOException except) { Trace.WriteLine("Could not delete invalid cache file: " + this.CachedTransformsFileName); } } } if (LoadedFromCache) { this.HasBeenWarped = true; return; } // Get the transform tiles from the source mapping, which loads the .mosaic if it hasn't alredy been loaded ReferencePointBasedTransform[] volTransforms = SourceMapping.TileTransforms; // We add transforms which surivive addition with at least three points to this list List<TriangulationTransform> listTiles = new List<TriangulationTransform>(volTransforms.Length); for (int i = 0; i < volTransforms.Length; i++) { TriangulationTransform T = volTransforms[i] as TriangulationTransform; //TriangulationTransform copy = (TriangulationTransform)T.Copy(); TriangulationTransform newTransform = null; // = (TriangulationTransform)T.Copy(); if (VolumeTransform != null) { TileTransformInfo originalInfo = T.Info as TileTransformInfo; TileTransformInfo info = new TileTransformInfo(originalInfo.TileFileName, originalInfo.TileNumber, originalInfo.LastModified < this.VolumeTransform.Info.LastModified ? originalInfo.LastModified : this.VolumeTransform.Info.LastModified, originalInfo.ImageWidth, originalInfo.ImageHeight); //FIXME newTransform = TriangulationTransform.Transform(this.VolumeTransform as TriangulationTransform, T, info); } if (newTransform == null) continue; //Don't include the tile if the mapped version doesn't have any triangles if (newTransform.MapPoints.Length > 2) listTiles.Add(newTransform); T.MinimizeMemory(); newTransform.MinimizeMemory(); } //OK, overwrite the tiles in our class this._TileTransforms = listTiles.ToArray(); this.HasBeenWarped = true; //Try to save the transform to our cache SaveToCache(); } }
/// <summary> /// Load mosaic from specified file and add it to transforms list using specified key /// </summary> /// <param name="file"></param> /// <param name="Key"></param> public static ReferencePointBasedTransform[] LoadMosaic(string path, string[] mosaic, DateTime lastModified) { if (mosaic == null || path == null) throw new ArgumentNullException(); string[] parts; int numTiles = 0; // double PixelSpacing; int formatVersion = 0; int iTileStart = 3; for (int i = 0; i < mosaic.Length; i++) { string line = mosaic[i]; if (line.StartsWith("format_version_number:")) { parts = line.Split(':'); formatVersion = System.Convert.ToInt32(parts[1]); } if (line.StartsWith("number_of_images:")) { parts = line.Split(':'); numTiles = System.Convert.ToInt32(parts[1]); } if (line.StartsWith("pixel_spacing:")) { parts = line.Split(':'); // PixelSpacing = System.Convert.ToDouble(parts[1]); } if (line.StartsWith("image:")) { iTileStart = i; break; } } Trace.WriteLine("Loading " + numTiles.ToString() + " tiles", "Geometry"); ReferencePointBasedTransform[] tileTransforms = new ReferencePointBasedTransform[numTiles]; int iTile = 0; if (formatVersion == 0) { for (int i = iTileStart; i < mosaic.Length; i++) { string Transform = mosaic[i]; //Trace.WriteLine(line, "Geometry"); //Get the second entry which is the file name string[] transformParts = Transform.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries); string TileFileName = transformParts[1]; //Make sure we don't pull in the full path TileFileName = System.IO.Path.GetFileName(TileFileName); string[] TileNameParts = TileFileName.Split(new char[] { '.' }, 3, StringSplitOptions.RemoveEmptyEntries); int iTileNumber = 0; //Viking originally used a format with section.number.png, but Iris may write number.png instead if (TileNameParts.Length == 3) { iTileNumber = System.Convert.ToInt32(TileNameParts[1]); } else { iTileNumber = System.Convert.ToInt32(TileNameParts[0]); } //Crop the tile file name fron the Transform string int iFileName = Transform.IndexOf(TileFileName); Transform = Transform.Remove(0, iFileName + TileFileName.Length); ReferencePointBasedTransform newTGT = ParseMosaicTileEntry(Transform, null); TileTransformInfo info = new TileTransformInfo(TileFileName, iTileNumber, lastModified, newTGT.MappedBounds.Width, newTGT.MappedBounds.Height); newTGT.Info = info; //GridTransform newTGT = new GridTransform(path, Transform, new TileTransformInfo(TileFileName, iTileNumber, lastModified)); tileTransforms[iTile++] = newTGT; //tileTransforms.Add(newTGT); } } else if (formatVersion == 1) { for (int i = iTileStart; i < mosaic.Length; i += 3) { string TileFileName = mosaic[i + 1]; string Transform = mosaic[i + 2]; //Trace.WriteLine(line, "Geometry"); //Make sure we don't pull in the full path TileFileName = System.IO.Path.GetFileName(TileFileName); string[] TileNameParts = TileFileName.Split(new char[] { '.' }, 3, StringSplitOptions.RemoveEmptyEntries); int iTileNumber = 0; try { //Viking originally used a format with section.number.png, but Iris may write number.png instead if (TileNameParts.Length == 3) { iTileNumber = System.Convert.ToInt32(TileNameParts[1]); } else { iTileNumber = System.Convert.ToInt32(TileNameParts[0]); } } catch (System.FormatException) { iTileNumber = i; } //Get the second entry which is the transform ReferencePointBasedTransform newTGT = ParseMosaicTileEntry(Transform, null); TileTransformInfo info = new TileTransformInfo(TileFileName, iTileNumber, lastModified, newTGT.MappedBounds.Width, newTGT.MappedBounds.Height); newTGT.Info = info; //string[] transformParts = Transform.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries); //TileGridTransform newTGT = new TileGridTransform(path, Transform, new TileTransformInfo(TileFileName, iTileNumber, lastModified)); tileTransforms[iTile++] = newTGT; //tileTransforms.Add(newTGT); } } else { Debug.Assert(false, "Unknown format version in mosaic file"); return new GridTransform[0]; } /* * Don't translate mosaics to 0,0 origin because the buildscripts do it automatically and the mosaic to volume transforms are broken by the translation GridRectangle R = ReferencePointBasedTransform.CalculateControlBounds(tileTransforms as ReferencePointBasedTransform[]); foreach (TransformBase T in tileTransforms) { //Adjusting to center here breaks vclume tranformation since volume transforms assume mosaic origin of 0,0 T.Translate(new GridVector2(-R.Left, -R.Bottom)); } */ //Add transform list to our collection of transforms return tileTransforms; }