30350n / pcb2blender

KiCad to Blender 3D model workflow
GNU General Public License v3.0
521 stars 11 forks source link

Importer: TypeError: object of type 'NoneType' has no len() #48

Closed Neywiny closed 6 months ago

Neywiny commented 7 months ago

Hi,

I am very keen to use this toolset because I've done this manually in the past. I tried out the example boards and they work. I tried out the AntMicro LPDDR4 testbed and that works too. However, on my custom board (admittedly from a few years ago) I'm not having success. The PCB substrate looks to be in, but there's no components. I see the following a few times in the console.

Traceback ``` Traceback (most recent call last): File "C:\Users\Username\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\addons\pcb2blender_importer\importer.py", line 1014, in execute result = import_x3d.load(context, self.filepath, global_matrix=matrix) File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 3631, in load load_web3d(context, filepath, File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 3530, in load_web3d importShape(bpycollection, node, ancestry, global_matrix) File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 3144, in importShape bpydata = geom_fn(geom, ancestry) File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 1896, in importMesh_IndexedFaceSet if len(points) >= 2 * len(index): # Need to cull TypeError: object of type 'NoneType' has no len() Error: Python: Traceback (most recent call last): File "C:\Users\Username\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\addons\pcb2blender_importer\importer.py", line 1014, in execute result = import_x3d.load(context, self.filepath, global_matrix=matrix) File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 3631, in load load_web3d(context, filepath, File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 3530, in load_web3d importShape(bpycollection, node, ancestry, global_matrix) File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 3144, in importShape bpydata = geom_fn(geom, ancestry) File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 1896, in importMesh_IndexedFaceSet if len(points) >= 2 * len(index): # Need to cull TypeError: object oTraceback (most recent call last): File "C:\Users\Username\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\addons\pcb2blender_importer\importer.py", line 205, in execute if (pcb := self.import_pcb3d(context, filepath)) == {"CANCELLED"}: File "C:\Users\Username\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\addons\pcb2blender_importer\importer.py", line 345, in import_pcb3d bpy.ops.pcb2blender.import_x3d( File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\modules\bpy\ops.py", line 109, in __call__ ret = _op_call(self.idname_py(), kw) RuntimeError: Error: Python: Traceback (most recent call last): File "C:\Users\Username\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\addons\pcb2blender_importer\importer.py", line 1014, in execute result = import_x3d.load(context, self.filepath, global_matrix=matrix) File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 3631, in load load_web3d(context, filepath, File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 3530, in load_web3d importShape(bpycollection, node, ancestry, global_matrix) File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 3144, in importShape bpydata = geom_fn(geom, ancestry) File "C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\addons\io_scene_x3d\import_x3d.py", line 1896, in importMesh_IndexedFaceSet if len(points) >= 2 * len(index): # Need to cull TypeError: object of type 'NoneType' has no len() Location: C:\Program Files\Blender Foundation\Blender 4.0\4.0\scripts\modules\bpy\ops.py:109 ```

All the components render ok (except 1 that's occasionally missing?) in the KiCad 3D viewer.

I am on Blender 4.0, KiCad release build 7.0.10, Windows 11 build 22621.

Thank you

30350n commented 7 months ago

That seems to be caused by a corrupted VRML model. The error comes from Blender's X3D/VRML importer.

I could try to catch that and display a warning which model is causing the problem.

Neywiny commented 6 months ago

Seems likely it's the 1 model that isn't showing up in the 3d view. I'll try and fix that. Another option is I'll modify the Python code to be more verbose and root cause it. Thank you

Neywiny commented 6 months ago

So turns out one of the packages I selected either never had (which seems unlikely?) the right 3D model or idk what, but I replaced the model with one that actually exists and that still didn't fix it.

So I ended up modifying your script by adding a print(f"{self.filepath = }"). After reloading the scripts in Blender, I saw it chewing on the files, eventually getting to one of my inductors. I vaguely recall modifying that model when I was making the board. Doing an import of it from the temp location raised the same error. Cad Assistant was also unable to open it. Luckily I had the step model I presumably made the wrl out of. After re-scaling it according to the datasheet, I could get the importer past that component.

I don't know how the code flow is, but after a bunch of prints of 3d models I got to setup_pcb_material which then failed.

Traceback (most recent call last):
  File "C:\Users\Username\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\addons\pcb2blender_importer\importer.py", line 205, in execute
    if (pcb := self.import_pcb3d(context, filepath)) == {"CANCELLED"}:
  File "C:\Users\Username\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\addons\pcb2blender_importer\importer.py", line 375, in import_pcb3d
    setup_pcb_material(board_material.node_tree, images, pcb.stackup)
  File "C:\Users\Username\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\addons\pcb2blender_importer\materials.py", line 145, in setup_pcb_material
    setup_node_tree(node_tree, nodes, label_nodes=False)
  File "C:\Users\Username\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\addons\pcb2blender_importer\custom_node_utils\__init__.py", line 11, in setup_node_tree
    node = nodes.new(node_type)
RuntimeError: Error: Node type ShaderNodeBsdfMat4cad undefined

However, in my attempt to add more printing to that area (which did work) I guess I kinda broke the extension part so I closed/reopened and the board imported just fine.

I really like the auto-generated through hole solder joints. It's really nifty. Thank you. SMD isn't working on my model with the smart option, but it may on others.

30350n commented 6 months ago

Great so everythings working again?

I really like the auto-generated through hole solder joints and hope you add auto-generated SMD solder joints in the future.

Thanks, there are auto generated SMD solder joints actually. They are just not very apparent.

Neywiny commented 6 months ago

Great so everythings working again?

Looks like it.

Thanks, there are auto generated SMD solder joints actually. They are just not very apparent.

I spoke too soon (hence the edit though maybe still speaking too soon).

image I guess I'd expect to see a nice fillet on the passives. Is this the intended effect or do I need to flip a setting?

30350n commented 6 months ago

Intended. It's meant to mimic what you get from factory assembly. (Atleast from my experience you only get the fillets when applying too much solder, e.g. hand soldering).