blender-3d 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3a057403b1d063c59505fb6cfcd7ac4c67640342
4
- data.tar.gz: f2cd8a90be5652c54e7b7ee209d09729d5df7665
3
+ metadata.gz: 2d7d79e2019e79e977ccb17593901bcb29bf7055
4
+ data.tar.gz: fcc968c990a9f9dd4c058bad499a74353b53871e
5
5
  SHA512:
6
- metadata.gz: 5aefe8b85d9f9b9d18ae496be42e4f73378dab00da0d0bfa853ae03449bad895a6c5ac0c36cae80f1bfdef77fa7ad8f79fd99123f8d201d83ce0f0a9675a47c2
7
- data.tar.gz: 77774c2a3e201ed5f4a09fc72432478dc4e4866f9e9c17cd186877e91e1c74a2ef76fd5578b837e85857bfc36f32ca9cb41ab944fde422cb82350d1235e3e953
6
+ metadata.gz: e6ac870573118372878c50209d112ab916881b808e5f8d179b26aaa8f75851b5d1fba62e3d373d2cc06e050d488299a9a1260106ac2ff412f0525e9c939cf655
7
+ data.tar.gz: 7305fb6e8a4ae54796491fccc2322a76b64c7e5041c776e57fbacfa16db93be6f9379f7c3fb0af9016e5b77d71e96eebfcfdc3e206e7cedece561abf5a9cc475
@@ -1,4 +1,6 @@
1
1
  require 'stringio'
2
+ require 'rexml/document'
3
+ require 'facets/module/basename'
2
4
 
3
5
  require_relative 'blender-3d/version'
4
6
  require_relative 'blender-3d/object_reader'
@@ -10,9 +12,9 @@ require_relative 'blender-3d/char_field_parser'
10
12
  require_relative 'blender-3d/generic_field_parser'
11
13
  require_relative 'blender-3d/field_parser_factory'
12
14
 
15
+ require_relative 'blender-3d/serializer'
13
16
  require_relative 'blender-3d/structure'
14
17
  require_relative 'blender-3d/structure_definition'
15
-
16
18
  require_relative 'blender-3d/file_header'
17
19
  require_relative 'blender-3d/file_block'
18
20
  require_relative 'blender-3d/dna_block'
@@ -1,5 +1,7 @@
1
1
  module Blender3d
2
2
  class FileBlock
3
+ include Serializer
4
+
3
5
  attr_accessor :code, :size, :pointer, :type_index, :count, :data, :type
4
6
 
5
7
  def initialize(reader = nil)
@@ -11,9 +13,29 @@ module Blender3d
11
13
  end
12
14
 
13
15
  def parse_data(model)
14
- file = StringIO.new(self.data)
16
+ file = StringIO.new(data)
15
17
  reader = model.create_reader(file)
16
- self.data = self.count.times.map { self.type.read(reader) }
18
+ self.data = count.times.map { self.type.read(reader) }
19
+ end
20
+
21
+ def to_xml
22
+ REXML::Element.new(self.class.basename).tap do |e|
23
+ e.add_attribute 'code', code
24
+ e.add_attribute 'pointer', pointer.inspect
25
+ e.add_attribute 'size', size.to_s
26
+ e.add_attribute 'type_index', type_index.to_s
27
+ e.add_element data_to_xml
28
+ end
29
+ end
30
+
31
+ private def data_to_xml
32
+ content = value_to_xml(@data)
33
+ return content if content.is_a?(REXML::Element)
34
+
35
+ REXML::Element.new('data').tap do |e|
36
+ e.add_attribute 'count', count.to_s
37
+ e.add_text content
38
+ end
17
39
  end
18
40
 
19
41
  class Reader
@@ -1,6 +1,6 @@
1
1
  module Blender3d
2
2
  class Model
3
- attr_reader :header, :blocks, :pointers
3
+ attr_reader :header, :blocks, :codes, :pointers
4
4
 
5
5
  def self.from_file(path)
6
6
  File.open(path, 'rb') { |file| new(file) }
@@ -21,26 +21,62 @@ module Blender3d
21
21
  break if reader.tell == reader.file.size
22
22
  end
23
23
 
24
+ @pointers = @blocks.reject { |block| block.code == 'ENDB' }.map { |block| [block.pointer, block] }.to_h
25
+
24
26
  dna_block = self.dna_block
25
27
  return self unless dna_block
26
28
 
29
+ render_block = @blocks.find { |b| b.code == 'REND' }
30
+ if render_block
31
+ render_block.type_index = dna_block.data.structures.size
32
+ dna_block.data.structures << render_info
33
+ end
34
+
27
35
  @blocks.select { |block| block.type_index != 0 }.each do |block|
28
36
  block.type = dna_block.data.structures[block.type_index]
37
+ end
38
+
39
+ @blocks.select(&:type).each_with_index do |block, i|
29
40
  block.parse_data(self)
30
41
  end
31
42
 
32
- @pointers = {}
33
- @blocks.each { |block| @pointers[block.pointer] = block.data }
43
+ @codes = @blocks.group_by(&:code).sort.to_h
34
44
 
35
45
  self
36
46
  end
37
47
 
48
+ def create_reader(file)
49
+ ObjectReader.new(file, self)
50
+ end
51
+
38
52
  def dna_block
39
53
  @blocks.find { |block| block.code == 'DNA1' }
40
54
  end
41
55
 
42
- def create_reader(file)
43
- ObjectReader.new(file, self)
56
+ def render_info
57
+ @render_info ||= begin
58
+ sizeof_int = dna_block.data.types.find { |name, _| name == 'int' }.last
59
+ struct_size = 2 * sizeof_int + 64
60
+ StructureDefinition.new('RenderInfo', struct_size, [
61
+ Field.new(SimpleType.new('int'), 'sfra'),
62
+ Field.new(SimpleType.new('int'), 'efra'),
63
+ Field.new(FixedLengthStringType.new(64), 'scene_name'),
64
+ ])
65
+ end
66
+ end
67
+
68
+ def to_xml
69
+ content = blocks.reject { |b| b.code == 'DNA1' }.map(&:to_xml)
70
+ REXML::Element.new(self.class.basename).tap do |e|
71
+ e.add_attribute 'identifier', @header.identifier
72
+ e.add_attribute 'pointer_size', @header.pointer_size.to_s
73
+ e.add_attribute 'endianness', @header.endianness.to_s
74
+ e.add_attribute 'version', @header.version
75
+ content.each_with_index do |c, i|
76
+ c.add_attribute 'index', i.to_s
77
+ e << c
78
+ end
79
+ end
44
80
  end
45
81
  end
46
82
  end
@@ -17,7 +17,7 @@ module Blender3d
17
17
  end
18
18
 
19
19
  def <=>(other)
20
- other.is_a?(Pointer) ? location <=> other.location : 1
20
+ other.is_a?(Pointer) || other.is_a?(Integer) ? to_i <=> other.to_i : 1
21
21
  end
22
22
 
23
23
  def ==(other)
@@ -0,0 +1,22 @@
1
+ module Blender3d
2
+ module Serializer
3
+ private def value_to_xml(val)
4
+ case val
5
+ when Pointer then REXML::Text.new(val.inspect, true)
6
+ when Array then array_to_xml(val)
7
+ else val.respond_to?(:to_xml) ? val.to_xml : REXML::Text.new(val.to_s, true)
8
+ end
9
+ end
10
+
11
+ private def array_to_xml(ary)
12
+ REXML::Element.new('data').tap do |e|
13
+ e.add_attribute 'count', ary.count.to_s
14
+ ary.each do |value|
15
+ value = value_to_xml(value)
16
+ value = REXML::Element.new('data-element').tap { |x| x << value } if value.is_a?(REXML::Text)
17
+ e << value
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -4,6 +4,8 @@ module Blender3d
4
4
  attr_reader :definition
5
5
  end
6
6
 
7
+ include Serializer
8
+
7
9
  def initialize(reader = nil)
8
10
  deserialize(reader) if reader
9
11
  end
@@ -15,5 +17,16 @@ module Blender3d
15
17
  end
16
18
  self
17
19
  end
20
+
21
+ def to_xml
22
+ vars = instance_variables.map do |n|
23
+ value = instance_variable_get(n)
24
+ REXML::Element.new(n[1..-1]).tap { |e| e << value_to_xml(value) }
25
+ end
26
+
27
+ REXML::Element.new(self.class.basename).tap do |e|
28
+ vars.each { |v| e.add_element v }
29
+ end
30
+ end
18
31
  end
19
32
  end
@@ -29,9 +29,10 @@ module Blender3d
29
29
  when 'ushort' then reader.read_uint16
30
30
  else
31
31
  dna = reader.model.dna_block.data
32
- struct = dna.structures.find { |struct| struct.name == @name }
32
+ name = @name[0].upcase + @name[1..-1]
33
+ struct = dna.structures.find { |struct| struct.name == name }
33
34
  return struct.read(reader) if struct
34
- length = dna.types.find { |name, size| name == @name }&.last
35
+ length = dna.types.find { |name, _size| name == @name }&.last
35
36
  return reader.read(length) if length
36
37
  raise 'type not found'
37
38
  end
@@ -54,7 +55,33 @@ module Blender3d
54
55
  end
55
56
 
56
57
  def read(reader)
57
- Pointer.new(reader.read_pointer)
58
+ pointer = Pointer.new(reader.read_pointer)
59
+
60
+ model = reader.model
61
+ block = model.pointers[pointer]
62
+ if block && block.data.is_a?(String) && !block.type
63
+
64
+ if block.count == 1
65
+ size = if @type.is_a?(PointerType)
66
+ model.header.pointer_size
67
+ else
68
+ model.dna_block.data.types.find { |type, _| type == @type.name }.last
69
+ end
70
+
71
+ if block.size > size && block.size % size == 0
72
+ block.type = ArrayType.new(@type, block.size / size)
73
+ else
74
+ block.type = @type
75
+ end
76
+
77
+ else
78
+ block.type = @type
79
+ end
80
+
81
+ block.parse_data(reader.model)
82
+ end
83
+
84
+ pointer
58
85
  end
59
86
  end
60
87
 
@@ -1,3 +1,3 @@
1
1
  module Blender3d
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blender-3d
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SilverPhoenix99
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-03 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2016-11-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: facets
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3'
13
27
  description: Blender 3d file parser.
14
28
  email:
15
29
  - silver.phoenix99@gmail.com
@@ -28,6 +42,7 @@ files:
28
42
  - lib/blender-3d/model.rb
29
43
  - lib/blender-3d/object_reader.rb
30
44
  - lib/blender-3d/pointer.rb
45
+ - lib/blender-3d/serializer.rb
31
46
  - lib/blender-3d/structure.rb
32
47
  - lib/blender-3d/structure_definition.rb
33
48
  - lib/blender-3d/types.rb
@@ -52,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
67
  version: '0'
53
68
  requirements: []
54
69
  rubyforge_project:
55
- rubygems_version: 2.6.6
70
+ rubygems_version: 2.6.7
56
71
  signing_key:
57
72
  specification_version: 4
58
73
  summary: Blender 3d file parser.