[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