Dev:Source/3D interaction/Transform Refactoring
目次
Notes
For simplicity sake, the whole transform code will be refered as a module.
Current State of the Refactoring
- DONE TransData conversions. PoseMode might need some polishing again (by Ton). **DONE Generic NumInput functions (input from event, output to headerprint).
- DONE Generic TransCon functions (simple input from mouse for global constraint, constraint line draw, generic projection matrix creation from constraint matrix)
- DONE TO Sphere (interactive version of the To Sphere tool and work on all possible TransData)
- DONE Translation (grab), Rotation, Resize, Shear, Warp, Shrink/Fatten, Free Rotate (press RKey twice)
- DONE Camera mode dolly and free rotate
- DONE Gears (Ctrl/Shift) are properly applied to constraints
- DONE Global/Local constraint toggle.
- DONE Proportional Editing: Added 3 new prop modes: Linear, Constant, Square Root demo image. LOD from the french community did a demo of that (including To Sphere too). With French audio commentary, you can get it here. And another one (with text commentary) here
. Ton added new icons for the dropdown menu last week too, so this pretty much wrap it up.
- OPTIMISATION DataType -> TransData: Ground work by Joeedh with some adaptation by myself. Ton redid a lot, generalised some functions.
- OPTIMISATION Designed a simple optimisation method for PET based on array sorting. The ground work is practicly there already and will require very little unlocalized changes yet bring good speed increase on large datasets. _this is finished_
- OPTIMISATION API design for constraints and context change (TransInfo). _Added context as a function argument to Transform. Much better that way._
- OPTIMISATION Constraint projection code. Single axis constraint could use a little tweaking. Also, possible incorrect result with planar constraints in perspective mode (when the view vector diverge from the plane orientation). NumInput is now applied correctly to constraints and prints correctly in the header.
- EXPERIMENTINGTrying my hand at a Connected option for PET, to restrict the area to connected geometry. Works with curves and meshes (curves don't take hiden CVs into account, will have to fix). Lots of work to do still, but not a bad start (the bulk of the work is in the conversion functions, the rest is easy stuff).
- Event driven functions separation
- Atomic function division
- Generic Modifiers (num input, constraints, ...)
Current State of the code:
The code has now been committed to Tuhopuu and Bf-Blender (Warning: the development is now done in bf-blender and since tuhopuu is synched once a week, it would be better if tests were done on bf-blender builds.)
KNOWN BUGS (in no particular order)
- Right now, None that I noted.
TODO (in no particular order)
- Constraint axis/plane drawing needs some beautifying.
- Two axis based constraints (Shear, Wrap without enhance). Different from planar constraints
- MetaElem resize (axis support, not just radius)
- Auto keyframe insertion
Principles
Type independance
The module needs to be data type unaware as much as possible. This implies two important points:
- We need a well defined internal data structure that can possibly contain all possible data which is to be transformed. This structure has to be scalable but that shouldn't be a problem.
- Each data type needs a conversion function. This ensures easy scalability to new data type and that changes to those do not have repercution on the module.
This will be known as transform data.
Global constraint
The module needs to be constraint oriented from the start. Therefore, it needs:
- Generic constraint data structure that is totally independant from transform data to ensure reusability
- Constraining code needs to be smart regarding view axis. By this I mean transformation is always possible on any constraint regardless of its orientation vis-à-vis the viewport.
Generic structure ensures we can not only constraint to local/global/view axis but also to edge axis, face normals, ... and the planes defined by all those vectors (perpendicular to).
Workflow suggestions
NOTE: I've explained the reasoning behind the new worlflow in the tuhopuu-devel mailing list in january, you can read it [[1]]. Transform was discussed on and off on that list so feel free to browse.
When constraining to axis space (local, global or view), axis can be selected by pressing axis key (X,Y,Z) through this new transform-widget-like workflow: Press and hold down MMB* _this pops up the axis in the view, colored and all_
- Move mouse near axis you want to constraint to _nearest axis (within limits) is highlighted_ Release MMB* to constrain to this axis
IMHO, this workflow is preferable to the "standard" transform widget/gizmo/whatever because selecting changes to the constraining axis can be done interactively and the action area (where user needs to click for an action) is not limited since axis are stretched to fit the screen.
This method can (and probably will) be extend to all constraining options: edges and face normals by adding a "Constraint method" mode which will toggle between:
- Global Axis
- Local Axis
- View Axis
- Edges
- Faces
To add Planar constraint to the system, the user can press Alt when selecting an axis to lock this axis (transform perpendicular to that axis).
Structures
- The data structures can be seen in Transform.h
Notes
- rot, quat and size are only set and used when needed (when transforming orientation and sized aware data). If not needed, the initial vectors don't need to be set either (logically)
- This data structure is not final but only the absolutely evident and required. I will probably be adding more as I re-go over the old mess and see what the convertion and after trans operation do in every case.
- Transformation is first passed through smtx to get the real transformation (after parenting, some constraints, ...) then applied to the data.
- Transformation is always calculated from the initial data (enables backtracing and easy reconstraining)
Comments
_Feel free to write any comments/note in this section_
- Having to hold down the mmb to change axis is a terrible idea. A better idea would be the same gizmo used in other apps+the regular blender method. Make it easy to switch back and forth to choose your preferred method.
- What about a transformation gizmo as in other 3d applications? A gizmo makes the access to axis and plane constraints easier. -- SOPPERA
- I addressed that point in the workflow section. Adding a gizmo would not be a problem, but you have a major convincing job ahead of you if you want me to do it. MP
- I've read the workflow section but I'm not sure that it will be as easy as with a gizmo. I'll be happy to test it as soon as it will be ready to use. SOPPERA
- It may actually require less time to add the gizmo and an enabling switch than to explain repeatedly why there is no gizmo :) Perhaps having it off as the default setting, with CTRL-SHIFT-G(izmo) to turn it on and off? EM
- I agree. The simple fact of the matter is, at this point most users _expect_ 3D transform widgets. I've watched people in Maya and Hash manipulate 3D data in an extremely fast, elegant way regardless of viewport and I've been holding my breath for this to get added to Blender. On top of that, clicking on the axes doesn't always pick the one you want in 3D views; it seems totally dependent on camera angle and how close the axes are to each other. Instead of having one long place to check, having simple dots / balls / arrows / whatever gives a much easier spot to grab. If the changes that are in the version of BF-Blender as of yesterday (19 April 2005 Tokyo time) are an indication of the workflow you've proposed I don't see that it's any easier than remembering the axis orientations (which is what I'm currently doing) -- I keep selecting the wrong axis in 3D views. I appreciate the work you've done, but I think that this is really one of those instances where ALL the other 3D programs adopted a feature for a good reason, and I hope you change your mind. If I had the coding abilities in 3D to add the widgets I would, but I don't, so all I can do is beg. CW
- I addressed that point in the workflow section. Adding a gizmo would not be a problem, but you have a major convincing job ahead of you if you want me to do it. MP
- For the constraint data type. Are you planning for it to hold limits or actual transformation data for the object. -- JW
- I'm not sure I understand what you mean with that. The constraint data will only hold information about the actual constrained to space, the actually constraining will be done in the per transformation code (since it's pretty much specific to each one how it is handled) MP
- Currently the blender system for constraints actually edits the object data to enforce the constraint. I was wondering if your refactor of the system intended to go with that same method or just a test with a pass/fail for the Transform function? -- JW
- I'm not sure I understand what you mean with that. The constraint data will only hold information about the actual constrained to space, the actually constraining will be done in the per transformation code (since it's pretty much specific to each one how it is handled) MP
- Why not incorporate the vertex weigth system into proportional editing. A modeller shaping a head would be able to paint weights on eg. the eyebrows, the lips, the nose, and then use the resulting vertex groups throughout his modelling session to adjust eyebrow and lip thickness, size of nose using standard transform tools. I know much of this is possible already with armatures, still I believe this would make things less complex and also allow weighted scaling (and would work a treat combined with a "Move along individual normals" tool). Please let me know if you would consider this, if not, I'll write a script for it. -- GDR
- Could be done, but not a priority. Actually, if wouldn't be that hard to implement using the owner pointer (when it will be there), but I never really touched the vertex group code so don't quote me on that ;) MP
- For the sqrt/linear fall off, maybe just have an option for "exponential" falloff, where the exponent is user definable (shift +/- keys or something to adjust). i.e. the extent of the influence is ((1 -( distance / radius ) ) ^ exponent) and the user can choose the exponent (0 = constant, 0.5 = sqrt, 1 = linear, 2 = qudaratic). It defaults to quadratic, and can be adjusted as the user seems fit (range 0->4 or something). That way there is less to cycle through to get the option you want. Or maybe more intutitive would be exponent = 2^afactor where the user chooses the factor, and the exponent is computed from that. So a = -1 -> sqrt, a=0 -> linear, a=1 -> quadratic (constant is then it's own separate option if really desired or just a very negative value of a will get it close enough.) -- TS (PS: Thanks for the topology based PET)
- Or some other formulae: influence = (1 - (distance / radius)^(2^fac))^(2^-fac) -- fac < 0 -> expoential fall off, fac = 0 -> linear, fac = 1.0 -> circle. This is a little more useful than what is proposed above, because when fac > 0, at distance 0 the derivative is also zero, thus no knob point like with sqrt falloff.
- or for fac >=0, use the formula above, for fac < 0, influence = 1 - (1 - (distance / radius)^(2^-fac))^(2^fac) -- this way when fac < 0, it's a mirror of the values for fac > 0. i.e. at fac = -1, the fall off is opposite of circular falloff.
-- DeveloperWikiMartinPoirier - 10 May 2005