Could someone please consider optimizing armature speeds.

Animation tools, character animation, non linear animation

Moderators: jesterKing, stiv

soletread
Posts: 83
Joined: Fri Jan 10, 2003 7:11 pm

Postby soletread » Fri Jun 27, 2003 9:54 pm

Michel wrote:
Instead of writing these long posts on the forums, you should spend your time at looking through the sources yourself and then I hope you get the feeling of what's possible and what's not possible.


I am a little concerned by this attitude.

As a user who has read positive comments from coders about how they should listen to users, I am surprised to see that some are expecting us to go through the code to see what is possible or not before discussing our ideas or run the risk of being black listed. I am sorry, that just doesn't feel right.

I think Thorax has mentioned many decent suggestions regarding the topic of this post. If they are not possible then so be it. At least it gets the ball rolling....

Be that as it may, I am still very positive about the future of IK for Blender. I started this post not expecting to see such positive potential outcomes and am really looking forward to experiencing what the coders do in this area.

My company is in the process of developing an animation series for broadcast and we will be starting within the next few weeks. We have researched many software options, doing test renders etc.

We are all very impressed with Blender but the IK problem has held us back from making the final decision. This project is HUGE and will span 2 years of development before we even start animating.

This particular discussion has swung my decision and I am sure the other members, when they have seen the posts, will agree.

Thanks guys....


---

harkyman
Posts: 278
Joined: Fri Oct 18, 2002 2:47 pm
Location: Pennsylvania, USA
Contact:

Postby harkyman » Fri Jun 27, 2003 11:33 pm

I think that this is not a general attitude toward the requests of users. It seems to be reserved solely for Thorax, who has obviously put a lot of thought into this. I myself am not a coder on this project, nor do I pretend to be, but I do write database apps for my employer, so I'm not completely ignorant. Thorax's posts are highly technical and complex in nature, going so far as discussing mock examples of switching from C to C++. All of this is fine, but I think the developers are saying, "Look, you're implying that you have all kinds of knowledge and mad skillz, so why don't you spend your time looking at the actual source instead of hypothesizing, because a lot of the stuff you're saying doesn't really apply here."

At least, that's the way I took it. Also, a poster in another thread is indicating (with evidence) his belief that the armature problem is a bug in the deformation code, as a subsurfed object runs fine, but attached to a completely unconstrained (plain) rig, you see the drastic drop in speed, which matches my experience. I think that Ton knows this, hence his exasperation with Thorax. There's no stifling of opinion going on here.

thorax
Posts: 320
Joined: Sun Oct 27, 2002 6:45 am
Contact:

Postby thorax » Sat Jun 28, 2003 1:34 am

I think you should check out the animanium demo movies at
http://www.animanium.com



Thanks Zarf for the lead.. This system is quite close to Kinemation,
Note that in the animation with the cat, the user selects the
feet of the cat and makes them blue, this is "sticky".. In my suggestions..
Notice how when the midpart of the cat is moved the feet stay sticky
and all the joints are recomputed..

There seems to be some kind of dapening because in the "dancer"
example, everytime an end effector is moved, the body eases
into the pose.. Could this be the solver, I don't know.. But the sticky
part of it was in Kinemation almost a decade ago. Kinemation
wasn't this smooth, but it did allow things to easily
be posed using this sticky feature.. There was no use of Empty's
or Null's in kinemation, but the nulls have a problem in that
you can't tell which null is which, in kinemation )like with Maya)
there was read line drawn through the bones with three pronged
axis, fairly easy to click on and move.. But nothing as extravagant
as the manipulators in maya.. Clicking on the end effector
put a box around it and you could just move it.. Sticky the
handle, rotate the root or move the root, which you can do in blender,
but rotation on the handles is something I miss from Kinemation,
you could rotate the handle and everything up the chain would
rotate.. But this kinemation system that Zarf handed me a link to,
goes beyond the root, and has some kind of way to pull the
skeletons into poses, possibly by eliminating the root and
solving forward and backward through the skeleton.. IK's
were computed from the root of the IK handle chain to
the end effector, not from the root of the skeleton to the
leaf segments.. Like I could skeleton a body and IK only the hand..
Blender seems to assume that all IK's start from the root,
unless I'm missing something..

This is sticky effect not a major feature, just a minor interface preference.. But it makes things easier..

I should seperate my Interface needs or feature needs from
my preference for a object oriented structure.. Both are
getting in the way of each other.. The feature
request would wait until Blender 3.0 as Ton suggests,
but I haven't time to work on this.. Because its not profitting
me any to have to specify it, and I'm sure someone here knows a
better way to do it..

thorax
Posts: 320
Joined: Sun Oct 27, 2002 6:45 am
Contact:

Postby thorax » Sat Jun 28, 2003 2:53 am

harkyman wrote:I think that this is not a general attitude toward the requests of users. It seems to be reserved solely for Thorax, who has obviously put a lot of thought into this. I myself am not a coder on this project, nor do I pretend to be, but I do write database apps for my employer, so I'm not completely ignorant. Thorax's posts are highly technical and complex in nature, going so far as discussing mock examples of switching from C to C++. All of this is fine, but I think the developers are saying, "Look, you're implying that you have all kinds of knowledge and mad skillz, so why don't you spend your time looking at the actual source instead of hypothesizing, because a lot of the stuff you're saying doesn't really apply here."



Read the source, take the source derive a diagram of the relationship of
data and modules.. Determine some logic of which things should be
working with what.. Determine which code doesn't belong..
But before anything is changed consider the direction the source should go (based on functionality concerns and design, what I've been suggesting ultimately is what goes in here, its just intermixed with jargon
any Bachelors level CS major would understand, plus some jargon
from IK and some approximation at ideas I have) , then
make changes to the sources considering a good path that is
combined of the suggestions.. And hopefully end up at something that
is both maintainable and what is wanted..

But before doing the feature request adds, we may want to consider a
direction for the sources and see how we can incrementally fix the code,
migrate to C++ and add features.. Its possible..

But Ton believes in coding ideas, this means someone has to make a
grand decision and code the sources into a design that is C++
because the code development is going to be like a bunch of coders who
will do what they want.. And I suppose that a random bunch of monkeys would have as good a chance, because then how do you organize
what two coders will want to do that may conflict? Split the codebase.
Which is what will happen unless we consider a target design and
discipline our coding.. Or you can do it like how Ton has tried to
do it.. Which is hack a feature, find 10 bugs, fix those, hack another feature, fix 100 bugs.. etc.. Does anyone remember what it was like when Ton himself was just hacking the code? Imagine multiplying Ton by
20 people and each overlapping in considerations and needs..

That will result in code splits and a lot of futile coding.. That can
be reduced if there is some thought about what everyone has in common
and combine the effort..







At least, that's the way I took it. Also, a poster in another thread is indicating (with evidence) his belief that the armature problem is a bug in the deformation code, as a subsurfed object runs fine, but attached to a completely unconstrained (plain) rig, you see the drastic drop in speed, which matches my experience. I think that Ton knows this, hence his exasperation with Thorax. There's no stifling of opinion going on here.


Constrained how?

I never subsurfed the bones, I just animated the skeleton and
compared it to something in Maya.. Read my original example..

But if the bones are fixed now, great, where is the example blend I
can try..

thorax
Posts: 320
Joined: Sun Oct 27, 2002 6:45 am
Contact:

Postby thorax » Sat Jun 28, 2003 8:59 am

Michel wrote:Hi Thorax,

thorax wrote:We do need people to look at the sources and determine what its doing...


From the above line, I get the impression that you haven't looked at the code at all. Also, I as one of the current developers on Blender, am getting pretty insulted at the way you're 'giving lecture' on the differences between C and C++. :evil: .

Instead of writing these long posts on the forums, you should spend your time at looking through the sources yourself and then I hope you get the feeling of what's possible and what's not possible.

I have not read all of your posts, because they are way too long and usually I have no idea what you're trying to tell. But what I do know from your posts is that you're trying to suggest things that are not possible in the current architecture, or at least really hard to do.

I, as a developer, try to listen to users. You, however, are the #1 on my ignore list. Currently the list contains 1 name.

With regards,
Michel


Really I was talking in general to inform the users who just
became coders.. If this hurt you, I'm sorry.. But I wasn't talking to the experienced coders.. Consider me just a lowly code designer talking about the virtues of good coding practice and hoping for a future
at least of good design in Blender.. I do tend to use
seeping generalities.. But I'm wondering about the shape of
the code, what the plans are to code it, if indeed it will end
up being hacked.. Or if it doesn't need it.. But I haven't seen
the plan.. I guess its just hack in place until it looks good..
But it doesn't help new coders coming in.. I'm just foreshadowing
what is yet to come..

Anyhow..

If it wasn't for all the gl function calls it would be pretty nearly unreadable.. I admit its tough but not impossible. Is it even possible
to put cpp on the end of the files and get it to compile in a C++
compiler.. If that's impossible, I guess its hopeless.. But
there is always a start.. A lot of the code I read was
modifying bitflags, referencing global data structures (note the number
of void functions with void input, that is an example of a function that
operates on global data.. Its not very good).. I'm not saying it
will change instantly, but there does need to be a conversion, otherwise
it will continue to look like assembly written in C, which is why it looks so
hard.. But I believe the C can be intermixed with the C++
unless there is something that happened to C++ in the last
decade that I'm missing..

Lets take this little piece of code for example..
ITs probably been updated since when I
got this source..

Code: Select all

/**
 * $Id: writeimage.c,v 1.2 2002/10/13 15:57:11 hans Exp $
 *
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */

#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"  // ImBuf{}
#include "DNA_scene_types.h"
#include "DNA_texture_types.h" // EnvMap{}
#include "DNA_image_types.h" // Image{}
#include "render.h"
#include "license_key.h"  // LICENSE_KEY_VALID
#include "BKE_utildefines.h" // ELEM

#include "BIF_writeimage.h"




Header files.. Hmmmm What are all these header files
for and what variables are defined.. Could they be globals..
#defines?? Some of this would be function prototypes..
Who knows.. Have to read those.. But the code here is pretty
readable..


Code: Select all


int BIF_write_ibuf(ImBuf *ibuf, char *name)
{


No need for this in C++ you would have
the Image buffer be an object, then you would make
"write" method.. Or save maybe.. What's the difference, not
much unification in names for methods, isn't this confusing?

Name is the filename I think, and so it would be
imagebuffer->save(name) ..


Code: Select all




   int ok;

   /* to be used for e.g. envmap, not rendered images */
   
   if(R.r.imtype== R_IRIS) ibuf->ftype= IMAGIC;
   else if ((R.r.imtype==R_PNG) && (LICENSE_KEY_VALID)) {
      ibuf->ftype= PNG;
   }




R is a global.. r is a attribute of R, and imtype is a char most likely, checked to see if the Image type is IRIS (a #define, uppercase characters).. This is checking the buttons in the interface to see
what the file type is before writing it out.. Why is this not
in the image buffer as part of its type? Then we have a method
"settype(type)" for image buffer. Checking globals from this code makes this code dependent on the interface code, so if that changes
variable names, this code will break..

ibuf another global points a structure that contains another
flag which is set to a #define "IMAGIC".

Elseif the image is a R_PNG ..

Okay its all just conditionals and flag checking..
This would be in the C++ probably, but then
again this would all be in the object, so no need to
check global variables for flags.. We should know this
by now without referencing stuff in outer space.

Why is this not an image buffer object and
this method acting directly on it? Practically
implying it without even refering to it directly by name but
by using something like "this->ftype = MAGIC".

I think overall if there was an Image buffer object that
had all the necessary methods, there would be no need for
maintaining external global flags elsewhere which is what this code is
doing, to maintain state eslewhere in the code that needs it..


Code: Select all




   else if ((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
      // fall back to Targa if PNG writing is not supported
      ibuf->ftype= TGA;
   }
   else if(R.r.imtype==R_RAWTGA) {
      ibuf->ftype= RAWTGA;
   }
   else if(R.r.imtype==R_HAMX) {
      ibuf->ftype= AN_hamx;
   }
   else if ELEM(R.r.imtype, R_JPEG90, R_MOVIE) {
      if(R.r.quality < 10) R.r.quality= 90;

      ibuf->ftype= JPG|R.r.quality;
   }
   else ibuf->ftype= TGA;
   
   RE_make_existing_file(name);
   
   ok = IMB_saveiff(ibuf, name, IB_rect);
   if (ok == 0) {
      perror(name);
   }

   return(ok);
}




From reading this code this looks like its accessing variables
in the interface and setting parameters in the image buffer..

It probably checks to make sure the file exists before writing to it,
ot creates it if it doesn't exist.. This was a function "RE_" that was
probably added later when this code was failing to save the file,
so they went throughout all the functions and added this code..


Proof:

I did an fgrep -ir "RE_make" * from the root directory and got..


Code: Select all


blender/blenkernel/BKE_bad_level_calls.h:void RE_make_existing_file(char *name); // from render, but these funcs should be moved anyw
ay
blender/blenkernel/bad_level_call_stubs/stubs.c:void RE_make_existing_file(char *name){} // from render, but these funcs should be mo
ved anyway
blender/blenkernel/intern/packedFile.c: RE_make_existing_file(name);
blender/blenkernel/intern/writeavi.c:   RE_make_existing_file(string);
blender/quicktime/linux/quicktime_export.c:     RE_make_existing_file(string);
blender/render/extern/include/render.h:void    RE_make_existing_file(char *name);
blender/render/intern/source/initrender.c:void RE_make_existing_file(char *name)
blender/renderconverter/RE_renderconverter.h:   void RE_make_stars(void (*initfunc)(void),
blender/renderconverter/intern/convertBlenderScene.c:void RE_make_stars(void (*initfunc)(void),
blender/renderconverter/intern/convertBlenderScene.c:   if(R.wrld.mode & WO_STARS) RE_make_stars(NULL, NULL, NULL);
blender/src/toets.c:            RE_make_existing_file(name);
blender/src/writeimage.c:       RE_make_existing_file(name);
blender/src/writequicktime.c:   RE_make_existing_file(string);
blender/src/writemovie.c:       RE_make_existing_file(string);
blender/src/draw_mods/drawview.c:                               if(G.scene->world->mode & WO_STARS) RE_make_stars(star_stuff_init_fun



How many occurences, abotu 10?? But its reuse at least!!

Here is the actual code..

Code: Select all


// this is in initrender.c
// and you will see notes throughout the code
// saying this should be moved out of "render"..
// because it has least to do with render and more to do
// with general file handling.. Thus a need for a file object..

void RE_make_existing_file(char *name)
{
   char di[FILE_MAXDIR], fi[FILE_MAXFILE];

   strcpy(di, name);
   BLI_splitdirstring(di, fi);

   /* exist testen */
   if (BLI_exists(di) == 0) {
      BLI_recurdir_fileops(di);
   }
}



And this code calls other code elsewhere.. Note why is the
Quicktime code using this function?

/* shrug */

So I've determined the naming pattern for functions, the first
several letters is a hint as to where the code is.. Maybe all we need is
to specify what every function does, create an class for
every class of functions, and call the class? I don't know I would
only be able to tell you something useful after a diagramming
of the source.. Then maybe plan a redesign that maps the diagram
to a reorganization.. I bet the outcome source would be a third at
least the size of the current blender source and easier to follow.





If you had a file object, this code would be only written once..
Not copied everywhere a file is to be written..

Notice the name of the function is "IMB_saveiff" this refers to the
Amiga IFF format that blender used from the beginning..
Most likely the save_iff function has code in it to check the
image buffer time and saves it according to its
proper format.. Again all this code should be in an object
that deals with image buffers.. Rather tha referencing
global flags and data types elsewhere.. If the image buffer
does not exist, this code would cause a core dump...

Also it check (finally an error check, if return is not okay
print up the filename.. using a special error function..).

But no, you don't see a "if(imbuf == NULL) return FALSE" or something
at the beginng of this code.. Since its not there this code would result in
a coredump.. This is where just changing the ordering of functions
elsewhere would yield different state and this code would core dump..
In objects this wouldn't happen because the precontions are in the
object, so there is no way it can not point to the object.. But in C
there is no guarantee unless you check to see if the image buffer
exists before operating on it.. In fact in C you would get tired after
doing this so much that you would just assume that it does exist
and open yourself up for future coredumps.. But if this was C++
you would only write this once, and when you
save a image buffer out you coulde assume it gets saved out
properly everytime because there is only one place this code would
ever exist..


Code: Select all


/* ------------------------------------------------------------------------- */

void BIF_save_envmap(EnvMap *env, char *str)
{
   ImBuf *ibuf;
/*     extern rectcpy(); */
   int dx;
   
   /* all interactive stuff is handled in buttons.c */
   
   dx= env->cuberes;
   ibuf= IMB_allocImBuf(3*dx, 2*dx, 24, IB_rect, 0);
   


The "/* .... extern rectcpy(); */" is called commenting out
code, it happens a lot when later you need to add code back in..
This is okay, all coders do this to some degree..

In C++ this would be implemented..
Envmap is another object, inherits from image buffer object type, as
"save" method call.. The parameter cuberes is a part of the EnvMap object in addition to what is defined for a Image Buffer that it
inherits from..

The "IMB_alloc..." allocates an image buffer struct (in C++ this
would be an object), and the constructor would setup the image
buffer with these parameters.. But note this wouldn't probably have to be in the EnvMap code, so the EnvMap's constructor would just call
the parent's constructor with the parameters.. This being ImageMap..
Also if later we want EnvMap to inherit from something else, we
can change it provided the new class has all the methods and attributes
that ImageMap has..

So again there is no need to allocate the bufferm copy the EnvMap
image structure to the ImageMapBuffer and use a ImageMap buffer's
writing method.. The only reason this is done anyhow is that
the ImageMap requires a pointer to a ImageMap structure,
but in C++ if EnvMap inherits from ImageBuffer it
it is a ImageMap object and thus can save itself without
doing the allocation and copy..

After reading the code more, the EnvMap is an array of
ImageBuffer objects. Or could EnvMap be a MovieObject
that stores only 6 frames.. We could write it out as an image or
as a movie if that were the case.. Assume that each frame is
of Object type ImageBuffer..

It would be better determined by looking at the entire structure
and how image buffers are used.. But the best things to
do is take all the code that is like three letters at the beginning
of a function name and consider that a possible object
method of say object type Render, or rather in this case a File object.

Code: Select all


   IMB_rectop(ibuf, env->cube[0]->ibuf,
         0, 0, 0, 0, dx, dx, IMB_rectcpy, 0);
   IMB_rectop(ibuf, env->cube[1]->ibuf,
         dx, 0, 0, 0, dx, dx, IMB_rectcpy, 0);
   IMB_rectop(ibuf, env->cube[2]->ibuf,
         2*dx, 0, 0, 0, dx, dx, IMB_rectcpy, 0);
   IMB_rectop(ibuf, env->cube[3]->ibuf,
         0, dx, 0, 0, dx, dx, IMB_rectcpy, 0);
   IMB_rectop(ibuf, env->cube[4]->ibuf,
         dx, dx, 0, 0, dx, dx, IMB_rectcpy, 0);
   IMB_rectop(ibuf, env->cube[5]->ibuf,
         2*dx, dx, 0, 0, dx, dx, IMB_rectcpy, 0);
   
   BIF_write_ibuf(ibuf, str);
   IMB_freeImBuf(ibuf);
}


All this code copies data from the Envmap to the Image buffer then
writes it out.. This would probably be simpler, a call to "write"
that the Image Buffer class already contains.. This is called a method
search for those who don't know C++.. When you inherit from another
object you obtain its functions unless you redefine them,
called overloading.. In this case there is no difference between an
Image Buffer and a Environment Map.. So we just REUSE the image
buffer objects method.. There would likely be very little code int he EnvMap..

See C++ is wicked!!

Of course I picked the simplest code in the source, but
you get the picture I think.. For this code I've deduced
a few methods and at least two classes, one that inherits from the
other.. Now how could we do this in UML if we had to..
Two boxes, one called ImageBuffer, the other EnvMap,
EnvMap inherits from ImageBuffer.. ImageBuffer
implments the "save" method (or write)..
And EnvMap may overload the "save" method..
But that it has a save method is implied by the inheritance..

Then you would go throughout the blender source looking
at every place this occurs, look for where image buffers are referenced,
saved, etc.. And replace them with an ImageBuffer object, poassibly..
But it requires a code redesign I suppose..

But maybe its not all that hard to hack.. Looks pretty clean for C code..
Maybe I had Blender wrong all this time.. Wow it could be
so easy to develop.. All I have to do is change 20 functions everytime
I want to write in a new feature.. Note, the amount of time required for a
redesign will pale in comparison to the amount of redundant coding you guys will be doing from here on out..

I can read more source if you like..
But if you have any really complex stuff that you can't
figure out, maybe I can take a stab at it.. I like challenges..

Michel
Posts: 208
Joined: Wed Oct 16, 2002 7:27 pm
Location: Somewhere below the rivers in Holland (but not Limburg)

Postby Michel » Sat Jun 28, 2003 11:23 am

soletread wrote:Michel wrote:
Instead of writing these long posts on the forums, you should spend your time at looking through the sources yourself and then I hope you get the feeling of what's possible and what's not possible.


I am a little concerned by this attitude.

As a user who has read positive comments from coders about how they should listen to users, I am surprised to see that some are expecting us to go through the code to see what is possible or not before discussing our ideas or run the risk of being black listed. I am sorry, that just doesn't feel right.


No no, I'm truly sorry if I've offended you. I had directed the post to Thorax - and I'm not going to change my stance on that issue. Your initial post in this thread is really valid, and looking through the replies (and skipping the posts from Thorax), you'll see some good suggestions being made.

soletread wrote:I think Thorax has mentioned many decent suggestions regarding the topic of this post. If they are not possible then so be it. At least it gets the ball rolling....


Well, Thorax seems to have some software development knowledge. He's showing of with it on these forums. He's really good at moving the focus from the original topic to some complete redesign, UML, C or C++ discussion. That way, the original intend of the post gets lost and confuses me and a lot of users who think that the posts by Thorax are a solution that's feassible to implement.

soletread wrote:Be that as it may, I am still very positive about the future of IK for Blender. I started this post not expecting to see such positive potential outcomes and am really looking forward to experiencing what the coders do in this area.


Me too. This is definately something that will get some attention in the future. A lot of exiting things can be added and changed within the current code structure and design.

With regards,
Michel

green
Posts: 81
Joined: Sun Oct 13, 2002 8:04 pm

Postby green » Sat Jun 28, 2003 12:07 pm

please give us another really long demented post

ton
Site Admin
Posts: 525
Joined: Wed Oct 16, 2002 12:13 am
Contact:

Postby ton » Sun Jun 29, 2003 12:01 pm

I lock this thread now. The original topic seems to be completely forgotten. Please, please, post on topic! If you have something new to say, make that a new topic in the forums. So much energy gets wasted this way.

For those confused by this discussion:

1- there are already active volunteers working on the Armature system in Blender. And of course we need more!
2- for current releases (2.28, etc) they first try to fix and improve what's already in Blender. The current Armature system still is the basis we work with.
3- when this work reveils structural weakness in the design, we'll look at either rebuilding/improving the system, or at implementing a complete new one.

Let's do things in the right order, and give people who work on steps 1 and 2 the credits to come with a meaningful contribution for step 3.
[/b]


Return to “Animation”

Who is online

Users browsing this forum: Google [Bot] and 1 guest