Created this thread primarily to discuss and update the work done on Bevel during this years summer of code.
Happy to see you guys working on it!
Would be amazing if Bevel after Booleans would not result in errors:
Let me (Rohan’s primary mentor on this project) get the ball rolling here. I’m giving some information that both Rohan and I know, so that others can follow along and offer their opinions, if they like.
First, some reference links:
- Rohan’s GSoC 2018 Proposal
- Developer notes on Blender’s Bevel
- Developer notes on Split Normals
- main code for bevel functionality, bmesh_bevel.c
The first task in the proposal is to add a ‘harden normals’ option to Bevel. This has been a long-standing user request. The suggestion in that request is to do what Y.A.V.N.E. does with certain settings of ‘weight type’ and ‘weight influence’ on the resulting faces of Bevel. I think that is approximately right, but we can do better for the specific case of Bevel because we don’t have to use weight types and influence types on the faces to get the normals strongly influenced by certain faces, but in fact can just state exactly what each normal should be based on the role of the face corner in the bevel.
Look at this diagram of the result of a typical multi-segment edge bevel:
First, some terminology used in the bevel code.
- Reconstructed (“existing”) polygons (green in picture): a face that contained a beveled edge or vertex and had to be rebuilt using the new vertices introduced by the bevel
- Edge polygons (blue in picture): for an edge bevel, these are the long thin polygons that replace the beveled edges along their length. There will be several replacing a given edge in the case of multi-segment bevels.
- Vertex polygons, also called VMesh in the code (pink in picture): these are the polygons that replace vertices where more than two beveled edges meet or where a beveled edge terminates. When segments = 1, it is just one ngon, but for segments > 1, it is a pattern of multiple quads with perhaps one ngon in the center. Some vertices involved in an edge bevel don’t get vertex polygons. For example the top front edge in the picture changes direction in the middle at what the code calls a ‘weld’ - since only two beveled edges meet there, there is no need for vertex polygons.
Now some background on custom split normals in Blender. Blender faces are made up of loops. You can think of a loop as a vertex and an outgoing edge in a particular face. With custom split normals, we can set separate normals at each loop vertex (so, since there are multiple faces around a vertex, and thus multiple loops, there can be many custom normals at a vertex). Except that’s a simplification. In the code, you can only have separate normals for a smooth fan - which is a set of loops sharing the same vertex, and belonging to faces joined by smooth edges only.
So what do we want with ‘harden normals’ for bevel? I would say something like this (feel free to disagree with or refine this, any readers):
- In reconstructed polygons, each loop at a vertex involved in a bevel should have a custom normal that is the same as the face normal. If the face isn’t planar, perhaps instead it should be the normal at each particular corner (use cross product on incoming and outgoing edges - which works unless the edges are parallel).
- The other faces attached to those vertices of reconstructed polygons are the edge faces and perhaps a ‘corner’ face of the VMesh. The loops at such a vertex should also get the normal we just made for the reconstructed face at that vertex. I think this means that the entire ring of loops around the vertex should be a smooth fan, but that wouldn’t be required, as along as the values of all smooth-loop-fan-group normals are all the same.
- For the other vertices of edge polygons (not adjacent to reconstructed polygons), some kind of weighted average of corner normals all around the vertex should likely be the correct value. Again, I think the whole ring can probably be one smooth loop fan. I don’t know what the appropriate weighting should be (opinions?).
All of this leaves out: what to do if an edge is marked sharp. Two cases to consider: when the edge is beveled, and when it is not. In the latter case, it is clear we should leave it sharp, and that means that in some cases we can’t just have one entire ring around a vertex be a smooth fan (e.g., the vertex at the bottom of the weld joint in the picture, if that vertical mid edge were marked sharp).
Wazou: I’m not sure I agree that there’s a problem in the image you posted. I’m interested to see if I’m out of touch here.
To your question about tool vs. modifier: the code for the two is almost completely shared, and I will push to keep the two feature-equivalent.
cgstrive: I suspect that the problems with Bevel-after-boolean are a combination of: (1) Boolean problems; (2) the fact that Bevel currently doesn’t do anything about cases when the bevel causes edges to move past other geometry (overlapping), unless one uses ‘clamp’, which itself is not perfect at calculating the right clamp value.
For problem (1), that is out of scope for this GSoC, though coincidentally it is my current personal project to improve Blender’s Booleans, and that may fix some of those problems. For problem (2), I think this is likely too hard to fit into the time we have for GSoC, but maybe there are some simple cases that could be made to work.
Thank you Howard for indepth explanation and reply, also your brilliant work on bevel and others modifiers (@DataTransfer!).
I have been using Rohans Weighted Normals Modifier in production for a while now(Ty Rohan!). 3/4 cases Bevel is not the last modifier in the stack(even with game assets). My fear is that when you combine it with Mirror(welding in center), deformers(such as Lattice) or other modifiers (booleans, solidify etc) then normals data would most likely get corrupted (as it does in my not up to date build). With weighted normals modifier as last one in the modifier in stack there are no problems! Works almost flawlessly. I suspect with Bevel doing it automatically, it would also require expensive patchwork for other modifiers. I fear it might complicate and clutter, require a lot of time to make it work.
The only scenario I can think of is for Beveled edges to have controlled, mostly minimal value(production experience wise as bevels are usually tiny).
Regarding my prior screenshot and request, it would be fantastic if you do get a chance to address it. It’s one of the most wanted features for modeling in any software. If anyone can do it, it’s you guys. Here’s one of many lengthy discussion on BA: https://blenderartists.org/t/mesh-fushion-bevel-boolean-fuse-blender-solution/693512
Edit. Added visual example:
very kind of you starting this thread - after skimming over the proposal, so the aim is mostly about improving the normals rather than to work on the behaviour of the generated mesh?
ah wazou was quick at pointing out some issues about the later…
Wazou: does profile=1 give you the result you expect in your case? (Seems to, to me) What if a user wants some amount of rounding on the beveled edges? That’s what the default result is trying to achieve. I wonder if other users find the first result really bad and unexpected?
kio: the scope of the GSoC is not limited to the normals; that is just the first task. We’ll see what else there is time for, but suggestions on this thread are welcome.
Hi Howard. I will like to ask about some improvements in bevel…
- Correct generation of edge data
- Correct bevel of vertex!!!
- Input/Output Groups
- Mark new polygons with weight value (Yeah, you don’t want it, but is really usefull)
- Bevel custom curve!!!
If we set the profile to 1 we want it to be strait, not rounded, in this case we decrease the profile.
So, the result is not wanted and it’s really bad when making hard surfaces.
I use Blender 2.79b, I will try on the daily builds.
Edit : Fixed in the daily builds, you can remove my message if you want
Yeah, I did some work on profile=1 (and 0) case fairly recently; sorry it didn’t make 2.79.
Alberto: I’m afraid I don’t understand most of your requests for improvements to bevel. I think I know what “Bevel custom curve” means (a custom curve for profiles), but you need to explain more what each of the others means.
Yeah, sorry, i wrote from mobile.
Correct generation of bevel data: Actually you obtain “holes” in some edge data when two bevel are generated. Other times some strange material is selected in a loop, in some parts of the loop the bevel select one side material, in other part the other side, but I don’t find the problem ritght now, maybe it’s solved?
Correct bevel of vertex: The vertex bevel is not coherent right now.
Output Groups: Other times you need to collapse the mesh and work with it, to have the possibility to have all bevel generated in a group will help in some workflows, and like before in a future node modifiers workflow it will help a lot. Could be better if we had face and edge groups, but blender doesn’t support these by the moment.
Mark new polygons with weight value: For example, when an artist made midpolys assets the bevel help a lot, also that bevel keep the normals like in this GSOC. But other times you need anyway a weight normal modifier, but you cannot change the bevel weight values because you need to collapse mesh to edit.
Bevel custom profile curve: Well, you explain this.
Note: I’m using blender since six years 8 hours each day and I didn’t see that we have “vertex group” in the limit method. ¬_¬U
Thanks Alberto. That makes it clearer. Some comments:
For "correct generation of bevel data" - I can’t tell from your diagram what you mean, but you say you couldn’t find the problem so maybe that’s just an unilluminating diagram right now. But I think what you are saying is that the material and other per-face data that is created for the new edge and vertex polygons are sometimes surprising to you. Keep in mind that sometimes there is no clear choice as to which adjacent face’s data to use: for example, if you bevel a cube edge with one segment and the materials are different on the two adjacent faces, which do you choose? The choice is arbitrary. One can try to make up rules as to how to break ties, to try to aim for “consistency” across the model, but I don’t have a good idea for what such a rule would look like; would welcome suggestions.
For “Correct bevel of vertex”: Yes, I see your point. I’ve been a little fixated on the question of which way should it bulge (inwards or outwards) - there seemed to be no good principle on which to decide, so I made them straight. But the border corner vertices have a bulge that varies with the profile parameter - it is close to a bug that the internal beveled vertices don’t also have a curve that varies with the profile parameter.
For “Output Groups” - I get it: besides selecting newly generated geometry, you would like an option to add the selected vertices to a vertex group (well, really, also you want edge and face groups too, but those don’t exist in Blender right now, as you say). This is an interesting idea and I see the value of it. It feels like this isn’t just applicable to Bevel, though. Maybe all modifiers that create geometry should do this. Or maybe we should add a new modifier that converts the selection into a vertex group. The Vertex Weight Edit modifier almost does this, but operates on weights, not selections. By the way, some other Blender developers have indicated no great objection to having edge and face groups; maybe they will get added to 2.8 if someone has the energy to do so.
For “Mark new polygons with weight value” - I’m not sure which weights you are talking about, but it seems to be related to the weights that would be used in Rohan’s weighted normal modifier if it occurs later in the stack?
For “Bevel custom profile curve” - yes, the concept is clear, and it has been on my wish list to add for quite a while. There are two difficulties to solve:
(1) How to choose the orientation of the curve – that is, on which face does the profile curve start and on which does it end? One could choose randomly and then provide a ‘flip’ option if one doesn’t like the choice, but unless there is a ‘flip’ option per edge (a new edge weight? ugh) then some might flip to the way one wants but others may not. In simple cases, like selecting disconnected chains and loops, it is easy to get a consistent choice per chain and per loop, but the choices for those disconnected groups would be incoherent. And the case where more than two beveled edges meet at a vertex is even trickier to handle. One could avoid all of these problems by making the profile symmetric: that is, assuming that the right end of the curve you’ve drawn is actually the middle of a symmetric profile; but that removes a large swath of desired effects from the table. Maybe the right thing is to do the best we can on the asymmetric case but have a ‘symmetric’ checkbox that will more likely work for all cases.
(2) A bit unknown to me is how hard it would be to calculate the vertex meshes (as I defined them in my first post in this thread). It could be easy, it could be very hard. I don’t know because I haven’t looked at this yet.
I’m talking about edge data, the bevel don’t keep the seam, mark sharp or other type of data.Normally you would expect the edge information to continue inside the bevel that has been generated. That’s what I meant by the image.
On the other hand, he also commented on the lack of material data of the faces generated. It is true that it is difficult to calculate, but many times I have encountered very difficult cases to understand, such as loops that have a material constantly except for “random” faces that have the opposite material. I understand it can’t be easy to design. And it’s still a minor problem.
Wouldn’t it be better if the profile simply changed not only the bulge but also the vertex edge?
If in the near future the modifiers appear by nodes (or everything nodes) it would be almost an obligation in most modifiers to be able to treat this information. Let’s see if with a bit of luck the groups are also implemented by edge and face.
Yes, the current problem is that nothing respects custom normals, no modifiers, almost no tools, not even modifying triangulate (which is a problem) and it would make the job much easier in some situations if the faces generated by the bevel modifier had a weight decided by the user.
I think you don’t have to worry about it, and just give it the option to flip and activate the symmetry. Nobody expects the profile to work perfectly, and most of the time it will be used simply for simple situations (Nobody will profile the frame of a painting and cross it dozens of times with themselves).
Houdini currently has that option, it would be nice to see how he solves the problem or if he just doesn’t do it. But as I say, as a user I am always in favour of giving the option even if it doesn’t work in 100% of the situations to not give the possibility. I’m sure @cgstrive will agree with me.
Merge near vertex- This option is perhaps crazy, but it would probably also be nice if the bevel were optionally able to merge the vertices of the bevel that are getting too close together or the ones that are “eating” from the piece itself as it moves to the surface. This way you can avoid shady strangers like the ones shown by cgstrive.
By far this may be the craziest thing I’ve ever said, but it would be a good way to make up for the lack of fillet.
If you find examples where the edge or face data created by Bevel seems wrong to you, file a bug and I can look at it. I tried to make it do the right thing. For seams, it is somewhat of a question which edges in a multisegment bevel should inherit the seam property.
The ‘merge near vertex’ idea is one I’ve worked a bit on, but is quite hard, so I never end up finishing. I understand how useful that would be. One of these days…
Hello guys! Please think about variation of bevel topology. Here is some comparision between c4d bevel and blender. c4d has 4 variants of bevel topology and it’s work well. Would be so cool to be able do the same thing in blender. Third variant of bevel topology in c4d just perfect for a lot of cases in hardsurface modelling. To get the same result in blender you should do it in two steps. And it turns in a big pain when you need to do this everywhere and many times