[Bf-committers] Thoughts on transform code rewrite - attention Theeth

bf-committers@blender.org bf-committers@blender.org
Thu, 20 May 2004 10:04:40 -0500


On 20 May 2004 at 11:43, Ton Roosendaal wrote:

> Hi,
> 
> Just separating the transform in a per-mode or per-object type won't  
> help really... too much code then needs to be maintained double.
> It is also important to at least try to provide the most uniform  
> possible access to each transform mode, also from user point of view.  
> There's a lot of overlap in code, and only few exceptions. Like for  
> bones, manipulating skeletons efficiently could be just a separate  
> piece of code.
Your right, after further investigation Bones or Posemode is the only 
real exception to most of the transform code. A separate PoseMode 
function is probably the best solution. But do we want to have that 
called seperately or called from the transform() function?
> 
> Another aspect is for example extrusion of faces, which should be  
> possible based on direction of normals of the faces. And don't forget  
> Python hooks!
> 
> The function pointer idea could assist yes in helping design of clearly  
> separated and small functions to do the transform, but I still miss the  
> big picture and a clear set of functional targets what to achieve. A  
> reconstruction of code should at least give same performance and  
> functionality, and open up easier access to improve and add  
> functionality.
> 
> I've also written a short summary of what I expect from it... there's a  
> *lot* of work todo here, but we shouldn't be afraid of targeting at  
> something thats truely an improvement.
> 
> Below copied my version of what we could do:
> 
> ---------------
> (reaction to Theeths transform proposal, mail from March 11)
> 
> I would like to see added some way to have Python playing with it. And  
> of course, enabling the much wanted 'transform 3d widget'  
> (manipulators).
> That would mean: the system has to become event based, and not with a  
> sub-loop anymore.
> 
>  From event based perspective it could be like:
> (note; constraint here means user input like X-axis constraint)
> 
> Start Transformer engine
> |- Parsing the mode
> |- Initialising Trans_Constraint with mode arguments (if needed)
I assume trans_constraint sets up the limits the handler will have to 
work in? Not really sure what your looking for here.
> |- Running all the pre-transform code (trans init, centre, ...)
> |
> |- maybe: some callback to verify if data operated on is still valid
> |-
> |- end with: setting up some 'transform handler' which can be called  
> from event loops
> 
> Handle Transformer
> |- mouse input
> |- keyboard input
> |- constraint
> |- etc
> 
> Close Transformer
> |- after trans code
> 
> None of these three chunks will have subloops. The old 'transform()'  
> function then can just still have a subloop calling the 'handler', but  
> python and a 3D widget then can use it as event based system.
> 
> To look at is:
> - where does 'transformer' data reside, in a Blender SpaceWindow, in a  
> scene?
> - what if 2 transformers operate simulteneously (could work!)
> 
> And also... the methods how IpoKey currently works with it is very  
> complex...
> 
> -Ton-
Good Question where does transformer data reside? I need to check on 
that.

> 
> 
> On Wednesday, May 19, 2004, at 01:27 Europe/Amsterdam,  
> jeremy@marzhillstudios.com wrote:
> 
> > On 18 May 2004 at 13:26, Chris McFarlen wrote:
> >
> >> I have been in this function recently too and it truly is a monster!   
> >> I think my idea parallels Jeremy's, it
> >> may just add a little detail (or too much :) ).
> >>
> >> In my opinion transform() should be table driven, where each  
> >> transform mode has
> >> an entry in the table with three function pointers.  One function  
> >> gets called
> >> when transform() is called and the mode is looked up, another every
> >> loop iteration, and the last when a key is pressed that is not a key  
> >> handled
> >> by transform directly (i.e. escape, MMB, x, y, z). (or maybe always  
> >> called after
> >> those keys change the state)
> > A table would be another way of branching out to the various modes.
> > The standard method for Blender right now is a case statement. By the
> > way when I say mode I don't mean translation/rotation/scale. I mean
> > PoseMode, EditMode, ObjectMode and so on. The
> > translation/rotation/scale modes could further branch out from these
> > Each of the pose edit and object modes have different requirements
> > for transformations.
> >
> >>
> >> Each function is passed a transform state struct that has the current  
> >> info.  Something
> >> like:
> >>
> >> struct TransformState
> >> {
> >>     int mode;  // 'g', 'G', 's', or ...
> >>     int xnow;
> >>     int ynow;
> >>     int xlast;
> >>     int ylast;
> >>     // axis constraints
> >>     // whatever else is important to all modes
> >>     union {
> >>         struct {
> >>             // mode 's' specific stuff
> >>         } s;
> >>         struct {
> >>            // mode 'g' specific stuff
> >>         } g;
> >>         ...
> >>     } m;
> >> };
> >>
> >> struct TransformEntry
> >> {
> >>     int    mode;
> >>     void (*init)(TransformState *);
> >>     void (*loop)(TransformState *);
> >>     void (*key)(int k, TransformState *);
> >> };
> >>
> >> TranformEntry modes[] = {
> >>   {  's', transform_s_init, transform_s_loop, transform_s_key },
> >>   ...
> >> };
> >>
> >> Then transform itself becomes: (rough pseudocode, no error checking)
> >>
> >> void transform(int mode)
> >> {
> >>     TransformEntry *te = lookup_transform_entry(tolower(mode));
> >>     TransformState  ts;
> >>
> >>     //initialize ts
> >>     ts.mode = mode;
> >>     ...
> >>
> >>     te->init(&ts);
> >>
> >>     while (!breakout) {
> >>          read mouse
> >>          if (we moved the cursor) {
> >>             update state
> >>             te->loop(&ts);
> >>             redraw
> >>          }
> >>
> >>          while (qtest()) {
> >>               Check key, maybe break the loop, update state
> >>               te->key(&ts);
> >>          }
> >>     }
> >>
> >>     check for escape, undo etc.
> >> }
> >>
> > I'm not sure we need new structs for transformation data. Especially
> > since the data for objects differs from the data for bones. And there
> > may be other differences too. Basically we just need to hold future
> > transformation data to test against a constraint before we apply it.
> >
> >> This provides a good clean separation.  You could even add to the  
> >> lookup table at runtime
> >> if for some reason that became desireable.  If you don't like the  
> >> table idea, you
> >> could have a switch at the beginning of transform() that assigns the  
> >> functions to function pointers.
> >>
> >> Chris
> >
> > _______________________________________________
> > Bf-committers mailing list
> > Bf-committers@blender.org
> > http://www.blender.org/mailman/listinfo/bf-committers
> >
> >
> ------------------------------------------------------------------------ 
> --
> Ton Roosendaal  Blender Foundation ton@blender.org  
> http://www.blender.org
> 
> _______________________________________________
> Bf-committers mailing list
> Bf-committers@blender.org
> http://www.blender.org/mailman/listinfo/bf-committers
> 
> 
>