[Bf-committers] Transform Whitepaper
Ton Roosendaal
bf-committers@blender.org
Wed, 18 Feb 2004 14:55:37 +0100
Hi,
Great, thanks. Give me some time to digest it. Currently I have a
couple of more urgent tasks on my desk... :)
-Ton-
On Sunday, Feb 15, 2004, at 21:29 Europe/Amsterdam, Martin Poirier
wrote:
> Like I said in this meeting this morning, I finished
> working on the new transform data structure and
> guidelines. This is not an extensive guide to how the
> code will work and some of it (especially part of the
> constraining code) is still in my brain. I'll continue
> adding to it as I code, so I'll probably end up
> putting it somewhere online and posting it with the
> code updates (I'll commit to tuhopuu first).
>
> I'm open to suggestions, comments and help (though
> there's not much to comment on right now).
>
> The main goal of redoing the transform code is of
> course to clean and split the nice 1600 lines of
> crammed up code and make it more easy to add new
> functionality (whether it's a new transformation mode,
> new constraining, etc).
>
> Martin
>
> __________________________________
> Do you Yahoo!?
> Yahoo! Finance: Get your refund fast by filing online.
> http://taxes.yahoo.com/filing.html
> Transform
> |
> |- Parsing the mode
> |
> |- Initialising Trans_Constraint with mode arguments (if needed)
> |
> |- Running all the pretransform code (trans init, centre, ...)
> |
> |- Actual transformation
> | |- Mouse Input
> | |- Keyboard Input
> | |- Constraint
> | |- Applying the transformation
> | |- Screen Update
> |
> |- After trans code
>
>
> Trans_Constraint is initialised in Transform(), this way it can be
> kept when chaining multiple transformations
> or when switching from one transformation to another.
> Some transformations do not support constraints (shear, warp,
> shrink/fatten), in those cases, it's just ignored.
>
> Num_Input is local to each transformation function since there's no
> point in keeping it, and we need to reset
> it when the user switches from one mode to another and depending on
> the transformation,
> the number of different input may vary (3 for grab/scale, 1 or 2 for
> rotate, 1 for the rest)
>
> Transform (int mode)
> Variable initialisation
> Parse_Mode (mode, T_Const) // Parsing mode and setting T_Const
> Pre trans code
> While mode != End of transform
> call the function corresponding to the mode
> After trans code
>
>
> Each mode transform function is structured like this:
>
> Take mouse motion and transfer as a 3D motion
> Apply Trans_Constraint (proper to each transformation)
> Apply Num_Input
> Num_Input uses Trans_Constraint to get the final motion
> (logically, when typing a value constraint to an axis, you want the
> value to be the motion along the axis)
> Apply the tranformation (copied over from original function with some
> cleaning due to the use of Trans_Constraint)
> Keyboard Handling Common to all transformations (PET +/-, switching
> from one mode to another)
> Keyboard Handling for Num_Input. A function interprets the keyboard
> events and puts it into a Num_Input struct
> but each transformation handle those struct differently
> Header_Print (Displays the motion
> Screen update
>
>
> Middle mouse once constraint to nearest global axis, twice enters a
> constraint selection mode
> X,Y,Z once constraint to the global axis, twice pop up a choice menu:
> OFF, GLOBAL, LOCAL, VIEW
>
> Constraint Selection mode
> Still to be completely designed, but it lets the user choose an axis,
> an edge or a face (normal)
>
>
>
>
> /*
> -----------------------------------------------------------------------
> ---------------------------------- */
> /* - - - - - - - - - - - - - - Transformation constraint data
> structure - - - - - - - - - - - - - - - - - - */
> /*
> -----------------------------------------------------------------------
> ---------------------------------- */
>
> typedef struct Trans_Constraint {
> char Text[50]; /* Description of the Constraint for
> header_print */
> float mtx[3][3]; /* Matrix of the Constraint space */
> float inv_mtx[3][3]; /* Inverse Matrix of the Constraint space */
> float centre[3]; /* copy of the transformation centre to define
> where to draw the view widget */
> int mode; /* Mode flags of the Constraint */
> } Trans_Constraint ;
>
> /*
>
> Corresponding index of the axis in the matrix
> 0: X_TRANS, E_TRANS, N_TRANS
> 1: Y_TRANS
> 2: Z_TRANS
>
> WARNING: All matrices are expressed in GLOBAL space and only include
> rotation info.
>
> */
>
> /* AXIS FLAGS also defines the color of the axis line */
> #define X_TRANS 1 /* Transformation along a X axis */
> #define Y_TRANS 2 /* Transformation along a Y axis */
> #define Z_TRANS 4 /* Transformation along a Z axis */
> #define E_TRANS 8 /* Transformation along an edge */
> #define N_TRANS 16 /* Transformation along a normal */
>
> /* MODIFIER FLAGS change the effect of the constraint */
> #define PLANE_TRANS 32 /* Transformation on the plane perpendicular to
> the defined axis */
>
> /* INFORMATION FLAGS helps to output a valid description */
> #define GLOBAL_TRANS 64 /* Transformation on a global axis */
> #define LOCAL_TRANS 128 /* Transformation on a local axis */
> #define VIEW_TRANS 256 /* Transformation on a view axis */
>
> #define X_PLANE_TRANS (X_TRANS|PLANE_TRANS)
> #define Y_PLANE_TRANS (Y_TRANS|PLANE_TRANS)
> #define Z_PLANE_TRANS (Z_TRANS|PLANE_TRANS)
> #define E_PLANE_TRANS (E_TRANS|PLANE_TRANS)
> #define N_PLANE_TRANS (N_TRANS|PLANE_TRANS)
>
> /* Constraint to a face is the same as Constraint to a plane
> perpendicular to the normal (obviously) */
> #define F_TRANS (E_TRANS|PLANE_TRANS)
>
> /*
> -----------------------------------------------------------------------
> ---------------------------------- */
> /* - - - - - - - - - - - - - - - - - - Numerical input data structure
> - - - - - - - - - - - - - - - - - - - */
> /*
> -----------------------------------------------------------------------
> ---------------------------------- */
>
> typedef struct Num_Input {
> float Val; /* Direct value of the input */
> float Ctrl; /* Control to indicate what to do with the numbers that
> are typed */
> } Num_Input ;
>
> /*
> if (abs(Ctrl) == 1)
> Val = Val*10 + Ctrl * Typed_Number;
> else {
> Val += Ctrl * Typed_Number;
> Ctrl /= 10;
> }
> */
>
> When "." is pressed, Ctrl is set to 1/10 if (Ctrl == 1 || Ctrl == -1)
> When "-" is pressed, Val *= -1 and Ctrl *= -1
> Ctrl is 0 by default. As soon as num input mode is entered, it changes
> to 1.
> This is done for transformation mode where a value of 0 does not
> means no transformation
>
>
>
> /*
> -----------------------------------------------------------------------
> ---------------------------------- */
> /* - - - - - - - - - - - - - - - - - - - - - - Pretransform code - - -
> - - - - - - - - - - - - - - - - - - - */
> /*
> -----------------------------------------------------------------------
> ---------------------------------- */
>
> /* INITIALISATION OF TRANSFORM OBJECTS */
>
> if(G.obedit) {
> if(mode=='N') vertexnormals(0);
>
> if(mode=='N') vertexnormals(0);
> /* min en max needed for warp, the last parameter is for PET */
> make_trans_verts(min, max, 0);
> }
> else if (G.obpose){
>
> switch (G.obpose->type) {
> case OB_ARMATURE:
> /* figure out which bones need calculating */
> figure_bone_nocalc(G.obpose);
> figure_pose_updating();
> make_trans_bones(mode);
> break;
> }
> }
> else {
> int opt= 0;
> if (mode=='g' || mode=='G') opt= 'g';
> else if (mode=='r' || mode=='R') opt= 'r';
> else if (mode=='s' || mode=='S') opt= 's';
>
> setbaseflags_for_editing(opt);
> figure_pose_updating();
> make_trans_objects();
> }
>
> /* CHECK FOR IMPOSSIBLE TRANSFORMATIONS */
>
> if(tottrans==0) {
> if(G.obedit==0) clearbaseflags_for_editing();
> return;
> }
>
> /* some checks missing for operations that only take place in edit
> mode */
>
>
> /* INITIALISATION OF centre */
>
> if(G.vd->around==V3D_LOCAL) {
> if(G.obedit) {
> centre[0]= centre[1]= centre[2]= 0.0;
> }
>
> }
> if(G.vd->around==V3D_CENTROID) {
> VECCOPY(centre, centroid);
> }
> else if(G.vd->around==V3D_CURSOR) {
> curs= give_cursor();
> VECCOPY(centre, curs);
>
> if(G.obedit) {
> VecSubf(centre, centre, G.obedit->obmat[3]);
> Mat3CpyMat4(mat, G.obedit->obmat);
> Mat3Inv(imat, mat);
> Mat3MulVecfl(imat, centre);
> }
>
> }
>
> /* Always rotate around object centroid */
> if (G.obpose){
> VECCOPY (centre, centroid);
> }
>
>
> SOME STUFF MISSING HERE, WILL NEED TO ASK TON WHAT THE CODE DOES.
------------------------------------------------------------------------
--
Ton Roosendaal Blender Foundation ton@blender.org
http://www.blender.org