Proposed Noise Modifier
AbandonedPublic

Authored by Campbell Barton (campbellbarton) on Feb 15 2014, 9:30 PM.
Tags
None
Tokens
"Love" token, awarded by PatB."Love" token, awarded by gandalf3."Love" token, awarded by erel96."Love" token, awarded by januz."Love" token, awarded by pecador."Love" token, awarded by Samoth."Love" token, awarded by ob3lisk."Love" token, awarded by monio."Love" token, awarded by bliblubli."Love" token, awarded by karja.

Details

Summary

Hello, I'd like to share with you a proposition for a new modifier. To save you some reading, I posted a short video presentation on Youtube.. You may also want to see Thomas's video in the "Rocket Science" series, with very good use cases.

From RC4, the "noise modifier" is integrated within the "displace modifier".

The features:

The displace modifier now has 2 mode, with 2 distinct UI pannels: texture and random.
The former proposed noise modifier is now the "random" mode of the displace modifier.

It has 3 modes.

All 3 modes share the following settings:

  • Seed: the seed used to initialize random number generators.
  • Probability: the probability that a given item (vertex, mesh object, loose part) is affected at all by the modifier.
  • Factor: the global effect of the modifier on the mesh.
  • Use name as seed: when checked, the (unique) name of the object is used to alter the seed, so that two copies of the same mesh object have different random variations.
  • Noise mode: one of Linear / Gaussian / Constant. In linear mode, the random amounts are evenly distributed within [0; max], or within [-max; +max]. In Gaussian mode, the random amounts follow a normal distribution with mean at max setting, and standard deviation as defined in UI. I n Constant mode, each item, *when affected* is offset by exactly the max amount; this makes sense together with the "probability" setting.
  • Std deviation: the standard deviation of the normal distribution, centered on the 'max' value (which in this case is the mean value).

(Only for whole mesh and loose parts)

  • Use object for offset: when this is checked, the max offset is provided by another object, in many cases an empty.
  • Offset object: the object that defines the max offsets.
  1. In vertex mode, the individual vertices are randomly displaced.

The settings are:

  • Translation along normals: vertices are offset along the vertex normals, by a random amount, with a maximum (or mean) amount defined by "Normal offset".
  • Translation X, Y, Z offsets. The maximum (or mean in case of Gaussian mode) amounts that vertices are offset.
  • Translation plus/minus. When checked, offset is within [-max; +max], when unchecked, offset is within [0; +max]
  • Affected group: a vertex group that defines how vertices are affected, with weight influencing offsets.
  1. In whole mesh mode, the mesh is offset as a whole. This mostly makes sense together with the "use name with seed" option. In this case, each copy (either shift-D or alt-D) of the object will have it's own random translation/rotation/scale, but the mesh will not be otherwise deformed.

Settings are:

  • Translation, Rotation, Scale in X, Y, Z (local) amounts.
  • Plus/Minus options
  • Pivot point vertex group (optionnal): defines the pivot point for rotations and scaling. The pivot point is the center of bounding box of group's vertices.
  1. In loose parts mode each loose part (set of vertices connected by edges) is offset as an independant item, and not otherwise deformed. This mode can be used with looseparts in the original mesh, or it can be used after an array modifier. An array modifier produces a single mesh with each original mesh as a distinct loose part (except if merge option was used).

The settings are the same as for the whole mesh mode.

Note that in loose parts mode, the modifier uses a cache of looseparts, which is updated whenever the number of vertices or of edges has changed. One could make up use cases where loose parts change with these numbers unchanged, while the modifier is not active.

Diff Detail

Branch
arcpatch-D320
There are a very large number of changes, so older changes are hidden. Show Older Changes

Global weight setting

Yes thats what i meant, thank you.
It looks as if this modifier will be a very extensive one for all purposes, really good work.


I wonder what a "loose parts" option may be able to in other modifiers.
For example in Shrinkwrap Modifier:
I can imagine this would be helpful to emulate a particle system in game engine if combined with your noise modifier. (Array > noise > shrinkwrap)
Shrinkwrap for sticking environmental objects like bushes and trees to the ground without deforming it.
Unfortunately object constraints dont work in game engine or for arrayed parts.

I thought I simply bring it up here, but its not that relevant so dont think about it to much.

Really nice job, works perfect on latest GIT.

I also think adding this "loose parts" option to the shrink wrap could be really usefull. When modeling some real towns for big scenes, many use the OSM data from streetmap, like in Tears of steal. While projecting the houses/building on the ground, with the actual shrink wrap, they get distortorded, increasing the polycount and making it hard to nicely extrude them. Adding constraints to 10000+ objects is no option either as it makes updating the frames awfully slow.
I'm sure there are many other cases where such an option would be appreciated.

Noise Modifier RC1
This patch is rebased on v2.70-rc
New features and fixes:

  • Rotation and scaling for whole mesh and loose parts, with pivot point at center of bounding box
  • Offset along vertex normals in vertex mode
  • Offset defined thru other object in whole mesh and loose parts mode, similar to array modifier
  • Three noise modes: constant, gaussian, linear.
  • Global factor setting
  • Corrections in handling of normals, setting dirty, and handling dependsOnNormals,
  • Correction in handling of euler degrees.

I would like to add the loose part method to other modifiers. What is the best/fastest way to get lists of vertices by loose parts so that it can be multi-threaded and use intrinsics? I mean, there should be no collision risk with loose parts and every loose part should get the same transformation on all its vertices. Campbell, maybe you could provide a little code snippet?

Just tested the patch. Works really great :) But for consistency, a scale of 1 should do nothing and 0 should make the mesh flat. At the moment -1 makes mesh flat and 0 makes no changes.

@mathieu menuet (bliblubli): Yes, I spent much time pondering this question. The thing is all other settings are DELTAs, zero meaning no change, so I figured why would this one be different ? Anyway, it's easy to change it back to 1 being the neutral point.

@Patrice Bertrand (PatB) many reasons lead me to that. In the property panel, and object panel, scales of 1 are for "nothing changed" 0 for flat, -1 for inverse.
Second reason is that scale is a factor (*)while translation is an offset(+) mathematically, neutral for * is 1, neutral for + is 0.
The most important for user is consistency. If they have to enter -1 in your modifier and 0 in viewport or 0 for 1, etc... they will get messy in their head ^^

@mathieu menuet (bliblubli): Yes, now I fully agree: scale is a multiplier thus 1 is neutral. I'll wait for (hopefully) more feedbacks, then fix this.

Another improvement could be to add the option to scale relative to the min or max and not only mid ( bounding box center ). When someone use it on leaves/stone/whatever on the ground scaling relative to centre makes them float in the air. Having the possibility to scale relative to their lowest vertex would allow realist use of the modifier.

Some suggestion:

adding
extern StructRNA RNA_NoiseModifier; //at line ~70
in source/blender/makesrna/RNA_access.h
could maybe be good?

and
case eModifierType_Bisect: //at line ~920
in source/blender/editors/space_outliner/outliner_draw.c
too (add an the appropriate Icon in the outliner?

See https://developer.blender.org/D184 for an example

this is an excellent modifier!
can i suggest adding the ability to easily seed the random number generator by the current frame number?
this would be extremely useful for animations!
thanks!

@tommy ob3lisk (ob3lisk) I don't have my compiled version at hand, but it should "magically" work if you just enter #frame in the "seed" field...it should create a driver automatically that alters it's value with every frame change...

Greetings, Thomas

@mathieu menuet (bliblubli): regarding the option to scale relative to the min or max, maybe something more generic would be to allow another vertex group to define pivot point. Vertex groups are copied correctly when array modifier generates meshes. Pivot point would be the center of the vertices in the loose part that belong to the said group, which in most cases would be a one-vertex group.

@tommy ob3lisk (ob3lisk): Yes it does work magically, just like Thomas says.

@campbell: I'm currently working on a version that will not use BMesh, as you suggested, with possibly a performance gain. For that purpose, I have coded a BKE_mesh_loosepart_vertex_map_create within mesh_mapping.c. Will post it soon, together with some performance figures.

@Patrice Bertrand (PatB) it would force the pivot point to be one of the vertices. For the ground, we sometime use geometry with a hole beneath (helps a lot to save 10 triangle when you instantiate an objects a million times = - 10 000 000 of triangles.), in such a case, the pivot couldn't be in the centre of the bottom part. It would also limit your modifier to geometry generated with the array modifier. Using you modifier for some time now, I use it a lot on imported objects for which we can't manually set a pivot for every loose parts in reasonable amount of time.
Maybe giving both possibilities for different usage ? Generated pivot and manual pivot through vertex group ?

Hello,
This is R2 of the Noise Modifier.
Includes the following:

  • Refactoring so as to be a "deform only" modifier and not use BMesh,
  • Which allows improved performance by a factor of 10.
  • Scale is neutral at 1.0
  • Added Vertex Group to define pivot point in Loose Parts (and Whole Mesh) Pivot point is the center of bounding box of vertices in loose part that belong to said group.
  • Added Plus/Minus option on translation, rotation and scale.

    Also added new function BKE_mesh_loosepart_vertex_map_create into mesh_mapping.c This function is inspired from others in this module. It builds a mapping of looseparts-to-vertices, which allows very easy loop into loose parts and their vertices. This new mapping function could be used by other modifiers or other functions needing to handle loose parts.

This version seems complete to me in terms of features. Actually it's even getting more complicated than I expected in its UI, but difficult to add features without UI settings... Now if someone would care to be a reviewer, I'd be very thankful.

I ran some performance measurements.
With an array of 1000 icospheres, each of 42 vertices, thus 42 000 vertices, the former BMesh version took

0.053 seconds (using PIL_check_seconds_timer) (1.26 ms / kVertices) for "individual vertices" and "whole mesh" modes
0.062 seconds (1.47 ms / kV) for loose parts mode without rotation/scale
0.071 (1.69 ms / kV) with rotation and scale (note that it's the pivot point that takes some extra cpu cycles not the actual rotation).

The RC2 version is about 10 times faster:
0.0013 seconds (0.03 ms / kV) for individual vertices.
0.0052 seconds (0.12 ms / kV) for loose parts, no rotation / scale.
0.0058 seconds (0.14 ms / kV) for loose parts with rotation / scale (and thus pivot point).

@mathieu menuet (bliblubli) : I think the pivot point vertex group, as implemented in the RC2 version should fit all needs. The vertex group used for pivot point may be a single vertex, but for example if you want to scale up from the lowest point you can just define a group that contains vertices at the bottom of the object. The pivot will be the center of bounding box of vertices in the group, so it is quite possible that there is no actual vertex at this point, say if the bottom face is a 10 vertices ngon circle, the pivot point will be the center of the circle.

Other than that, I think I must stop adding features now, else users will get disturbed, or lost.

Very nice new version. I did some test on very heavy scene (millions of polygons in about 20 objects all having the same plane to cut. It rotates, with real time bisect on an I5 3450 :) Thanks a lot as well for making part of your code easily reusable, really kind of you. For the options I need, I can add them myself, no problem if it doesn't go in trunk.

I just realized that since I am isolating loose parts starting with polys then going through all connected polys, I am missing loose parts that do not include any polys, that is to say either unconnected vertices, floating edges, or even loops of edges without an actual face. This is wrong, I need to scan all vertices, and follow not polys but edges. I had figured working on the basis of polys could be more efficient, but actually there is not much difference. I will fix this quickly.

Noise Modifier RC3
(Patch from 2.70-RC2)

  • Change in the way of spliting loose parts in BKE_mesh_loosepart_vertex_map_create. Was initially done by walking through polys, but this does not work if there are no faces, in case of either isolated vertices or vertices connected by edges without faces. Now done by following edges, which turns out to be not only more correct, but also simpler,
  • Fixed bug when vertex normals are needed and dm is NULL.

Sorry about the multiple patches.

Hi PatB,
Some fine tuning:

  • When Object offset is chosen, "translation", "rotation" and "scales" are displayed also with plus/minus (should be hidden in release/scripts/startup/bl_ui/properties_data_modifier.py)
  • When I choose Object Id as seed, changing the seed value changes the noise. Is that a wanted behaviour ?
  • Most people will use your modifier for the "looseparts" option ("whole mesh" mode can be replaced by a driver, "vertex" is more like displace modifier), making that mode default would save many clicks.

Not sure about this modifier, it seems to be a catch-all for moving mesh data about... which is ok.

but the whole mesh option seems a bit odd (you could use warp modifier already for this),
loose parts seems to be the most useful feature but the way it works by calculating loose parts every time - Im not so happy with either

source/blender/makesdna/DNA_modifier_types.h
1407

This is very much like displace. not sure duplicate functionality is really good.

source/blender/modifiers/intern/MOD_noise.c
61 ↗(On Diff #1275)

is this needed?

418 ↗(On Diff #1275)

its fairly inefficient to calculate this every time, its possible to cache this data.

PatB or someone who used the "Whole mesh" mode could maybe tell us why it's good (drivers and/or particles are much more memory efficient to randomise instances). I couldn't find a usefull case to use the that mode either.
For the per vertex mode, for me it's like displace, so it could be removed as well.
The loose part option could be added to all modifiers needing this. Reading post from other on Blenderartists and based on my work, Shrinkwrap and displace would have a great benefit of it. Maybe other members of the community could tell us where they would use it?

PatB or someone who used the "Whole mesh" mode could maybe tell us why it's good (drivers and/or particles are much more memory efficient to randomise instances). I couldn't find a usefull case to use the that mode either.
For the per vertex mode, for me it's like displace, so it could be removed as well.
The loose part option could be added to all modifiers needing this. Reading post from other on Blenderartists and based on my work, Shrinkwrap and displace would have a great benefit of it. Maybe other members of the community could tell us where they would use it?

@mathieu menuet (bliblubli): whole mesh really makes sense together with the "Use ID as seed" option checked. When this option is checked, the unique name of the object is used to alter the seed (hash of the name, then xor with seed). The effect of this is that you can then copy the object with either Shift-D or Alt-D, and each of the copied object will be affected by noise differently. For example you could place trees on a landscape, and with a single mesh object you would have your trees with random sizes and random Z-axis rotation. I don't see any other modifier that would do this, but maybe I'm wrong.

I do agree that vertex mode is very much similar to what the displacement modifier does.

I added a reusable BKE_mesh_loosepart_vertex_map_create function into mesh_mapping.c, which hopefully can be used by other modifiers needing looseparts. I will try to add openmp support to it, although it is a bit more difficult than for simple for loops.

As suggested by Campbell, I will work on integrating the loose parts mode alone into the displacement modifier, and work on adding openmp support on both which seems quite straightforward. Campbell also suggests caching the looseparts map data. I will look into this as well.

Actually having to calculate loose parts after an array modifier is a work-around. Array modifier produces a single mesh object with multiple loose parts. But what we really want is not so much working on loose parts as working on the multiple objects that the array modifier has produced. In other words, whereas modifiers take a mesh as input, and produce a mesh as output, it might help to have modifiers that output a set of meshes, and the next modifier on the stack would be called separately for each mesh. Could be an option of the array modifier, and the overall modifier manager would be altered to handle this. But this might be getting too complicated, for a relatively minor need. Dealing with loose parts is very simple in comparision.

source/blender/modifiers/intern/MOD_noise.c
61 ↗(On Diff #1275)

Not needed anymore indeed.

418 ↗(On Diff #1275)

Could easily keep loosepart_vertex_map into modifier data, but how would I know that the count of an array modifier above me on the stack has been changed and my loosepart mapping is stale ?

We could do somewhat like Laplacian modifier does: keeping the count of verts and edges and assume that if these counts have not changed, then loose parts have not changed either. This would imply a "Bind" button to force updating loose parts if needed. But this is cumbersome. First need to check if this noise modifier in loose parts mode is really slower than the average modifier out there. I will run some more benchmarking.

@Patrice Bertrand (PatB) I didn't mean a modifier, but drivers : http://wiki.blender.org/index.php/Doc:2.6/Manual/Animation/Basics/Drivers . They also allow randomising scale and rotation while keeping only one mesh in memory (instancing), thus saving huge amount of memory. Your whole mesh option doesn't allow instancing as it produces new meshes for every objects. The good part of your idea was to take the object Id as seed, which can be really usefull to have a randomisation that is constant relative to time and space. Someone is looking for a solution like that for drivers on Stackexchange http://blender.stackexchange.com/questions/7758/how-can-i-get-a-random-number-that-is-constant-per-object-in-a-driver . If someone has the answer :) From a user POV, it's much easier for sure, but it leads to bad memory management. It's in no way a critic, I'm really happy you did that modifier, it's just some options are redundant and can be done better with existing tools.

Did not review code at all, but feature is interesting imho. However, it should be merged with Displace modifier, those two share many things (would then have two main modes, Texture and Random). Would be a good way to review UI of Displace as well, kinda odd currently (with tex mapping at the opposite of texture selector… tst).

As for cache, using number of vertices and number of edges as key would tackle 99% of situations imho, I do not see having a small "Refresh" button for the few cases that may break as an issue (and if we want to be 100% sure, we can make some kind of hashsum of all vertices used by all edges… do not think it would be worth it though).

Noise Modifier RC4

  • Noise Modifier pannel is now integrated within the original Displace Modifier
  • Looseparts mapping is now cached while numverts and numedges have not changed.
Bastien Montagne (mont29) requested changes to this revision.Mar 31 2014, 10:16 AM

Please update the patch against latest master, it does not applies cleanly currently (I made some changes in rna_modifiers recently, getter/setters of vgroups & co are now factorized in simpler macro).

Hi. This is the rc4 of the noise/displace modifier, after merging latest build and solving conflict. I tested it again. But I'm not very familiar with git commands, so I hope this is correct.

So, those comments were done while refactoring the patch, they highlight issues I found on the process.

I’ll now commandeer the rev, update the patch, and make comments on points that still need discussion imho…

release/scripts/startup/bl_ui/properties_data_modifier.py
52

Please double check your diffs, we do not want such meaningless changes in them. :)

This is also valid for general style guidelines (http://wiki.blender.org/index.php/Dev:Doc/Code_Style), like tabs/spaces, spaces around operators, etc.

285–295

Just a note here, CAPITAL_NAMES are a special case to help pick the right draw function, they should be strictly reserved to matching modifiers' define. Any helper func should have usual python name.

Anyway, we can highly compress all this (also, we usually do not hide settings that are not valid currently, but rather inactivate them, so that they show grayed out in the UI).

source/blender/blenkernel/intern/mesh_mapping.c
322

Only use calloc when you need to init values. Else, prefer malloc.

325

Better to use a stack here, in usual cases this should allow to reduce at least mem usage by two, and makes code easier to follow.

source/blender/modifiers/intern/MOD_displace_noise.c
70–83 ↗(On Diff #1402)

Indeed, moved to BLI_rand.

126 ↗(On Diff #1402)

We tag unused parameters like this: int UNUSED(vgroup_pivot), this avoids some grumpy compilers like gcc to issue warnings...

252–253 ↗(On Diff #1402)

You should set zero translation first, then set pivot, then set translation. Else you get rather ugly results ;)

369–370 ↗(On Diff #1402)

Same remark as for doNoise_wholemesh

438 ↗(On Diff #1402)

Note ob cannot be NULL here (or it would be a nasty bug).

source/blender/modifiers/intern/MOD_displace_noise.h
1 ↗(On Diff #1402)

We do not need separated files for noise, MOD_displace.c is not really that big...

Bastien Montagne (mont29) updated this revision.

This is mostly a big refactor of proposed Noise patch, as well as of existing Texture-based displace code, with following goals in mind:

  • Integrate better the various modes: some settings from Noise were redundant with existing Texture ones, and some new features from Noise could be added to Texture as well (like the per-axis factors). This also involved reworking UI of the modifier.
  • Factorize code (Texture and RandomVertex can share most of their code, the same goes for LooseParts and WholeMesh).
  • General cleanup (mostly code style).
  • Remove MOD_displace_noise files, complete MOD_displace.c stays below 700 lines, remains more than reasonable.

Additionally, I made the following changes on algo/behavior POV:

  • BKE_mesh_loosepart_vertex_map_create now uses a BLI_SMALLSTACK instead of a plain array, for verts_todo flags.
  • All loc/rot/scale values are now pure factors (i.e. they have null effect at 0.0), special handling/correction for rotation and scale is integrated in code.
  • Scale now has both per-axis factors and a uniform one, so that people can chose how much per-axis/uniform randomness they want for it (similar wetting for loc and rot would not make any sense imho?).

I still see three opened questions with this patch:

  • Usage of smallstack: Campbell, do you think it’s safe to use smallstack here? One can imagine worst-case crashing meshes (e.g. and insane cone with several millions of vertices around its base would fill the stack with those millions of elements, crashing rather likely as stackoverflow, since smallstack uses alloca), do we want to support such corner-cases?
  • Not critical, but imho, in final version of BKE_mesh_loosepart_vertex_map_create, we should remove the multi-states of todo vertices, would save us a few assignments and equality tests for each vertex...
  • On a more general level, I'm not convinced the WholeMesh mode belongs to modifier world. Imho, it should rather be a constraint. However, now it does not take much place neither in code nor in UI, so might still be OK to keep it?

Tsst… I still forgot some cleaning… :P

Btw, @Patrice Bertrand (PatB), feel free to comandeer the rev again if you want. :)

release/scripts/startup/bl_ui/properties_data_modifier.py
1279–1281

Grr, to be removed! xD

source/blender/makesdna/DNA_modifier_types.h
419

comment to be removed, actually used with noise as well!

1413

to be removed.

source/blender/makesrna/intern/rna_modifier.c
247

to be removed

3744

to be removed

source/tests/bl_pyapi_mathutils.py
293 ↗(On Diff #1411)

xD to be removed

Thanks for the thorough review and improvements. I will try to remember for my next Blender endeavor ! There is just the stack thing that I'm not convinced about, but I'll look into it a little more.

source/blender/blenkernel/intern/mesh_mapping.c
325

I'm not a great fan of those STACK__XXX things, I find them cumbersome and not that easy to read, with tiny gains in most cases. Probably they become readable after you've used them for a while. But as far as memory usage is concerned, if you consider we are at the very end of the call stack, so there is no other function's needs added to our own, and we are just allocating totvert bytes for a thousandth of a second, then freeing it. Furthermore, it seems dynamic stack size is doubled every time its previous size is reached (with a bulk copy), which could end up requiring twice as much as our maximum need in the worst case.

and I hope I get to see my name in the header section ? This is really the reward that one gets as a contributor, that your efforts be remembered.

Well, I find stack simpler to read/follow than the kind of "sliding window" you used, but that may be matter of personal tastes.

Did a few checks, with a single cube subdivided 6 times (about 24k vertices), max stack size is 3635. With about the same number of vertices, but in 32 different loose parts, max stack size is 383.

With same mono-block cube subdivided 9 times to get about 1.5 millions of vertices, max stack size is 83839. With about the same number of vertices, but in same 32 different pieces, max stack size if 7344.

With a 2M vertices subdivided Suzanne, max stack size if 57715.

TBH, the main issue I see in smallstack is that it allocates one element after the other - not sure how much 57k calls to alloca() weight in the final time…

Minor updates (also against latest master).

Hi thanks for integrating the modifier,
-Scaling of 0 doesn't make flat like in all other parts of Blender. For consistency, it was better with scale of 1 for not scaling and scale of 0 to make flat. Follows math rules too, so more logical.
-Allowing to use textures for the "loose part" mode could also be great. As displace value for each loose part, let the user choose between max/min/mean would allow precise positioning like the old displace, but without deforming the loose parts. It would also save space to only have "Vertices" and "Loose part" modes with a choice for each between texture or noise for the displace values.
-Is there really a use case for the whole mesh mode ?

@mathieu menuet (bliblubli) I disagree about scale, these are factors, and imho it makes much more sense for a factor to have no effect at 0.0 than at 1.0 (and it also makes it consistent with the other factors).

As for texture, you can already get undeformed displacement of looseparts, just assign the same color to a whole UVs of a loosepart, and you’ll get it.

About whole mesh, yep, I said it would be better as a constraint imho.

Hmmm, in the N panel, scale factor of 0 makes the object flat and scale of 1 does nothing (object is same as mesh).
In the Displace modifier, a Strength factor of 1 displace exactly like the Bump data defines it (100m if the height data is 100m at that point), a strength factor of 0 makes the mesh flat.
In math, 0*x=0(flat) and 1*x=x (nothing)

For the solution regarding texture with UV, it requires manual positioning of all the UVs, really long on a many thousands vertices mesh and, if the mesh is changed during the project, you have to unwrap it again. This modifier I think is more to rapidly displace huge quantities of "objects" in a single mesh. Imagine an artists made a nice city, the other one a nice terrain modelling, you want to put every building/house on the terrain, the height-map texture would allow it dynamically (both artists can modify their work and the final result is always good without intervention).

Hi @Patrice Bertrand (PatB),
is there anything left to do before this should got to master? I would really like to see it in 2.72, as it's providing much needed functionality in the mograph field - especially the separation of loose parts is important there.

Greetings, Thomas

@Thomas Beck (plasmasolutions), @Bastien Montagne (mont29): Hello Thomas. I would love to see it in 2.72 as well. Last time I worked on it was to merge it into the displace modifier. In April, the revision was commandeered by Bastien. He did some cleanup and it seemed ready for release. Maybe Bastien can tell if it's possible to get it into 2.72..

I’m OK with the patch (wouldn’t have spent hours on it otherwise ;) ), but we need final yes or no from Campbell, he’s maintainer of this area.

Hi @Campbell Barton (campbellbarton), what's your opinion on this? Functionality wise I am absolutely for an include. You simply can't do certain things without this modifier (like moving & animating individual chars from a converted text object). Is it ok for you if this goes into master?

From IRC:

Issue I have with this modifier is its in effect trying to make modifiers able to manipulate a single mesh as many, thats not bad in its self but its not how modifier system works currently and its clumsy to do it in the current modifier stack

Current code hashed object name and attempts to find if input changes, so it works around the fact that our API isnt well suited to the task.

if we have some improved modifier stack - nodal, for example, we could have a node that splits a mesh into many, then all operations after could be applied onto each, but IMHO this should be supported in a general way. Not everyone having to write own mesh-split-caching.

It seems useful to be able to take a mesh. convert each loose part into a triangle (for example), sent that through the modifier stack deformations etc... then apply the result back to the loose parts.

Hello @Campbell Barton (campbellbarton),

The nodal modifier design seems to be the holy grail. And yet it could take years to come, and we should not, in the meantime, give up on interresting features just because they would fit so much better with nodes. I think new features can be added within the current model when relevant, and may be then replaced by their nodal equivalent in the future.

Actually, I don't see a huge number of modifier features that would draw great benefits from a nodal model. In most cases, the current, linear, one-dimensionnal or stack model is exactly what one needs: do this, then do that, then that. In most cases, in a nodal modifier model, one would just layout nodes in a straight line, and join them with noodles.

Where would the nodal model really make a difference ? Where a given node is the parent of two or more child nodes, or where many nodes are joined as input into a single node. When would this happen ? Indeed, we could have a "Join" Node, that would take two meshes and perform a dynamic Join operation. We could have a Mix Node, that would take two displace-only deformations of a given mesh, and yield a weighed mix of the two, where each vertex is the weighed average position of its two deformed instances.

A nodal model would not handle only "deformed meshes", but should handle both "deformed meshes" and "mesh objects", so we would have two array nodes (or one with two outputs), one that yields a mesh with loose parts as today, and one that outputs as many mesh objects as there are items.

In a nodal model, a "Split loose parts" Node would take a mesh as input, and output many single mesh objects. But what would it mean for downstream nodes ? They should process each loose part chunk independently. The same with the array modifier Node: it could either yield a single mesh object as it does today, or yield as many independent mesh objects as array items. Before any coding, it seems there are some conceptual issues to be pondered here.

Let me get back to the Noise Modifier, now integrated as a new behaviour of the Displace Modifier.

Of the 3 modes:

  • I agree that vertex mode brings little added value as compared to the texture based displace. It could be trashed altogether. But then again it would have its use cases I'm sure.
  • Loose parts mode is the most specific, and really brings possibilities that do not exist otherwise. Acting separately on each item following one or several array modifiers is the most typical case, and it would justify the modifier by itself. There are other use cases. As Thomas mentions, moving & animating individual chars from a converted text object is another one.
  • Whole Mesh mode also brings in unique possibilities. Being able to copy objects, either by shift-D or alt-D, and yet have each copy be a little different is something that many would find very helpful. For example you place trees in a park, using a single model mesh object, and you would then modify each of them one by one, making some a little larger, some smaller, then turning them around their Z axis so they don't look alike. All of this would become automatic.

Cheers,

Patrice.

@Campbell Barton (campbellbarton) is there a plan for the new modifier stack? Will it be released this year? If not, it would be better to offer the solution to work on loose parts as it is now.
If I remember correctly, particle nodes were started in 2011 and we still don't have them. I sincerely that the money from gooseberry will help prevent projects stretching on so many years but as an artist, I see that it's working now, even if from a developer point of view it may not be perfect.
By the way, not everyone has to implement it's own loosepart algorithm, the code was made to be reusable.

Hi,
Just saw the video, very interesting development.
If loose part is the problem, there might be a workaround if the vertex numero can be used:
1/ we select the 'stack depth': the number of stacked modifiers we used.
For example, if we want the modifier to be applied for 2 two last (array) modifiers, just before the noise modifier, the 'stack depth' will be 2.

2/ we count the number of vertices BEFORE the last stack depth' modifiers are applied.
Example: 10 vertices (0 to 9).

3/ we use DIV operation to apply the noise to the vertices:
Example: apply the noise to vertices 0 to 9, then 10 to 19, ...

@Boris Fruhauf (bofzevampire),

I don't think working on loose parts was the actual blocking factor. Determining loose parts is actually pretty fast, and I had implemented caching of loose parts, so it was not a performance issue. The very notion of loose parts may have been a workaround for finding the original object (in most cases) after array modifiers have been applied. But actually loose parts do have a topological meaning of their own, and so it is not strange or dirty to have something act on loose parts. Many people had suggested that other modifiers could benefit from some loose parts setting.

From what I understand, loose parts put aside, the idea is that nothing that adds to modifiers is welcome at the moment.

It is true that it would be great to have more atomic modifiers : one that separates loose parts, and a different one to act on loose parts provided by the first one, and maybe another one doing a 'join' later on. This is the idea of a 'node based modifier', but it does not seem to be in the priorities.

As for what you propose, relying on vertex numbering to find the original object after an array modifier, that seems ugly to me ! There is nothing to say that modifiers will not change vertex numbering, event deform-only modifiers, even though for deform-only it is the case. Still, what about an array modifier, followed by bevel, followed by modifier working on loose parts ?

Is there a chance that this will be accepted into master?

I have applied this against HEAD and found that the rotation and scale failed with Loose parts, it always uses object centre as pivot point. The following patch fixes this for me.

diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 8d5c303..3749bbc 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -323,15 +323,14 @@ void static noise_displace_mesh_part(DisplaceModifierData *dmd, float (*vertexCo
                }
 
                /* Now prepare transform mat4 for this loose part. */
-               /* Since we are going to change the pivot point, we do not want any translation for now! */
-               loc_eul_size_to_mat4(mat, zero_v, rot, scale);
+               loc_eul_size_to_mat4(mat, trans, rot, scale);
                transform_pivot_set_m4(mat, pivot);
        }
        else {
                /* Loose part is affected but only with translation, much simpler. */
                unit_m4(mat);
+               copy_v3_v3(mat[3], trans);
        }
-       copy_v3_v3(mat[3], trans);
 
        for (i = 0; i < vcount; i++) {
                const int iv = vmap ? vmap->indices[i] : i;

Hello Shane,

I'm happy to see one more person interrested.

The answer is No: from what I understand, there is no chance that this will go into master. Which is sad and of course disappointing to me because a lot of work was wasted here, both by myself, and later by Bastien. But mostly it's disappointing because it really filled a need, and as a standalone modifier it is hard to see how it could have had any negative impact.

I have given up contributing to Blender, so I cannot give you feedback on your patch, because I don't have a dev environment ready anymore. I do find the reported bug surprising though, because the development was, at the time, thoroughly tested by many persons and various use-cases. Maybe a side-effect of some change in master ?

Best regards, Patrice ( & Charlie)

I've been eagerly awaiting this for a while so it's very disheartening to hear this isn't going in just because sometime in the future there MAY be a new modifier system. This really fulfills a need now and as you say is a standalone modifier so doesn't seem to be a downside. It would be sooo useful - please reconsider.

The answer is No: from what I understand, there is no chance that this will go into master. Which is sad and of course disappointing to me because a lot of work was wasted here, both by myself, and later by Bastien. But mostly it's disappointing because it really filled a need, and as a standalone modifier it is hard to see how it could have had any negative impact.

I would love to see this in blender as well. Why is a great work from the community not being honored and made compliant to be accepted? And this seems to be from a theoretical hindering reason.
Anyways, can this functionality just be converted into an AddOn? Or must it be maintained then continuously?

It's great work and really fills in a lack of functionality right now.

This is an absolute must have and it will solve many limitations that Blender has now for Motion Graphics. Just to give an example the E3D has very similar system that gives pretty cool results.

Just as Ton says is better a piece code that is not technically perfect but solves a problem than having that problem unsolved (more or less)

@Patrice Bertrand (PatB) I know it can be disheartening to have your work scrapped, you should put this down to an exercise in learning your way around blender's code and find another task to work on, maybe go with modifier nodes ;-)

@Mark Titchener (swmo) - this started as a standalone modifier but was merged into the displace modifier.

@Johannes Thomas Meyer (Samoth)

Anyways, can this functionality just be converted into an AddOn?

There is now an addon in the blender market - Random Object Array, while it isn't free it fills the gap, unless someone else creates a free version as well.

Before this was AMA - The advanced modifier array which added similar randomness only to the array modifier, it was developed after a funding drive so users voted by paying for it's development - that was also scrapped. So two attempts at getting this functionality into the main source code and now an addon has been made to do similar functionality. For reference the addon has had 25 sales in less than a month, the more popular addons have had several months head start to get ahead of it. This should give some indication that this functionality is wanted/needed in blender.

@Shane Ambler (sambler),

It's ok, I did get the re-engineering of the array modifier into the 2.72, so I will have left a tiny little trace into Blender source code.

I'm not disgruntled, and yet I think there is much to be done in order to avoid such huge wastes of energies. Indeed, I'm not the only one who's work was trashed, we see it happening every other day on the developpers' list. I'm not suggesting of course that whatever is proposed should be taken in, no matter the interest or the quality. Obviously, strenious filtering is necessary.

It's not the filtering that is a problem, what's missing is a known and open decision process. For the moment, only the final step of the process is known: the module owner is the one who says Yes or No. That's ok with me, since the product owner is also the one who will have to deal with the proposed feature and its impact on the whole module. It's only natural that he/she can say what is going in.

What is missing, however is an open process starting at earlier stages. Except for the mailing list, and some revision comments, there is no known way of proposing a feature and collect opinions and ideas, then hold an open discussion, with many participating, on how relevant it is, and whether it's worth doing it, and finally reaching a decision that: "if you work on this feature and your code is good, then it will be accepted, so from now on you can start working on it, you are not wasting your time". I don't think that this exists. It is likely that some developpers in an informal inner circle can trust that their work will be accepted or can get assurance from the module owner whom they know well, but first time developpers will have to work for weeks or months, then hope.

This is an important issue really, because what is wasted ultimately is not just the weeks of work that could have made Blender better, what is wasted is far bigger, it is the many contributions, over the many years to come, that these new contributors could have brought had they not been driven away.

Every day, we witness new would-be contributors knocking at the door, asking how they can get into Blender development. Out of these, probably less than one in 5 will ever submit usable code, but they of course must all be welcome because of this one in 5 that will emerge. But the developers that have already passed this 1 in 5 filter and have already shown their ability to submit good enough code, those represent an incredible potential for Blender. It is a small population of developpers that have climbed up the learning curve on their own, have demonstrated they have the IT knowledge, the time and the will to do useful things. Those should be identified better, should be cherished and should feel they matter, should even be called upon to work on new projects.

These are my thoughts on the matter. I hope it starts a fruitful discussion within the Blender community. As for me, I am using my time and energy elsewhere now.

Patrice.

Closing, see:

https://developer.blender.org/D320#9483

These kinds of modifiers (which attempt to edit a single mesh as many) dont fit well into the current design.

Rather then continuing to add modifiers which have to recalculate groups every update I would rather spend energy on a nodal modifier stack which had this built-into its design.