blender-3d 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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.