public override void Execute(ScriptState state) { var filepath = state.ResolvePath(File); state.Log.Status($"Importing from {filepath}"); FileTypeInfo effectiveType = null; if (ForceType != null) { effectiveType = ForceType; } else { var ext = System.IO.Path.GetExtension(filepath); if (!FileTypeInfo.TryParseName(ext, out effectiveType)) { throw new Exception($"Unrecognised file extension \"{ext}\". Use a conventional extension or specify the type explicitly."); } } if (!effectiveType.CanImport) { throw new Exception($"No import support for {effectiveType}"); } var parentObjects = new Dictionary <string, S.Object3D>(); foreach (var kv in Parents) { var parent = state.Data.SectionsOfType <S.Object3D>().FirstOrDefault(i => i.Name == kv.Value); if (parent == null) { throw new Exception($"Cannot find rootpoint element {kv.Value}"); } parentObjects.Add(kv.Key, parent); } S.Object3D defaultRootObject; if (DefaultRootPoint != null) { defaultRootObject = state.Data.SectionsOfType <S.Object3D>().FirstOrDefault(i => i.Name == DefaultRootPoint); } else { defaultRootObject = state.DefaultRootPoint; } var throwOnNoParent = effectiveType == FileTypeInfo.Obj; S.Object3D ParentFinder(string name) { if (parentObjects.ContainsKey(name)) { return(parentObjects[name]); } if (defaultRootObject == null && throwOnNoParent) { throw new Exception($"No default- nor object-rootpoint set for {name}"); } return(defaultRootObject); } Importers.IOptionReceiver opts = effectiveType.CreateOptionReceiver(); foreach (var kv in ImporterOptions) { opts.AddOption(kv.Key, kv.Value); } bool createObjects = CreateNewObjects ?? state.CreateNewObjects; effectiveType.Import(state.Data, filepath, createObjects, ParentFinder, opts); }
public static void ImportNewObj(FullModelData fmd, String filepath, bool addNew, Func <string, Object3D> root_point, Importers.IOptionReceiver _) { Log.Default.Info("Importing new obj with file: {0}", filepath); //Preload the .obj List <obj_data> objects = new List <obj_data>(); List <obj_data> toAddObjects = new List <obj_data>(); using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read)) { using (StreamReader sr = new StreamReader(fs)) { string line; obj_data obj = new obj_data(); bool reading_faces = false; int prevMaxVerts = 0; int prevMaxUvs = 0; int prevMaxNorms = 0; string current_shade_group = null; while ((line = sr.ReadLine()) != null) { //preloading objects if (line.StartsWith("#")) { continue; } else if (line.StartsWith("o ") || line.StartsWith("g ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); current_shade_group = null; } if (String.IsNullOrEmpty(obj.object_name)) { obj.object_name = line.Substring(2); Log.Default.Debug("Object {0} named: {1}", objects.Count + 1, obj.object_name); } } else if (line.StartsWith("usemtl ")) { obj.material_name = line.Substring(7); } else if (line.StartsWith("v ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } String[] verts = line.Replace(" ", " ").Split(' '); Vector3 vert = new Vector3(); vert.X = Convert.ToSingle(verts[1], CultureInfo.InvariantCulture); vert.Y = Convert.ToSingle(verts[2], CultureInfo.InvariantCulture); vert.Z = Convert.ToSingle(verts[3], CultureInfo.InvariantCulture); obj.verts.Add(vert); } else if (line.StartsWith("vt ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } String[] uvs = line.Split(' '); Vector2 uv = new Vector2(); uv.X = Convert.ToSingle(uvs[1], CultureInfo.InvariantCulture); uv.Y = Convert.ToSingle(uvs[2], CultureInfo.InvariantCulture); obj.uv.Add(uv); } else if (line.StartsWith("vn ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } String[] norms = line.Split(' '); Vector3 norm = new Vector3(); norm.X = Convert.ToSingle(norms[1], CultureInfo.InvariantCulture); norm.Y = Convert.ToSingle(norms[2], CultureInfo.InvariantCulture); norm.Z = Convert.ToSingle(norms[3], CultureInfo.InvariantCulture); obj.normals.Add(norm); } else if (line.StartsWith("s ")) { current_shade_group = line.Substring(2); } else if (line.StartsWith("f ")) { reading_faces = true; if (current_shade_group != null) { if (obj.shading_groups.ContainsKey(current_shade_group)) { obj.shading_groups[current_shade_group].Add(obj.faces.Count); } else { List <int> newfaces = new List <int>(); newfaces.Add(obj.faces.Count); obj.shading_groups.Add(current_shade_group, newfaces); } } String[] faces = line.Substring(2).Split(' '); for (int x = 0; x < 3; x++) { ushort fa = 0, fb = 0, fc = 0; if (obj.verts.Count > 0) { fa = (ushort)(Convert.ToUInt16(faces[x].Split('/')[0]) - prevMaxVerts - 1); } if (obj.uv.Count > 0) { fb = (ushort)(Convert.ToUInt16(faces[x].Split('/')[1]) - prevMaxUvs - 1); } if (obj.normals.Count > 0) { fc = (ushort)(Convert.ToUInt16(faces[x].Split('/')[2]) - prevMaxNorms - 1); } if (fa < 0 || fb < 0 || fc < 0) { throw new Exception("What the actual flapjack, something is *VERY* wrong"); } obj.faces.Add(new Face(fa, fb, fc)); } } } if (!objects.Contains(obj)) { objects.Add(obj); } } } //Read each object foreach (obj_data obj in objects) { //One would fix Tatsuto's broken shading here. //Locate the proper model var hashname = HashName.FromNumberOrString(obj.object_name); Model modelSection = fmd.parsed_sections .Where(i => i.Value is Model mod && hashname.Hash == mod.HashName.Hash) .Select(i => i.Value as Model) .FirstOrDefault(); //Apply new changes if (modelSection == null) { toAddObjects.Add(obj); continue; } PassthroughGP passthrough_section = modelSection.PassthroughGP; Geometry geometry_section = passthrough_section.Geometry; Topology topology_section = passthrough_section.Topology; AddObject(false, obj, modelSection, passthrough_section, geometry_section, topology_section); } //Add new objects if (addNew) { foreach (obj_data obj in toAddObjects) { //create new Model Material newMat = new Material(obj.material_name); fmd.AddSection(newMat); MaterialGroup newMatG = new MaterialGroup(newMat); fmd.AddSection(newMatG); Geometry newGeom = new Geometry(obj); fmd.AddSection(newGeom); Topology newTopo = new Topology(obj); fmd.AddSection(newTopo); PassthroughGP newPassGP = new PassthroughGP(newGeom, newTopo); fmd.AddSection(newPassGP); TopologyIP newTopoIP = new TopologyIP(newTopo); fmd.AddSection(newTopoIP); Object3D parent = root_point.Invoke(obj.object_name); Model newModel = new Model(obj, newPassGP, newTopoIP, newMatG, parent); fmd.AddSection(newModel); AddObject(true, obj, newModel, newPassGP, newGeom, newTopo); //Add new sections } } }