It isn’t easy to do this in Python, you’d have to set up a loop through the faces in the mesh, text their normals, and then set the vertices to be in the group or not. Then you’d have to add an event handler to make it update. If you wanted to control it with materials, Python is really not able to access the data in the procedural textures. It can create noise, and do a lot of the same math, but it can’t test a location on a mesh for a color or value in a material.
I think you should try finding other ways of doing what you want. Here’s a blend file with a novel way of controling particle systems using the vertex weight proximity modifier. https://my.pcloud.com/publink/show?code=XZkvG0kZUYVo8T7cjO8CTLfU4nIcPfcLj9qy
Note that you have to click on the particle emitter to get it to update, but aside from that it’s interactive (actually I was able to get it to be interactive after re-setting the density weight group in the particle settings; just play with it and Blender should figure it out). If a point in the emitter mesh is near a point on a face in the control, it will emit particles. If you want to create volume “brushes” to choose where one place gets particles, you have to make sure there are faces, as vertex weight proximity doesn’t test volume-- this is why I’ve stacked a bunch of faces in the control mesh.
First, create a vertex group containing all the vertices in the mesh at weight 1 (or rather, anywhere you want particles; this value is multiplied by the modifier value, so if it’s zero, there will be no emission no matter what). Then create the control mesh, and use it to drive a vertex weight proximity modifier. Important: Set the lowest value to the distance you want the “brush” to affect, and the highest value to 0 (I know it’s counter-intuitive, but it works). Set the falloff as you like, I used spherical falloff. Now, create your particle system. Check the box next to advanced and under emission, choose Use Modifier Stack. You might create any number of interesting shapes in the brush mesh with a combination of an array modifier and some boolean modifiers, a few displace modifiers, etc. You could use the Data Transfer modifier to add vertex weights, too.
As a final step, I used the Select Similar tool to select all the parts of the mesh that were flat and created a Z-Up vertex group, smoothed it, and added a Vertex Weight Mix modifier multiplying the proximity group by the Z-Up mask. This is the part that you’d probably want to make a Python tool for, a simple macro that repeats this process would be enough.
I’m not sure if this is really what you want, but it’s easier than writing functions to test each face for a condition and set the vertex weight. If this is close to what you want, I think you’ll get faster results using the features you already have (modifiers) rather than adding new features.