porting adaptive spacing to head branch (from GSoC 2010)
Closed, ArchivedPublic

Description

This is porting of a completed feature (adaptive spacing) from GSoC 2010, that accidentally got dropped during the merge.

It is working now but slow on larger meshes (suspect I introduced a bug during porting) so not yet ready for review, but adequate for some user testing.

Original work by Jason Wilkins during GSoC 2010

Details

Type
Patch

Hi Eric,

Adaptive spacing results in even daub spacing even though the geometry curves dramatically away from the viewport.

please see the two following images, the first shows two crease brush strokes done from the viewport, one without adaptive spacing (left) the other with (right)

After you rotate the view, you can see that there is uneven overlap with the stroke without adaptive spacing since the pixel space distance is drastically different than the on surface distance to the the geometry curvature. The adaptive spacing maintains a uniform daub distance even though the angle changes dramatically.

new version of patch - this includes the 'sampling range' for planes. Will split into two patches soon. Sampling range allows the radius for determining the area plane to be smaller/larger than the radius used for sculpting the geometry - this allows the user to more precisely determine which faces they want to use to determine the plane when using a locked plane, or make the brush follow the surface more/less closely when using an unlocked plane.

Added versioning so that sampling_range for area_normal is added to brushes.

Found the bug(s) wasn't calculating adaptive spacing so was always doing 1% doh! and then I was using the view_normal instead of true_view_normal. All seems to be working right now.

Bug fix, I was doing an clamping and scaling that was unneccessary resulting in any brush that wasn't close to 50px radius getting the wrong spacing, sometimes dramatically.

line and curve are both 'space' strokes, and thus should have the space options available.

I hate to bike-shed my own feature, but I hate the name "adaptive spacing". It seems like this should be the default behavior and the old screen-space based spacing should be called "spacing *based on screen distance" and adaptive spacing should just be "spacing". If you have to call this anything it should be "spacing *based on object distance"

I agree that it should be the default behaviour, eventually I'll make the old behaviour the option (screen spacing). Not quite ready to do that yet because I don't think it always gives better results.

I think it probably needs to over sample the surface (extra samples between where it will place dabs) and maybe even consider the derivative of the slope and do a proper quadrature to predict how much it should change spacing, instead of the simple change it does now (sorry if the implementation has been improved over my original simple one, I haven't had a chance to go over this patch)

Nope I haven't improved the design, and I agree that that would be a great improvement.

Dalai Felinto (dfelinto) closed this task as "Archived".Mon, May 22, 2:54 PM

Please create a proper patch in https://developer.blender.org/differential/diff/create/ using arcanist. Closing for now, but refer to this task when creating the patch so developers can read back the discussion.

I have just picked it up as a first starting project for GSoC and will create a patch if i have anything proper.
For now i have already hit a design snag.
The current problem is, changing the "screenspace" line spacing to "objectspace" line spacing.
As Jason already mentioned we need to sample the surface, measuring the distance traveled on the 3D object rather than measuring the distance moved by the mouse.
This poses quite a challenge in the aspect of performance because the surface needs to be sampled.

As long as we are not doing any fancy methods like evaluating the depth-framebuffer to calculate distance underneath the Strokeline i see two options:

  1. calculate the true distance by measuring the "crossline" over all faces underneath the stroke. (performance scales proportional to mesh complexity).
  2. sample the surface along the stroke with a reasonable amount of points (maybe taking normal into account) and calculate the distance between these points.

If any, which option is reasonable to realise this feature? In which direction should I investigate further?
Currently i think option 2. is reasonable. A small sample size would result in a similar effect like screenspace spacing and a bigger sample size results in more precise spacing.
For testing i tried it with the standard brush polling and got decent results when moving the mouse slowly (slow => more sample points on a surface)

Maybe there is already a system to get the 3D projected shape of a stroke which i am missing? (Grease pencil seems to sample the surface like option 2 but i have not checked the code thoroughly)

Edit:
I did some more research on the way GP handles the "draw on surface". It turns out that it uses view3d_opengl_read_Z_pixels to sample the depth per point created. So it is

doing any fancy methods like evaluating the depth-framebuffer

I was not expecting that but may be an option as well. The question then arises what to do if the sculpt object gets obscured by other objects.