Loomis Heads

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

Loomis Heads

mondo
Although 'Blender' is often recommended for modelling the human or other
natural forms, i am wondering if anyone has tried modelling faces in
openscad, using the Loomis method, or similar. I am not considering
photographic accuracy, but in sufficient detail to give some variation
to model figures, say. I think a representative face could be
constructed, from modules, relatively easily, and the individual modules
could be detailed as needed. It could be useful if there was a
transformation, such as 'hull()' but one in which the surface could be
altered in regions to more closely follow the underlying shapes, to sort
of smooth the internal corners.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Loomis Heads

JordanBrown
https://en.wikipedia.org/wiki/Andrew_Loomis
https://www.amazon.com/Drawing-Head-Hands-Andrew-Loomis/dp/0857680978
https://www.alexhays.com/loomis/Andrew%20Loomis%20-%20Drawing%20the%20Head%20and%20Hands.pdf

Fascinating.

Yes, I think that's entirely practical.

I'm an engineer, not an artist.  The process of producing realistic-looking drawings of organic things has always been a total mystery to me.  This, on the other hand, is a geometric approach to the problem.  Coupled with curved-surface tools - Bezier patches, perhaps - it seems like it would be totally amenable to use in OpenSCAD.

And, of course, if you do it right it'd all be parameterized.  Tweak a number, and the head gets a little wider at the top.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Loomis Heads

leebc
I had a similar question a couple months ago and was directed to the "Make
Human" project.

It does exactly what you describe: human figure with parameters to tweak
body style.
It filled my needs, though I'm still trying to figure out how to adjust a
pose in Blender for import.


Thus Jordan Brown hast written on Sat, Mar 06, 2021 at 12:18:30AM +0000, and, according to prophecy, it shall come to pass that:
> I'm an engineer, not an artist.  The process of producing realistic-looking
> drawings of organic things has always been a total mystery to me.  This, on the
> other hand, is a geometric approach to the problem.  Coupled with
> curved-surface tools - Bezier patches, perhaps - it seems like it would be
> totally amenable to use in OpenSCAD.
>
> And, of course, if you do it right it'd all be parameterized.  Tweak a number,
> and the head gets a little wider at the top.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Loomis Heads

JordanBrown
On 3/5/2021 4:36 PM, Bryan Lee wrote:
I had a similar question a couple months ago and was directed to the "Make
Human" project.

Now all somebody needs to do is to port their models from Python to OpenSCAD :-)


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Loomis Heads

mondo
In reply to this post by JordanBrown
 From 60 years ago, i remember using these
https://n.stuccu.co.uk/s/Artist+Manikin in 'A level' art, and a few
rules wrt drawing faces - eyes halfway up face, bottom of nose half way
'twixt eyes and chin, so I'm thinking along the lines of facial feature
additions (like Mr. Potato Head, or as now, just gender neutral  'Potato
Head')  and then pose the manikin and drape over clothing. Hair could be
awkward, but baseball caps could help there, initially.

I think, based on a Loomis type construction set, my initial thought is
to have the cranium sphere at a size of 1000 units, which would most
likely allow integer values for details of ear lobes/whatever. If it has
to look realistic, then there will need to be some controllable curve
blending/contouring, which I've always found tricky in openscad, and
most other cad packages too. Ideally the ability to simply to push
things around, as in using modelling clay would be useful, but nothing
in openscad is manipulated in that way, afaik. However, with the correct
choice of values, then that will not be needed so much.

Although it would be nice to construct a face from spheres and other
basic shapes, I believe that eye sockets and lips would be awkward, and
instead it may be simpler to combine a few  extruded cross sections, but
I would consider that, and using polygons as cheating.

Could be fun!

On 06/03/2021 00:18, Jordan Brown wrote:

> https://en.wikipedia.org/wiki/Andrew_Loomis
> https://www.amazon.com/Drawing-Head-Hands-Andrew-Loomis/dp/0857680978
> https://www.alexhays.com/loomis/Andrew%20Loomis%20-%20Drawing%20the%20Head%20and%20Hands.pdf
>
> Fascinating.
>
> Yes, I think that's entirely practical.
>
> I'm an engineer, not an artist.  The process of producing
> realistic-looking drawings of organic things has always been a total
> mystery to me.  This, on the other hand, is a geometric approach to
> the problem.  Coupled with curved-surface tools - Bezier patches,
> perhaps - it seems like it would be totally amenable to use in OpenSCAD.
>
> And, of course, if you do it right it'd all be parameterized. Tweak a
> number, and the head gets a little wider at the top.
>

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Fwd: Loomis Heads

mondo

 From 60 years ago, i remember using these
https://n.stuccu.co.uk/s/Artist+Manikin in 'A level' art, and a few
rules wrt drawing faces - eyes halfway up face, bottom of nose half way
'twixt eyes and chin, so I'm thinking along the lines of facial feature
additions (like Mr. Potato Head, or as now, just gender neutral  'Potato
Head')  and then pose the manikin and drape over clothing. Hair could be
awkward, but baseball caps could help there, initially.

I think, based on a Loomis type construction set, my initial thought is
to have the cranium sphere at a size of 1000 units, which would most
likely allow integer values for details of ear lobes/whatever. If it has
to look realistic, then there will need to be some controllable curve
blending/contouring, which I've always found tricky in openscad, and
most other cad packages too. Ideally the ability to simply to push
things around, as in using modelling clay would be useful, but nothing
in openscad is manipulated in that way, afaik. However, with the correct
choice of values, then that will not be needed so much.

Although it would be nice to construct a face from spheres and other
basic shapes, I believe that eye sockets and lips would be awkward, and
instead it may be simpler to combine a few  extruded cross sections, but
I would consider that, and using polygons as cheating.

Could be fun!

On 06/03/2021 00:18, Jordan Brown wrote:

> https://en.wikipedia.org/wiki/Andrew_Loomis
> https://www.amazon.com/Drawing-Head-Hands-Andrew-Loomis/dp/0857680978
> https://www.alexhays.com/loomis/Andrew%20Loomis%20-%20Drawing%20the%20Head%20and%20Hands.pdf
>
> Fascinating.
>
> Yes, I think that's entirely practical.
>
> I'm an engineer, not an artist.  The process of producing
> realistic-looking drawings of organic things has always been a total
> mystery to me.  This, on the other hand, is a geometric approach to
> the problem.  Coupled with curved-surface tools - Bezier patches,
> perhaps - it seems like it would be totally amenable to use in OpenSCAD.
>
> And, of course, if you do it right it'd all be parameterized. Tweak a
> number, and the head gets a little wider at the top.
>

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Loomis Heads

mondo
In reply to this post by mondo
Well, I've made a start. From pages 43 and 44 of the pdf mentioned by
Jordan, I've decided that since everything is more or less thirds, to
chose a size of 300 for the cranium. I've roughly constructed a face,
place holders for parts, really, but having printed it at a more a less
a 7mm to the foot scale, (scaled the total height of this stl to about
10mm height) it has a far better potential  than a scaled model of an
more accurate facial rendering.  When making scale models, in order for
them to 'look right', adjustments have to be made, hiding some details,
emphasising others, change colours, etc - you can't scale nature.

Now to do some various hats/hair styles, then examine the body details.,
drape clothing and so on. I'm not sure if trying to make it more
parametric at this stage is worth while. I'm not sure of what would be
involved in the automatic placement of the ears, for example, but
certain basic features could be calculated, nose flare etc.

I think the limbs of the manikin could be interesting, in particular if
I limit the joint rotations, etc. I will probably add hair/hat to this
face first.

//face3 based on loomis p43,44
// 300 max ball
module base(){
     union()
        sphere(d=300);
        translate([0,-50,-100])sphere(d=200);
        translate([0,-110,-150])sphere(d=90);//pointed chin
}

module slice(){
     cube([1000,1000,1000],true);
}

module head(){
hull()
difference(){ //slice off side of head
     base();
     translate([610,0,0])rotate([0,8,0])slice();
     translate([-610,0,0])rotate([0,-8,0])slice();
}
}

module nose(){
   cylinder(100,50,20);
}

module eyesocket(){
   rotate([0,90,0])cylinder(500,20,20);
}

module ear(){
   cylinder (15,40,40);
}

module neck(){
     translate([0,90,-350])rotate([10,0,0])cylinder(350,95,95);
}


module lips() {
     union(){
        cylinder(5,40,50);
        translate([0,0,-5]) cylinder(15,50,40);
}
}

$fn=60;
//place features on head
union(){
    difference(){
       union(){
          neck();
          head();
          translate([90,10,-40]) rotate([90,0,65])ear();  //left ear
          translate([-90,10,-40]) rotate([90,0,-65])ear();  //right ear
}
      translate([-250,-130,0])eyesocket();
}
   translate([0,-130,-90])  nose();
   translate([0,-115,-140]) lips();
}


On 06/03/2021 16:02, Ray West wrote:

> From 60 years ago, i remember using these
> https://n.stuccu.co.uk/s/Artist+Manikin in 'A level' art, and a few
> rules wrt drawing faces - eyes halfway up face, bottom of nose half
> way 'twixt eyes and chin, so I'm thinking along the lines of facial
> feature additions (like Mr. Potato Head, or as now, just gender
> neutral  'Potato Head')  and then pose the manikin and drape over
> clothing. Hair could be awkward, but baseball caps could help there,
> initially.
>
> I think, based on a Loomis type construction set, my initial thought
> is to have the cranium sphere at a size of 1000 units, which would
> most likely allow integer values for details of ear lobes/whatever. If
> it has to look realistic, then there will need to be some controllable
> curve blending/contouring, which I've always found tricky in openscad,
> and most other cad packages too. Ideally the ability to simply to push
> things around, as in using modelling clay would be useful, but nothing
> in openscad is manipulated in that way, afaik. However, with the
> correct choice of values, then that will not be needed so much.
>
> Although it would be nice to construct a face from spheres and other
> basic shapes, I believe that eye sockets and lips would be awkward,
> and instead it may be simpler to combine a few  extruded cross
> sections, but I would consider that, and using polygons as cheating.
>
> Could be fun!
>
> On 06/03/2021 00:18, Jordan Brown wrote:
>> https://en.wikipedia.org/wiki/Andrew_Loomis
>> https://www.amazon.com/Drawing-Head-Hands-Andrew-Loomis/dp/0857680978
>> https://www.alexhays.com/loomis/Andrew%20Loomis%20-%20Drawing%20the%20Head%20and%20Hands.pdf 
>>
>>
>> Fascinating.
>>
>> Yes, I think that's entirely practical.
>>
>> I'm an engineer, not an artist.  The process of producing
>> realistic-looking drawings of organic things has always been a total
>> mystery to me.  This, on the other hand, is a geometric approach to
>> the problem.  Coupled with curved-surface tools - Bezier patches,
>> perhaps - it seems like it would be totally amenable to use in OpenSCAD.
>>
>> And, of course, if you do it right it'd all be parameterized. Tweak a
>> number, and the head gets a little wider at the top.
>>

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

mondo
In reply to this post by mondo
I've found some average dimensions for a manikin, based on the size of
the head, which will give a starting point for the body. However, I'm at
a loss as to how to manipulate the joints. (not necessarily the
geometry, cos/sin, etc., but how to get it to work in openscad).

As an example, I've put a snippet of code and comments below. I was
hoping to have a list of vectors, one for each end of a limb, and then
be able to write some code to adjust the angles of a particular limb.
I'm sure it can be done, except I'm thinking of it more as a
'traditional sequential problem', using global variables for the limb
ends, and sub routines called as required to move the end points around.
It's a similar problem to con rods and cranks, I guess that's been done.
Anyway, any help would be very much appreciated.

// length of p1 to p2 = 10
// length of s1 to s2  = 20
// s1 is 'hinged' to p2

//start positions

p1=[0,0,0];
p2=[0,0,10];
s1=[0,0,10];
s2=[0,0,30];

//How to change the values to the following?

p1=[0,0,0];
p2=[10,0,0];
s1=[10,0,0];
s2=[10,0,20];

//the syntax, I can't seem to be able to use anything like p2.x = 10
// can't pass values back from modules
// functions limited to one line?
// No 'global variables'?
// there will be about 50 sets of vectors



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

nophead
There are no variables in OpenSCAD, just named constants (except in for loops).

Functions are not limited to one line if you use let() you can assign intermediate variables and use them later.  Here is an unrelated example of a complex function:

function catenary_points(l, x, y, steps = 100) = //! Returns a list of 2D points on the curve that goes from the origin to `(x,y)` and has length `l`.
    let(
        d = x / 2,
        a = catenary_find_a(d, sqrt(sqr(l) - sqr(y))),   // Find a to get the correct length
        offset = argsinh(y / catenary_s(d, a)),
        t0 = sinh(-d / a + offset),
        t1 = sinh( d / a + offset),
        h = a * cosh(-d / a + offset) - a,
        lowest = offset > d / a ? [0, 0] : offset < -d / a ? [x, y] : [d - offset * a, -h],
        p0 = catenary(t0, a)
    )
    steps ? [for(t = [t0 : (t1 - t0) / steps : t1]) catenary(t, a) - p0] : lowest;


You can have global constants. A constant at file scope is accessible to modules and functions after it. If the name starts with a $ it is available in any module or function called after.

On Sun, 7 Mar 2021 at 20:12, Ray West <[hidden email]> wrote:
I've found some average dimensions for a manikin, based on the size of
the head, which will give a starting point for the body. However, I'm at
a loss as to how to manipulate the joints. (not necessarily the
geometry, cos/sin, etc., but how to get it to work in openscad).

As an example, I've put a snippet of code and comments below. I was
hoping to have a list of vectors, one for each end of a limb, and then
be able to write some code to adjust the angles of a particular limb.
I'm sure it can be done, except I'm thinking of it more as a
'traditional sequential problem', using global variables for the limb
ends, and sub routines called as required to move the end points around.
It's a similar problem to con rods and cranks, I guess that's been done.
Anyway, any help would be very much appreciated.

// length of p1 to p2 = 10
// length of s1 to s2  = 20
// s1 is 'hinged' to p2

//start positions

p1=[0,0,0];
p2=[0,0,10];
s1=[0,0,10];
s2=[0,0,30];

//How to change the values to the following?

p1=[0,0,0];
p2=[10,0,0];
s1=[10,0,0];
s2=[10,0,20];

//the syntax, I can't seem to be able to use anything like p2.x = 10
// can't pass values back from modules
// functions limited to one line?
// No 'global variables'?
// there will be about 50 sets of vectors



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

JordanBrown
In reply to this post by mondo
The way that I would think of a body and joints is to start with some part - probably the torso, but technically you could start anywhere - and attach limbs, heads, et cetera as children.  A joint rotates its children.  So you have a torso with a shoulder joint, which rotates its child the upper arm, with an elbow joint which rotates its child the lower arm, and so on.  (But remember, the joints aren't simple hinge-like connections; they can twist too - and twist sometimes happens along a part.  Lower-arm twists happen along the entire arm, not exclusively at either joint.)

The essence is that the hand doesn't have to care what the shoulder is doing.  The hand just does its thing, relative to wherever the shoulder, upper arm, elbow, lower arm, and wrist put it.

You could start with any part, but starting with the torso probably results in the most natural behavior.  If you started with the big toe, wiggling the toe would have the toe stay motionless while the rest of the body moved.  That's sort of technically correct, but is probably unexpected.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

mondo
Yes, I'm looking at various methods of altering limb positions, but I
can't get my head around the openscad syntax and methodology. I could
probably knock something out quickly in freebasic/c#/whatever, but the
lack of global variables, and examples that I can understand and
replicate in openscad, is my stumbling block. Even a simple hinge,
operating in one plane I find incapable of using the results where I
want, in the way i want them. (i.e., not difficult calculating the new
positions, but putting the results where I want them, seems impossible.
I'll have to think of it in some other way). I'm not worried at this
stage with freedom of joint movements, just wanting to be able to pass
vectors too and fro, between modules/whatever - very basic stuff, that
has me stumped...

On 07/03/2021 21:01, Jordan Brown wrote:

> The way that I would think of a body and joints is to start with some
> part - probably the torso, but technically you could start anywhere -
> and attach limbs, heads, et cetera as children.  A joint rotates its
> children.  So you have a torso with a shoulder joint, which rotates
> its child the upper arm, with an elbow joint which rotates its child
> the lower arm, and so on.  (But remember, the joints aren't simple
> hinge-like connections; they can twist too - and twist sometimes
> happens along a part.  Lower-arm twists happen along the entire arm,
> not exclusively at either joint.)
>
> The essence is that the hand doesn't have to care what the shoulder is
> doing.  The hand just does its thing, relative to wherever the
> shoulder, upper arm, elbow, lower arm, and wrist put it.
>
> You could start with any part, but starting with the torso probably
> results in the most natural behavior.  If you started with the big
> toe, wiggling the toe would have the toe stay motionless while the
> rest of the body moved.  That's sort of technically correct, but is
> probably unexpected.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

adrianv
BOSL2 has an attachment feature that lets you position objects relative to parent objects.  I find it very useful for this kind of thing.  It was inspired by the Relativity library.  There is also a library called obiscad with a similar functionality.  

mondo wrote
Yes, I'm looking at various methods of altering limb positions, but I
can't get my head around the openscad syntax and methodology. I could
probably knock something out quickly in freebasic/c#/whatever, but the
lack of global variables, and examples that I can understand and
replicate in openscad, is my stumbling block. Even a simple hinge,
operating in one plane I find incapable of using the results where I
want, in the way i want them. (i.e., not difficult calculating the new
positions, but putting the results where I want them, seems impossible.
I'll have to think of it in some other way). I'm not worried at this
stage with freedom of joint movements, just wanting to be able to pass
vectors too and fro, between modules/whatever - very basic stuff, that
has me stumped...

On 07/03/2021 21:01, Jordan Brown wrote:

> The way that I would think of a body and joints is to start with some
> part - probably the torso, but technically you could start anywhere -
> and attach limbs, heads, et cetera as children.  A joint rotates its
> children.  So you have a torso with a shoulder joint, which rotates
> its child the upper arm, with an elbow joint which rotates its child
> the lower arm, and so on.  (But remember, the joints aren't simple
> hinge-like connections; they can twist too - and twist sometimes
> happens along a part.  Lower-arm twists happen along the entire arm,
> not exclusively at either joint.)
>
> The essence is that the hand doesn't have to care what the shoulder is
> doing.  The hand just does its thing, relative to wherever the
> shoulder, upper arm, elbow, lower arm, and wrist put it.
>
> You could start with any part, but starting with the torso probably
> results in the most natural behavior.  If you started with the big
> toe, wiggling the toe would have the toe stay motionless while the
> rest of the body moved.  That's sort of technically correct, but is
> probably unexpected.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

JordanBrown
In reply to this post by mondo
On 3/7/2021 2:12 PM, Ray West wrote:
Yes, I'm looking at various methods of altering limb positions, but I can't get my head around the openscad syntax and methodology. I could probably knock something out quickly in freebasic/c#/whatever, but the lack of global variables, and examples that I can understand and replicate in openscad, is my stumbling block. Even a simple hinge, operating in one plane I find incapable of using the results where I want, in the way i want them. (i.e., not difficult calculating the new positions, but putting the results where I want them, seems impossible. I'll have to think of it in some other way). I'm not worried at this stage with freedom of joint movements, just wanting to be able to pass vectors too and fro, between modules/whatever - very basic stuff, that has me stumped...

You have to think in a very top-down way.  You can only pass things down, never up.  (You can sort of simulate passing things up by having functions that parallel the modules and tell you things about what the modules would do.)

But I don't immediately see why you would ever need to pass anything up.

Here's a quick and dirty stick figure.  Load it up, enable the customizer (Window / Hide Customizer), and play.  Most of the interesting things are in the Joint Positions section.  (Note:  I haven't implemented all of the degrees of freedom, and I haven't implemented the real-world limits on motion at the various joints.)


// Cheap and dirty stick figure.
// Note that measurements are global values and picked up directly
// by the modules, while joint positions are parameters
// (which in turn come from global values).
// This is mostly because you can generally assume that the left and
// right arms are the same length, but the shoulders and elbows may
// be in different positions.

/* [ Measurements ] */
torso_h = 24;
torso_w = 18;
torso_d = 8;
shoulder_h = torso_h - 4;
shoulder_d = 4;
neck_h = 4;
neck_d = 4;
head_w = 6;
head_h = 9;
head_d = 8;
uarm_l = 12;
uarm_d = 4;
elbow_d = 3;
larm_d = 3;
larm_l = 10;
uleg_l = 18;
uleg_d = 6;
lleg_l = 18;
lleg_d = 4;
/* [ Joint positions ] */
lshoulder_theta = 30;
lshoulder_phi = 45;
rshoulder_theta = 30;
rshoulder_phi = 45;
lelbow_theta = 45;
relbow_theta = 45;
lhip_theta = 0;
lhip_phi = 20;
rhip_theta = 0;
rhip_phi = 20;
lknee_theta = 20;
rknee_theta = 0;

// Children:
// 0 - neck
// 1 - left shoulder
// 2 - right shoulder
// 3 - left leg
// 4 - right leg
module torso() {
    scale([1, torso_d/torso_w, 1]) cylinder(h=torso_h,d=torso_w);
    translate([0,0,torso_h]) children(0);
    translate([torso_w/2, 0, shoulder_h]) children(1);
    translate([-torso_w/2, 0, shoulder_h]) children(2);
    translate([torso_w*0.5, 0, 0]) children(3);
    translate([-torso_w*0.5, 0, 0]) children(4);
}

// Children:
// 0 - head
module neck() {
    cylinder(h=neck_h, d=neck_d);
    translate([0,0,neck_h]) children(0);
}

module head() {
    translate([0,0,head_h/2]) scale([head_w/head_h, head_d/head_h, 1]) sphere(d=head_h);
}

// Children
// 0 - upper arm
module shoulder(theta, phi) {
    sphere(d=shoulder_d);
    rotate([theta, 0, -phi]) children();
}

// Children
// 0 - elbow
module upper_arm() {
    rotate([0,90,0]) {
        cylinder(h=uarm_l, d=uarm_d);
        translate([0,0,uarm_l]) children();
    }
}

// Children
// 0 - lower arm
module elbow(theta) {
    sphere(d=elbow_d);
    rotate([theta,0,0]) children();
}

module lower_arm() {
    cylinder(d=larm_d, h=larm_l);
}

module hip(theta, phi) {
    rotate([-theta, -phi]) children();
}

module upper_leg() {
    rotate([180,0,0]) cylinder(h=uleg_l, d=uleg_d);
    translate([0,0,-uleg_l]) children();
}

module knee(theta) {
    rotate([theta,0,0]) children();
}

module lower_leg() {
    rotate([180,0,0]) cylinder(h=lleg_l, d=lleg_d);
}

torso() {
    neck() {
        head();
    }
    shoulder(lshoulder_theta,lshoulder_phi)
        upper_arm()
        elbow(lelbow_theta)
        lower_arm();
    mirror([1,0,0]) shoulder(rshoulder_theta,rshoulder_phi)
        upper_arm()
        elbow(relbow_theta)
        lower_arm();
    hip(lhip_theta, lhip_phi)
        upper_leg()
        knee(lknee_theta)
        lower_leg();
    mirror([1,0,0]) hip(rhip_theta, rhip_phi)
        upper_leg()
        knee(rknee_theta)
        lower_leg();
}


  


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

Ronaldo
That seems nice but you also need to provide a movement flow bottom-up too. That happens when you want to find the joint angles in order to get for instance the hand reaching some point relative to the head or torso center. You defined something that may be called a forward kinematic by the animation people. But you also need an inverse kinematic. Just my two cents.

Em seg., 8 de mar. de 2021 às 02:19, Jordan Brown <[hidden email]> escreveu:
You have to think in a very top-down way.  You can only pass things down, never up.  (You can sort of simulate passing things up by having functions that parallel the modules and tell you things about what the modules would do.)

But I don't immediately see why you would ever need to pass anything up.

Here's a quick and dirty stick figure.  Load it up, enable the customizer (Window / Hide Customizer), and play.  Most of the interesting things are in the Joint Positions section.  (Note:  I haven't implemented all of the degrees of freedom, and I haven't implemented the real-world limits on motion at the various joints.)


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

JordanBrown
On 3/8/2021 1:48 AM, Ronaldo Persiano wrote:
That seems nice but you also need to provide a movement flow bottom-up too. That happens when you want to find the joint angles in order to get for instance the hand reaching some point relative to the head or torso center. You defined something that may be called a forward kinematic by the animation people. But you also need an inverse kinematic. Just my two cents.

Yes.  I have absolutely no idea how to do reverse kinematics, determining joint position based on an intended goal.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
tp3
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

tp3
On 08.03.21 18:30, Jordan Brown wrote:
> Yes.  I have absolutely no idea how to do reverse kinematics,
> determining joint position based on an intended goal.

Examples -> Advanced -> Animation shows 2D reverse kinematics.
There's a link in the source code to RepRap wiki where I got
the math from.

Doing that in 3D is slightly more interesting though :-).

ciao,
  Torsten.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

jon_bondy
I found this to be useful and interesting:

https://www.youtube.com/watch?v=IN8tjTk8ExI

Jon

On 3/8/2021 12:55 PM, Torsten Paul wrote:

> On 08.03.21 18:30, Jordan Brown wrote:
>> Yes.  I have absolutely no idea how to do reverse kinematics,
>> determining joint position based on an intended goal.
> Examples -> Advanced -> Animation shows 2D reverse kinematics.
> There's a link in the source code to RepRap wiki where I got
> the math from.
>
> Doing that in 3D is slightly more interesting though :-).
>
> ciao,
>    Torsten.
>
>

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Loomis Heads

mondo
In reply to this post by mondo
Thanks to Jordan's code, and further assistance, I've added place
holders for feet and hands. I think, I will make all joints, knees,
ankles, hips etc, to give full 360deg articulation,  then maybe impose
limits on each axis if required. I have  put  the parts into a rough
proportion, based on an adult  figure being approximately 7.5 times the
height of the head. I can pose it, but I've yet to scale it down, print
it, and see if it looks right. Later on, it can be modified to give
shorter legs, bigger heads, child proportions/whatever. The code below,
needs my previously designed head added, also I need to refine hands and
feet and torso shape. I'm undecided on setting the angle for joints.
There are a lot of parameters to adjust. Will possibly need to be able
to twist the torso, but at the final small scale I am interested in I
doubt it will be noticeable, or a special case could be designed. It is
not easy positioning hands, etc, I may revert to restricting movement
earlier than i thought. Anyway, it's getting there.


//Cheap and dirty stick figure.
// Note that measurements are global values and picked up directly
// by the modules, while joint positions are parameters
// (which in turn come from global values).
// This is mostly because you can generally assume that the left and
// right arms are the same length, but the shoulders and elbows may
// be in different positions.

/* [ Measurements ] */

// dimensions in relation to head diameter - hd=350
  hd=350;

torso_h = hd*3;
torso_w = hd*2;
torso_d = hd*1;
shoulder_h = torso_h *7/8;
shoulder_d = hd*.7;
neck_h = hd/2;
neck_d = hd/2;
head_w = hd*.6;
head_h = hd*.86;
head_d = hd;
uarm_l = hd*1.5;
uarm_d = hd*.7;
elbow_d = hd*.4;
larm_d = hd*.4;
larm_l = hd*1.2;
uleg_l = hd*2;
uleg_d = hd*0.8;
hip_d=hd*0.8;
knee_d=hd*0.5;
lleg_l = hd*1.8;
lleg_d = hd*0.5;
hand_l=hd*.8;
hand_w=hd*.5;
hand_h=hd*.2;
foot_l=hd*1.2;
foot_w=hd*.4;
foot_h=hd*.3;
wrist_d=hd*.3;
ankle_d=hd*.4;



/* [ Joint positions ] */
lshoulder_xa = -90;
lshoulder_ya = 125;
lshoulder_za = -90;
rshoulder_xa = -90;
rshoulder_ya = 55;
rshoulder_za = -90;
lelbow_theta = 25;
relbow_theta = 5;
lhip_theta =18;
lhip_phi = 0;
rhip_theta = 0;
rhip_phi = 0;
lknee_theta =190;
rknee_theta =-170;
lwrist_xa=-90;
lwrist_ya=0;
lwrist_za=98;
rwrist_xa=90;
rwrist_ya=190;
rwrist_za=90;
lank_xa=-5;
lank_ya=5;
lank_za=-6;
rank_xa=-10;
rank_ya=0;
rank_za=-7;

// Children:
// 0 - neck
// 1 - left shoulder
// 2 - right shoulder
// 3 - left leg
// 4 - right leg
module torso() {
     scale([1, torso_d/torso_w, 1]) cylinder(h=torso_h,d=torso_w);
     translate([0,0,torso_h]) children(0);
     translate([torso_w/2, 0, shoulder_h]) children(1);
     translate([-torso_w/2, 0, shoulder_h]) children(2);
     translate([torso_w*0.3, 0, 0]) children(3);
     translate([-torso_w*0.3, 0, 0]) children(4);
}

// Children:
// 0 - head
module neck() {
     cylinder(h=neck_h, d=neck_d);
     translate([0,0,neck_h]) children(0);
}

module head() {
     translate([0,0,head_h/2]) scale([head_w/head_h, head_d/head_h, 1])
sphere(d=head_h);
}

// Children
// 0 - upper arm
module shoulder(xa,ya,za) {
     sphere(d=shoulder_d);
     rotate([xa,ya,za]) children();
}

// Children
// 0 - elbow
module upper_arm() {
     rotate([0,90,0]) {
         cylinder(h=uarm_l, d1=uarm_d,d2=uarm_d*0.6);
         translate([0,0,uarm_l]) children();
     }
}

// Children
// 0 - lower arm
module elbow(theta) {
     sphere(d=elbow_d);
     rotate([theta,0,0]) children();
}

module lower_arm() {
     cylinder(d=larm_d, h=larm_l);
     translate([0,0,larm_l])children();
}

module wrist(xa,ya,za){
      sphere(d=wrist_d);
     rotate([xa,ya,za]) children();
}

module hand(){
   translate([-hand_w*.5,-hand_l,-hand_h*.5])cube([ hand_w,hand_l,hand_h]);
}


module hip(theta, phi) {
     sphere(d=hip_d);
     rotate([-theta, -phi]) children();
}

module upper_leg() {
     rotate([180,0,0]) cylinder(h=uleg_l, d1=uleg_d,d2=uleg_d*0.7 );
     translate([0,0,-uleg_l]) children();
}

module knee(theta) {
     sphere(d=knee_d);
     rotate([theta,0,0]) children();
}

module lower_leg() {
      cylinder(h=lleg_l, d1=lleg_d, d2=lleg_d*0.8);
     translate([0,0,lleg_l])children();
}
module ankle(xa,ya,za){
      sphere(d=ankle_d);
     rotate([xa,ya,za]) children();
    }

module foot(){
  translate([0,foot_l*.5, foot_h*.5])cube([ foot_w,foot_l,foot_h],true);
}

$fn=50;
torso() {
     neck() {
         head();
     }
     shoulder(lshoulder_xa,lshoulder_ya,lshoulder_za)
         upper_arm()
         elbow(lelbow_theta)
         lower_arm()
         wrist(lwrist_xa,lwrist_ya,lwrist_za)
         hand();

     mirror([1,0,0]) shoulder(rshoulder_xa,rshoulder_ya,rshoulder_za)
         upper_arm()
         elbow(relbow_theta)
         lower_arm()
         wrist(rwrist_xa,rwrist_ya,rwrist_za)
     echo(rwrist_za)
         hand();

     hip(lhip_theta, lhip_phi)
         upper_leg()
         knee(lknee_theta)
         lower_leg()
      ankle(lank_xa,lank_ya,lank_za)
         foot();
     mirror([1,0,0]) hip(rhip_theta, rhip_phi)
         upper_leg()
         knee(rknee_theta)
         echo(rknee_theta)
         lower_leg()
       ankle(rank_xa,rank_ya,rank_za)
       echo(rank_xa)
        foot();
}



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org