30350n / pcb2blender

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

Blender crashes when Rasterization is enabled #8

Closed Haschtl closed 1 year ago

Haschtl commented 1 year ago

Thanks for your nice project! I like the structure with the exporter and importer! It allows to check/optimize the output of KiCAD before merging it with the importer.

Sadly, I cannot use the Importer with Rasterization. I assume there are some problems with the texture generation.

I tested it with the 123.zip from #1 I just added the pads folder inside the 123.pcb3d because the importer expects it to exist.

Versions

Blender version: 3.3.0 KiCad version: 6.0.5 pcb2blender version: 2.0 OS: Windows 11 22H2 (Before I also tested it with Blender 3.3.2 and KiCad 6.0.9 with same results)

Import type 3D

I can load the file using 3D layers and visualize the Rendered view in blender: image and export any format, e.g. glb: image

Import type Rasterization

I can also load it with Rasterization enabled, image

but when I switch to the Material preview or Rendered view in blender, it crashes. Blender's .\blender_debug_log.cmd gives the following output:

I1210 17:37:38.142694 22208 device.cpp:32] CUEW initialization succeeded
I1210 17:37:38.142694 22208 device.cpp:34] Found precompiled kernels
I1210 17:37:38.149230 22208 device.cpp:56] HIPEW initialization failed: Error opening HIP dynamic library
I1210 17:37:38.196555 22208 device.cpp:70] oneAPI kernel shared library has been loaded successfully
Switching to fully guarded memory allocator.
Blender 3.3.0
Build: 2022-09-07 00:44:18 Windows release
argv[0] = C:\Program Files\Blender Foundation\Blender 3.3\\blender
argv[1] = --debug
argv[2] = --debug-cycles
argv[3] = --python-expr
argv[4] = import bpy; bpy.ops.wm.sysinfo(filepath=r'C:\Users\hasch\AppData\Local\Temp\blender\debug_logs\blender_system_info.txt')
Read prefs: C:\Users\hasch\AppData\Roaming\Blender Foundation\Blender\3.3\config\userpref.blend
Info: Deleted 1 object(s)

mesh_ensure_tessellation_customdata: warning! Tessellation uvs or vcol data got out of sync, had to reset!
    CD_MTFACE: 0 != CD_MLOOPUV: 1 || CD_MCOL: 0 != CD_PROP_BYTE_COLOR: 0
mesh_ensure_tessellation_customdata: warning! Tessellation uvs or vcol data got out of sync, had to reset!
    CD_MTFACE: 0 != CD_MLOOPUV: 1 || CD_MCOL: 0 != CD_PROP_BYTE_COLOR: 0
mesh_ensure_tessellation_customdata: warning! Tessellation uvs or vcol data got out of sync, had to reset!
    CD_MTFACE: 0 != CD_MLOOPUV: 1 || CD_MCOL: 0 != CD_PROP_BYTE_COLOR: 0
...
...
...
<ininite loop until crash>
...

Sometimes it shows the correct visualization with all layers, sometimes it shows nothing, sometimes the PCB is visualized white transparent. But in any case I see it for a short time only and Blender freezes and crashes.

Anyway, I tried to avoid the Rendered view in Blender and tried to export it as glb directly. When I open the glb, the file has no texture on it: image Same with obj:

image

30350n commented 1 year ago

Hey! Thanks for checking out the project and reporting this issue.

Just fyi: Regarding the different import types: The 3D one is more or less an old deprecated approach I've tried, which I haven't really kept up to date much, so the materials aren't looking that great etc. The Rasterized mode is the recommend one you should use.

Regarding the crash

That seems to be something out of my control from what I can tell. The file you mentioned imports and renders fine for me. image

I'm guessing this might be something like a memory limitation maybe? As the textures produced can get quite big and blender might not handle this very gracefully.

Did you try reducing the Texture DPI when importing? image

If that doesn't work, feel free to share a blend file of an imported board, then I can check if it works for me.

Regarding exporting to GLTF/OBJ

That's something I've sadly not considered yet and the way the materials are currently setup (especially in Rasterized mode), no exporter will be able to detect any textures, color information etc. (Because pcb2blender heavily relies on custom group nodes, that other exporter addons "can't understand").

This is something I'll keep in mind for the future though, so I might create a exporter friendly mode in the future ^^

Haschtl commented 1 year ago

Thanks for your quick response! I tried it with reduced Texture DPI (around 200). Then it crashes later, and I can see the texture more often. I don't think it's a memory issue, I have 16GB RAM and a RTX 3050 Mobile ... Here is my imported .blend-file: 123_imported.zip. Would be nice, if you could check if you can render this file.

Export

I got the point regarding the export, which is a different usecase than high-quality renderings. I need gltf-models for web, so I prefer performance over render-quality. I don't know much about blender, but I read about the requirements of textures for gltf-export.

I've written some code to create the base_color, normalmap, metal, occlusion and roughness maps based on the svgs in the .pcb3d file.

B_base_color

I then manually removed the textures from the PCB and added my own, which looks quite good in glb: image

Here is my code to create the maps.

How much effort is it to automate the UV-mapping and texture creation for that? Or is it even possible? Also i found it's better to export the .step from KiCAD, open it in FreeCAD, remove the layers and export it as wrl. This way the mesh contains much less vertices.

Here is the outcoming .blend and .glb: 123_export.zip

30350n commented 1 year ago

Ahhhh you're trying to use Eevee! Of course, that makes sense. So yeah, the plugin/materials setups are really meant for use with the Cycles render engine, I just tried Eevee with your file and it also rendered for me, but pretty much completely slowed down/killed everything else on my PC while doing so.

I should probably just add a stylized/low end compatible material mode, which also works with exporters. That's a good idea.

(Will take a closer look at your pbr map creation code later, maybe I can integrate that, or something similar, into the addon at some point :) )

Haschtl commented 1 year ago

I've made some progress I have adapted your Blender-Importer and created a second Importer, which only creates the Material. UV-mapping is still a manual process.

I have some more changes I want to do:

  1. The wrl of the board contains lots of useless information if I create the textures, because it contains meshes from the pcb-layers. My plan is to export the Edge_Cuts layer and extrude the SVG in blender. This also makes UV-mapping easier. I already adapted the Exporter to export the Edge_cuts layer
  2. Sometimes layer-exports from KiCAD has an issues, where footsprints are not included in the mask. So I plan to export the gerber files and use them. There are some gerber renderers out there, I will check how they perform. I already added the gerber export
  3. I think It would be nice, if colors and layer-heights would be exported from KiCAD, as this is configurable since KiCAD 6. Unfortunately the PythonAPI to read the stackup info is not yet working. I decided to parse the content from the kicad_pcb file directly. I included the stackup info in the pcb3d file as board.yaml.
  4. There is a small bug with your nice pad-renderings. You select every Pad of every Footprint. Unfortunatley its not always the case, that every pad has solder on it. Luckily its possible to GetLayerSet() of every pad. I changed the code to only export a pad, if there is a layer containing Paste in the LayerSet
  5. I plan to use CI/CD as much as possible. Therefore I want to use KiBot to automate all of the exports - I will create an exporter based on KiBot that is compatible with pcb2blender.
30350n commented 1 year ago

Oh I've forgot to mention that actually: The current importer already sets up UV maps for the textures in Rasterized mode, so that shouldn't really be an issue.

Regarding the other things:

  1. Yes, but it's by far the easiest way to get a mesh with the right shape, including holes and everything. Edge_Cuts layer alone won't cut it, as it doesn't contain Vias, Through Holes etc. iirc.
  2. Can you send/share an example of that behavior? I've considered a lot of different options for getting the textures rasterized when making the addon and settled on skia mostly because a) it doesn't require any additional dependencies (unlike cairosvg) and b) actually seems to produce correct results and is fairly quickly (unlike svglib/reportlib iirc). I've also considered rasterization directly from gerber files, but couldn't find anything that worked really.
  3. Definitely thought about that, but haven't gotten to it really (also unfortunate if the python api doesn't support it yet).
  4. That's a good point, I already have a similar strategy in place, which only adds solder joints if 3D models are present. The way things are setup right now though, all pads should still always be exported. The information whether or not a pad has solder paste or not, should be a parameter of the pad.
30350n commented 1 year ago

Properly fixed 4. in https://github.com/30350n/pcb2blender/commit/c2358650c47b6a90ddb01130e463c63f722d9e96 also made a new release (v2.1). Thanks a lot for the idea! 👍

Haschtl commented 1 year ago

Update:

  1. Thats correct, didn't think about the through holes, etc. Nevertheless - for my usecase with gltf in web, I don't want these small details. But importing the edge_cuts svg is not that easy, so I will modify this by hand. Also, I always saw the mesh created in the 3D mode - where all the layers are joined in one object. As this is not the case in my implementation, its ok.
  2. This is not a problem of pcb2blender. The svg2img works fine, the svg from kicad is not correct.
  3. I implemented it in my fork now. As the python API is not complete here, I used a hacky workaround by parsing the .kicad_pcb directly.
  4. Thanks for the quick fix!
  5. KiBot does not support exporting wrl. So sadly its not that easy to make a headless version of the exporter with KiBot.

I now integrated my texture creation into the importer including correct UV-mapping (only the PCB-edges are wrong). But I still have one weird bug:

Do you maybe have any idea what could cause this behavior? Here are the three files: 123_gltf.zip

Back to the initial issue

My blender is still crashing if I use rasterization mode There seems to be a difference in the blender file I created and the files you created... can you maybe send me your blender-file of the 123 example? Then I can check if it works for me

30350n commented 1 year ago
  1. Can you still share an example of where that bug occurs? Curious to take a look at the problem and possibly report a bug to the KiCAD devs.
  2. Nice, looks a little bit hacky I guess, but yeah. Maybe I'll look into properly implementing this some day ....

I'm still not totally sure what you mean with "unnecessarily complicated" exactly, do you mean all the extra faces you get because of the through holes/vias? If so, are you sure these are that much of a problem (performance wise)?

I imported your 123_only_board.glb file in Blender again and it also looks dark, like this: image Seems like the default node setup it produces multiplies the Color texture with the vertex colors of the mesh for some reason. Not sure if that's a thing gltf does by default, but I'd guess you can disable that somehow? Otherwise try to set all the vertex colors to white, that should fix it aswell. image

Regarding the initial issue

Like I mentioned earlier, you are probably using the Eevee real-time render engine in Blender. The rasterized mode is meant for use with the Cycles render engine. If you use the newest version of the importer, it should switch to Cycles when importing in Rasterized mode automatically.

(Eevee did also semi-work for me, but it completely lagged out my machine, because the materials are to complicated for it probably).

I've thought about it some more and I think the ideal solution would simply be to offer an option to bake out the complex materials to a set of PBR textures. So you could preview your board in Blender with Cycles, change around Colors etc. if you want and once your happy bake everything out to a set of Albedo, Roughness, Metal, etc. maps that you can then use with Eevee or export via the GLTF exporter and use for web stuff.

Haschtl commented 1 year ago
  1. Thats correct. Here is a minimal example: kicad_export_problem.zip. Plotting the file as svg gives only one dot, plotting the gbr in tracespace shows the real output of the gerber.
  2. Yes, very hacky. But at some point in time KiCad will have a real working API for the stackup. Here is a discussion about this topic and the stackup = board.GetDesignSettings().GetStackupDescriptor() function, which is not very helpful.

With "unnecessarily complicated" I initially referred to the mesh with the joined objects you used in the 3D mode (bpy.ops.object.join()). This mesh included all the layers of the PCB. The holes/vias are not a big problem for me - but still, if you imagine a web-application which loads many PCBs, performance is very important. But in this case I would first replace the detailed components with simpler ones, use lower-resolution textures and then - if it's still not enough - remove the vias in the board...

Initial issue

I checked it both - Eevee and Cycles (with GPU Compute selected) - with your new version. With Cylces it works better, I can see the PCB... but blender still doesnt respond as soon as I change to the Viewpoint Shading.

That would be a nice alternative! Is it a big deal to bake out the materials to PBR?

Edit: Regarding the black PCB: There is indeed a export_colors option in bpy.ops.export_scene.gltf. Setting it to False fixed this. Thanks!

Haschtl commented 1 year ago

I don't know why, but the RASTERIZED mode works now... I think it was some kind of blender issue

Regarding the material selection based on the KiCAD stackup: I've added automatic material selection in rasterized mode in the setup_pcb_material() function of materials.py

set-soft commented 1 year ago

Hi @30350n and @Haschtl !

I'm the KiBot author. Now KiBot can generate PCB3D files in a headless fashion (CLI, CI/CD, etc.). I also wrote a Blender script to export the imported PCB3D into various formats and to render it. KiBot can add a simple light and a camera that points to the PCB, so you can get acceptable renders without even knowing what Blender is ;-)

Here are some experiments:

light_control-3D_blender_100 light_control-3D_blender_bottom ArduinoLearningKitStarter-3D_blender

I'll add Blender and pcb2blender to my docker images in the next days, so KiBot users can start playing with it.

@30350n: you did an impressive job with the shader nodes.

30350n commented 1 year ago

Hey! Thanks a lot, I've never used KiBot before, but I'll definitely look into it! Being able to completely automate good looking renders of PCBs definitely seems nice.

@30350n: you did an impressive job with the shader nodes.

Thanks. I haven't touched this much for a while, but it's nice to see that it generally seems to work for other people as well, I think I might still need to do some optimizations though, especially to make it viable/work for lower hardware devices as well.

Great renders!

30350n commented 1 year ago

@Haschtl

That would be a nice alternative! Is it a big deal to bake out the materials to PBR?

Well ... it's not trivial at least. Ideally I'd have some tooling in place to automatically bake PBR maps for the main PCB and possibly the components and update the materials to use those. I've actually started implementing this a couple weeks ago, but haven't gotten around making it work yet.

There's still one relatively big issue though, which is UVs: The mesh topology of the WRL files from KiCAD is nonoptimal for baking and (atleast when I tried it, left visible artifacts). There's a lot of stretched out triangles, because of all the holes in the boards, which cause these issues. One should be able to remesh the PCB though, in a way where this isn't an issue, this seems to be non-trivial though.

Actually, just while writing this I've had another idea: It might be possible to simply "plug up" all the holes before baking, leaving us with a few big faces hopefully. This could be reversed afterwards and the textures should work completely fine with the original mesh still (which can be restored afterwards), as long as the UVs match up. This might be the way to go actually, I'll try to look into this soon!

Haschtl commented 1 year ago

The initial issue was fixed by automatically switching to cycle rendering mode, so I will close this issue

30350n commented 1 year ago

The initial issue was fixed by automatically switching to cycle rendering mode, so I will close this issue

Thanks! I've actually done some work regarding the baking idea, but it's not really in a useable state yet. I've just pushed the code to the baking branch if you want to check it out ^^