/// <summary> /// Parse one layer. Drill down recursively for groups. /// </summary> private static Layer ParseLayer(dynamic l) { if (l == null) { return(null); } Layer layer; LayerType type = ParseEnum <LayerType>(l.Type); switch (type) { case LayerType.Group: { layer = new LayerGroup(); LayerGroup lg = layer as LayerGroup; foreach (var c in l.Implementation.Children) { Layer child = ParseLayer(c); if (child != null) { lg.Children.Add(child); } } break; } case LayerType.Paint: { layer = new LayerPaint(); LayerPaint lp = layer as LayerPaint; lp.Framerate = ParseInt(l.Implementation.Framerate, lp.Framerate); lp.MaxRepeatCount = ParseInt(l.Implementation.MaxRepeatCount, lp.MaxRepeatCount); if (l.Implementation.Drawings != null && l.Implementation.Frames != null) { foreach (var d in l.Implementation.Drawings) { Drawing drawing = ParseDrawing(d); if (drawing != null) { lp.Drawings.Add(drawing); } } lp.Frames = l.Implementation.Frames.ToObject <List <int> >(); } else if (l.Implementation.BoundingBox != null && l.Implementation.DataFileOffset != null) { // Old format from Quill 1.3, circa 2017, before animations. Drawing drawing = new Drawing(); drawing.BoundingBox = ParseBoundingBox(l.Implementation.BoundingBox); long offset; bool parsed = long.TryParse((string)l.Implementation.DataFileOffset.ToObject(typeof(string)), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out offset); drawing.DataFileOffset = parsed ? offset : -1; lp.Drawings.Add(drawing); lp.Frames.Add(0); } break; } case LayerType.Viewpoint: { layer = new LayerViewpoint(); LayerViewpoint lv = layer as LayerViewpoint; lv.Version = l.Implementation.Version; lv.Color = ParseColor(l.Implementation.Color); lv.Sphere = ParseVector4(l.Implementation.Sphere); lv.AllowTranslationX = l.Implementation.AllowTranslationX; lv.AllowTranslationY = l.Implementation.AllowTranslationY; lv.AllowTranslationZ = l.Implementation.AllowTranslationZ; lv.Exporting = l.Implementation.Exporting; lv.ShowingVolume = l.Implementation.ShowingVolume; lv.TypeStr = l.Implementation.TypeStr; break; } case LayerType.Camera: { layer = new LayerCamera(); LayerCamera lc = layer as LayerCamera; lc.FOV = l.Implementation.FOV; break; } case LayerType.Model: case LayerType.Picture: case LayerType.Sound: case LayerType.Unknown: default: layer = null; break; } if (layer != null) { ParseLayerCommon(layer, l); } return(layer); }