PDA

View Full Version : List edges in clockwise/render order?


daval
05-23-2003, 10:16 PM
Hi,

I'm trying to find the counterclockwise order of a series of connected border edges. But I'm always ending up with the edges in numerical order.

To get my scene:
Create a box and delete a face. Then select 3 of the border edges surrounding the hole. These I'd like to list in clockwise order. The reason is I'm inputing these in polyAppend later on and I want to make sure the normal is pointing in the right direction.

I've read the how-to on ewertb but that one deals with faces and doesn't seem to work with edges or vertices.

Any help is appreaciated. Thanks =)

gmask
05-27-2003, 03:52 AM
You have to use a scriptjob that manually puts the edges in an array in the order you select them. For whatever reasons Maya cannot return components in the order selected only objects.

Submit those feature requests!

dbissell
05-28-2003, 05:43 AM
Below is a function from a MEL script that I've been developing. It lists the vert indexies from a face on a polygon object. I believe the return order of the verts is in render order. Check it out. Maybe it will give you some help to get you going in the right direction. Any comments on the code are welcome.

Let me know,
-Dan

//-----------------------------------
//polyGetFaceVertices(string, int)
// Given an object and an index to one of it's polygon faces this function returns the vertices indecies that
// make up that given face
//Input:
// String $objectName = the polygon object's name in the scene
// int $faceIndex = the index number of the face whose vertex indecies you want
//Output:
// int [] = a list of the vertices indecies that make up the face.
//-----------------------------------
proc int [] polyGetFaceVertices(string $objectName, int $faceIndex)
{
int $retVal[];

string $faceName = $objectName + ".f[" + $faceIndex + "]";
string $tokenList[];
string $vtxInfo[] = `polyInfo -fv $faceName`;
tokenizeList($vtxInfo[0], $tokenList);
//Dump the first two items on the list
for($i=2; $i<size($tokenList); $i++)
$retVal[$i-2] = $tokenList[$i];

return $retVal;
}

daval
05-28-2003, 09:45 AM
Hi again,

Thanks gmask an dbissell for helping me.

---------------------------
dbissell:
I believe the following also will return the vertices in a CCW order from a face:
polyListComponentConversion -fromFace -toVertexFace $faceName;

This result must also be processed to retreive the actual index of the vertices though.

-----------------------------

I recently solved my problem using the CCW order of the vertices from the faces connected to the border edges. By comparing the border edges vertices, for each edge, to the ccw vertices from the connected face and then reversing the matching border edge vertice (if necessary) I got the border edge vertices in correct order. Then I wrote another algorithm to place the edges in a connected order. This seems to work just fine.

If anyone is interested, tell me and I'll expalin it in more detail.

daval

ktpr
05-28-2003, 05:31 PM
Hey I would like to know (or perhaps see the code :) ). I think getting edges in an consistent order could lead the way to a poly and subd pick walk function.

cheers
ktpr

daval
05-30-2003, 10:51 PM
Hi again,

Sorry if this post is a bit long :)
The algorithm in (perhaps) more detail is as follows:

1. Find which faces are related to the selected edges. Since the edges are border edges only one face per edge is involved.
2. Retrieve the facevertices from the face. These are returned in a counter clockwise order.
3. Retrieve the vertices at the end points of the edges.
4. Extract the interesting vertices in counter clockwise order by matching the retrieved facevertices in step two with the retrived vertices in step three.
5. If necessary reverse the order of the indexes.
6. Repeat step two to six for each edge. This gives us the vertices of the border edges in counter clockwise order.
7. Each edge now has a pair of vertices in counter clockwise order. Match the last vertex listed for each edge with the first vertex listed for the other two edges. Repeat until a match is found.
8. We now know which two border edges are connected. Since there is only three edges we now can write out the complete series of connected border edges in counter clockwise order.

===============================
The working code for this follows here.
Any suggestions or optimizations to the code below is much appreaciated. Here we go:


// Make sure we get the list of edges in render order (clockwise order). This to
// ensure correct normal direction

string $edgeFacesArray[] = `polyInfo -ef $connectedEdges`;
string $tmpFaces[];
int $faceIndexArray[];

// Find the index of the faces connected to the edges
for($item in $edgeFacesArray){
tokenize $item $tmpFaces;
$faceIndexArray[size($faceIndexArray)] = $tmpFaces[2];
}

// Create face descriptions from edge numbers
string $faceArray[];
for ($item in $faceIndexArray){
$faceArray[size($faceArray)] = $selectedTransform + ".f[" + $item +"]";
}

string $vertexFaces[];
string $component;
string $suffix[];
string $tmp[];
string $tmpEdgeVertexIndexArray[];
string $selIndex[3];
int $vertexOrder[2];
int $ccw[6];

// Find the vertices in counter clockwise order. Repeat for each face
$i = `size($faceArray)`;
while ($i--){

$vertexFaces = `polyListComponentConversion -tvf $faceArray[$i]`;
$vertexFaces = `filterExpand -sm 70 -expand true $vertexFaces`;

$component = `match "\\..*" $connectedEdges[$i]`;
$selIndex[size($selIndex)] = `match "[0-9]+" $component`;

$tmp = `polyInfo -ev $connectedEdges[$i]`;
tokenize $tmp[0] $tmpEdgeVertexIndexArray;


// Find the index of the CCW facevertices, store these in suffix.
for ($item in $vertexFaces){
$component = `match "\\..*" $item`;
$suffix[size($suffix)] = `match "[0-9]+" $component`;
}

// Check if CCW face vertices is a part of the edge. If it is we want to use it.
for ($j = 0; $j < size($suffix); $j++){
if ($suffix[$j] == $tmpEdgeVertexIndexArray[2] || $suffix[$j] == $tmpEdgeVertexIndexArray[3]){
$vertexOrder[size($vertexOrder)] = $suffix[$j];
}
}

// Special case (if the last index in facevertices is connected to the first, we don't need to reverse)
if (($suffix[0] == $vertexOrder[0] && $suffix[size($suffix)-1] == $vertexOrder[1]) || ($suffix[0] == $vertexOrder[1] || $suffix[size($suffix)-1] == $vertexOrder[0])) {
print "\n no need to reverse:\n";
print $vertexOrder;
}
else {
// Reverse if the above is NOT true
int $tmpVertexOrder[];
$tmpVertexOrder[0] = $vertexOrder[1];
$tmpVertexOrder[1] = $vertexOrder[0];
$vertexOrder[0] = $tmpVertexOrder[0];
$vertexOrder[1] = $tmpVertexOrder[1];
clear $tmpVertexOrder;
}

// Store the "completed" vertices for the edge and face and continue.
$ccw[size($ccw)] = $vertexOrder[0];
$ccw[size($ccw)] = $vertexOrder[1];

clear $suffix;
clear $vertexOrder;
}

int $finalEdgeCCW[3];
string $edges = "";

if ($ccw[1] == $ccw[2]){
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[0];
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[1];
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[2];
}

else if ($ccw[1] == $ccw[4]){
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[0];
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[2];
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[1];

}

else if ($ccw[3] == $ccw[4]){
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[1];
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[2];
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[0];
}

else if ($ccw[3] == $ccw[0]){
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[1];
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[0];
$finalEdgeCCW[size($finalEdgeCCW)] = $selIndex[2];
}

// $finalEdgeCCW now contains the edges in counter clockwise order

CGTalk Moderation
01-15-2006, 06:00 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.