/// <summary> /// Adds a new group layer at the specified path, creating all the groups along the way if necessary. /// The path should not contain the "Root" group, use a single "/" instead or nothing. /// For example, to create a group layer named "Group" under Root/MyGroup, call this with path="/MyGroup/Group". /// </summary> public LayerGroup CreateGroupLayerAt(string path, bool isSequence = false) { LayerGroup group = RootLayer; if (group == null) { return(null); } string[] nodes = path.Split(new string[] { "/", "\\" }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < nodes.Length; i++) { Layer child = group.FindChild(nodes[i]); if (child == null || child.Type != LayerType.Group) { child = new LayerGroup(nodes[i], isSequence); group.Children.Add(child); } group = child as LayerGroup; } return(group); }
/// <summary> /// Adds a new paint layer at the specified path, creating all the groups along the way if necessary. /// The last element of the path is the name of the new layer. /// If the layer already exists it will be returned instead of a new one. /// The path should not contain the "Root" group, use a single "/" instead or nothing. /// For example, to create a paint layer named "Paint" under Root/MyGroup, call this with path="/MyGroup/Paint". /// </summary> public LayerPaint CreatePaintLayerAt(string path) { string groupPath = Path.GetDirectoryName(path); LayerGroup group = CreateGroupLayerAt(groupPath, false); if (group == null) { return(null); } // At this point we have found or created the insertion point. // Double check in case the layer itself already exist. string name = Path.GetFileName(path); LayerPaint paint = null; foreach (Layer child in group.Children) { if (child.Type != LayerType.Paint || child.Name != name) { continue; } paint = child as LayerPaint; break; } if (paint == null) { group.Children.Add(new LayerPaint(name)); } return(paint); }
/// <summary> /// Finds a layer at the specified path. Does not create the groups along the way if not found. /// </summary> public Layer FindLayer(string path) { string[] nodes = path.Split(new string[] { "/", "\\" }, StringSplitOptions.RemoveEmptyEntries); LayerGroup parent = this; Layer layer = parent; for (int i = 0; i < nodes.Length; i++) { if (parent == null) { return(null); } Layer child = parent.FindChild(nodes[i]); if (child == null) { return(null); } if (i == nodes.Length - 1) { return(child); } else { parent = child as LayerGroup; } } return(layer); }
/// <summary> /// Creates a default sequence with a spawn area. /// This does not add any paint layer. /// </summary> public static Sequence CreateDefault() { Sequence seq = new Sequence(); seq.RootLayer = LayerGroup.CreateDefault(); seq.RootLayer.Children.Add(LayerViewpoint.CreateDefault()); return(seq); }
/// <summary> /// Inserts an existing layer to a group, creating all the groups along the way if necessary. /// The parent group is identified by its path. /// The path must not contain the name of the leaf layer. /// For example, to insert a paint layer under Root/MyGroup, call this with path="/MyGroup". /// </summary> /// <param name="child">The layer to add to the group layer.</param> /// <param name="path">The path to the group layer.</param> public void InsertLayerAt(Layer child, string path) { LayerGroup group = CreateGroupLayerAt(path, false); if (group != null) { group.Children.Add(child); } }
private static JObject WriteLayerImplementationGroup(LayerGroup layer) { JObject jLayer = new JObject(); JArray jChildren = new JArray(); foreach (Layer child in layer.Children) { if (IsSupported(child)) { jChildren.Add(WriteLayer(child)); } } jLayer.Add(new JProperty("Children", jChildren)); return(jLayer); }
/// <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); }