niftools / blender_niftools_addon

The Blender Niftools Addon is a Blender add-on to enable import and export of NetImmese File Formats including .nif, .kf, .egm.
http://www.niftools.org
Other
387 stars 104 forks source link

Python reports syntax error in Blender 3.5 #580

Closed reddraconi closed 1 year ago

reddraconi commented 1 year ago

@niftools/blender-niftools-addon-reviewer -

Before creating a new issue, ensure that

Issue Overview

Installed latest release in blender 3.5.0 and attempted to import a Fallout 3 NIF (attached). When doing so, the NIF plugin crashes with the following Python stacktrace. Looks like generated code may not be using 'False' for falsy boolean in some cases.

Version Information

Version Info

Blender 3.5.1 NifTools Addon v.0.1.0 Nif XML Versrion: 0.9.3.0 Microsoft Windows 11 22H2

Steps to Reproduce

  1. Start blender with a blank template
  2. Import the NIF attached to this ticket
  3. Receive the following Python trackback error
  4. Nothing is imported

Python Traceback

Python: Traceback (most recent call last): File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\operators\nif_import_op.py", line 134, in execute return NifImport(self, context).execute() File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\nif_import.py", line 74, in execute self.load_files() # needs to be first to provide version info. File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\nif_import.py", line 140, in load_files NifData.init(NifFile.load_nif(NifOp.props.filepath)) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\file_io\nif.py", line 65, in load_nif data = NifFormat.NifFile.from_stream(nif_stream) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\formats\nif\__init__.py", line 531, in from_stream instance.read_blocks(stream) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\formats\nif\__init__.py", line 299, in read_blocks block = block_class.from_stream(stream, self, 0, None) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\base_struct.py", line 403, in from_stream cls.read_fields(stream, instance) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\base_struct.py", line 204, in read_fields setattr(instance, field_name, field_type.from_stream(stream, instance.context, *arguments)) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\array.py", line 107, in from_stream new_array.read(stream) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\array.py", line 64, in read self[:] = self.fill(lambda: self.dtype.from_stream(stream, self.context, self.arg, self.template)) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\array.py", line 79, in fill self[:] = [function_to_generate() for _ in range(self.shape[0])] File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\array.py", line 79, in <listcomp> self[:] = [function_to_generate() for _ in range(self.shape[0])] File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\array.py", line 64, in <lambda> self[:] = self.fill(lambda: self.dtype.from_stream(stream, self.context, self.arg, self.template)) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\base_struct.py", line 401, in from_stream instance = cls(context, arg, template, set_default=False) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\formats\nif\bshavok\structs\TriangleData.py", line 21, in __init__ self.welding_info = name_type_map['BhkWeldInfo'](self.context, 0, None) File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\bitfield.py", line 50, in __init__ self.set_defaults() File "C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\formats\nif\bshavok\bitfields\BhkWeldInfo.py", line 20, in set_defaults self.unused_bit = false NameError: name 'false' is not defined. Did you mean: 'False'?

TL;DR: formats/nif/bshavok/bitfields/BhkWeldInfo.py, line 20, in set_defaults, self.unused_bit = false should be self.unused_bit = False

Expected Result

File should be imported with no errors

Actual Result

  1. Blender recognizes the file as: (this looks correct)
    • Fallout 3, Gamebryo File version 20.2.0.7
    • Version: 335675399
    • User Version: 11
    • User Version2: 34
  2. Blender drops the attached trace back.
  3. Mesh is not imported.

Possible Fix

Fix generated python syntax to use 'False' instead of 'false' for boolean values.

Screenshot

Not relevant.

Logs and Files

Traceback above

Info Bar Output

[Output from the Info View, available at top of Blender view port, drag to expand]

Console Output

[Set the logging level to 'Debug' and attach the output of the console. Enable via Window -> Toggle Console]

Nif File

See attached file: washingtonmoninttop01.zip

reddraconi commented 1 year ago

I was planning to submit a PR for this, but I haven't figured out how to work with the generated code yet. :(

reddraconi commented 1 year ago

Manually modifying the C:\Users\reddr\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\io_scene_niftools\dependencies\generated\formats\nif\bshavok\bitfields\BhkWeldInfo.py file to

  def set_defaults(self):
    self.angle_edge_1 = 15
    self.angle_edge_2 = 15
    self.angle_edge_3 = 15
    self.unused_bit = False

fixed the above issue.

Candoran2 commented 1 year ago

Ah. That would probably be an issue in how we process default values. The Bitfield codegen class here should have something like the Union class does here to convert false to False.

reddraconi commented 1 year ago

Alrighty! I submitted a PR to OpenNaja. Hopefully I did okay with it.