General Category > ASL Scripts

SetFacePointIndex method

(1/3) > >>

NickE:
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: ---for $k = 0 to $source.GetNumSides($otherface)-1 do {
   $source.SetFacePointIndex($otherface,$k,$ofptindex[$source.GetNumSides($otherface)-1-$k]);
}

--- End code ---

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: ---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

--- End code ---
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: ---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 *

--- End code ---

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!

Claude:
When you're finished editing  the mesh,do you call Close() ? I have to ask since you didn't post
the code and I assume it's what should get rid of the unwanted edges.

NickE:
The full code is below.  Unfortunately, I have opened and closed the mesh properly.


--- Code: ---/* 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;
--- End code ---

Thank you!

Claude:
NickE
You're using it the way I would have.
It's disappointing that calling Close() doesn't clean up.
Which way are you going now?
Cleaning up yourself,delete face and rebuild or else.

Happy new year.
Claude

Steve:
I'll look into this. You should be able to do this.

Navigation

[0] Message Index

[#] Next page

Go to full version