Curve data structures relation design #94193

Closed
opened 2021-12-17 15:53:02 +01:00 by Brecht Van Lommel · 34 comments

We currently have multiple curve data types. The new ones:

  • CurveEval: #87245 (Geometry Nodes: Curve Support Implementation)
    Editable with geometry nodes Supports different types of curves
    Data structure simpler to edit (like editmesh) Not a datablock
    C++ data structure that cannot be saved to file Not in Python API
    ** No rendering support
  • Hair: #68981 (New curves object type)
    Not editable with geometry nodes Always Catmull-Rom curve
    Data structure more memory efficient Is a datablock
    DNA C data structure that can be saved to file In the Python API for exporters/renderers
    ** Renderable with Cycles and Eevee

And then the older ones:

  • Curve
    Supports both curves and surfaces with multiple types, as well as text Datablock
    Can be saved to file Not renderable directly, but converted to mesh
  • EditNurb
    Supports both curves and surfaces with multiple types Runtime data structure created from Curve, like EditMesh
    ** Supports curve/surface edit mode
  • ParticleSystem hair
    Part of modifier on Object datablock Can be saved to file
    Edited in particle edit mode Renderable with Cycles and Eevee

With the addition of D11592: Alembic/USD: use geometry sets to import data, it raises the question how for Alembic curves should be imported, since usually that is hair you want to render. Alembic (and many other applications and file formats) do not make a distinction here, so choosing one or the other is not ideal. And of course in terms of functionality users would want to be able to do everything with the same datablock.

I'd like to get this design decided on so we are clear on the way forward, even if not everything might be implemented immediately. Some potential options:

  1. Have CurveEval as an EditMesh-like runtime representation that can convert to/from Hair, which is what remains used for rendering and the Python API.
  2. Remove CurveEval and use Hair (renamed to something more general) instead.
  3. Keep both data types as distinct for users, and extend both to support all required features.
We currently have multiple curve data types. The new ones: * `CurveEval`: #87245 (Geometry Nodes: Curve Support Implementation) **Editable with geometry nodes** Supports different types of curves **Data structure simpler to edit (like editmesh)** Not a datablock **C++ data structure that cannot be saved to file** Not in Python API ** No rendering support * `Hair`: #68981 (New curves object type) **Not editable with geometry nodes** Always Catmull-Rom curve **Data structure more memory efficient** Is a datablock **DNA C data structure that can be saved to file** In the Python API for exporters/renderers ** Renderable with Cycles and Eevee And then the older ones: * `Curve` **Supports both curves and surfaces with multiple types, as well as text** Datablock **Can be saved to file** Not renderable directly, but converted to mesh * `EditNurb` **Supports both curves and surfaces with multiple types** Runtime data structure created from `Curve`, like `EditMesh` ** Supports curve/surface edit mode * `ParticleSystem` hair **Part of modifier on `Object` datablock** Can be saved to file **Edited in particle edit mode** Renderable with Cycles and Eevee With the addition of [D11592: Alembic/USD: use geometry sets to import data](https://archive.blender.org/developer/D11592), it raises the question how for Alembic curves should be imported, since usually that is hair you want to render. Alembic (and many other applications and file formats) do not make a distinction here, so choosing one or the other is not ideal. And of course in terms of functionality users would want to be able to do everything with the same datablock. I'd like to get this design decided on so we are clear on the way forward, even if not everything might be implemented immediately. Some potential options: 1. Have `CurveEval` as an `EditMesh`-like runtime representation that can convert to/from `Hair`, which is what remains used for rendering and the Python API. 2. Remove `CurveEval` and use `Hair` (renamed to something more general) instead. 3. Keep both data types as distinct for users, and extend both to support all required features.
Author
Owner

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Author
Owner

Added subscriber: @brecht

Added subscriber: @brecht
Author
Owner
Added subscribers: @HooglyBoogly, @kevindietrich, @JacquesLucke
Author
Owner

@kevindietrich, @HooglyBoogly, @JacquesLucke, I would like to get your opinion on this, since it affects the design of D11592 which would be nice to have in 3.1.

Personally I would think of option (1) or even (2) if possible. From experience the mesh/editmesh distinction does lead to performance issues and code complexity, and curves don't need complex topological operations like meshes. But I feel like perhaps I'm missing the bigger picture of where you want to go with CurveEval.

@kevindietrich, @HooglyBoogly, @JacquesLucke, I would like to get your opinion on this, since it affects the design of [D11592](https://archive.blender.org/developer/D11592) which would be nice to have in 3.1. Personally I would think of option (1) or even (2) if possible. From experience the mesh/editmesh distinction does lead to performance issues and code complexity, and curves don't need complex topological operations like meshes. But I feel like perhaps I'm missing the bigger picture of where you want to go with `CurveEval`.
Member

When building CurveEval I saw it as corresponding to Blender's existing curves (Curve/Nurb) and eventually replacing their implementation.
I've wondered before if going further towards the design of the hair data structure might have been preferable. While CurveEval gives some contiguous chunks of memory to work on (better than Nurb), it wouldn't be nearly as efficient as Hair for the many small splines case.

I always thought that the two could compliment each other. CurveEval for doing more "CAD-like" tasks that require more precision, Hair when the number of splines is important, and for more organic situations. Edit mode operations would also be quite different.
While one could probably be made to do the tasks of the other, that wouldn't necessarily be most efficient or intuitive for the user. It's similar to the mesh vs. point cloud distinction. They're separated for clarity and efficiency, not necessarily because mesh couldn't do the same thing.

Python API
I'd like to add CurveEval to the python API. I had two main questions:

  • Should it be a new API, or use implicit conversion to and from Nurb to emulate the old one?
  • Attributes should be supported, but point domain attributes aren't stored contiguously, complicating the API a bit.

Rendering
I'd think both could be rendered, maybe even using the same implementation. For me the question is what happens to curves in existing files that didn't have a "bevel/curve to mesh node" before? Would we accept changing what those files looked like?

Datablock
Since CurveEval can be embedded into Curve (and already is for rendering), this one doesn't seem like a big deal to me.

Geometry Nodes
Obviously CurveEval is already supported in quite a few nodes. Some of those node operations could also support Hair, or we could add a separate node that processes hair (I think I prefer the latter).
As far as I know there are still open questions about how hair should be generated/rooted. It seemed to me like a node with Points, Normal, and Length inputs would be a good start.

When building `CurveEval` I saw it as corresponding to Blender's existing curves (`Curve`/`Nurb`) and eventually replacing their implementation. I've wondered before if going further towards the design of the hair data structure might have been preferable. While `CurveEval` gives some contiguous chunks of memory to work on (better than `Nurb`), it wouldn't be nearly as efficient as `Hair` for the many small splines case. I always thought that the two could compliment each other. `CurveEval` for doing more "CAD-like" tasks that require more precision, `Hair` when the number of splines is important, and for more organic situations. Edit mode operations would also be quite different. While one could probably be made to do the tasks of the other, that wouldn't necessarily be most efficient or intuitive for the user. It's similar to the mesh vs. point cloud distinction. They're separated for clarity and efficiency, not necessarily because mesh couldn't do the same thing. **Python API** I'd like to add `CurveEval` to the python API. I had two main questions: - Should it be a new API, or use implicit conversion to and from `Nurb` to emulate the old one? - Attributes should be supported, but point domain attributes aren't stored contiguously, complicating the API a bit. **Rendering** I'd think both could be rendered, maybe even using the same implementation. For me the question is what happens to curves in existing files that didn't have a "bevel/curve to mesh node" before? Would we accept changing what those files looked like? **Datablock** Since `CurveEval` can be embedded into `Curve` (and already is for rendering), this one doesn't seem like a big deal to me. **Geometry Nodes** Obviously `CurveEval` is already supported in quite a few nodes. *Some* of those node operations could also support `Hair`, or we could add a separate node that processes hair (I think I prefer the latter). As far as I know there are still open questions about how hair should be generated/rooted. It seemed to me like a node with `Points`, `Normal`, and `Length` inputs would be a good start.
Member

Ah, I typed that comment before I saw your edit and comment, so I didn't see that you were proposing to remove CurveEval. I still think the distinction is important, similar to meshes vs. point clouds like I mentioned above. I could write more, but I'll see what you think about what I wrote already. I'll just add a comment about the point you added.

Saving in Files
I didn't make a real design for saving CurveEval in files yet (since it's just a runtime data structure at the moment). But I thought about having a DNA struct that would just be storage for saving and loading it, basically just a pointer to a few arrays and custom data.

Ah, I typed that comment before I saw your edit and comment, so I didn't see that you were proposing to remove `CurveEval`. I still think the distinction is important, similar to meshes vs. point clouds like I mentioned above. I could write more, but I'll see what you think about what I wrote already. I'll just add a comment about the point you added. **Saving in Files** I didn't make a real design for saving `CurveEval` in files yet (since it's just a runtime data structure at the moment). But I thought about having a DNA struct that would just be storage for saving and loading it, basically just a pointer to a few arrays and custom data.
Brecht Van Lommel changed title from Hair and CurveEval relation design to Curve data structures relation design 2021-12-17 16:33:58 +01:00

For simplicity and "proceduralism", I would go for option 2, and just have a single data block for anything curve-like. We can have object level attributes to tell how control points should be interpreted and interpolated. I don't see the reason to have specific data structures for every case (BezTriple, etc.). This is how some other software packages handle it, and similarly for I/O formats like Alembic and USD.

Another of my concerns is arbitrary attributes, besides D11592: Alembic/USD: use geometry sets to import data, there is also D11591: Alembic: import arbitrary attributes which works for meshes and point clouds, but not curves (I do have files from users to help develop this feature), as I am basing it on the attribute API which uses an ID block. The old datablocks do not really support attributes, and CurveEval is awkward to work with here, and would introduce a lot of code complexity.

Option 1 makes sense if we need a data structure that is more fitted for manual edits (like BMesh in edit mode).

In #94193#1274649, @HooglyBoogly wrote:
I still think the distinction is important, similar to meshes vs. point clouds like I mentioned above.

There is a fundamental difference between meshes and point clouds. Having them separated makes sense. Curve (et al.) vs CurveEval is more comparable to Mesh vs BMesh, IMO.

For simplicity and "proceduralism", I would go for option 2, and just have a single data block for anything curve-like. We can have object level attributes to tell how control points should be interpreted and interpolated. I don't see the reason to have specific data structures for every case (`BezTriple`, etc.). This is how some other software packages handle it, and similarly for I/O formats like Alembic and USD. Another of my concerns is arbitrary attributes, besides [D11592: Alembic/USD: use geometry sets to import data](https://archive.blender.org/developer/D11592), there is also [D11591: Alembic: import arbitrary attributes](https://archive.blender.org/developer/D11591) which works for meshes and point clouds, but not curves (I do have files from users to help develop this feature), as I am basing it on the attribute API which uses an ID block. The old datablocks do not really support attributes, and `CurveEval` is awkward to work with here, and would introduce a lot of code complexity. Option 1 makes sense if we need a data structure that is more fitted for manual edits (like `BMesh` in edit mode). > In #94193#1274649, @HooglyBoogly wrote: > I still think the distinction is important, similar to meshes vs. point clouds like I mentioned above. There is a fundamental difference between meshes and point clouds. Having them separated makes sense. `Curve` (et al.) vs `CurveEval` is more comparable to `Mesh` vs `BMesh`, IMO.
Author
Owner

Curve also includes NURBS surfaces and Text that are definitely distinct from Hair, and probably should never have been part of the same data structure in the first place. So assuming we are not considering those as part of this.

Beyond that there are still distinct features between hair and other curves that matter on a user level, even if it would all just be attributes. Hair has an (optional) attachment to surfaces (probably polygon index + barycentric uv). Other curves have tilt, cyclic and poly spline types, which at least most renderers generally can't render directly.

I think it makes sense to have some level of distinction on a user level, but more only on the level of a "curve type" or "render as" setting on a shared datablock. There are definite trade-offs, but it's what currently seems better to me.

If it's a shared datablock you get reduced code complexity, better interop with other apps and file formats, and nodes/operators working on both that otherwise probably only would have been implemented for one. A downside is that the UI can be confusing in that some nodes, operators or settings may be exposed but don't work for unclear reasons. This can be clarified somewhat but not hidden completely from the user.

I also imagine that you would have separate edit mode and groom mode, much like we have a separate edit and sculpt modes for meshes. One for more precise CAD like operations, the other for editing lots of curves at once with brushes.

Under this assumption, you would of course end up with a different data structure. There could still be an equivalent to EditMesh in CurveEval. However I think it is important that you can e.g. load an Alembic file, modify the positions and render that without converting to such a data structure.

`Curve` also includes NURBS surfaces and Text that are definitely distinct from `Hair`, and probably should never have been part of the same data structure in the first place. So assuming we are not considering those as part of this. Beyond that there are still distinct features between hair and other curves that matter on a user level, even if it would all just be attributes. Hair has an (optional) attachment to surfaces (probably polygon index + barycentric uv). Other curves have tilt, cyclic and poly spline types, which at least most renderers generally can't render directly. I think it makes sense to have some level of distinction on a user level, but more only on the level of a "curve type" or "render as" setting on a shared datablock. There are definite trade-offs, but it's what currently seems better to me. If it's a shared datablock you get reduced code complexity, better interop with other apps and file formats, and nodes/operators working on both that otherwise probably only would have been implemented for one. A downside is that the UI can be confusing in that some nodes, operators or settings may be exposed but don't work for unclear reasons. This can be clarified somewhat but not hidden completely from the user. I also imagine that you would have separate edit mode and groom mode, much like we have a separate edit and sculpt modes for meshes. One for more precise CAD like operations, the other for editing lots of curves at once with brushes. Under this assumption, you would of course end up with a different data structure. There could still be an equivalent to `EditMesh` in `CurveEval`. However I think it is important that you can e.g. load an Alembic file, modify the positions and render that without converting to such a data structure.
Author
Owner

If we do make a change like this it can of course it is a significant project. For example we don't have an edit mode for Hair currently, and so you can't just move over curves to that without loosing functionality. Steps would probably look something like this:

  • Use Hair in Alembic/USD importers (for 3.1)
  • Add geometry nodes feature to auto convert Hair to CurveEval, or rewrite geometry nodes to use Hair and add Curve to Hair conversion (whenever the new hair project starts)
  • Add edit and groom/sculpt mode for Hair (whenever the new hair project starts)
  • Rename Curve to NURBS and move individual curves over to Hair, perhaps renamed to Curves (much later)
If we do make a change like this it can of course it is a significant project. For example we don't have an edit mode for `Hair` currently, and so you can't just move over curves to that without loosing functionality. Steps would probably look something like this: * Use `Hair` in Alembic/USD importers (for 3.1) * Add geometry nodes feature to auto convert `Hair` to `CurveEval`, or rewrite geometry nodes to use `Hair` and add `Curve` to `Hair` conversion (whenever the new hair project starts) * Add edit and groom/sculpt mode for `Hair` (whenever the new hair project starts) * Rename `Curve` to `NURBS` and move individual curves over to `Hair`, perhaps renamed to `Curves` (much later)

Added subscriber: @Garek

Added subscriber: @Garek
Member

Hans and I discussed the topic a bit today. We have some notes here: https://hackmd.io/@II9-Bkl4TJifCqGL2jgbUw/BJmWeEs9Y
We can continue talking about it next week.

Hans and I discussed the topic a bit today. We have some notes here: https://hackmd.io/@II9-Bkl4TJifCqGL2jgbUw/BJmWeEs9Y We can continue talking about it next week.

Added subscriber: @GeorgiaPacific

Added subscriber: @GeorgiaPacific

Added subscriber: @nantille

Added subscriber: @nantille

In reply to the question in your notes @JacquesLucke : "Under what circumstances can render engines benefit from rendering curves directly instead of a mesh generated from a curve?".
Easily any work related to using lots of splines like in my case in neuroscience. When rendering billions of custom splines, this is where you want to avoid meshes. But there are other cases than this of course.

I've submitted code for making curves renderable as hair in Cycles several years ago (https://developer.blender.org/D3822). I've even kept up to date my code that supports the latest master branch (and Hair object) in Cycles. Feel free to ping me, should you want to test it.

Ideally, the new Hair object would allow users to generate any number of splines with any number of points (+ radius + optional custom data thanks to new data attribute) and to set their positions/orientation manually or by code, not necessarily attached to a mesh surface. A great addition would be to be able to anchor one spline to another.

Also, the data would not be copied from Blender to Cycles. Instead Cycles would directly use the objects that Blender has in memory, otherwise we're looking at huge amounts of wasted memory.

In reply to the question in your notes @JacquesLucke : "Under what circumstances can render engines benefit from rendering curves directly instead of a mesh generated from a curve?". Easily any work related to using lots of splines like in my case in neuroscience. When rendering billions of custom splines, this is where you want to avoid meshes. But there are other cases than this of course. I've submitted code for making curves renderable as hair in Cycles several years ago (https://developer.blender.org/D3822). I've even kept up to date my code that supports the latest master branch (and Hair object) in Cycles. Feel free to ping me, should you want to test it. Ideally, the new Hair object would allow users to generate any number of splines with any number of points (+ radius + optional custom data thanks to new data attribute) and to set their positions/orientation manually or by code, not necessarily attached to a mesh surface. A great addition would be to be able to anchor one spline to another. Also, the data would not be copied from Blender to Cycles. Instead Cycles would directly use the objects that Blender has in memory, otherwise we're looking at huge amounts of wasted memory.
Member

Added subscriber: @lichtwerk

Added subscriber: @lichtwerk
Member

Added subscriber: @ChengduLittleA

Added subscriber: @ChengduLittleA
Author
Owner

A few comments on the doc:

  • Renderers generally can not render poly splines natively. Only catmull-rom, bezier and other smooth curves that can be converted to these with a simple basis transform. We could add support for them in Cycles and Eevee since OptiX and Embree added support for them (relatively recent I think). But I don't think that should be the default. Catmull-rom seems a good default since it's easy to edit both with nodes and brushes, since there are no handles to deal with.
  • I don't remember seeing segment or segment corner domains in file formats and renderers, not sure how useful that is and inteop would not be ideal. I think segments endpoints generally don't really have a meaning in a smooth curve, only for poly splines where there is a sharp transition point.
  • One additional domain type I have seen in renderers is where for a bezier curve you don't store attributes on the handles, which saves some memory. Not sure that's worth supporting.
  • Just renaming hair should be fine, don't even have to keep DNA compatibility.
  • Renderers and file formats generally do not support curves where different curves or points have different handle types. This could be supported in Blender, but probably would need to be converted to a single type for rendering and I/O. For example for Bezier curves there is not attribute to determine what is a handle, it's implicit from the index of the point in the spline.
  • Attachment of hair on a surface is currently poly index + barycentric coordinates for the particle system. UVs are not ideal since it requires the user to first unwrap the mesh, and lookup is slower. However Alembic in Unreal does work with UVs for example, so export might convert to this. The poly index instead of tessellated triangle index is used so we can attach the hair at varying subdivision surface levels (or even the limit surface).
A few comments on the doc: * Renderers generally can not render poly splines natively. Only catmull-rom, bezier and other smooth curves that can be converted to these with a simple basis transform. We could add support for them in Cycles and Eevee since OptiX and Embree added support for them (relatively recent I think). But I don't think that should be the default. Catmull-rom seems a good default since it's easy to edit both with nodes and brushes, since there are no handles to deal with. * I don't remember seeing segment or segment corner domains in file formats and renderers, not sure how useful that is and inteop would not be ideal. I think segments endpoints generally don't really have a meaning in a smooth curve, only for poly splines where there is a sharp transition point. * One additional domain type I have seen in renderers is where for a bezier curve you don't store attributes on the handles, which saves some memory. Not sure that's worth supporting. * Just renaming hair should be fine, don't even have to keep DNA compatibility. * Renderers and file formats generally do not support curves where different curves or points have different handle types. This could be supported in Blender, but probably would need to be converted to a single type for rendering and I/O. For example for Bezier curves there is not attribute to determine what is a handle, it's implicit from the index of the point in the spline. * Attachment of hair on a surface is currently poly index + barycentric coordinates for the particle system. UVs are not ideal since it requires the user to first unwrap the mesh, and lookup is slower. However Alembic in Unreal does work with UVs for example, so export might convert to this. The poly index instead of tessellated triangle index is used so we can attach the hair at varying subdivision surface levels (or even the limit surface).
Member

The curve trimming support thing I'm researching on is here: https://devtalk.blender.org/t/better-curve-surface-support/21113/44

The main thing I'm concerned here is that I need to use a curve in uv space to do the trim. I thought I should just keep you guys posted on this 🤔 .

The curve trimming support thing I'm researching on is here: https://devtalk.blender.org/t/better-curve-surface-support/21113/44 The main thing I'm concerned here is that I need to use a curve in uv space to do the trim. I thought I should just keep you guys posted on this 🤔 .
Member

In #94193#1277646, @brecht wrote:

  • ... But I don't think that should be the default. Catmull-rom seems a good default since it's easy to edit both with nodes and brushes, since there are no handles to deal with.

It seems fine to default to the type that's fastest for rendering. However, Poly and Bezier splines have important use cases in many workflows (like converting from mesh edges to splines).

  • I don't remember seeing segment or segment corner domains in file formats and renderers, not sure how useful that is and inteop would not be ideal. I think segments endpoints generally don't really have a meaning in a smooth curve, only for poly splines where there is a sharp transition point.
  • One additional domain type I have seen in renderers is where for a bezier curve you don't store attributes on the handles, which saves some memory. Not sure that's worth supporting.

What we did for CurveEval was just add right and left handle positions and types as attributes on the control points. The handles aren't control points then, they're just attributes that are used to find the evaluated shape for Bezier splines. That approach has worked quite well I think.

  • Just renaming hair should be fine, don't even have to keep DNA compatibility.

Great! I also think we should move part of the data structure to a separate DNA struct so it can be embedded in grease pencil data.

  • Renderers and file formats generally do not support curves where different curves or points have different handle types. This could be supported in Blender, but probably would need to be converted to a single type for rendering and I/O....

In Blender it is already supported, so we have to support it if we actually want to replace the implementation of the current curve object.

In #94193#1277649, @ChengduLittleA wrote:
The curve trimming support thing I'm researching on is here: https://devtalk.blender.org/t/better-curve-surface-support/21113/44

The main thing I'm concerned here is that I need to use a curve in uv space to do the trim. I thought I should just keep you guys posted on this 🤔 .

I don't think these tasks are that related actually, since this is really about curves rather than surfaces. Though I think the general purpose Curve data-block should be replaced with a more specific type for surfaces.

> In #94193#1277646, @brecht wrote: > * ... But I don't think that should be the default. Catmull-rom seems a good default since it's easy to edit both with nodes and brushes, since there are no handles to deal with. It seems fine to default to the type that's fastest for rendering. However, Poly and Bezier splines have important use cases in many workflows (like converting from mesh edges to splines). > * I don't remember seeing segment or segment corner domains in file formats and renderers, not sure how useful that is and inteop would not be ideal. I think segments endpoints generally don't really have a meaning in a smooth curve, only for poly splines where there is a sharp transition point. > * One additional domain type I have seen in renderers is where for a bezier curve you don't store attributes on the handles, which saves some memory. Not sure that's worth supporting. What we did for `CurveEval` was just add right and left handle positions and types as attributes on the control points. The handles aren't control points then, they're just attributes that are used to find the evaluated shape for Bezier splines. That approach has worked quite well I think. > * Just renaming hair should be fine, don't even have to keep DNA compatibility. Great! I also think we should move part of the data structure to a separate DNA struct so it can be embedded in grease pencil data. > * Renderers and file formats generally do not support curves where different curves or points have different handle types. This could be supported in Blender, but probably would need to be converted to a single type for rendering and I/O.... In Blender it is already supported, so we _have to_ support it if we actually want to replace the implementation of the current curve object. > In #94193#1277649, @ChengduLittleA wrote: > The curve trimming support thing I'm researching on is here: https://devtalk.blender.org/t/better-curve-surface-support/21113/44 > > The main thing I'm concerned here is that I need to use a curve in uv space to do the trim. I thought I should just keep you guys posted on this 🤔 . I don't think these tasks are that related actually, since this is really about curves rather than surfaces. Though I think the general purpose `Curve` data-block should be replaced with a more specific type for surfaces.
Author
Owner

For @kevindietrich to continue work on better hair import from Alembic / USD, I suggest the following:

  • Kévin updates D11592 to import into the existing Hair data structure, so that it can be rendered by Cycles & Eevee.
  • Kévin adds support for Alembic / USD attribute import and rendering with this data structure.
  • Geometry nodes team can then rename and extend this data structure when they have time, and add support for editing it with geometry nodes.

Does that seem reasonable?

For @kevindietrich to continue work on better hair import from Alembic / USD, I suggest the following: * Kévin updates [D11592](https://archive.blender.org/developer/D11592) to import into the existing `Hair` data structure, so that it can be rendered by Cycles & Eevee. * Kévin adds support for Alembic / USD attribute import and rendering with this data structure. * Geometry nodes team can then rename and extend this data structure when they have time, and add support for editing it with geometry nodes. Does that seem reasonable?
Member

Is this about run-time data only? Can we disable storing Hair objects in files for now? That would make the refactoring much easier, also because Hair objects can remain experimental and hidden from the user.
It feels like the id data block renaming should happen before we expose it to users.

Is this about run-time data only? Can we disable storing `Hair` objects in files for now? That would make the refactoring much easier, also because Hair objects can remain experimental and hidden from the user. It feels like the id data block renaming should happen before we expose it to users.
Author
Owner

It is mainly about runtime only data, but since you can apply modifiers this could actually get saved in .blend files.

We could leave them out of applying modifiers or even file saving. But if we could rename the data structure and make any other required changes first that would be better I think, since it's quite confusing to have such limitations.

For the datablock name, we could use Curves to be consistent with USD / Alembic, though it is confusing with the existing Curve datablock name. The HairMapping stuff could be removed until we decide on a convention for that.

It is mainly about runtime only data, but since you can apply modifiers this could actually get saved in .blend files. We could leave them out of applying modifiers or even file saving. But if we could rename the data structure and make any other required changes first that would be better I think, since it's quite confusing to have such limitations. For the datablock name, we could use `Curves` to be consistent with USD / Alembic, though it is confusing with the existing `Curve` datablock name. The `HairMapping` stuff could be removed until we decide on a convention for that.
Member

Jacques and I discussed the naming on the #core module channel for a while. In general we agreed that using a name with a plural like "curves" doesn't work because you might have multiple "curves" objects, and the double plural sounds quite weird. We also thought about common variable names. Here are the final changes proposed:

  • Hair -> SplineGroup (with spline_group variable name) (DNA and RNA)
  • New Splines type for embedding in an ID data-block (for future grease pencil support) (with splines variable name) (only DNA)
  • HairCurve -> SplineSlice (DNA and RNA)
  • Delete HairMapping struct
  • OB_HAIR -> OB_SPLINE
  • BKE_hair.h -> BKE_spline.h (BKE_spline_group.h would be another option)
  • BKE_spline.hh -> BKE_curve_eval.hh (in order to be different from the previous name)
  • DNA_hair_types.h -> DNA_spline_types.h
  • hair.cc -> spline.cc (spline_group.cc would be another option)

See P2700 for the proposed DNA_spline_types.h file.
Another option would be to embed the Splines data structure in the existing Curve data block. That might make naming simpler. Personally I think that makes any transition in the UI and the code much less clear though.

Jacques and I discussed the naming on the #core module channel for a while. In general we agreed that using a name with a plural like "curves" doesn't work because you might have multiple "curves" objects, and the double plural sounds quite weird. We also thought about common variable names. Here are the final changes proposed: - `Hair` -> `SplineGroup` (with `spline_group` variable name) (DNA and RNA) - New `Splines` type for embedding in an ID data-block (for future grease pencil support) (with `splines` variable name) (only DNA) - `HairCurve` -> `SplineSlice` (DNA and RNA) - Delete `HairMapping` struct - `OB_HAIR` -> `OB_SPLINE` - `BKE_hair.h` -> `BKE_spline.h` (`BKE_spline_group.h` would be another option) - `BKE_spline.hh` -> `BKE_curve_eval.hh` (in order to be different from the previous name) - `DNA_hair_types.h` -> `DNA_spline_types.h` - `hair.cc` -> `spline.cc` (`spline_group.cc` would be another option) See [P2700](https://archive.blender.org/developer/P2700.txt) for the proposed `DNA_spline_types.h` file. Another option would be to embed the `Splines` data structure in the existing `Curve` data block. That might make naming simpler. Personally I think that makes any transition in the UI and the code much less clear though.
Author
Owner

I would really argue for following existing naming standards and conventions. I don't know which other software calls equivalent data structures "spline group" or something involving "spline", but at least that's not what is used in USD/Alembic/Houdini/Maya. To me the term "spline" also sounds more like a technical term than one for users.

I agree multiple "Curves" objects is a bit odd, but it's also the most common name for this. I think it can work anyway, but if it's really considered a problem I would still prefer something like "CurveGroup", "CurveGeometry", "CurveSet".

I would really argue for following existing naming standards and conventions. I don't know which other software calls equivalent data structures "spline group" or something involving "spline", but at least that's not what is used in USD/Alembic/Houdini/Maya. To me the term "spline" also sounds more like a technical term than one for users. I agree multiple "Curves" objects is a bit odd, but it's also the most common name for this. I think it can work anyway, but if it's really considered a problem I would still prefer something like "CurveGroup", "CurveGeometry", "CurveSet".
Member

Even if we go for Curves and ignore the annoyances it causes when naming variables, it's still not clear to me how we present the difference between the two curve object types in the ui. If we allow having non-experimental Curves objects in .blend files, then we have to teach users that there are now two different kinds of curve objects, and what their difference is, and when to use which one, and what the limitations of each are. That definitely has to be approved by ui team people and probably Ton. I'm also not sure if adding a new data-block/object type in bcon2 is ok.

All of that would be quite a bit easier of the new data block would stay run-time only data in 3.1. That would give us time to decide how to present the two different curve object types in the ui.

Even if we go for `Curves` and ignore the annoyances it causes when naming variables, it's still not clear to me how we present the difference between the two curve object types in the ui. If we allow having non-experimental Curve**s** objects in .blend files, then we have to teach users that there are now two different kinds of curve objects, and what their difference is, and when to use which one, and what the limitations of each are. That definitely has to be approved by ui team people and probably Ton. I'm also not sure if adding a new data-block/object type in bcon2 is ok. All of that would be quite a bit easier of the new data block would stay run-time only data in 3.1. That would give us time to decide how to present the two different curve object types in the ui.
Author
Owner

We can move the whole thing to 3.2 regardless since this is getting complicated.

Thinking about it more, it's probably good regardless to keep this a runtime only data structure until there is some type of editing tool for this, or at least geometry nodes. Otherwise it's not particularly useful, and confusing that the curves are not editable. It's not so different from particular hair which you also can't apply with a modifier to become its own object.

For the UI, perhaps in a transition period this could be called "Hair Curves" or something along those lines, until it can actually existing general purpose curves. In other places like datablock filters we could avoid making a distinction and group them together under a single name.

We can move the whole thing to 3.2 regardless since this is getting complicated. Thinking about it more, it's probably good regardless to keep this a runtime only data structure until there is some type of editing tool for this, or at least geometry nodes. Otherwise it's not particularly useful, and confusing that the curves are not editable. It's not so different from particular hair which you also can't apply with a modifier to become its own object. For the UI, perhaps in a transition period this could be called "Hair Curves" or something along those lines, until it can actually existing general purpose curves. In other places like datablock filters we could avoid making a distinction and group them together under a single name.

Added subscriber: @hlorus

Added subscriber: @hlorus
Contributor

Added subscriber: @RedMser

Added subscriber: @RedMser

Added subscriber: @AndyCuccaro

Added subscriber: @AndyCuccaro

Added subscriber: @DuarteRamos

Added subscriber: @DuarteRamos

This issue was referenced by fcec55796e

This issue was referenced by fcec55796ee63cfaed366608b94ff85103344e8b

Added subscriber: @Osares

Added subscriber: @Osares

Added subscriber: @hzuika

Added subscriber: @hzuika
Member

Changed status from 'Confirmed' to: 'Resolved'

Changed status from 'Confirmed' to: 'Resolved'
Jacques Lucke self-assigned this 2022-03-22 14:37:49 +01:00
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
16 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#94193
No description provided.