none
parse 2 diffent text files and get certin text RRS feed

  • Question

  • ok i have a question about parsing files and find text lines in one then opening another depending on the name it found and retriving data of the second file that had _c _n specmap 

    so the first file i want to get data from is the .map file witch contains format like this.

    // brush 22
    {
     ( 200 512 -8 ) ( 200 520 -8 ) ( -248 520 -8 ) berlin_wall_brick_clean_plain4_wet 128 128 0 0 0 0 lightmap_gray 16383.492 16384 -711.99646 -136 -90 0
     ( -248 520 128 ) ( 200 520 128 ) ( 200 512 128 ) berlin_wall_brick_clean_plain4_wet 128 128 0 0 0 0 lightmap_gray 16384.516 16384 -712.00427 -136 -90 0
     ( -456 520 0 ) ( -456 512 0 ) ( -456 512 -8 ) berlin_wall_brick_clean_plain4_wet 128 128 0 0 0 0 lightmap_gray 16384.264 -16384 -712 0 180 0
     ( -264 512 0 ) ( 184 512 0 ) ( 184 512 -8 ) berlin_wall_brick_clean_plain4_wet 128 128 0 0 0 0 lightmap_gray 16384 16384 136 0 0 0
     ( 328 520 128 ) ( -120 520 128 ) ( -120 520 120 ) berlin_wall_brick_clean_plain4_wet 128 128 0 0 0 0 lightmap_gray 16384 16383.975 136 0 0 0
     ( -8 520 95.5 ) ( -8 504 95.5 ) ( -8 504 127.5 ) berlin_wall_brick_clean_plain4_wet 128 128 0 0 0 0 lightmap_gray 16384 16384 0 0 0 0
    }

    then form there i want to get the line that has the texture name witch is 

    berlin_wall_brick_clean_plain4_wet

    but the issue being each brush type can be diffent so its not a consistant the same textures each brush has diffent textures usally 

    then once that is saved i want to find the material file witch will be same name as the one above wich i know how to do but then i want to go though the material file and in the material file there is plain text the rest is computer lanuage but is has a format like this 

     berlin_wall_brick_clean_plain4_c colorMap normalMap berlin_wall_brick_clean_plain4_n specularMap ~berlin_wall_brick_gritty_wet~42b35898 envMapParms colorTint dynamicFoliageSunDiffuseMinMax 

    but the issue being i need to get it just by the _c _n and specmap need to get the whole name including the _n at the end as well but not sure how i would go about this at all as i not had much parsing experiance then at the end of it all i would do a copy because they are names of texture files and i would copy those textures to a folder. 

    any help would be much appeiated sorry such a long explaition thanks in advance elfenliedtopfan5 

    Thursday, March 21, 2019 1:41 PM

Answers

  • You need to break this problem up into smaller pieces. You said you have to read the first file (map) so create some code to do just that. It looks like your map file is a series of data points that, unfortunately, is not in a standard format. Assuming you can trust the map file to be always valid then you can parse the file out by hand (using a class like MapDocument or MapReader that you create). It should create an instance of a type (e.g. Map) that represents a line in your map file. Note that this all assumes the file isn't too large and/or performance is not critical. If this code is called inside a high performance block of code (like a game engine frame or something) then you'll need to optimize such that it isn't necessary to read all the lines of the file.

    public class MapDocument
    {
       public IEnumerable<Map> Load ( string fileName )
       {
          foreach (var line in File.ReadAllLines(fileName))
          {
             //Parse the line
             var map = ParseMapLine(line);
             yield return map;
          }
       }
    
       private Map ParseMapLine ( string line )
       {
          //Logic to read the string and parse out the values you need either using Regex or simple string parsing, whichever works better here
       }
    }

    Once you have the code to read the map file you can enumerate through the lines (maps) and then move on to your next step. Again, for a small # of lines, then LINQ can be used to find the elements that you want. For a very large file then you are better streaming the lines across but you'll want to cache the results in case you need them again later.

    var doc = new MapDocument();
    var maps = doc.Load("...");
    
    //Use LINQ to find the maps related to berlin wall, whatever that means
    var berlin_wall = maps.Where(m => m.Field1 == "berlin_wall");

    For the material file I don't understand what you mean by it has the same name as the one above. The one above what? Filename of the map file? Filename of the berlin_wall thing? In either case, if you already know what you're looking for then do you really need to read the map file at all?

    In either case reading the material file would follow a similar approach. Create a separate type to read the file (e.g. MaterialDocument or MaterialReader). Then put the appropriate parsing logic into that file based upon the line format.

    As for your last paragraph I don't understand what you're asking about. You mention getting just by _cn _n and specmap. Getting what? In your sample line above this paragraph I see a _c and _n but nothing else. This is just a stream of text so identifying what each "value" is would help clarify this. Ultimately though you're going to end up having to read each line and then pick out what part of the line you care about. In this particular case it seems like each "value" is separated by the next with a space. In this case you can use String.Split to split the line by a space. Assuming the file is consistently formatted you should be able to figure out that the first value may be the value you want. So you could just look at the first element in the array returned by split to see if this is the line you want. If you need to look at several values then you'll just build on that.

    //Assumes a relatively small file
    var desiredTextureName = "berlin_wall_brick_clean_plain4";
    
    var cValue = desiredTextureName + "_c";
    var nValue = desiredTextureName + "_n";
    
    foreach (var line in File.ReadAllLines("..."))
    {
       //No error checking here - assuming every line is properly formatted
       var tokens = line.Split(' ');
    
       //Assuming that value 1 needs to end with _c and value 4 needs to end with _n, assume case matters
       if (tokens[0] == cValue && tokens[3] == nValue)
       {
           //This is the correct line, now what?
       };
    };


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, March 21, 2019 2:12 PM
    Moderator