Feedback

What's your question?

By: [ Editor ] Asked

metaball solution for maya

Does anyone know a metaball solution for maya ? I wan't to be able to cover several objects with a single smooth surface. Right now, all I can do is to emit-stick particles from surfaces, export to realflow, and use it's mesher. This gives nice meshes, but the workflow is far from productive.

thx

Add comment viewed 750 times Latest activity 11 months ago

or Cancel

2 answers

  • 1

manny [ Editor ]

See if you like the results from the following script I wrote. I tested on a very simple case so it might be slow. But the resulting mesh should be better than the nParticle mess.

/////////////////////////////////////////////////////////

string $sel[] = ls -sl; $sel = listRelatives -type particle $sel; string $particle = $sel[0]; int $pNum = getAttr ($particle+".count");

///////////////////////////////////////////////

// DETERMINE ROUGH PARTICLE VOLUME

float $minX = 1000000.0; float $minY = 1000000.0; float $minZ = 1000000.0; float $maxX = -1000000.0; float $maxY = -1000000.0; float $maxZ = -1000000.0;

float $ppos[] = getParticleAttr -at position -array true $particle; for($i=0;$i$maxX) $maxX = $ppos[3*$i];

if($ppos[3*$i]<$minX)
    $minX = $ppos[3*$i];

if($ppos[3*$i+1]>$maxY)
    $maxY = $ppos[3*$i+1];

if($ppos[3*$i+1]<$minY)
    $minY = $ppos[3*$i+1];

if($ppos[3*$i+2]>$maxZ)
    $maxZ = $ppos[3*$i+2];

if($ppos[3*$i+2]<$minZ)
    $minZ = $ppos[3*$i+2];

}

float $cx = ($maxX+$minX)*0.5; float $cy = ($maxY+$minY)*0.5; float $cz = ($maxZ+$minZ)*0.5;

float $max = $maxX-$minX; if($max < ($maxY-$minY)) $max = $maxY-$minY;

if($max < ($maxZ-$minZ)) $max = $maxZ-$minZ;

$max *= 2;

print "IGNORE FOLLOWING ERROR\n";

float $rad[]; $rad[0] = getAttr ($particle+".radius"); int $rPP = 0; if( catch( getParticleAttr -at radiusPP $particle ) == 0) { $rPP = 1; $rad = getParticleAttr -at radiusPP $particle; float $rMax = -1; for($val in $rad) if($val > $rMax) $rMax = $val;

clear $rad;
$rad[0] = $rMax;

} $max += $rad[0];

// CREATE META BALL MESH...USING POLY CUBE

int $res = 2; // ADJUST THIS TO SET YOUR START RESOLUTION

string $cube[] = polyCube -w 1 -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 0; polySmooth -mth 0 -dv $res -c 1 -kb 1 -ksb 1 -khe 0 -kt 1 -kmb 1 -suv 1 -peh 0 -sl 1 -dpe 1 -ps 0.1 -ro 1 -ch 0 $cube[0]; scale -a $max $max $max $cube[0]; move -a $cx $cy $cz $cube[0];

// LOOP THROUGH VERTICES TO ENVELOPE PARTICLES string $pts[] = ls -flatten ($cube[0]+".vtx[*]"); for($pt in $pts) { float $p[] = pointPosition -w $pt;

float $min = 1000000.0;
float $p1[3];
for($i=0;$i<$pNum;$i++)
{
    float $pp[] = `getParticleAttr -at position ($particle+".pt["+$i+"]")`;
    if($rPP)
        $rad = `getParticleAttr -at radiusPP ($particle+".pt["+$i+"]")`;

    float $results[] = `angleBetween -v1 $p[0] $p[1] $p[2] -v2 $pp[0] $pp[1] $pp[2]`;
    float $angle = $results[3];
    float $hypot = mag( << $pp[0], $pp[1], $pp[2] >> );
    float $opp = $hypot * sind($angle);

    if($opp < $rad[0])
    {
        float $dist = mag( << ($pp[0]-$p[0]), ($pp[1]-$p[1]), ($pp[2]-$p[2]) >> );
        if($dist < $min)
        {
            $min = $dist;
            $p1 = $pp;
        }
    }
}

float $results[] = `angleBetween -v1 $p[0] $p[1] $p[2] -v2 $p1[0] $p1[1] $p1[2]`;
float $angle = $results[3];
float $hypot = mag( << $p1[0], $p1[1], $p1[2] >> );
float $opp = $hypot * sind($angle);
float $adj = $hypot * cosd($angle);
float $angle1 = acosd($opp/$rad[0]);
float $opp1 = $rad[0] * sind($angle1);
float $dist = $adj + $opp1;
vector $v = unit( << $p[0], $p[1], $p[2] >> ) * $dist;
float $x = $v.x;
float $y = $v.y;
float $z = $v.z;
move -a $x $y $z $pt;

}

NN comments
michalf
-

that’s an interesting script Manny ! Even though it doesn’t solve the problem (because it’s slow and not animated) I think I can learn smth from it. thanks !

manny
-

Hi Michal,

Conceptually, this script can animate the resulting mesh. The only thing would be the section where the particle volume is roughly calculated. As your particles move, the volume would change. But I don’t think it would be difficult to solve this. Maybe start with a unit volume mesh and multiply point positions with the changing radius of the particles. Then use this resulting position to find the closest particle. I’ll try this when I have some free time.

As for the speed issue, this could be converted into a plugin. That should speed things up.

manny
-

By “changing radius”, I mean the volume radius of the particles.

or Cancel
  • 0

julian [ Admin ]

You can create a mesh from nParticles. See here.

You still have to go through the particles stage of course, and that makes it pretty slow. It would be nice if there was a tool to make an iso-surface direct from meshes, or curves.

NN comments
michalf
-

Yeah I tried meshing nparticless as soon as they were available in maya, but they’re much slower than realflow mesher and results are crappy. Something interactive, working from set of surfaces would be best. Strange that nothing like that was created for maya. Maybe some 3rd party plugin I could buy?

or Cancel