Anim8or Community

Please login or register.

Login with username, password and session length
Advanced search  

News:

An update to Anim8or, v1.00b, is available with a few bug fixes. Get your copy HERE. See the "ReadMe" file for details.

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - NickE

Pages: [1] 2 3 ... 11
1
ASL Scripts / Re: Find tri's, quads etc in model
« on: February 05, 2017, 12:01:02 am »
Attached is a simple script that will mark the faces, edges, and vertex points of any face that has more than four sides.

2
Have you ever had a collection of points and wanted a mesh that corresponded to the surface of those points?

In my never ending quest to bring physics (or to effects that look mostly like physics) to Anim8or through scripting, I was working with smoothed particle hydrodynamics (SPH) to simulate fluids.  Using Anim8or points as particles, I was able to write scripts to simulate the fluid action, but had no real way of rendering just points.  The actual SPH script is still in development.

One popular way to extract a surface mesh from a point cloud is to use a technique called Marching Cubes.

Below is an implementation of the the Marching Cubes Algorithm in ASL.  The documentation for usage is within the script itself.

3
General Anim8or Forum / Re: poly groups/ vertex groups
« on: June 23, 2016, 09:42:42 pm »
It is unclear what you are asking.  There is the ability to select by material:  Edit->Select->Select by Material

4
ASL Scripts / Re: Boolean operation problem!
« on: May 08, 2016, 03:53:34 am »
JSmith,

I personally do not use Kubajzz Boolean Scripts A-B or B-A.  I use the one attached below.

I looked at the an8 file you attached.  Your mesh "meshHH" had several problems including interior lines and duplicate points.  Your mesh "meshSS" had all its normals flipped inward, a couple of extra edges and several duplicate points.  These issues are probably what is causing the errors with the Kubajzz A-B Boolean script.

When I fixed these issues and ran the attached boolean operations script (selecting the "meshSS" so it would be subtracted from "meshHH"), the result was a good subtraction with the exception of a few faces with flipped normals.  I have attached the an8 file so you can compare the original vs repaired meshes and the results of the Boolean subtraction.

NickE

5
ASL Scripts / Re: Boolean operation problem!
« on: May 06, 2016, 10:51:08 pm »
JSmith,

In the header of the script file is the instruction on how to execute the script.

Quick instructions:
Have an object that contains the two meshes that you want use for the boolean operations.
If you wish to do a Union operation, do not select either mesh and execute the script by Scripts->Run Script File...
If you wish to do a Difference operation, select the mesh that will be subtracted from the other, then execute the script
If you wish to do a Intersection operation, select both meshes, then execute the script

If you need more guidance, please let me know.

NickE

6
Anim8or v0.98 Discussion Forum / Re: Bug/Issue: Normals (ASL)
« on: March 09, 2016, 01:08:06 am »
Raxx,

When I calculate the face normals from the average of the face vertex normals (calculated from the edge vectors from each point of the face), I do get different values than your script returns.  The edge vector calculated values return symmetrical normals for mirrored faces on your attached mesh.  I modified your script to add the manually calculated normals to the output.  You can see the variation in the individual vertex based face normals.  It seems the algorithm that Anim8or is using is significantly different or is suffering from a precision problem.

Code: [Select]
file $c;
shape $s, $childShapes[0];
int $i, $j, $k;
int $numSides;
point3 $faceNormal;

//added
int $l,$back,$fwd;
point3 $facePoint[0];
point3 $facePointNormal[0];
point3 $fPNavg;
 
$c.open("$console", "w");
 
project.curObject.GetShapes($childShapes);
 
for $i = 0 to $childShapes.size - 1 do
{
if($childShapes[$i].GetKind() == SHAPE_KIND_MESH)
{
$s = $childShapes[$i];
 
for $j = 0 to $s.GetNumFaces() - 1 do
{
if ($s.GetFaceSelected($j) == 1)
{
//$faceNormal = $s.GetNormal($s.GetFaceNormalIndex($j, 0));
$faceNormal=(0.0,0.0,0.0);
$fPNavg=(0.0,0.0,0.0);
$numSides = $s.GetNumSides($j);
        $facePoint.size = $numSides;
        $facePointNormal.size = $numSides;
for $k = 0 to $numSides - 1 do
{
$faceNormal = $faceNormal + $s.GetNormal($s.GetFaceNormalIndex($j, $k));
$facePoint[$k]=$s.GetPoint($s.GetFacePointIndex($j,$k));
$facePointNormal[$k]=(0.0,0.0,0.0);
}
 
$faceNormal = normalize(($faceNormal.x/(1.0 * $numSides), $faceNormal.y/(1.0 * $numSides), $faceNormal.z/(1.0 * $numSides)));

for $k = 0 to $numSides-1 do
{
          $back = $k - 1;
          if ($back < 0) $back = $numSides - 1;
          $fwd = $k + 1;
          if ($fwd > ($numSides - 1)) $fwd = 0;
          $facePointNormal[$k] = normalize(cross(($facePoint[$back]-$facePoint[$k]),($facePoint[$fwd]-$facePoint[$k])));
          $c.print("Calc FP %d Normal (%.3f,%.3f,%.3f)\n",$k,$facePointNormal[$k]);
          $fPNavg = $fPNavg + $facePointNormal[$k];
        }
        $fPNavg = normalize(($fPNavg.x / (1.0 * $numSides),$fPNavg.y / (1.0 * $numSides),$fPNavg.z / (1.0 * $numSides)));
$c.print("Face %d Anim8or normals (%.3f, %.3f, %.3f) Calc (%.3f, %.3f, %.3f)\n", $j, $faceNormal, $fPNavg);
}
}
}
}
 
$c.close();
 

NickE

7
ASL Scripts / Re: BVH File Import into Anim8or
« on: January 24, 2016, 04:51:51 pm »
RemiD,
Like Claude posted, if you post the BHV file and parameters, I will take a look.  Often, these issue happen because so many different BVH generators write slightly differing formats that the parser does not anticipate or the file is simply malformed.

NickE

8
ASL Scripts / Re: SetFacePointIndex method
« on: January 07, 2016, 05:39:01 pm »
Kreator,

I am not sure which script your are referring to as "parametric SourceMesh2Target".

If you are referring to the parametric script in http://www.anim8or.com/smf/index.php/topic,906.msg6613.html#msg6613 called "mesh2mesh_1.a8s", I tested it in Build 1205 and it worked fine for me.  You kind of have to click the script button, then sort of click-drag a bit in some open area and the parametric copies appear.

What behavior are you seeing?

Thank you,
NickE

9
ASL Scripts / Re: SetFacePointIndex method
« on: January 06, 2016, 06:52:07 pm »
Kreator,

When I ran through the tank tread tutorial (including downloading the scripts posted there) on Build 1205, it worked properly.

Also the mesh_2_path_2 worked properly without hanging when I tried it.

Could it be something unique to your setup?  I am happy to help in any way.

10
ASL Scripts / Re: SetFacePointIndex method
« on: January 05, 2016, 01:38:32 pm »
Claude,
Luckily, "new" edges are always added to the end of the list, so as a workaround, I can just delete them without it causing problems with rearranging the index.

Kreator,
I had no idea that these scripts had stopped working.  I haven't used them in quite some time.  I will investigate further.

Steve,
Thank you!

11
ASL Scripts / Re: SetFacePointIndex method
« on: December 31, 2015, 02:16:34 pm »
The full code is below.  Unfortunately, I have opened and closed the mesh properly.

Code: [Select]
/* fix normals
   change all faces to the same orientation by starting with the first face.
   The direction of vertex winding is noted and compared to each edge adjacent face.
   If the direction of vertex winding is the same (should be opposite), fix it.
*/

/* section to initialize console output */
file $output;
string $fname;
$fname="$console";
$output.open($fname,"w");

object $curObject;
shape $shape, $shapes[0], $childShapes[1],$source;

int $havesource,$sourcenumpts,$sourcenumfaces,$sourcenumedges;

int $i,$j,$k,$m,$n;
int $tempedgeindex,$epi1,$epi2,$epi1_p,$epi2_p,$firstface;
int $tepi1,$tepi2,$tepi1_p,$tepi2_p;
int $f1,$f2;
int $cw1,$cw2;
int $flipped;
int $facestatus[0],$edgeface1[0],$edgeface2[0];
int $mainedge,$checkedge;
int $otherface;
int $ofptindex[0];

$curObject = project.curObject;
$curObject.GetShapes($childShapes);
$shapes.size = 0;
while ($childShapes.size > 0)
    $shapes.push($childShapes.pop());
   
while ($shapes.size > 0) {
    $shape = $shapes.pop();

    if ($shape.GetKind() == SHAPE_KIND_MESH && $havesource == 0)
    {
       $source=$shape;
       $sourcenumpts=$source.GetNumPoints();
       $sourcenumedges=$source.GetNumEdges();
       $sourcenumfaces=$source.GetNumFaces();
       $facestatus.size=$sourcenumfaces;
       $edgeface1.size=$sourcenumedges+1;
       $edgeface2.size=$sourcenumedges+1;
       $havesource=1;
    }
}

$shape.Open();
if ($havesource == 1) {
    /* build index of Edges to Faces to save cycles*/
    for $i = 1 to $sourcenumedges do
    {
        $firstface=0;
        for $j = 0 to $sourcenumfaces-1 do
        {
            for $k = 0 to $source.GetNumSides($j)-1 do
            {
                $tempedgeindex = $source.GetEdgeIndex($j,$k);
                if (abs($tempedgeindex) == $i) {
                    if ($firstface==0) {
                        $edgeface1[$i]=$j;
                    } else {
                        $edgeface2[$i]=$j;
                    }
                    $firstface=1;
                }
            }
        }
    }
   
    /* output list of the edges with the faces connected to it */
    for $i = 1 to $sourcenumedges do {
        $output.print("E:%d F1:%d F2:%d\n",$i,$edgeface1[$i],$edgeface2[$i]);
    }
   
   
    /* Cycle through faces edges to determine if adjacent faces have the same normals
       If the clockwise-counterclockwise order of face points is the same for adjacent faces,
       the normals are flipped
    */
   
    for $i = 0 to $sourcenumfaces-1 do {
        for $j = 0 to $source.GetNumSides($i)-1 do {
            $mainedge = $source.GetEdgeIndex($i,$j);                                /* current edge of current face */
            $epi1=$source.GetEdgeIndex0($mainedge);                                 /* end point of current edge */
            $epi2=$source.GetEdgeIndex1($mainedge);
            for $k = 0 to $source.GetNumSides($i)-1 do {
                if ($epi1==$source.GetFacePointIndex($i,$k)) $epi1_p=$k;            /* position in face vertex winding */
                if ($epi2==$source.GetFacePointIndex($i,$k)) $epi2_p=$k;
            }
            $output.print("F:%d E:%d ep1:(%d,%d) ",$i,$mainedge,$epi1_p,$epi2_p);
            if ($edgeface1[$mainedge] == $i) {                                     
                $otherface=$edgeface2[$mainedge];
            } else {
                $otherface=$edgeface1[$mainedge];
            }
            $ofptindex.size=$source.GetNumSides($otherface);                        /* retrieve other face with same edge */
            for $k = 0 to $source.GetNumSides($otherface)-1 do {
                $ofptindex[$k] = $source.GetFacePointIndex($otherface,$k);
                if ($epi1==$source.GetFacePointIndex($otherface,$k)) $tepi1_p=$k;   /* position in other face vertex winding */
                if ($epi2==$source.GetFacePointIndex($otherface,$k)) $tepi2_p=$k;
            }
            $output.print("F:%d E:%d ep1:(%d,%d) ",$otherface,$mainedge,$tepi1_p,$tepi2_p);
            if (abs($epi1_p - $epi2_p)==1) {                                        /* logic to determine direction of winding */
                if ($epi1_p > $epi2_p) {                                            /* can be simplified a bit :) */
                    $cw1=0;
                } else {
                    $cw1=1;
                }
            } else {
               if ($epi1_p > $epi2_p) {
                    $cw1=1;
               } else {
                    $cw1=0;
               }
            }

            if (abs($tepi1_p - $tepi2_p)==1) {
               if ($tepi1_p > $tepi2_p) {
                    $cw2=0;
               } else {
                    $cw2=1;
               }
            } else {
               if ($tepi1_p > $tepi2_p) {
                    $cw2=1;
               } else {
                    $cw2=0;
               }
            }
            $flipped=0;
            if ($cw1 == $cw2) $flipped=1;
            $output.print("->%d\n",$flipped);
            if ($cw1 == $cw2) {
                for $k = 0 to $source.GetNumSides($otherface)-1 do {
                    $source.SetFacePointIndex($otherface,$k,$ofptindex[$source.GetNumSides($otherface)-1-$k]);  /* reverse winding order of other face */
                    $output.print("Alter F:%d v:%d was:%d now:%d\n",$k,$otherface,$ofptindex[$k],$ofptindex[$source.GetNumSides($otherface)-1-$k]);
                }
            }
           
           
        }
    }
 }     

$shape.Close();
$output.close;

Thank you!

12
ASL Scripts / SetFacePointIndex method
« on: December 30, 2015, 11:56:01 pm »
I am trying to write an ASL script to essentially do what the Edit->Fix Normals command does.

I am using the technique of picking a face as the standard and testing whether the adjacent faces have the edges (or points) are wound in the same direction, then testing the adjacent to the adjacent, etc.  If I find a face that is wound in the same direction as the previous, I would like to reverse the winding.

I am trying to use the mesh.SetFacePointIndex method to do this:

Code: [Select]
for $k = 0 to $source.GetNumSides($otherface)-1 do {
   $source.SetFacePointIndex($otherface,$k,$ofptindex[$source.GetNumSides($otherface)-1-$k]);
}

where $ofptindex[] is the list of the index to the face points in the original order. 

I am working with a cube converted to a mesh as a test. E=EdgeIndex, F1:Face containing edge, F2:Other Face containing edge

Code: [Select]
E:1  F1:0 F2:5
E:2  F1:0 F2:3
E:3  F1:0 F2:4
E:4  F1:0 F2:2
E:5  F1:1 F2:2
E:6  F1:1 F2:4
E:7  F1:1 F2:3
E:8  F1:1 F2:5
E:9  F1:2 F2:4
E:10 F1:2 F2:5
E:11 F1:3 F2:5
E:12 F1:3 F2:4
So, if the original vtxIndex were [4,5,7,6], then the new would be [6,7,5,4].  Unfortunately, the above code results in three extra edges: 6-5, 5-5, and 4-4.

Code: [Select]
E:1  F1:0 F2:5
E:2  F1:0 F2:3
E:3  F1:0 F2:4
E:4  F1:0 F2:2
E:5  F1:1 F2:2
E:6  F1:1 F2:4
E:7  F1:1 F2:3
E:8  F1:1 F2:5
E:9  F1:2 F2:4
E:10 F1:2 F2:5
E:11 F1:3 F2:5
E:12 F1:3 F2:4
E:13 F1:0 F2:0 *
E:14 F1:0 F2:0 *
E:15 F1:0 F2:0 *

I am guessing that the extra edges are left over when the Face Point Index is re-assigned one vertex at a time.

Am I understanding the mesh.SetFacePointIndex method correctly?  What is the proper way to accomplish this?

Thank you!

13
ASL Scripts / Re: Boolean operation problem!
« on: December 11, 2015, 10:45:10 pm »
I have attached a different Boolean Operations script that might work in those tricky situations.  The instructions are a bit different, so be sure to read the header in the script file.


14
ASL Scripts / Re: BVH File Import into Anim8or
« on: July 03, 2015, 03:26:30 pm »
SubDrag,

The file from the link is working fine for me.  I have attached the latest version of the program (executable and source) and the an8 file from the conversion.  The latest version is smarter about white space in the bvh file than the previous version.  I found that GoldenEye bvh files tend to use multiple spaces as a separator rather than the single space or tab.  In the previous version, multiple spaces as a separator would cause parsing errors.

The only parameter I changed in BVH2Animator is the scale factor to 0.15, so the figure (originally at 638) would not be so large (more like 100).

15
ASL Scripts / Re: BVH File Import into Anim8or
« on: June 15, 2015, 11:33:03 pm »
The missing pieces of required information is the reference frames for the rotations.  Does FBX use a right-handed or left-handed reference frame?  Are the skeletal orientation given in the global reference frame, object reference frame, or local reference frame?  Are the keyframe joint rotations given in the global reference frame, object reference frame, or local reference frame?

Since you already have the Anim8or skeleton constructed from the FBX file, you have some knowledge of the FBX reference frame.  Otherwise the skeleton would be distorted or rotated.   So, essentially what you need to do is transform the FBX Euler rotation angles from whatever reference frame they are in to the Anim8or local bone reference frame (the rotation of the bone relative to the parent).

The BVH2Anim8or source code routine "Calc_Figure_Orientation" calculates the each bone orientation relative to its parent bone.  The root bone (the ultimate parent) is located in the Anim8or global reference frame Left-Handed (0,1,0).  The routine "Calc_NetOrient" calculates the each bone orientation relative to the Anim8or global reference frame.  The routine "Calc_Sequence_Motion" transforms the BVH keyframe joint rotations to the Anim8or local bone reference frame.

I know this is very confusing and extremely frustrating.  While writing the BVH2Anim8or and SMD2Anim8or converters, I kept having to remind myself "What frame I am in?  What frame do the actions take place?  What frame does Anim8or need?"

Pages: [1] 2 3 ... 11