text:
Differential Mesh Growth
I'm looking for a way to achieve non-destructive, generative differential mesh growth with blender.

I know of the differential growth add-on. That doesnt really work for me as it's

destructive
doesnt really work on closed 3d geometry

what I tried:
1. Animation Nodes
Get Mesh from Object with Remesh Modifier, cache Mesh once per frame, move vertices, apply mesh back to the cached object and repeat.
Kind of worked - but not really.
2. Geometry Nodes
doesnt work at all because there is no way to reapply a modifier or loop a function with iterations
3. Sverchok
Gave up pretty quickly to test ideas in Animation Nodes (which I am more familiar with)
My main problem is the subdivision part of most differential growth algorythms (Common rule is "Subdivide if edge is longer than x"). Not sure how I could solve that in Blender.
Any Tips, Ideas on that?

Would running something like this every frame of your animation do the trick?
import bpy
import bmesh

# This is just the most expedient way to get in and out of access to the
# mesh data.
# You don't necessarily have to do it in edit mode, it just takes like 3-4
# more lines of code.

obj = bpy.context.active_object
mesh = obj.data
bm = bmesh.from_edit_mesh(mesh)
too_long = 1
num_subdivs = 1

long_edges = [e for e in bm.edges[:] if e.calc_length() >= too_long]
bmesh.ops.subdivide_edges(bm, edges=long_edges, cuts=num_subdivs)
bmesh.update_edit_mesh(mesh)

Edit
So I wrote a sort of DIY "mesh cache" wrapped around a function that distorted the mesh and "Remeshed" it using the essence of my previous method. Theoretically this should be entirely "non-destructive" because each state of the mesh is written to disk and can be loaded back in at will.
import bpy
import bmesh
from mathutils import noise
import statistics
import json
from pathlib import Path

bpy.ops.mesh.primitive_uv_sphere_add()
bpy.ops.object.shade_smooth()

# get the object and convert it to a workable mesh
obj = bpy.context.active_object
mesh = obj.data
bm = bmesh.new()
bm.from_mesh(mesh)

# just values I fiddled with until the noise
# and displace didn't completely destroy the mesh
strength = 4
displace_strength = 3

# stand in function for whatever procedural growth operation
# you have going, just a proof of concept

def displace_mesh(verts, strength=4, displace_strength=3):
    # loop through the vertices, displace them
    # on their normal vector, then offset that by using
    # a noise from mathutils
    for vert in verts:
        norm_offset = vert.normal / displace_strength
        vert.co += norm_offset
        pos = vert.co
        noise_pos = noise.noise_vector(pos) / strength
        sub = pos + noise_pos
        vert.co = sub
        vert.co += norm_offset

    # get all the edges and "Remesh" them according to
    # whether the exceed the average length of all edges
    # then triangulate the whole mesh
    edges = bm.edges[:]
    edge_l = [e.calc_length() for e in bm.edges[:]]
    edge_mean_l = statistics.mean(edge_l)
    long_edges = [e for e in edges if e.calc_length() > edge_mean_l]
    bmesh.ops.subdivide_edges(bm, edges=long_edges, cuts=1)
    bmesh.ops.triangulate(bm, faces=bm.faces[:])

# get the number of frames
num_frames = bpy.data.scenes["Scene"].frame_end

# loop through the frames
for i in range(num_frames):
    # create a python dictionary of the mesh, we can write
    # write each iteration out as a .json file and then later
    # reread it in using bpy.types.Mesh.from_pydata().
    # Basically a DIY "cache".
    pydata = {}
    faces = []
    edges = []
    verts = [vert.co.to_tuple() for vert in bm.verts[:]]
    for face in bm.faces[:]:
        faces.append([v.index for v in face.verts])
    for edge in bm.edges[:]:
        edges.append([v.index for v in edge.verts])

    pydata["vertices"] = verts
    pydata["edges"] = edges
    pydata["faces"] = faces

    file_name = parent_dir / f"mesh_data_frame_{str(i).zfill(3)}.json"

    # writing the file to disk
    with open(file_name, "w") as json_file:
        json.dump(pydata, json_file)

    # At this point we have copied the mesh in it's current
    # state to disk. Now that it's saved, we can use or distortion function
    # to mess with it
    displace_mesh(bm.verts[:])

    # and repeat

Later, in a separate script we can import each mesh individually. You could do whatever you want with each mesh at this point, render it's frame, then delete it and move on to the next, add more modifiers etc. I only offset them to show them all lined up.

import bpy
import json
import bmesh
from pathlib import Path

# get all .json files from the current directory
file = Path('.')
files = sorted(list(file.glob("*.json")))

# iterate over the files and create a new object and mesh
# from the data in the file, the link it to the scene
for i, j in enumerate(files):
    with open(j.name, 'r') as f:
        data = json.load(f)

    obj_name = f'mesh_{i}'
    mesh = bpy.data.meshes.new(name=obj_name)
    mesh.from_pydata(**data)
    obj = bpy.data.objects.new(obj_name, mesh)
    bpy.context.collection.objects.link(obj)

# line em up for display
offset = 0
for obj in bpy.data.objects:
    obj.location.x += offset
    offset += 10

End Result:

Not at all unfortunately as your solution is destructive.

@bstnhnsl a Python solution is not destructive if you keep the original object copy. Otherwise any iterative process is destructive, because each step needs to create a new state (so "destruct" current state by changing it) to be used by the next step. You said yourself geonodes don't work, because you can't reapply the modifier, but applying the modifier is a destructive step.

Yeah especially as you already said the Remesh modifier wasn't working, I don't see how else you could repeatedly add new geo to the mesh in a wholly non-destructive way other than that.

If there was a Remesh node in animation nodes would be satisfied 100%. I would have control over WHEN the remesh happens and can go back to my original geometry and change it without making copies or continuously pressing cmd+z. You are totally right, applying a modifier like "go to modifier section and hit apply" is a destructive step, that not what I mean or try to do.

@bstnhnsl do you consider a physics simulation destructive? You can code a (somewhat elaborate) Python solution that works like physics simulations in that it maintains cache of evaluated states. https://blender.stackexchange.com/questions/238383/distributed-interaction-visualization/238409#238409

@bstnhnsl I expanded my answer with something that might more closely align with your goals.

I‘ll have a look at it when I find time. Thanks!

I found a somewhat working solution with sverchok and a python script for the actual mesh growth and subdivision. That works a bit better for me than your solution (probably just personal preference).
I'll add an answer showcasing my solution


text:
How to find out the exact Frequency of F-Curve Modifiers
I want to create harmonic looping animations using the built-in functions for F-Curve modifiers.
Example: move an object back and forth along the z axis in a sine motion.
In order to make a perfect loop, i need to figure out the exact frequency of the built-in sine function. The docs don't mention the frequency at all and the value to change the frequency "phase multiplier" is rather obscure to me.

It looks like the base modifier is set to f(t) = sin(t) . That is to say, f(0) = 0, f(pi/2) = 1, f(pi) = 0 and f(3*pi/2) = -1

So the frequency is 2 * pi (The curve repeats itself every 6,283185307... units).
If you want to tweak the frequency, say you want a cycle every 10 frames, multiply the phase by 2 * pi and divide by 10.

Phase Multiplier to generate 1Hz = 6.2831853069/FPS
Each frame is ~ 0.1591549431 Cycles (1/2pi)
So for a 24 FPS you get 0.1591549431*24=3.8197186344 Cycles per second
So to convert this to 1Hz to get 1 Cycle per second
your multiplier would be --> 1Hz = Multiplier * 3.8197186344 --->
Multiplier = 0.2617993878
Here is a generic formula for any specific FPS you are working in your project
1/(0.1591549431*FPS) would give you 1Hz for your project FPS.
To simplify --> (6.2831853069 * 1/FPS) = 1Hz
**
If you are trying to sync this to music, convert your BPM to Hz then multiply the value that you found from (6.2831853069 * 1/FPS) to your note values**.
For example a quarter note for a 141 BPM song equals 2.35Hz, if I'm working in blender in 24FPS then my multiplier to sync to a quarter note in music would be (0.2617993878 * 2.35) = 0.6152285613 then use the phase offset to sync the wave to the downbeat of your music.
I have tested this and confirmed the music stays in sync with these values.
If you are using Ableton you can use this time calculator plugin to convert BPM to Hz https://ableton.expert/product/565427 or use any delay calculator that can convert BPM to Hz
Hope this helps

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Weird noise warping in material nodes
Spot highlighted in pink doesn't warp, unlike the rest of noise texture and i can't figure out why

Texture im using to warp the noise doesn't show it

Nor is it visible if i just check the coordinate space itself

If i separate the X axis from it, there's a little spot visible exactly between X and Z axis

It wasn't there before i applied the rotation transform, but i can't find any reason for it to appear
Node setup:

Blend file:

It seems to happen on both sides, and both spots are in-between mirrored warping. Apparently, the noise happens to align with the UV space there.

I have managed to fix this by just plugging it into rotation, and applying some offsets

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Label on Packaging Surface / Texture Problems
I have a question about my label on a packaging. I created the packaging myself and now I want to put my label on the front of the packaging. Unfortunately, it's always distorted and doesn't look nice. The surface isn't perfectly flat, but I think it should still be represented somewhat nicely. I created a mesh plane and used a text image as material. Then I tried to get it onto the surface of the packaging using the Shrinkwrap Modifier. However, the result doesn't look good.
Another question is about the packaging itself: there are two vertical stripes on the left and right with different material textures. I can't get rid of them; could this possibly be due to incorrect vertices?
And my last question is, once I render the image, the result is completely white and totally overexposed. I probably have a setting that leads to this error. However, I can't find the solution.

I'll attach the Blender file and would be grateful for any help, as I've been struggling with these issues for several hours. Thank you very much.

Hello, please pack your image (File > External Data > Pack Resources) before saving and sharing

@moonboots Okay, I also didn´t know. However I did now and edited again. I think it should packed and updated now.

For the over-exposition you have a light that is hidden for preview but visible for render, disable it. For the Shrinkwrap you could switch to the Wrap Method > Project, move it towards the pack until it sticks to its surface and play with the Offset. That said, you could have made this sticker part of the object material. Also don't forget to right click > Shade Smooth to smooth the shading.

As for the vertical lines it's because of the bad topology, rework it a bit, for example here you have overlapping faces:

Wow, thank you for the detailed answers!! I will try it (I am still beginner). However this is very helpfull!


text:
Face orientation viewport overlay doesn't show up
Good day!
I can't see anything when ticking the face orientation option...
No X-Ray mode, Theme colors are okay and I turn off all 3rd party addons and it doesn't fix it either.
When loading factory preferences, It fixs it but I lose all my custom Keymaps so I wouldn't want to do that.
Are there any related options that I'm missing?

Hi. You turned off all 3rd party addons. Did you close Blender and then turn them back on one at a time and check what happens after turning on each addon? It is important that you close Blender after deactivating your addons. You mention that loading factory settings fixes it. That is usually a sign that a 3rd party addon is causing the problem.

Apparently, The alpha values of Face Orientation Front/Back color in themes were set to 0 somehow. Setting them to 1 got both colors back to normal! I wasn't aware of that I should restart Blender after deactivating addons... Learnt a new thing! Appareciate your reply!

If this is a fix, could either one of you post it as an answer, please? ... or, (trpid,) delete, or drop us a note here, saying you don't mind closing your post. Thanks.

@RobinBetts I will post an answer based on the comment if nothing more is heard from trpld. What would be a reasonable amount of time to wait?

Thanks @curious_1 .. I guess, if convenient,  leave it a day for trpid to self-answer and earn a bit of rep, just to be nice to a beginner? But no blame for going right ahead :)

Sorry guys, new to here. Is there anything further to do? Have no idea how this works haha. So I post a question and should delete the post when it's fixed or something??? How do I post this as an answer? I don't see any buttons like Pick this comment as an answer or like Solved! or something

TL;DR It can be confusing for newbies. I suggest scroll to the bottom of the page. In that blue "footer" area in the left hand column labeled "Blender" click on Help. Another suggestion is that when you have time, to look at some of the topics in that Help section and look at the Tour section. It will give you a better idea of how the site works. For now, here is the link about answering your own question: https://blender.stackexchange.com/help/self-answer   Continued...

To input your answer scroll down below the comment section to where it says "Your Answer". Click inside the box and write your answer. In what I will call the header of the Answer box, on the right side is a blue question mark for help with formatting it. It looks like the first sentence of your first comment will do for the answer. I recommend that if you could add some details, like an image showing where these changed theme settings are located, it would improve your answer considerably. Also note that after 48 hours you can accept your self-answered question.

Thanks for your detailed info! It helps a lot.

If you don't see anything when ticking Face Orientation in the Viewport Overlays options, Check

X-Ray mode should be off
Under Preferences > Themes > 3D Viewport > Face Orientation Back/Front check Alpha values of both colours shouldn't be 0


text:
Geometry Nodes: Array items and rotate randomly on a 90° basis
Need to array this square frame in a grid layout but they need to rotate randomly every 90° using geometry nodes.
1st image: Array i made, the one inside the green square is the main
2nd image : Reference Image from ArchDaily, its what i want to replicate
PD: first time posting here, and 0 knowledge on geometry nodes
Thanks in advance

with this node tree:

you hopefully get what you want.
Just create a random number from 0 to 3 and multiply it with pi/2 so that you get random values for rotation (GN calculates in radians).
Then rotate your instances with rotate instances.

It did worked, but a little nitpick, the center object seems offset and doesnt perfectly stack even tho its on the perfect geometric center
https://imgur.com/a/b5XNQ25

than you made something wrong....maybe your pivot point isn't in the middle. Pls provide blend file, so that i can check it out.

You were right, the origin point was a bit off, thanks for the help
way faster than reddit lmao


text:
raycasting light beam with loop node
By referencing the infinity laser reflection project (https://windmiller.gumroad.com/l/raycastinglaser), I am currently attempting to recreate it using a loop node. However, it is not functioning properly. It appears to work fine after the first iteration, but starts to go wrong from the second iteration.
The loop:

Inside the loop:

Could you provide your Blender file using https://blend-exchange.com/ ?

yes! thank you for the link! I added it in the post!

Raycasting with bounces (using margin)
I've restarted from scratch, having a hard time understanding your own setup.
The idea is quite simple. For each point (bounces), compute the hit position, move a point of the mesh accordingly, and update both position and direction of the laser.

So for each bounce, we have the position $\vec{p}$, the direction of the laser $\vec{d}$ and at the hit position, the normal of the surface $\vec{n}$. The blue dot represent the starting point of the current bounce/loop iteration.
1. Base mesh generation
I'm starting with a mesh line, setting the resolution to the number of bounces + 1. Because we are gonna set each point individually, I'm setting all positions to the origin by default.
Additionnaly, we can already set the first point to be at the start of the laser (here Laser head).

2. Repeat zone initialization
The repeat zone have 3 custom fields :

Source location : the starting point of the current laser segment
Source direction : the starting direction of the segment
Iteration : an integer counting our loop number

I'm using two Empty objects to set the position and direction : Laser head and Laser target.

3. Repeat zone process
So we give explicitly the position and direction for the first segment. Then, for each loop (bounce), we compute the Raycast and we get the position of the hit. This position helps us move the current point of the laser.
The new position is a bit tricky. If we just plug the Hit Position to the Source location, a problem arises : our new starting point is inside one face of the cube. Then, the raycast would sometimes work, sometimes not (I believe a side effect of floating point calculation). To be sure to not take into account the current face, on which we just bounced, I'm giving the position a very small margin, based on the normal of current face. Keep in mind that because of it, the laser bounces will be slighty off. Visually unvisible, but still ...
The new direction is easy, just Reflect the direction around the normal.

Note that normals are pointing outwards, and thus we need to invert the normal vector when computing positions and directions.
4. Full node tree

5. Results
Here is an example of use, followed by the blend file.

6. Additionnal informations
I've included in the blend file another setup. The idea was to delete the current face instead of adding a small margin, and so having a perfectly accurate bounce. Sadly, I wasn't able to make it work.

Thank you for setting up the node and explaining the method!


text:
Emissive gradient sphere
I saw some answers to this question but they do not really work for my need.
I have an ellipsoid. I want the center to have a 100% full strength emission at the center, and gradually increase transparence to be fully transparent at the surface.
All I can manage to render is this but we see the border of the sphere and the center is still transparent.

Thanks for your help !
EDIT : Tried this solution from lutzi but doesn't work as it is supposed to...

Maybe you could add a Fresnel or a Layer weight instead of the gradient texture. And then a color ramp with inverted black and white.

Emission will never prevent light to go through, i.e. no matter how strong the emission, it will still be transparent. Maybe try using a Principle Volume with some density ?

Here is one setup that gives what you are looking for. I'm simply using the distance to the center of the object, remapping it from [0,1] to [1,0], and apply a square function and a multiplier. I'm using a sphere of radius 1. If your sphere has another radius, then you have to change on value as shown below.

I would suggest using a Power node, set to anything above 1. It will help counterbalance the high emission you want and having a smoother decrease. The higher the exponent, the more the emission will decrease when going away from the center. As you can see in my example, an exponent of 2 is already smoothing the outer part of the volume.
Note that the input of the power node should be in the [0,1] range.
I've also drawn a mathematical representation of how an exponent of 2 will affect your input. You'll notice that the area below the curve decreases as the exponent increases. This means the overall emission will be smaller. That's why I'm using a Multiply node at the end.

That seems totally perfect but I triple checked the node config to have the same as yours and I cant have the same rendering. Is it working with cycles ?

I edited my question so you can see the screenshot. Thx

@16ar It is not mentioned in the answer, but I assume Lutzi uses a default sphere which has a radius of 1 m. Your screenshot shows your ellipsoid has the dimensions X = Y = 28.5 mm, Z = 29.5 mm. While the Texture Coordinate > Generated output always maps the coordinates of an object from 0 to 1 matching the object's bounding box, the Object output gives absolute local dimensions. Since your object only has a length of 0.01425 m from the center in X and Y, the Map Range node results in a value of 0.98575 (still almost 1) at the border of your ellipsoid, not 0 to be fully transparent.

So in order to get it transparent on the edges, you should use a From Max value of 0.01425 or slightly less. But this makes a round glow, not an elliptical one. To get an elliptical shape I would use the Generated output, set Location to -500 mm (or -0.5 m) for XYZ in the Mapping node to center the coordinates and then set the From Max value in the Map Range node to 0.5, then it works with an ellipsoid as well (vertical dimension exaggerated compared to yours to show the effect better): ellipsoid glow.

@16ar In my example I'm using Cycles but there shouldn't be much difference with Eevee. Gordon is right about the size of the sphere. I've highlighted in my screenshot where you are supposed to put the radius of your sphere. Also, be sure you Apply Scale if not already 1.

This is excellent thank you to both of you it works perfectly !

You can use the Input > Layer Weight (Facing output) as factor between an Emission and a Transparent node:


text:
Bone animations only work in the viewport and are not displayed in the final render
I'm using Blender Octane Edition version 4.0, which I installed today, and from the moment I installed it I started having this problem. When I animate any object associated with an armature, it's as if nothing happens in the final render, only in the viewport does the animation work. I've attached an example of the scene I'm trying to render, and you can see that everything is working in the viewport, but not in the rendered version. This is happening in every project.
EXAMPLE: Frame range 194-218 is the animation of the box opening. If I put the timeline at frame 218 and click on Render Image, I'll get the correct scene, of the box already open. However, when I set the frame range to 194-218 and click on Render Animation, the animation of the box is not reproduced, it remains closed in all the frames. One observation is that this problem only occurs with the keyframes that are in the bones of the armor, because animations of cameras and other objects work normally in the scene.
Frame 218, box opened:

Frame range 194-218, nothing happens to the box, it stops at the first frame and there is no more movement after that, and the rest of the animation continues:

Hello, please edit your post with screenshots of your problem.

Hi, I've just added the images!

Hello and welcome to BSE. Could you try to make a minimal reproducible example blend file https://blend-exchange.com

problem solved, I just changed the object type to Reshapeable Proxy


text:
Quick smoke not animating the fire and the smoke
I'm trying to generate smoke in Blender using the quick smoke effect but it was not working. What I had done was that I added a plane into my scene, went on 'objects'- 'quick effects'- selected the emitter and changed the flow type to Fire + Smoke and then when I hit play, I see the smoke appear but it is not moving upwards. I'm also wondering how can I make the smoke appear on a specific frame.

A picture of the emitter and the settings.

A picture of the outer box and its settings.

I tried your suggestions, all I got was an extra layer of the same smoke. I'll add my blender file in just in case no one mind checking it for me.

Here is the blender file:

Thanks for your help! Turns out I just needed to bake the domain!.

You can set key frames for the eye and render icon deciding when they are visible and invisible during the scene.
This is the easiest and laziest method
Using the smoke cache alone will not make the smoke disappear the smoke will just freeze.
A better option for a final animation is to set a key frame for the density value in the smoke setting for the flow object

That way you can make the smoke die out on its own if that is what you want by setting a keyframe for the density value to hit zero at a certain frame

I just now realized that this is a post from a long time ago but i found it somewhere around what i thought was the recent posts page so my mistake

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Why am I unable to see AA sample when selected branch path tracing and unable to render animation when select GPU Compute on Mac?
I reinstalled Blender and I'm still unable to see AA sample when I selected Branch Path Tracing.

Also, when I tried rendering it with GPU Compute, it comes out blank. I really need to figure out how to get the AA samples as I tried to render the animation on CPU 5000 render samples and looks the same (Which is blurry).I also tried rendering this animation on my Windows laptop and it took 7 hours to just render a 2 seconds animation which looks blurry.
Here's the link to my Blender file:

I downloaded the newest version of Blender today so surely is the most recent. No, Path tracing is not causing any issues, I deliberately selected branched path tracking so I could reduce the blurriness. For my windows laptop, it is taking unbelievable long 7 hours for 8 frames that it is so blurry is totally crazy. For other youtube videos i seen it only took them no more than half an hour to render. I also increased the sample render to 800 which was recommended by many people to reduce the blurriness, i guess that did not help. Please help, this is my school assignment and it is due soon.

My windows laptop have: NVIDIA GT 520M , 8GB of ram , 64-bit operating system.

Would you mind if i can have you email so i could talk to you further about this problem?

I have a solution to the bluriness. I don't have all the images though (cobblestone and others don't show up), but I have been able to get Steve to be much clearer.

Can you please tell me the solution? I'm begging for help now as this whole animation weighs 98% of my grade.

Typing it up now.

Just sent it. Please do consider my offer at the bottom. You can Automatically Pack Into .blend all image files via the File > External Data > Automatically Pack Into .blend option.

Ok, I'm so sorry.

I cannot help with your GPU because I don't have access to your computer. However, I was able to figure out the bluriness.
Problem
In your scene, one of the first things I noticed was that it was inside an enclosed space. Bluriness in enclosed spaces can often be caused by low lighting.
Solution
I selected the area lamp near the top of the cabin and turned up the Emission Strength to 1000 from 300. I also turned the Max Bounces: to 1024.
I also optimized the .blend file.
I made some adjustments in the Render tab of the Properties panel, namely that I set the Max: and Min: Light Path Bounces to 0 (for faster rendering). I also turned the Filter Glossy: value to 0.7. Additionally, I changed the resolution to just 1920x1080 (1080p; you had it set to 4k which really won't make any difference except causing the rendering to take 4 times as long). Furthermore, I turned the Sampling > Settings: > Clamp Indirect: value to 3.00. I turned the AA render samples to 100. Lastly, I optimized the Tile Size for CPU rendering (Properties panel > Render Tab > Performance Drop Down Menu > Tiles:). If you want it to be optimized for GPU rendering, change each (x/y) from 16 to 256.
On my 8-year-old mac with CPU and not all the image textures, one frame (probably) took a bit under an hour (I didn't wait for it to finish). On my Nvidia 970 4GB STRIX, one frame took just 54 seconds and looked like this:

Final Notes
Here is the fixed up .blend file:

I don't generally offer this (haven't before), but if you can get me a .blend file with all the images included, I will render it for you. 90 frames x 1 min each = about 90 min. --A fellow Blender-using student.

The images were basically from this website: https://github.com/TheDuckCow/MCprep/releases once you download it comes as an addon for blender. You import the addon and select an object in the secene click mcprep mineways and prep materials and everything should be in coloured.

Can you not do what I suggested in the comments? I may be able to follow the link, but I'm pressed for time today.

Oh yes, I want to thank you so much for helping me!. I was wondering whether I could have your email or something so I keep in touch with you.

I'll always answer on the stack exchange app, but there is a thing called chat on BSE. Maybe I'll look into that. P.s. If my answer helped, please consider accepting it (the check mark) and the one on your other question. I will try to follow that link later today to render.

Ok! I want to thank you again for all your help!

You're very welcome.

I'll contact you soon from the chat in BSE. P.S I think ill just need you to find me the best render settings like what you have done today. I'll render the whole animation by myself as because if we keep sharing files it would take forever to download and upload.

Ok. I added a chat called ShadyPuck. You can contact me there. Don't forget to accept, please! Also, that link is for Windows, and I have a mac.

Hi, I downloaded the file you uploaded. I was wondering whether it is possible to reduce the light indoor so it doesn't look like it is day time?

Possibly. But it might be more blurry.

Hi, Shady Puck I'm closing into finishing my animation. I'm wondering whether you could render it for me?

@JeffTeoh If you can get me a .blend with all of the images, caches, and whatever else, then sure (you could share a google drive link).

How would i be able to include all the images into a blender file? Can I just send you my whole folder with all the images?

@JeffTeoh That would be fine.

I just figured how to pack all the textures into a file. So now I'm uploading  the Blender file. Can I give it to you tomorrow?

@JeffTeoh Just let me know when and where.

Would you be able to render it as png? Because I still need to import all of them into Adobe Premie Pro.

@JeffTeoh A sequence of PNGs could take up several GB. I could do it, but it would be very unwieldy.

I'm so sorry for the inconvenience :-(.

I'll give you the blend file around this week. I'm wondering whether you have an email address I could contact you with?

@JeffTeoh Can you not post the link in chat and let me know, or even just comment it?

Well, I tried joining your chat but got no response. If you want I can just post the link here and we can communicate on here.

@JeffTeoh That would be best. I didn't get any notifications from the chat, but I'll accept you later.

This is the link:  https://drive.google.com/open?id=0B6r1cIO-s6iGWU5Tek5rTnM1NUU

If it doesn't work I'll try again. Thanks alot for helping !

Your welcome. I should be able to start it around 4 when I get home.

Let us continue this discussion in chat.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
BGE: unwanted patterns in ground texture from repeated, seamless image
I need to texture a 5km x 5km plane. Repeating the texture produces unwanted pattern, although the texture is seamless.
This issue has been already addressed for Cycles but not for BGE.
Is there any way to solve this in the BGE?

It is the nature of a grid to repeat the same pattern in a recognizable way. What you need is something that breaks the pattern.
Adding variations to the size does not really help as our brain can easily handle different scales.
Changing rotation can help more as long as the rotation is good enough. But this usually breaks the "seamless".
You can add variations by using more than one tile type. When you have 5+ with random order the repetition is much less noticeable.
Another option is to combine different tiles. This means you mix different tiles to confuse our brain. The repetition of the different "layers" should have a different scale. This way you can get easily a large field with just a few texture tiles that does not look repetitive (like dirt on the ground).
These are just a few ideas.

Thank you, I will try. I'm also looking at some BlenderSwap terrain models, but these always include mountains, on the contrary my terrain is pretty flat. It's easier to make things look good when there are mountains all around. Also, do you know of any open project with wide terrains and background that I can look into?


text:
Pixel Coordinates of Image with Python
I need to get Pixel coordinates of an image. Here is explanation:

In the Image Editor, I can see the coordinates in the bottom left corner by clicking on the image. Is it possible to get the coordinates with Python? Solution for this question Pixel Coordinates of Rendered Image with Python doesn't help, because it works only for rendered image and I need this for any image.

Can you elaborate on what your workflow is going to look like. Are you importing external images first?

@ToddMcIntosh yes, I just load image from file system. I am creating a tool that will add and move objects on image. For this I need to get coordinates of mouse pointer on image.

Eeeeeeh… that answer sounds horribly complicated to me!
Assuming you are getting mouse coordinates from event e (from invoke or modal callbacks of an operator), and assuming that operator runs into the main ('WINDOW' type) region of the UVEditor space, something like that should work (code not tested):
region = C.region
reg_x, reg_y = e.mouse_region_x, e.mouse_region_y
img_size = C.space.image.size

uv_x, uv_y = region.view2d.region_to_view(reg_x, reg_y)

img_x, img_y = uv_x * img_size[0], uvèy * img_size[1]


text:
How can I select and remove excess loops from an edge outline using python?
How can I select these vertices in this weird loops encircled in red using python? In this example I only have 5 vertices excess but it's possible for more or lesser vertices to be junctioned like that.

Or any solution for a filled mesh:

How would you characterize such "excess loops" ? Do you have something like "protruding inside/outside" ? Or is it a "path" ?

its just flat on the XY plane. and all edges are connected to the same common vertex. I feared it's probably not possible because it seems there is no way to characterize such excess loop.

It is possible. 100+ lines of code to write and debug. Recursively traversing the mesh using bmesh and link_edges, detect and delete loops that longer than some amount of verts.

yup that's exactly what i thought. i meant not possible in simple terms though haha. thanks alot for your feedback! but maybe its possible with a few lines to check for loops that are smaller than 10 edges. so basically it will check for junction vertices with 4 edges connected to them and then check only up to 10 linked edges which is longer to traverse. shouldnt be too computationally expensive?

Did something alike lately https://gist.github.com/unwave/7d360719853b67d7a1735700a34b2b6e, I think you will still have to make a walker that will check all the vertices.

@unwave i found the solution. So initially this shape had faces which i removed. So before I remove those faces, I just extrude it temporarily then i can do select "Interior" faces and it selects these parts.

Found the solution. Just extrude the mesh and then you can do Select Interior Faces. And then unextrude.
import bpy

obj = bpy.context.active_object
bpy.ops.object.mode_set(mode='OBJECT')
obj.select_set(True)
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={"value":(0, 0, 0.01)})
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.mesh.select_interior_faces()
bpy.ops.mesh.delete(type='FACE')
bpy.ops.object.mode_set(mode='OBJECT')

mesh = obj.data
for face in mesh.polygons:
    normal = obj.matrix_world @ face.normal
    if normal.z > 0:
        face.select = True
        break

bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_similar(type='FACE_NORMAL', threshold=0.01)
bpy.ops.mesh.delete(type='VERT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.normals_make_consistent(inside=True)


text:
How can I remove a point of junction and reconnect 2 meshes via python?
I have a set of problematic meshes that have junction vertices (those with 4 edges). And I have to remove these via python and connect those vertices marked in green. Is this possible?

Basically I would like to make sure the parts are all connected as "manifold" 2D mesh.

I can select these vertices linked to 4 edges like this
import bpy
import bmesh

obj = bpy.context.active_object
mesh = obj.data

bpy.ops.object.mode_set(mode='EDIT')

bm = bmesh.from_edit_mesh(mesh)
bm.edges.ensure_lookup_table()
bm.verts.ensure_lookup_table()

bpy.ops.mesh.select_all(action='DESELECT')

for vert in bm.verts:
    if len(vert.link_edges) == 4:
        vert.select = True

bmesh.update_edit_mesh(mesh)

But I don't know how I can "dissolve" this vertex and reconnect the mesh with those green lines.
Here's a sample mesh with several intersections:

is this limited to 2d meshes?

@jupiterbjy yes only 2d meshes

Angle based method

There is a n-panel button you can test it.

import bpy, bmesh
from bpy.props import *

from collections import defaultdict
from math import asin, pi

# return a bm vert and shared amount that have largest shared amount
def get_common_vert(edges):
    d = defaultdict(list)
    for e in edges:
        d[e.verts[0]].append(None)
        d[e.verts[1]].append(None)

    k = max(d, key=lambda x: len(d[x]))
    return k, len(d[k])

def get_angle(v0, v_center, v1):
    vec1 = (v0.co - v_center.co).normalized()
    vec2 = (v1.co - v_center.co).normalized()
    if vec1.dot(vec2) >= 0.0:
        return 2.0 * asin((vec1 - vec2).length / 2.0)
    return pi - 2.0 * asin((vec1 + vec2).length / 2.0)

class ModalOperator(bpy.types.Operator):
    bl_idname = "wm.modal_operator"
    bl_label = "Simple Modal Operator"
    bl_options = {'REGISTER', 'UNDO'}

    is_even : BoolProperty(name="Even", default=False)

    def warn(self, s):
        self.report({"WARNING"}, s)
        return {'CANCELLED'}

    def execute(self, context):
        if context.area.type != "VIEW_3D": return self.warn("Requires 3D Viewport")
        if not context.object: return self.warn("Active object not find")
        if context.object.mode != "EDIT": return self.warn("Requires Edit Mode")
        if not hasattr(context.object, "type") or context.object.type != "MESH": return self.warn("Mesh not found")

        bm = bmesh.from_edit_mesh(context.object.data)
        selected_edges = [e for e in bm.edges if e.select]
        if not selected_edges: return self.warn("No edge selected")

        vert, amount = get_common_vert(selected_edges)
        if amount != 4: return self.warn("Largest shared vertex must equal to 4.")

        # find 2 pair edge (Angle based)
        e1, e2, e3, e0 = vert.link_edges
        if self.is_even:
            e1, e3 = e3, e1

        e0_e1_angle = get_angle(*[e for e in e0.verts if e is not vert], vert, *[e for e in e1.verts if e is not vert])
        e0_e2_angle = get_angle(*[e for e in e0.verts if e is not vert], vert, *[e for e in e2.verts if e is not vert])

        if e0_e1_angle > e0_e2_angle:
            v0, = [e for e in e0.verts if e is not vert]
            v1, = [e for e in e2.verts if e is not vert]
            v2, = [e for e in e1.verts if e is not vert]
            v3, = [e for e in e3.verts if e is not vert]
        else:
            v0, = [e for e in e0.verts if e is not vert]
            v1, = [e for e in e1.verts if e is not vert]
            v2, = [e for e in e2.verts if e is not vert]
            v3, = [e for e in e3.verts if e is not vert]

        bm.verts.remove(vert)
        bm.edges.new((v0, v1))
        bm.edges.new((v2, v3))
        bmesh.update_edit_mesh(context.object.data)
        bm.free()

        return {'FINISHED'}

class MY_PT_Panel(bpy.types.Panel):
    bl_label = "My Tool"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "My Tools"

    def draw(self, context):
        self.layout.operator(ModalOperator.bl_idname, text=ModalOperator.bl_label)

def register():
    bpy.utils.register_class(ModalOperator)
    bpy.utils.register_class(MY_PT_Panel)

def unregister():
    bpy.utils.unregister_class(ModalOperator)
    bpy.utils.unregister_class(MY_PT_Panel)

if __name__ == "__main__":
    register()

I didn't know one could add their own panel, cool! I'm learning new things everyday here.

Hi XY thank you for your answer. You almost got it but not so quite. I need the other vertices to be connected like here in your result with the expected result if that can hopefully clarify the problem. I also updated the question with a screenshot to make it more clear and added a sample mesh blend file.

hey it works now exactly how i want by changing using this line e1, e2, e3, e0 = vert.link_edges thank you so much! so what i will do is basically just select 1 intersection at a time and execute this script.

Assuming that you're doing 2D, verts with no intersections other than that junction, this might cut it.

import bpy
import bmesh
import itertools

obj = bpy.context.active_object
mesh = obj.data

bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_mode(type="VERT")

bm = bmesh.from_edit_mesh(mesh)
bm.edges.ensure_lookup_table()
bm.verts.ensure_lookup_table()

bpy.ops.mesh.select_all(action='DESELECT')

def get_middle_pos(*vs):
    """Get middle position List[float, float, float] from given verts"""
    return [
        sum(v.co[idx] for v in vs) / len(vs)
        for idx in range(3)
    ]

def is_close(pos1, pos2, margin=0.05):
    """Returns true if Root Mean Squared error between position is < margin"""
    return sum(
        ((pos1[idx] - pos2[idx]) ** 2) ** 0.5
        for idx in range(3)
    ) < 0.05

# find junction vert
junction_vert = None

for vert in bm.verts:
    if len(vert.link_edges) == 4:
        junction_vert = vert
        break

# fetch adjacent 4
adjacent_verts = [
    e.other_vert(junction_vert) for e in junction_vert.link_edges
]

# connect combinations of each pair where pair's mean position isn't close to center
new_edges = [
    bm.edges.new((vert_a, vert_b))
    for vert_a, vert_b in itertools.combinations(adjacent_verts, 2)
    if not is_close(
        get_middle_pos(vert_a, vert_b),
        junction_vert.co
    )
]

# remove junction vert
bm.verts.remove(junction_vert)

# select one from adjacents, as we know at least those will be at edge loop
adjacent_verts[0].select = True

# select edge loop
bpy.ops.mesh.select_linked(delimit={'SEAM'})
bpy.ops.mesh.select_mode(type="EDGE")

# create face from selection & switch to face mode
bpy.ops.mesh.edge_face_add()
bpy.ops.mesh.select_mode(type="FACE")

# do limited resolve to remove inner edges and delete face.
bpy.ops.mesh.dissolve_limited()
bpy.ops.mesh.delete(type='ONLY_FACE')

# go back to object mode
bpy.ops.object.mode_set(mode='OBJECT')

Since it's 03:26AM right now expect long delay on feedback(if needed) until I return from workplace!

Hello thank you for your answer. Although this solution may work for the simple mesh you have demonstrated with, it generally doesn't work for other meshes. you can try with the sample blend file i attached. also i updated the question with the expected result.

@MeganLove now I see the whole picture, welp guess I'll delete mine later, now it no longer fit the question and might get downvoted eventually for those who doesn't know. btw It almost seems like you're using pixelated noise map and trying to create low poly continents! Mind if I ask what that actually is?


text:
Streamlining Video Editing: Using Grease Pencil Directly on VSE Footage
Is it possible to use Grease Pencil directly on top of footage edited in the Video Sequence Editor (VSE)? Currently, my workflow involves editing the video in VSE, rendering it as a final MP4, and then re-importing it using Add > Image > Mesh Plane. I use Grease Pencil on top of this footage and render the MP4 again. However, this process results in a second rendering step, which reduces the overall video quality.
I’m wondering if it’s possible to combine video editing in the VSE with Grease Pencil annotations in a single workflow, allowing me to render the final MP4 directly in one step, without any loss of quality. Or is there a better workflow I didn't realize exists?

I have seen this thread but take note the answer provided does not cater for a VSE that has several edits and several other clips in it. I need something that completely displays the entire VSE video output in the 2D view as reference to draw on.
Would be cool if there was something like Camera > Data Properties > Background Images > Add Active VSE and then you could see a reference video of the VSE through the camera to draw on.

as far as quality goes, you don't have to render your grease pencil with an already compressed video. you could have the video disabled in render (or use image empties instead of mesh planes, which aren't renderable), and append your grease pencil scene to the VSE where you have your original video editing.

@Lauloque true I could do that. But still I'm looking for a way to put grease pencil on VSE. Or somewhat have the currently-edited-VSE show up as the reference in 3D view. It seems what I'm asking for in the original question is not doable as single workflow? Since I still have to render out the final edited VSE video (for the reference video) and then import it as reference in 2D animation. And then render out the GP without video and then import it on top of the currently-edited-VSE video and render the final video with GP on top. But now it's 3 render steps. Even worse?

@Lauloque I suggested a new feature on right click select https://blender.community/c/rightclickselect/YVyM/ what do you think?

You can use this add-on to get the VSE output as background in the camera in the 3D View:
https://github.com/tin2tin/vse_to_camera_background

Hi, thanks for the post. This site is not a regular forum, answers should be substantial, stand on their own, and thoroughly explain the solution and required steps. One liners and short tips rarely make for a good answer. If you can, [edit] your post and provide some more details about the procedure and how it works, perhaps add a few images illustrating some steps and final result. See How to write a good answer?, otherwise it may be converted to a comment.

wow exactly what I was looking for thank you so much for sharing!! just a side note, would be also cool if it worked in 2D animation workspace. Currently the VSE only shows up in the 3D View but not in the 2D animation's 3D view.

What would then be the workflow to render this footage with the GP stuff? Maybe would be cool to detail that in the answer on the usage of the addon and then how to render the footage with GP workflow?

I'm sorry. I do not have any more time to invest in trying to do a workaround for this unexisting Blender feature. If anyone wants to build on this script-solution, they're welcome.

hey don't worry thank you so much for sharing! i will just duplicate the VSE scene and then slap the GP scene on top of that to avoid recursion :)


text:
Blender 3: boolean modifier works no more on object instance
I have a test case taken from another model:

white_mesh is a digitized mesh, it works properly with booleans;

white_mesh_scaled is an empty mesh unioned with white_mesh; it works properly with booleans if a fast modifier is used (looks like a bug in exact if one of the arguments is empty, but it is not the subject of this question);

black_mesh uses Instance on Points in order to copy and move white_mesh_scaled.

Here is the problem: Point instance has been obsoleted in Blender 3. Because black_mesh did not work properly with booleans in Blender 3 (it did work in Blender 2.93), I replaced the obsoleted node with the new Instance on Points in a hope of fixing that:

The resulting mesh black_mesh looks ok but it also does not work with some booleans anymore. In particular, its modifier Difference with black_cut_side does not change anything.
Of course, the problem may be outside of geometry nodes, because Blender's version changed. Anyway, how to correct for that?

Add Realize Instances node before Output ...

... you can also use Mesh Boolean node instead of modifier.


text:
Why this simple polygon-to-star does not work in a particular document
I am trying to repeat this: https://www.youtube.com/watch?v=-1RPYlTl_uI&t=45s
In a certain document, the "s for scale" does nothing in case of a polygon:

In case of a cylinder, it shortens the edges instead of moving them to the center. Can it be, there is some switch on in this document, which prevents the scaling?

Because you have the "individual origins" set as transform pivot point.
Change it to "median point"


text:
A modifier which unions all input meshes in the stream
Meshes may overlap if, for example, a modifier like Array produces overlapping elements or if an object consists simply of several meshes. The middle-row object is an example:

It looks identical to the object in the bottom row, where the two funnels have been merged with Union. However, the middle object gives problems to succeeding boolean operations, while the bottom one does not do that necessarily.
I can use the modfier Union Self intersection but that turns out to not always help, and also can be very slow up to making Blender unresponsive for a large number of polygons (reaction times of minutes).
There is also the modifier Remesh (example in the top row), but it produces a lot of triangles (again, performance problems with booleans) and decreases quality at the same time.
Any way of cleaning up such overlapping meshes, as in removing their internal walls?

There isn't general or all-in-one approach, if you search that powerful  Booleans and non-destructive workflow CAD apps would be more appropriate. For Blender, all the principles already settled down still apply: no overlapping faces with no shared vertices, no faces in the same place (z-fighting), no double verts, no flipped normals, enclosed / watertight mesh. For some cases with doubles / overlaps after Array Weld modifier can help. For others Remesh, then Decimate. For yet other ones, maybe another approach to model. Maybe show screenshots and file, it's too broad now.

I rephrased the question and gave an example. I guess that a trivial modifier which joins all the meshes in the modifier pipe (?)  using Union would do exactly what I asked for.


text:
Make the pipe end follow an arc
I would like the end of the pipe to form an approximate 270deg arc, as sketched, rather that the parabola as it is now:

I have no idea, which deform to use.
It is going to be dust-vacuuming pipe, the dust source a bit below the centre of the blue arc. As of the final shape, it is not precisely determined as far as it works well. In any case, the object should be bounded with two parallel planes from the top and from the bottom, as it is now, and the blue sketch lies on the bottom plane.
The pipe's profile should change, from top to bottom, somewhat like that:

Model source:

do you have a picture of the final object you want?

@moonboots I don't, there is some arbitrariness, but I added a more precise description of what I want to the question.

maybe show some pictures, it's hard to interpolate what a 2D curve could give in 3D. Also, do you have any reason to use a Mesh Deform modifier?

@moonboots no, in fact the Mesh Deform gave me a parabola which I do not want. I added an image with a series of desired profiles of the pipe.

@moonboots no, it should be a pipe similar to what is now, but its bottom exit should surround more a vertical axis, not a horizontal one.

too hard to visualise but maybe someone will understand  ;)

Whichever shape you want the nozzle, it's probably better to loft it than to deform it. Make a series of profiles with the same number of vertices, use 'Bridge Edge Loops', adjusting its options, (Number of cuts, Profile, Smoothness, etc)...

... and then you can use modifiers to Solidify, Bevel, and Subdivide the geometry.


text:
How to get the brush pack for Grease Pencil Tools on Blender 4.3?
Using this YouTube tutorial in Blender 4.2 I am able to use this cool grass brush from the extension Grease Pencil Tools. But in Blender 4.3 I cannot find the option Download and import texture brush pack under Active Tool and Workspace settings.

How do I do I get these brushes for Blender 4.3? In Blender 4.2 it is this red-boxed option which is not available in 4.3.

@JohnEason Thank you. I took a look at this YT video, and yes, you can append the brushes and then mark them as assets, but when you use them, they are only black—the colors are gone. This method is just a workaround, though. There should be a way to install the brushes properly through the addon.

Fair enough. There's a section about the 4.3 Sculpt, Paint and Texture brushes on the Developer web site here. I've not read it but there might be something there to help.

It appears to me that what you want is a detailed answer instead of a brief one.  So, let's make a thorough answer for completeness.
As of Blender 4.3, the entire brush system was replaced by the Asset Library to streamline the customization process. That means all brushes and custom brushes can be converted into assets and automatically be used in any blender file. The creator of the Add-on that was included in your question has also noticed this and has thus notified us of discontinuing the import function. So, there is no way to import new brushes through his add-on.

What John Eason has given you is not a work around, but the official method to convert old textured brushes into assets for Blender 4.3. This method was officially recognized by the developers of blender in the following link.
https://developer.blender.org/docs/release_notes/4.3/sculpt/#blender-43-sculpt-paint-texture
To keep things brief, I'll omit the asset library details. If you're having trouble adjusting to the asset library, then you can search this site (BSE) for questions relating to the asset-browser or any other asset related tag. Likewise, you can also check the Manual to learn how to use the asset library.
That being said, for my demonstration, I'll use Daniel's original file in Blender 4.3 instead appending the textured brushes from an old file. This is the link to Daniel's brush pack.
https://cloud.blender.org/p/gallery/5f235cc297f8815e74ffb90b
In the Outliner, change the Display Mode from View Layer to Blender File.

Find the brush(es) that you want to make into assets and right click to Mark as Asset.

For me, I organized the brush assets into a catalog which I made visible in the asset shelf as well. Now save the file in your asset library folder.

When you start any new project, the brushes should be available for use.

As a final note, I noticed that Daniel created this brush pack during Blender's 2.9 series. If I recall correctly, this was also during the time when Blender introduced a feature called vertex colors with color palettes which Daniel seemed to have incorporated into his textured brushes. So, switch from Material to Color Attribute to see if you can fully utilize Daniel's brushes.


text:
GN: How to replace the Points to Volume node in place of Mesh to Volume?
I have this voxelizer modifier setup which works for the rotated cube nicely as shown but I have to lower the version to Blender 3.2 so I cannot use Mesh to Volume node. Is Points to Volume the only alternative? When I use Points to Volume it requires me to input a Radius but putting radius will give this weird billowing cube. And setting it to zero will make the object disappear. How do I solve this?

UPDATE: I realized as @Gordon Brinkmann has mentioned, this may indeed not be possible to do a one is to one conversion for this node. I will have to completely change the approach without using Mesh to Volume node.

I'm no expert in these things, so I cannot give a real answer... I can only imagine that it might not be possible to completely convert everything to an older version of Blender, because some things only have changed in how they could be done with different nodes, but sometimes new features have been added that simply were not possible before. Which means there is no "translation" from new nodes to old nodes.

The  mesh to volume is filling the source object (cube shape) with points so it gives you a box shape full of points but the Points to volume is just giving you the original 26 points of your cube, which you scale up to try and fill the cube shape.

@GordonBrinkmann yes i understand this limitation but i was hoping that perhaps there is a feasible solution i have not thought about.

A possible way is to use distribute points on faces with a density that ensure there is (most likely) no hole.
There will be some inner geometry and some non manifold parts (if you merge at the end), but that could do it:

Distribute points on faces using voxel size input as density factor multiplied by (say) 10.
Round the positions considering also the wanted voxel size.
Merge the points.
Instanciate and, eventually, realize and merge.
 (Blender 3.2)

You need to fill your cube with more points to simulate the mesh to volume function. Subdivide the source then shrink the point size.

I've added a scale point size function to fill the object and limit the number of subdivisions

Hello thank you for your post. This will leave holes when you change the voxel size. Hmm also this is pretty heavy processing. So I guess there is no other way especially with the subdivide modifier which by level 5 could be pretty heavy for bigger models?

I expect that the mesh to volume node is generating the same number of points so should be equally heavy? Perhaps deleting a parts (edges/faces) after subd would help?

Not sure how to fill the envelope without recursion of some kind

I tried points to volume>distribute points in volume>points to verts>points to volume> But it doesnt work :(

Any particular reason why you are using Blender 3.2 instead of 3.6.8 which is the current LTS version 3?

because some users are still on lower versions.

Hi @3pointedit thanks for the update. Unfortunately this approach will not work consistently due to the magic numbers like 6.7 etc which still can cause holes depending how big you will scale and apply the scale. And that is only tested on a cube. More organic models will be even more problematic. As Gordon has mentioned in the comments in my question, there is no one to one conversion. I was assuming I could just replace the node but in reality my entire setup needs to be changed to allow voxelizing. But I appreciate the time and effort :)

Yes that's totally fair


text:
How to make popup auto adjust width?
I want my popups to be wider to fit the label but it seems it is limited to this width as shown with a label with ellipsis. How do I make it wider? I tried col.label(text=self.message, width=1000) but width does not work. What am I missing? Or is it possible to auto adjust like width=auto?

Here's this simple working popup class but with limited constant width.
import bpy
import bpy_types

class MyPopup(bpy.types.Operator):
    bl_idname = "wm.my_generic_popup"
    bl_label = "my message box"
    bl_description = "generic popup"
    bl_options = {'INTERNAL'}

    message: bpy.props.StringProperty(name="Message", default="")

    @classmethod
    def poll(cls, context: bpy_types.Context) -> bool:
        return True

    def invoke(self, context: bpy_types.Context, _: bpy.types.Event) -> set[str]:
        return context.window_manager.invoke_props_dialog(self)

    def draw(self, _: bpy_types.Context) -> None:
        layout: bpy.types.UILayout = self.layout
        col: bpy.types.UILayout = layout.column()
        col.label(text=self.message) #, width=1000) # DOES NOT WORK WITH width="1000"

    def execute(self, _: bpy_types.Context) -> set[str]:
        print("OK CLICKED")
        return {'FINISHED'}

def register() -> None:
    bpy.utils.register_class(MyPopup)

def unregister() -> None:
    bpy.utils.unregister_class(MyPopup)

def create_generic_popup(message: str) -> None:
    bpy.ops.wm.my_generic_popup('INVOKE_DEFAULT', message=message)

register()
create_generic_popup("Why is this very verry verrry verrrrry looooong text capped?")

use the width property of invoke_props_dialog()
context.window_manager.invoke_props_dialog(self, width=1000)
import bpy
import bpy_types

class MyPopup(bpy.types.Operator):
    bl_idname = "wm.my_generic_popup"
    bl_label = "my message box"
    bl_description = "generic popup"
    bl_options = {'INTERNAL'}

    message: bpy.props.StringProperty(name="Message", default="")

    @classmethod
    def poll(cls, context: bpy_types.Context) -> bool:
        return True

    def invoke(self, context: bpy_types.Context, _: bpy.types.Event) -> set[str]:
        return context.window_manager.invoke_props_dialog(self, width=1000)

    def draw(self, _: bpy_types.Context) -> None:
        layout: bpy.types.UILayout = self.layout
        col: bpy.types.UILayout = layout.column()
        col.label(text=self.message) #, width=1000) # DOES NOT WORK WITH width="1000"

    def execute(self, _: bpy_types.Context) -> set[str]:
        print("OK CLICKED")
        return {'FINISHED'}

def register() -> None:
    bpy.utils.register_class(MyPopup)

def unregister() -> None:
    bpy.utils.unregister_class(MyPopup)

def create_generic_popup(message: str) -> None:
    bpy.ops.wm.my_generic_popup('INVOKE_DEFAULT', message=message)

register()
create_generic_popup("Why is this very verry verrry verrrrry looooong text capped?")

Hi thank you very much for your answer! Is there also a way to auto adjust it depending on the text? Or only hard-coded?

There is no such thing builtin. However you can work out a proportional relationship with a few tests (eg. a character takes roughly 20 pixels so if you have 20 characters you need at least 400 width or something like that). Note this will still be very weak and break if users use a different UI scale or a different alphabet I guess.

@Gorgious yes exactly what I'm currently experimenting now haha thank you for confirming this limitation :)


text:
Blender Internal. Edge post processing showing as see though
I've been having an issue with a few models I've been working on that include the edge post processing option turned on.

For some reason some edges can be seen through certain polys.
As you can see on the head of this model you can see the edging that is suppose to be on the other side. I've tried inverting the faces, deleting the faces and re-creating them but it doesn't seem to work. Is there any other option anyone knows besides re-creating that entire section of the mesh?
Thank you!

Sorry I should have clarified. I added a picture in the original post showing what setting I'm using.

Yeah, just added it to the post. Thanks for your help!

Holy cow, thank you so much!! I'm not sure how those got turned on but thank you for pointing that out. You're the best!


text:
Problem rigging with automatic weights and shape keys for Unity
Greetings nice community! I'm having problems rigging my character (a simple panda), probably because it's the first time I actually try to rig something.
Anyway I got to the point where I made the rig using Mixamo, did a separate rig for the eyes and set up shape keys for the mouth and the blink animation. I want to use the animations from mixamo in my Unity project and I was hoping I can keep the eyes rig separate so the animations would have no problem working with that mesh, but the eyes rig doesn't work in Unity for some reason.
I tried clearing the auto weights and joining the rigs together and then parenting the whole model to the combined rig,but got wicked mesh deforms.
My questions is what is the right path to follow from the point that I reached and what I'm doing wrong? Should I make bones for the shape keys first? Should I even join the separate rigs into one? And I also tried using preserve volume in the modifiers tab but the animations work perfect only in Blender - when I get them to unity I get slight but noticeable mesh deforms.
I'm uploading a cleaned version of my .blend file with the modifiers not applied and the rigs not parented hoping someone would show me the right way. Thanks in advance!

Have you tried using a Driver for that?

Add a bone to your armature that will be your Driver, it works
similar to an IK bone, as in, it doesn't affect the mesh directly.
Select the shapekey you want to add the driver to, click with the
right mouse button on the bar below and select Add Driver, it shall
turn purple.
Then on the Graph editor window, where it says F-Curve, change it to
Drivers. Click on "Key", there you can select each shapekey that will
be controlled by the Driver.
Expand the right panel, there you can select the bone that will
control the shapekey, a.k.a. the Driver.
One detail though, On the right panel where it says Type, change it
to Average Value, then moving the bone will change the values on the
shapekey.

There rest is up to your preferences.
Hope it helped.


text:
Shatter object with rigidbody physics with constraints (cell fracture)
I'm having this problem with shattering my object following this quick tips video of Gleb Alexandrov:
https://www.youtube.com/watch?v=wJFE2pb0Ri4
I am trying to achieve the 3rd effect.
So I set a particle system and used the cell fracture addon, but my object pieces look kind of different from my original object, and they are moved to the next layer in my blender file. Could someone please tell me what I'm doing wrong? I can't seem to finish the animation.
Here is my blend file:

Well, it looks like your numerous WALL.002_cell.* elements are out of position, and have no physics elements to them.  How did they go from being pieces of a wall to being scattered rubble?  Existing in the next layer is perfectly normal for the cell fracture addon (it helps you work with them without tripping over all the other objects in the scene)

Yes,the elements are completely out of position. I tried applying the object rotation and scale before using the cell fracture add-on and still got the same result.


text:
Python api - Rotate selected around vertex using bpy operator
I want to rotate a selected item around a specific vertex like this:
 vertex.select=true
 bpy.ops.transform.rotate(value=1)

This code basically rotates at the bounding box center.
I have tried setting the pivot point cursor and manually setting the cursor but this does not work.
bpy.context.scene.tool_settings.transform_pivot_point = 'CURSOR'
bpy.context.scene.cursor.location = (1,1,1)

bpy.ops.transform.rotate(value=1)

The result is still a rotation with axis at the objects center point.
I'm looking for a simple, scripting level solution to this problem.

The bpy.ops.transform.rotate() rotates on the object's origin.
You can  do bpy.ops.transform.rotate(value=yourValue,center_override=(x,y,z)) where x, y and z are the x, y and z of the vertex.
Basically the center_override overrides the rotation pivot position.

Amazing! I can't believe I missed that!


text:
Find opposite angle range in radians
Building on this question  here
I have the range, in radians, of an angle formed by three points on a 2d plane and need to find the opposite range as shown here as range2:

The function I am using (from the previous question) looks like this
    def anglexy(self, a, b):
        vec0 = Vector((1,0,0))
        vecQ = Vector(    (b[0]-a[0], 0, b[1]-a[1])    )

        rad =  vec0.angle(vecQ)

        return rad

It's called like this:
    a1 = self.anglexy(v3,v2)
    a2 = self.anglexy(v3,v1)

To be clear, when I say 'range' I mean that I can use any radian value between a1 and a2 as a rotation value with bpy.ops.transform.rotate(value=a, center_override=v3) and it will place vertices on the range1 or range2 curves.

Have a look at https://blender.stackexchange.com/a/203355/15543

@batFINGER The edgeangle function used in that answer is far beyond my math ability -- likely because the question is much more complicate. The if branch with the negate() call makes it look like he's using the whole circle then omitting the results in the acute range?

Think of it like walking around a table with left hand on surface. The table's up is face normal, our up (or the corner's up going thru v3 in question) is axis.  A certain condition flipped axis, making us upside down, the test and negate fixed this. The main gist is need some reference to get the angle into 2d and hence get a signed value.

If the whole circle is 360 or -pi, pi in radians, shouldn't you be able to just subtract the first angle from 360 and then project that distance from v2 to v1 instead of v1 to v2?

I've been tryin to do this and it works sometimes but there are so many corner cases. I don't really understand blender's angle system very well thought there might be an easier way built in.

@batFINGER theses vertices are already aligned on a 2d plane -- mentioned in the question I referenced but I added an edit

If these are 2d vectors Look at angle_signed then.

Revisit Previous question
Python: Calculate angle between vertices
The answer: Interior Face Angles
Think of it like walking around a table with left hand on surface. The table's up is face normal, our up (or the corner's up going thru v3 in question) is axis. A certain condition flipped axis, making us upside down, the test and negate fixed this. The main gist is need some reference to get the angle into 2d and hence get a signed value.
The verts are ordered the choice is which side of the line of verts is the table top (or face).  We need some reference ie since the projection is onto Y plane would use Y or -Y axis as a proxy for face normal (in front view -Y is coming at us).
In the other question, if edges are made from the verts in x order, if the area below is a "face" with normal pointing at us (front view) then we are going clockwise, if above counter clockwise around the face.
Signed angle of 2D vectors.
Simple example, 2 points (p1, p2) and an origin point o  If the 2d vectors represent the xy plane, the origin in middle,  then this is y axis (12 o'clock) to (1, 1) (half past one).  Travelling clockwise it's 45 degrees, counter clockwise 315
import bpy
from mathutils import Vector
from math import degrees, pi

context = bpy.context

o = Vector((0, 0))
p1 = Vector((0, 1))
p2 = Vector((1, 1))
#p1, p2 = p2, p1 # flipped
v1 = p1 - o
v2 = p2 - o

# if in z=0 plane this is axis of rotation
axis = v1.to_3d().cross(v2.to_3d())

a1 = v1.angle_signed(v2)

if a1 <= 0:
    a2 = 2 * pi + a1
else:
    a2 = a1 - 2 * pi

print(degrees(a1), degrees(a2))

# Results
#45.00000125223908 -314.9999987477609
#-45.00000125223908 314.9999987477609 flipped

So to re-iterate need to know what direction to go in. Assuming clockwise then return positive result above, p1 -> p2 is 45 degs, p2 -> p1 is 315.

but the range values do not work and I can't explain why. uniform(a1,
a2) in a loop produces a complete circle

The angles are how far to rotate from p1 to get to p2 either the short way or the long way. Adding them together (range) is effectively adding questions two ranges together.

The only thing I can think of is that v1, v2, v3 positions, relative
to one another, are variable and can occur in different orders.

Yes. It is clear in face edge angle answer link that the order is known. In this case it is not.
To get to p2 from p1 either rotate relative to p1 range (0, a1) or (0, a2)
3D Vectors
Can calculate the rotation difference between two vectors as a quaternion, ie how much to rotate vector to get to match alignment of other vector.
import bpy
from mathutils import Vector
from math import degrees, pi

context = bpy.context

o = Vector((1, 1, 1))

p1 = Vector((2, 3, 4))
p2 = Vector((5, 1, 5))

v1 = p1 - o
v2 = p2 - o

# to rotate v1 to v2

axis, angle = v1.rotation_difference(v2).to_axis_angle()

print(axis, degrees(angle))

if angle <= 0:
    angle2 = 2 * pi + angle
else:
    angle2 = angle - 2 * pi

print(degrees(angle2))

output
<Vector (0.5774, 0.5774, -0.5774)> 40.89339099490394
-319.10660900509606

Rotate about a pivot point
Recommend look at answer here https://blender.stackexchange.com/a/194802/15543 re making a matrix to rotate about a pivot point.
The example above gives us the angle and axis required to make the rotation matrix R
R = Matrix.Rotation(angle, 4, axis)

the direction of this rotation is determined by the sign of angle and the way the axis is pointing.

This all looks like it should be correct -- but the range values do not work and I can't explain why. uniform(a1, a2) in a loop produces a complete circle

The only thing I can think of is that v1, v2, v3 positions, relative to one another, are variable and can occur in different orders. For this reason, perhaps the directions calculations are being thrown off?

The issue I'm trying to go from the start of a1 to a2 -- not from 0 to a1 or zero to a2. I am trying to find all the points on the blue curve in the drawing.

I was using a similar math.pi*2 to get there but my errors were probably in direction and the signed function should solve that. I will eventually need to do this in 3d possibly but I will deal with that another time


text:
Rendering applies weird squares over my model
When I do the final render its all good until 99% and when it reaches 100% then it shows out of nowhere this random square.
How can i fix this? this square doen't exist in my collection. also i have tried CPU and GPU and same problem with booth of them.
UPDATE; i moved my camera away and this happened![
]1

Check for; - Render layers - Hidden objects (that still have the render flag turned on - Animation key frames (in case it's only there on one frame of a series)

nothing wrong with these

Can you post your file?

it says too large more tahn 2Mb

Google drive, or similar?

give me your email ill share with google drive

You should be able to post the link here.

https://drive.google.com/open?id=1Sd-EmmRmA1HseeKzuaB-vbJH0-Gel47n

You have this in your compositor;

It's showing up at the end because it's the last thing to be rendered and composited in.

soo what do i need to do ?

i removed it and it went all black after the final render

can ufix it and send me the drive link so i can see what you changed soo i know what i did wrong?

oh man thanks. i had the FAC full at the alfa over and i changed it to 0 and now it all good. i realy than kyou for your time mate. have a good one

@Phill Hello :). If the answer helped you, please mark it as accepted ✓ :). Thanks.


text:
Airtight seal in blender animation
I want to model a rigid bowl with a diaphragm over the top of the bowl.
I want an airtight seal between the two.
I want to be able to animate changing the pressure inside so that the diaphragm rises and falls with the pressure change.
The two things I'm having trouble with are:

An airtight seal between the bowl and the diaphragm.
Animating pressure changes.

Here's an example of how far I've gotten.
If you run the animation the diaphragm will drop onto the bowl and deform nicely.
I just want to know how to go about attaching the cloth to the bowl with an airtight seal so I can pressurise the inside.
bowl_and_diaphragm.blend
Any tips on where to look?
Many thanks.

Sorry Graham but you want to many things at once! Better split it in multiple questions that can be then applied to different problems. Also, may be provide info on what you've tried so far, screenshots etc., that will help you get better answers.

Looks like the new cloth physics pressure setting might have what you need

@Bruno, thanks for that. I hope the edits clarifies things.

@DuarteFarrajotaRamos, thanks, yes, I'd got that far.


text:
How to add click event listener to button operator?
How do you add a listener to a button? I need to handle something in the panel once a button is clicked but I don't know how to add this click event listener.
import bpy
class SimplePanel(bpy.types.Panel):

    def on_button_click(self, context):
        print("button clicked")

    def draw(self, context):
        layout = self.layout
        row = layout.row()
        op = row.operator("object.simple_operator")
        op.add_click_listener(on_button_click) #FIXME

If I add a callback setter function in my operator like
def set_exec_callback(self, callback):
   self.exec_callback = callback

and then do:
op.set_exec_callback(on_click)

It mistakenly tells me that

AttributeError: 'OBJECT_OT_my_operator' object has no attribute
'set_exec_callback'

even though it is clearly defined in my operator
Here's a script that reproduces the bug:
import bpy

class SimpleOperator(bpy.types.Operator):
    bl_idname = "object.simple_operator"
    bl_label = "Simple Operator"

    def __init__(self):
        self.callback = None

    def set_callback(self, callback):
        self.callback = callback

    def execute(self, context):
        self.callback()
        return {'FINISHED'}

def my_callback():
    print("Callback function called")

class TestPanel(bpy.types.Panel):
    bl_label = "Test Panel"
    bl_idname = "PT_TestPanel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Test'

    def draw(self, context):
        layout = self.layout
        op = layout.operator(SimpleOperator.bl_idname, text="Execute Simple Operator")
        op.set_callback(my_callback) # AttributeError: 'OBJECT_OT_simple_operator' object has no attribute 'set_callback'

def register():
    bpy.utils.register_class(SimpleOperator)
    bpy.utils.register_class(TestPanel)

def unregister():
    bpy.utils.unregister_class(SimpleOperator)
    bpy.utils.unregister_class(TestPanel)

# Test the panel
if __name__ == "__main__":
    register()

I found a hacky way to solve my problem but I'm sure that's not the right answer as it causes namespace pollution and is sort of spaghetti coding. I just define the following in my panel file:
bpy.types.Scene.on_button_click = on_button_click

and then call context.scene.on_button_click(context) in the operator class file's execute function.
Crappy solution but it does what I need it to do.

The API abstracts some stuff from what you actually code in python, so the actual operator construct that is executed is not the class you define in python. You need to serialize your properties using Blender's serialization system if you want it to work. Unfortunately I think in your case since you can't serialize a function, that means storing your callback as a string and exec'ing it.
That opens up a whole can of worms of vulnerabilities though, so make sure you know what you're doing if you use this solution. I'm sure there is other solutions to your problem, like storing a variable on a data block like you did in your answer.
import bpy

class SimpleOperator(bpy.types.Operator):
    bl_idname = "object.simple_operator"
    bl_label = "Simple Operator"
    # We set the option so it resets to default on each operator call
    callback: bpy.props.StringProperty(default="", options={"SKIP_SAVE"})

    def execute(self, context):
        if self.callback:
            exec(self.callback)
        return {'FINISHED'}

def my_callback():
    print("Callback function called")

class TestPanel(bpy.types.Panel):
    bl_label = "Test Panel"
    bl_idname = "PT_TestPanel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Test'

    def draw(self, context):
        layout = self.layout
        op = layout.operator(SimpleOperator.bl_idname, text="Execute Simple Operator")
        op.callback = "my_callback()"

def register():
    bpy.utils.register_class(SimpleOperator)
    bpy.utils.register_class(TestPanel)

def unregister():
    bpy.utils.unregister_class(SimpleOperator)
    bpy.utils.unregister_class(TestPanel)

# Test the panel
if __name__ == "__main__":
    register()

Hi @Gorgious thank you for your response! I shall try this one. But you mentioned it opens a can of worms? haha. So what do you think about my solution with bpy.types.Scene.on_button_click = on_button_click?

exec is an infamous bad code smell, it can be used to inject malicious code and it makes debugging a nightmare. If used properly there really isn't any risk but it should be avoided when possible. I think your solution is the most sane and blender-y. You can prevent namespace pollution by providing a custom name eg my_addon_on_button_click or by using a PropertyGroup to hold your custom props

thank you for this info! :)


text:
How to python print out all voxel blocks and their corresponding colors?
I'm able to create a blocky voxel mesh with this thread different materials thanks to Markus von Broady. Now I continued the setup to add center point for each surface voxel. I added Mesh Lines going along the normal of each voxel face and extended them inward by half voxel size so they intersect. And realize instances so they become vertices and will do a Merge By Distance. I just use these intersected vertexes as reference so I could get the voxel position so these Mesh Lines are not really needed if ever there is a better method to get the center position of each voxel.

Now I'm trying to use python to print out a list of all the voxel positions (based on the intersecting center points) with their corresponding hex color (as if I used an eye-dropper tool to get the color 0xHHHHHH) but I'm stuck because I'm unsure how to do that.

This is my blend file https://blend-exchange.com/b/1RVKOMpZ

By color, what do you mean? Is it the material index, or the value you've plugged as output of the node group (which is not valid)?

hi lemon, by color i literally meant the diffuse color of the output as i can see in the 3d view. so in this example there are voxels that have green, red, and different shades of gray since that's from a texture. as if i would use an eye-dropper tool on each voxel i would like to get the hex value 0xHHHHHH

To be sure there is no more simple way to do it, could you describe the purpose of this? Because I don't know what is the role of the mesh lines here.

i want to store the result as a qb file using https://github.com/dee-gmiterko/qb-reader/blob/master/qb-reader.py but first i would need a list of all the voxels positions and their colors. i dont need the mesh lines, i just needed the intersecting vertex as a reference for voxel position

"I just use these intersected vertexes as reference so I could get the voxel position so these Mesh Lines are not really needed if ever there is a better method to get the center position of each voxel. " - for each face, you can get the center of the face, offset it by the face's normal scaled by half the width of the voxel - that's the center of the voxel.

To see diffuse color you need renders. Try setting vertex attribute

A script that should work (please check this is ok with no bug...)
Note: it supposes the uv coordinates are calculated as done in your gn setup. Meaning for a given voxel 'cube' all uv coords are at the same location.
The principle:
Calculate key data for each material associated to the object.
A material (through Principled BSDF) can be either its color or an image texture. The first part of the script retreives that.
Then, it calculates voxel centers corresponding to each face as face center minus half normal scaled by edge length.
And populate a kdtree with it.
Last, loop over the faces and get the color of it if not already encountered in the kdtree.
Commented code:
import bpy
import bmesh
from math import sqrt
from mathutils import Color, kdtree

# get material key data: either direct color or image
def get_material(i, m):
    # assume we only have a "Principled BSDF"
    # which have either a texture input or a simple color
    # many things should be checked, but we go straight as the materials are here
    p = m.node_tree.nodes['Principled BSDF']
    if len(p.inputs[0].links) == 0:
        c = p.inputs[0].default_value
        return (i, m, Color((c[0], c[1], c[2])), None, None)
    else:
        tex_node = p.inputs[0].links[0].from_node
        image = tex_node.image
        return (i, m, None, image.size, image.pixels[:])

# get all materials key data
def get_materials(obj):
    return [get_material(i, m) for i, m in enumerate(obj.data.materials) if m]

# get the color from a give face index
def get_color(bm, materials, i):
    m = materials[bm.faces[i].material_index]
    if m[2]:
        # either direct color
        return m[2]
    else:
        # or the color in the image texture
        uv = bm.faces[i].loops[0][bm.loops.layers.uv[0]].uv
        px = int((m[3][0]-1) * uv.x)
        py = int((m[3][1]-1) * uv.y)
        pixel = 4 * (m[3][0] * py + px)
        color = Color((m[4][pixel], m[4][pixel+1], m[4][pixel+2]))
        return color

# create a bmesh object
dg = bpy.context.evaluated_depsgraph_get()
o = bpy.context.object
e = o.evaluated_get(dg)

bm=bmesh.new()
bm.from_object(o, dg)
bm.faces.ensure_lookup_table()

# get the object materials
materials = get_materials(e)

# create a kd tree for fast distance comparison
centers_kd = kdtree.KDTree(len(bm.faces))

# calculate voxel center for each face
# as a face is a square, edge length is sqrt the surface
centers_voxel = [f.calc_center_median() + (-0.5 * f.normal * sqrt(f.calc_area())) for f in bm.faces]

# populate the tree
for i, f in enumerate(bm.faces):
    centers_kd.insert(centers_voxel[i], i)

centers_kd.balance()

epsilon = 0.001

for i, c in enumerate(centers_voxel):
    # if not processed
    if c:
        # get the color
        col = get_color(bm, materials, i)
        # mark as processed
        for _, fi, d in centers_kd.find_n(c, 6):
            if d < epsilon:
                centers_voxel[fi] = None
        # print the result
        print(c, col)

Thanks to your other question, I realized that we finally need integer coordinates for the Qubicle matrix.
In consequence, using a KDTree is useless, as we can simply use a dictionary with the tuple of integer coordinates as keys (no more float rounding issues).
That should gain a significant step in terms of performance.
Here is the modified part, from your last complete code.
The KDTree is removed and the face colors are calculated directly in the first loop, mapping over bmesh faces.
I've also modified QB matrix data calculation as the min and max dimensions are not known when calculating the colors.
class FaceColorReader:
    def __init__(self, object, voxel_size):

        dg = bpy.context.evaluated_depsgraph_get()
        e = object.evaluated_get(dg)

        self.bm = bmesh.new()
        self.bm.from_object(object, dg)
        self.bm.faces.ensure_lookup_table()

        self.materials = [self.get_material(m) for i, m in enumerate(e.data.materials) if m]

        self.colors = {}

        min_x, min_y, min_z = float('inf'), float('inf'), float('inf')
        max_x, max_y, max_z = -float('inf'), -float('inf'), -float('inf')

        for f in self.bm.faces:
            center = f.calc_center_median()
            normal = f.normal
            area = sqrt(f.calc_area()) # as a face is a square, edge length is sqrt the surface
            displacement = -0.5 * normal * area
            voxel_center = center + displacement

            # translate to integer and make it a tuple
            center_x, center_y, center_z = round(voxel_center.x / voxel_size - 0.5), round(voxel_center.y / voxel_size - 0.5), round(voxel_center.z / voxel_size - 0.5)
            center = (center_x, center_y, center_z)

            if not center in self.colors:

                col = self.get_face_color(f.index)
                self.colors[center] = col

                min_x, min_y, min_z = min(min_x, center_x), min(min_y, center_y), min(min_z, center_z)
                max_x, max_y, max_z = max(max_x, center_x), max(max_y, center_y), max(max_z, center_z)

        self.min_values = Vector((round(min_x), round(min_y), round(min_z)))
        self.max_values = Vector((round(max_x), round(max_y), round(max_z)))

    def get_material(self, m):
        p = m.node_tree.nodes['Principled BSDF']
        base_color = p.inputs[0]
        link = base_color.links[0] if len(base_color.links) else None
        if not link: # nothing connected to Base Color socket
            c = base_color.default_value
            return (round(c[0]*255), round(c[1]*255), round(c[2]*255), 255)
        if link.from_node.type == 'TEX_IMAGE':
            tex_node = p.inputs[0].links[0].from_node
            image = tex_node.image
            return (image.size, image.pixels[:])
        if link.from_node.type == 'VERTEX_COLOR':
            c = base_color.default_value
            return (round(c[0]*255), round(c[1]*255), round(c[2]*255), 255)
        return (0, 0, 0, 255) # unhandled or undefined linked node

    def get_face_color(self, face_index):
        f = self.bm.faces[face_index]
        m = self.materials[f.material_index]
        tuple_len = len(m)
        if tuple_len == 4: # either direct color as tuple length 4
            return m
        elif tuple_len == 2: # or the color in the image texture
            uv = f.loops[0][self.bm.loops.layers.uv[0]].uv
            size = m[0]
            px = int((size[0]-1) * uv.x)
            py = int((size[1]-1) * uv.y)
            pixel = 4 * (size[0] * py + px)
            pxs = m[1]
            return (round(pxs[pixel]*255), round(pxs[pixel+1]*255), round(pxs[pixel+2]*255), 255)
        #TODO: get vertex colors

    def get_voxel_dimensions(self):
        min_x, min_y, min_z, max_x, max_y, max_z = self.get_voxel_ranges()
        return max_x-min_x+1, max_y-min_y+1, max_z-min_z+1

    def get_voxel_ranges(self):
        min_x, min_y, min_z = round(self.min_values.x), round(self.min_values.y), round(self.min_values.z)
        max_x, max_y, max_z = round(self.max_values.x), round(self.max_values.y), round(self.max_values.z)
        return min_x, min_y, min_z, max_x, max_y, max_z

    def get_color_data(self):
        min_x, min_y, min_z, max_x, max_y, max_z = self.get_voxel_ranges()
        empty = (0, 0, 0, 0)
        data = [self.colors[x, y, z] if self.colors.get((x,y,z)) else empty
                for z in range(min_z, max_z + 1)
                for y in range(min_y, max_y + 1)
                for x in range(min_x, max_x + 1)]
        return data

Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on [meta], or in [chat]. Comments continuing discussion may be removed.

The code works wonderfully. I have implemented a bake feature that UV maps each face to a 1x1 px square on the UV map like in this image but I had to change px = int((size[0]-1) * uv.x) to px = round((size[0]-1) * uv.x) to make it work perfectly. Using int cast would make the colors jumble around in the final QB file. Do you see any potential issues with this change in the future? Would have been cool if float values for pixels worked so I can be sure I sample exactly the center of the 1x1px UV squares.

I think round is fine.


text:
Why is render stacking less efficient (noisier) than rendering normally?
Why are stacked renders noisier than straight renders which have the same number of samples?
Using this technique for resuming noise based on the rate at which pixels change outlined on the wiki (further explained on BA), I have run some tests. I'm not sure I understood the entire measuring process correctly, so I hope I haven't measured anything wrong..
I rendered 7 images, all with different seeds. 5 at 10 samples, 1 at 50 and 1 at 40.
In the compositor I combined the 10 sample renders with a series of mix nodes with mix factors of .5, .33, .25, and .2:

As an interesting side note, the combined image has fewer fireflies than the straight render.
The setup of the "Noise Detect" node group is:

Now if I understood correctly, the brighter the pixel, the faster it changes (the more noisy).
The histogram for the straight render:

The histogram for the combined render:

And an overlay version. The straight render is orange (click for full size):

As you can see, except for occasional spikes (fireflies) the straight render is changing less, which means it's less noisy according to the above links.
Assuming my above tests are correct, what is the reason for this and is there a way to stack renders more efficiently?
Here is the blendfile used for testing.

I wonder if rendering each pass at a different seed would be better than all passes using the same seed.

@Vader That's more or less what I'm doing, except I'm only changing the seed every ten samples rather than every sample.

@Vader Oh.. I think I just realized that you said passes. I'll have to test that.

Cycles uses Quasi Monte Carlo sampling:
http://en.wikipedia.org/wiki/Quasi-Monte_Carlo_method
That means it will try to evenly distribute samples so rendering converges faster. If you render multiple times with different seeds however then this even distribution is lost because it mixes different distributions without ensuring that the combined result is even too.
Since Blender 2.78 there is a sample offset command line option to avoid that problem, where you can set it so that each render uses a subset of samples from the same distribution.

Does this also explain the stacked render consistently having fewer fireflies? I'm not sure I understand how a more even distribution would create more fireflies..

The combined image has fewer fireflies because you are storing the intermediate results in PNG files. This means that bright values get clamped because PNG does not support high dynamic range. If you used EXR files this would not be the case.

You need to use more samples per seed - 10 samples (from the regular Path Tracing integrator) isn't really enough to sample all the materials and lights consistently. Try 100 or even more.
That said, stacking seeds will never really be as accurate as a straight render, but the more samples per seed you use, the more accurate it will be. I use this method purely as a resume-able render type of thing.

I realize that more samples are needed for a good result, but I used 10 samples because I wanted to have the same number of cumulative samples as the straight render (5 images * 10 samples each = 50 total samples).