12 releases

0.2.9 Jun 2, 2022
0.2.8 Apr 19, 2022
0.2.7 Mar 10, 2022
0.2.6 Feb 8, 2022
0.1.1 Jan 19, 2022

#55 in Data formats


Used in rs_pbrt

MIT/Apache

200KB
1.5K SLoC

blend_info

crates.io builds.sr.ht status dependency status

blend_info 0.2.9
Print some information about a Blender scene file

USAGE:
    blend_info [FLAGS] [OPTIONS] <path>

FLAGS:
        --dna         Print information about DNA of Blender
    -h, --help        Prints help information
        --pointers    Print code (e.g. OB, CA, LA, MA, DATA) and pointers
    -V, --version     Prints version information

OPTIONS:
    -n, --struct_name <struct-name>    Print information about a particular struct

ARGS:
    <path>    The path to the file to read

lib.rs:

blend_info

Print some information about a Blender scene file.

$ ./target/release/blend_info -h
blend_info 0.2.9
Print some information about a Blender scene file

USAGE:
    blend_info [FLAGS] [OPTIONS] <path>

FLAGS:
        --dna         Print information about DNA of Blender
    -h, --help        Prints help information
        --pointers    Print code (e.g. OB, CA, LA, MA, DATA) and pointers
    -V, --version     Prints version information

OPTIONS:
    -n, --struct_name <struct-name>    Print information about a particular struct

ARGS:
    <path>    The path to the file to read

Usage as a crate (used in your own code)

use blend_info::{print_pointer, read_dna, use_dna, DnaStrC};
// std
use std::collections::HashMap;
use std::path::PathBuf;

fn main() -> std::io::Result<()> {
    println!("use_dna");
    // .blend file
    let path: PathBuf = PathBuf::from(r"blend/factory_v279.blend");
    println!("Try to read {:?} file ...", path);
    // read DNA
    let mut dna_types_hm: HashMap<String, u16> = HashMap::new();
    let mut dna_structs_hm: HashMap<String, DnaStrC> = HashMap::new();
    let mut dna_pointers_hm: HashMap<usize, usize> = HashMap::new();
    let mut dna_2_type_id: Vec<u16> = Vec::new();
    let mut types: Vec<String> = Vec::new();
    let mut num_bytes_read: usize = 0;
    let print_dna: bool = false;
    let print_pointers: bool = true;
    read_dna(
        print_dna,
        print_pointers,
        &path,
        &mut dna_types_hm,
        &mut dna_structs_hm,
        &mut dna_pointers_hm,
        &mut dna_2_type_id,
        &mut types,
        &mut num_bytes_read,
    )?;
    println!("{} bytes read by read_dna() ...", num_bytes_read);
    // use DNA
    println!(
        "Try to read {:?} file again (camera/lamp centric this time) ...",
        path
    );
    let print_dna: bool = true;
    let names: Vec<String> = vec!["Camera".to_string(), "Lamp".to_string()];
    let mut bytes_read: Vec<u8> = Vec::with_capacity(num_bytes_read);
    let mut structs_read: Vec<String> = Vec::with_capacity(names.len());
    let mut data_read: Vec<u32> = Vec::with_capacity(names.len());
    let mut pointers_read: Vec<(usize, u32)> = Vec::with_capacity(names.len());
    use_dna(
        print_dna,
        &path,
        &dna_types_hm,
        &dna_structs_hm,
        &names,
        &dna_2_type_id,
        &types,
        &mut bytes_read,
        &mut structs_read,
        &mut data_read,
        &mut pointers_read,
    )?;
    println!("bytes_read: {:?}", bytes_read);
    println!("structs_read: {:?}", structs_read);
    println!("data_read: {:?}", data_read);
    println!("pointers_read: {:?}", pointers_read);
    print!("SDNAnr = {}: ", pointers_read[0].1);
    print_pointer(pointers_read[0].0, &names[0], &dna_pointers_hm);
    print!("SDNAnr = {}: ", pointers_read[1].1);
    print_pointer(pointers_read[1].0, &names[1], &dna_pointers_hm);
    Ok(())
}

Examples (used as a standalone executable to query .blend files)

DNA

Find Blender version and read all bytes:

$ ./target/release/blend_info --dna blend/factory_v279.blend | less
BLENDER-v279
...
459792 bytes read
$ ./target/release/blend_info --dna blend/factory_v300.blend | less
BLENDER-v300
...
806388 bytes read

Get an idea what structs might be useful and which names are defined:

$ ./target/release/blend_info --dna blend/factory_v279.blend | grep "\[SDNAnr =" -A 1
  [SDNAnr = 0]
  Link (len=16) {
--
  [SDNAnr = 1]
  LinkData (len=24) {
...
--
  [SDNAnr = 620]
  CacheFile (len=1200) {

Structs and their contained data

$ ./target/release/blend_info -n Camera blend/factory_v279.blend
Camera 248
struct Camera { // SDNAnr = 25
    ID id; // 120
    AnimData *adt; // 8
    char type; // 1
    char dtx; // 1
    short flag; // 2
    float passepartalpha; // 4
    float clipsta; // 4
    float clipend; // 4
    float lens; // 4
    float ortho_scale; // 4
    float drawsize; // 4
    float sensor_x; // 4
    float sensor_y; // 4
    float shiftx; // 4
    float shifty; // 4
    float YF_dofdist; // 4
    Ipo *ipo; // 8
    Object *dof_ob; // 8
    GPUDOFSettings gpu_dof; // 24
    char sensor_fit; // 1
    char pad[7]; // 7
    CameraStereoSettings stereo; // 24
}; // 248
$ ./target/release/blend_info -n ID blend/factory_v279.blend
ID 120
struct ID { // SDNAnr = 10
    void *next; // 8
    void *prev; // 8
    ID *newid; // 8
    Library *lib; // 8
    char name[66]; // 66
    short flag; // 2
    short tag; // 2
    short pad_s1; // 2
    int us; // 4
    int icon_id; // 4
    IDProperty *properties; // 8
}; // 120
$ ./target/release/blend_info -n Object.id.name blend/factory_v279.blend
Object.id.name = "OBCamera"
Object.id.name = "OBCube"
Object.id.name = "OBLamp"
$ ./target/release/blend_info -n Camera.id.name blend/factory_v279.blend
Camera.id.name = "CACamera"
$ ./target/release/blend_info -n Lamp.id.name blend/factory_v279.blend
Lamp.id.name = "LALamp"
$ ./target/release/blend_info -n Mesh.id.name blend/factory_v279.blend
Mesh.id.name = "MECube"
$ ./target/release/blend_info -n Camera.lens blend/factory_v279.blend
Camera.lens = 35_f32
$ ./target/release/blend_info -n Object.obmat blend/factory_v279.blend
Object.obmat = [
    0.68592066,
    0.72767633,
    0.0,
    0.0,
    -0.32401347,
    0.30542085,
    0.89539564,
    0.0,
    0.6515582,
    -0.6141704,
    0.4452714,
    0.0,
    7.4811316,
    -6.50764,
    5.343665,
    1.0,
]
Object.obmat = [
    1.0,
    0.0,
    0.0,
    0.0,
    0.0,
    1.0,
    0.0,
    0.0,
    0.0,
    0.0,
    1.0,
    0.0,
    0.0,
    0.0,
    0.0,
    1.0,
]
Object.obmat = [
    -0.29086465,
    0.95517117,
    -0.05518906,
    0.0,
    -0.7711008,
    -0.19988336,
    0.60452473,
    0.0,
    0.5663932,
    0.2183912,
    0.79467225,
    0.0,
    4.0762453,
    1.005454,
    5.903862,
    1.0,
]

Dependencies

~3.5MB
~67K SLoC