polyNurbsIntersect 2.0.3 for Maya (maya script)

split polygonal meshes using NURBS surfaces

Feature Request

Polygon

Status:pending
Date:02/27/2013
Submitted by: roboguy roboguy
Same thing but with a polygon mesh not nurbs that would be amazing!

Comments on this feature request:

  • nowayfra

    nowayfra said over 13 years ago:

    Yeah internally i added the function for my personal use, but the problem is that the cut path wont follow the mesh/mesh intersection if used with for example a cube. You can cut meshes using other meshes as long as they are overall smooth shaped, then the cut path will follow the intersection more ore less but never as precise as it does using nurbs surfaces as cut object. At least using the algorithm as it is implemented at the moment. The other thing is that the script will hang up if meshes are used as cut object together with the option "subdivide by curvature" checked because meshes have no real curvature so each crinkle will lead to infinite subdivisions. But keeping this in mind you can use meshes at your own risk if you use the script extension below. Select the meshes you want to cut and at last the cutting mesh, then go on as uasual (but never use "subdivide by curvature"!!). Copy the script below and replace the whole content of polyNurbsIntersect.mel with it, then restart maya. proc string[] intersect( int $subdivisions, int $useMaxEdgeLength, int $useCurvature, int $iterations, int $separateShells, int $createIntersectionCurves, int $keepHistory, float $maxEdgeLength, float $maxAngle, string $selection[], string $infoNodes[]) { $timer = `timerX`; int $show = 1; // turns on displaying progress string $return[], $intersectingEdges[], $doubleIntersectingEdges[], $intersectingEdgesTmp[], $subdivideFaces[], $subdivideEdges[], $evalSplit[], $splitVertexName[], $edgesToCheck[], $evalCurves[], $splitPathEdges[]; vector $cutPosition[], $cutPositionID[], $midPoints[], $betweenPoints[], $normalDirection[], $normalDirectionID[], $splitVertexCorrectPosition[]; int $offset, $loopCounter, $intersections, $splitPaths, $splitVertexCount, $searchMethod, $vertices[], $index[]; float $currentMaxAngle[], $currentMaxEdgeLength[]; float $accuracy = .00001; int $adaptiveLoop = 1; int $doMainLoop = 1; int $numEdges[] = `polyEvaluate -e $selection[0]`; int $numVtx[] = `polyEvaluate -v $selection[0]`; $iterations = `pow 2 $iterations`; $maxAngle = deg_to_rad($maxAngle); string $parentName[] = `listRelatives -p $selection[0]`; string $nonManifoldEdges[] = `polyInfo -nme $selection[0]`; if(!$keepHistory) delete -ch $selection[0]; if(!$useMaxEdgeLength && !$useCurvature && !$subdivisions) $iterations = 1; if($useMaxEdgeLength || $useCurvature) $subdivisions = 0; if($iterations != 1) { $searchMethod = 1; for($i=0;$i<$numedges[0];$i++)><=$subdivisions;$i++)> 0 || $useMaxEdgeLength && $loopCounter >0 || $useCurvature && $loopCounter > 0) { if($show) { refresh; select -cl; }; }; int $doLoop = 1; if(!$useMaxEdgeLength && !$useCurvature) $intersections = 0; while($doLoop == 1) { if($searchMethod == 0) { string $vertIn[]; string $vertOut[]; for($k=0;$k<$numvtx[0];$k++)> 1.570796) $vertIn[`size $vertIn`] = $selection[0] + ".vtx[" + $k + "]"; else $vertOut[`size $vertOut`] = $selection[0] + ".vtx[" + $k + "]"; }; if(`size $vertIn` == $numVtx[0] || `size $vertOut` == $numVtx[0]) break; string $nonIntersectingEdges[]; string $edgeIn[] = `polyListComponentConversion -fv -te -in $vertIn`; string $edgeOut[] = `polyListComponentConversion -fv -te -in $vertOut`; $nonIntersectingEdges = `stringArrayCatenate $nonIntersectingEdges $edgeIn`; $nonIntersectingEdges = `stringArrayCatenate $nonIntersectingEdges $edgeOut`; int $edgeCountSize = `size (string($numEdges[0]))`; int $size = `size $nonIntersectingEdges`; for($k=0;$k<$size;$k++)><$numtoken;$n++)><$edgecountsize;$x++)><$size;$k++)>< 1) { $startID = $secondID + 1; } else if(($firstID - $startID) == 1) { $intersectingEdges[$counter] = $buffer[0] + "[" + $startID + "]"; $startID = $secondID + 1; $counter++; } else if(($firstID - $startID) > 1) { $intersectingEdges[$counter] = $buffer[0] + "[" + $startID + ":" + ($firstID - 1) + "]"; $startID = $secondID + 1; $counter++; }; if($k == ($size - 1) && $secondID != ($numEdges[0] - 1)) { $intersectingEdges[$counter] = $buffer[0] + "[" + ($secondID + 1) + ":" + ($numEdges[0] - 1) + "]"; }; }; $intersectingEdges = `filterExpand -ex 1 -fp 1 -sm 32 $intersectingEdges`; if($i == $subdivisions) { for($k=0;$k<`size><<$evp[3],$evp[4],$evp[5]>> - <<$evp[0],$evp[1],$evp[2]>>; $midPoints[$intersections] = (<<$evp[3],$evp[4],$evp[5]>> + <<$evp[0],$evp[1],$evp[2]>>) / 2; $intersections++; }; }; clear $vertIn $vertOut $nonIntersectingEdges; }; if($searchMethod == 1) { for($k=0;$k<`size><<$evp[0],$evp[1],$evp[2]>>; vector $edgeVertex1Pos = <<$evp[3],$evp[4],$evp[5]>>; vector $midPoint = ($edgeVertex0Pos + $edgeVertex1Pos) / 2; vector $between = $edgeVertex1Pos - $edgeVertex0Pos; setAttr ($infoNodes[0] + ".inPosition") ($midPoint.x) ($midPoint.y) ($midPoint.z); vector $cPos0 = getAttr($infoNodes[0] + ".position"); if(mag($cPos0 - $midPoint) <= mag><=><=$currentiteration;$n++)> 1) { $doubleIntersectingEdges[`size $doubleIntersectingEdges`] = $edgesToCheck[$k]; } else { $intersectingEdges[$intersections] = $edgesToCheck[$k]; if($i == $subdivisions) { $midPoints[$intersections] = $midPoint; $betweenPoints[$intersections] = $between; }; $intersections++; }; $newEdge = 1; break; }; }; $currentIteration *= 2; }; }; }; }; if(!$useMaxEdgeLength && !$useCurvature) print("subdivision loop: " + $i + " / intersecting edges: " + `size $intersectingEdges` + "\n"); if($i == $subdivisions && `size $nonManifoldEdges`) { $nonManifoldEdges = `polyInfo -nme $selection[0]`; $nonManifoldEdges = `filterExpand -ex 1 -fp 1 -sm 32 $nonManifoldEdges`; string $intersector = `stringArrayIntersector`; stringArrayIntersector -edit -intersect $nonManifoldEdges $intersector; stringArrayIntersector -edit -intersect $intersectingEdges $intersector; $nonManifoldEdges = `stringArrayIntersector -q $intersector`; deleteUI $intersector; if(`size $nonManifoldEdges`) { $numEdges = `polyEvaluate -e $selection[0]`; string $verticesToSplit[] = `polyListComponentConversion -fe -tv $nonManifoldEdges`; polySplitVertex -ch $keepHistory $verticesToSplit; int $newEdgeCount[] = `polyEvaluate -e $selection[0]`; $edgesToCheck = `filterExpand -ex 1 -fp 1 -sm 32 ($selection[0] + ".e[" + $numEdges[0] + ":" + ($newEdgeCount[0] - 1) + "]")`; $searchMethod = 1; clear $nonManifoldEdges; } else $doLoop = 0; } else $doLoop = 0; }; if($i < $subdivisions && `size $intersectingEdges`) { int $faceCount[] = `polyEvaluate -f $selection[0]`; string $faces[] = `polyListComponentConversion -fe -tf $intersectingEdges`; polySubdivideFacet -dv 1 -ch $keepHistory -m 0 $faces; int $newFaceCount[] = `polyEvaluate -f $selection[0]`; $faces[`size $faces`] = $selection[0] + ".f[" + $faceCount[0] + ":" + ($newFaceCount[0] - 1) + "]"; string $newEdges[] = `polyListComponentConversion -ff -te $faces`; $edgesToCheck = `filterExpand -ex 1 -fp 1 -sm 32 $newEdges`; clear $intersectingEdges; $searchMethod = 1; } else { clear $edgesToCheck; break; }; }; if(`size $intersectingEdges` || `size $doubleIntersectingEdges`) { for($i=$offset;$i<(`size> $minDistance && $loops <=><`size><$numintersectingedges;$i++)><`size><`size> $maxEdgeLength) $doStore = 1; if($useCurvature == 1 && `angle $currentNormalDirection[$i] $previousNormalDirection[$i]` > $maxAngle) $doStore = 1; if($doStore == 1) { $subdivideFaces[`size $subdivideFaces`] = $adjacentFace[$i]; $subdivideEdges[`size $subdivideEdges`] = $edgesToCheck[$k]; $intersectingEdges = `stringArrayRemove {$edgesToCheck[$k]} $intersectingEdges`; if(!`stringArrayContains $startEdge $subdivideEdges`) { $subdivideEdges[`size $subdivideEdges`] = $startEdge; $intersectingEdges = `stringArrayRemove {$startEdge} $intersectingEdges`; }; } else $usePreviousEdge[$i] = 1; }; break; } else { $newEdge[$i] = 0; if($i == 0) $searchLoops[$i] = 1; if($i == 1) $searchLoops[$i] = 0; }; }; }; while(($newEdge[0] + $newEdge[1]) != 0) { for($i=$searchLoops[0];$i<=$searchloops[1];$i++)><`size> $maxEdgeLength) $doStore = 1; if($useCurvature == 1 && `angle $currentNormalDirection[$i] $previousNormalDirection[$i]` > $maxAngle) $doStore = 1; if($doStore == 1) { $subdivideFaces[`size $subdivideFaces`] = $adjacentFace[0]; $subdivideEdges[`size $subdivideEdges`] = $edgesToCheck[$k]; $intersectingEdges = `stringArrayRemove {$edgesToCheck[$k]} $intersectingEdges`; if($usePreviousEdge[$i] == 1) { $subdivideEdges[`size $subdivideEdges`] = $currentEdges[$i]; $intersectingEdges = `stringArrayRemove {$currentEdges[$i]} $intersectingEdges`; }; $usePreviousEdge[$i] = 0; } else $usePreviousEdge[$i] = 1; }; $currentEdges[$i] = $edgesToCheck[$k]; break; } else if(`stringArrayContains $edgesToCheck[$k] $edgePath` == 1) { $newEdge = {0,0}; $isSplitLoop = 1; if(($useMaxEdgeLength + $useCurvature) != 0 && $adaptiveLoop == 1) { int $doStore = 0; string $temp[]; tokenize $edgesToCheck[$k] "[]" $temp; int $componentID = int($temp[1]); $previousCutPosition[$i] = $currentCutPosition[$i]; $previousNormalDirection[$i] = $currentNormalDirection[$i]; $currentCutPosition[$i] = $cutPositionID[$componentID]; $currentNormalDirection[$i] = $normalDirectionID[$componentID]; if($useMaxEdgeLength == 1 && `mag ($currentCutPosition[$i] - $previousCutPosition[$i])` > $maxEdgeLength) $doStore = 1; if($useCurvature == 1 && `angle $currentNormalDirection[$i] $previousNormalDirection[$i]` > $maxAngle) $doStore = 1; if($doStore == 1) { $subdivideFaces[`size $subdivideFaces`] = $adjacentFace[0]; if(!`stringArrayContains $edgesToCheck[$k] $subdivideEdges`) { $subdivideEdges[`size $subdivideEdges`] = $edgesToCheck[$k]; $intersectingEdges = `stringArrayRemove {$edgesToCheck[$k]} $intersectingEdges`; }; if($usePreviousEdge[$i] == 1) { $subdivideEdges[`size $subdivideEdges`] = $currentEdges[$i]; $intersectingEdges = `stringArrayRemove {$currentEdges[$i]} $intersectingEdges`; }; }; }; break; } else { if($counter < (`size $edgesToCheck` - 1)) { $newEdge[$i] = 1; } else if(($useMaxEdgeLength + $useCurvature) == 0 || (`size $subdivideFaces` + $adaptiveLoop) == 0 && $iterations != 1) { string $edgeVertices[] = `polyListComponentConversion -fe -tv $currentEdges[$i]`; $edgeVertices = `filterExpand -ex 1 -fp 1 -sm 31 $edgeVertices`; string $faceVertices[] = `polyListComponentConversion -ff -tv $adjacentFace[0]`; $faceVertices = `filterExpand -ex 1 -fp 1 -sm 31 $faceVertices`; $faceVertices = `stringArrayRemove $edgeVertices $faceVertices`; int $doBreak = 0; for($n=0;$n<`size><`size><<$evp[3],$evp[4],$evp[5]>> + <<$evp[0],$evp[1],$evp[2]>>) / 2; $currentEdges[$i] = $adjacentEdges[$x]; string $face[] = `polyListComponentConversion -fe -tf $matchingEdge[0]`; $face = `filterExpand -ex 1 -fp 1 -sm 34 $face`; $face = `stringArrayRemove {$adjacentFace[0]} $face`; $previousFace[$i] = $face[0]; $newEdge[$i] = 1; $numIntersectingEdges++; $doBreak = 1; break; } else print("// Warning: split paths are not correctly connected. Increasing the intersection search depth could solve this problem.\n"); } else if(`stringArrayContains $adjacentEdges[$x] {$edgePath[$switch[$i]]}`) { $matchingEdge = `polyListComponentConversion -fv -te -in {$edgeVertices[0],$edgeVertices[1],$faceVertices[$n]}`; $matchingEdge = `filterExpand -ex 1 -fp 1 -sm 32 $matchingEdge`; $matchingEdge = `stringArrayRemove {$currentEdges[$i]} $matchingEdge`; if($i == 0) $edgePath = `stringArrayCatenate {$matchingEdge[0]} $edgePath`; if($i == 1) $edgePath[`size $edgePath`] = $matchingEdge[0]; $intersectingEdges[`size $intersectingEdges`] = $matchingEdge[0]; float $evp[] = `xform -q -ws -translation $matchingEdge[0]`; string $temp[]; tokenize $matchingEdge[0] "[]" $temp; $cutPositionID[int($temp[1])] = (<<$evp[3],$evp[4],$evp[5]>> + <<$evp[0],$evp[1],$evp[2]>>) / 2; $newEdge = {0,0}; $isSplitLoop = 1; $numIntersectingEdges++; $doBreak = 1; break; }; clear $matchingEdge; }; if($doBreak) break; }; if($doBreak) break; else { $newEdge[$i] = 0; if($i == 0) $searchLoops[$i] = 1; if($i == 1) $searchLoops[$i] = 0; }; } else { $newEdge[$i] = 0; if($i == 0) $searchLoops[$i] = 1; if($i == 1) $searchLoops[$i] = 0; }; $counter++; }; }; }; }; }; if(($useMaxEdgeLength + $useCurvature) == 0 || (`size $subdivideFaces` + $adaptiveLoop) == 0) { string $splitArray[]; string $curveArray[]; $vertices = `polyEvaluate -v $selection[0]`; if($isSplitLoop) $edgePath[`size $edgePath`] = $edgePath[0]; $splitArray[0] = "polySplit -ch " + $keepHistory + " -s 1 -sma 0 "; if($createIntersectionCurves) $curveArray[0] = "curve -d 1 "; for($i=0;$i<`size>< (`size $edgePath` - $isSplitLoop)) { $splitVertexName[$splitVertexCount] = $selection[0] + ".vtx[" + ($vertices[0] + $splitVertexCount) + "]"; $splitVertexCorrectPosition[$splitVertexCount] = $cutPositionID[$componentID]; $splitVertexCount++; }; }; $evalSplit[$splitPaths] = `stringArrayToString $splitArray ""`; if($createIntersectionCurves) $evalCurves[$splitPaths] = `stringArrayToString $curveArray ""`; clear $splitArray $curveArray; }; $splitPaths++; }; if($useMaxEdgeLength == 1 || $useCurvature == 1) { if(`size $subdivideFaces` != 0 || `size $doubleIntersectingEdges` != 0) { if(`size $doubleIntersectingEdges`) { string $adjacentFaces[] = `polyListComponentConversion -fe -tf $doubleIntersectingEdges`; string $adjacentEdges[] = `polyListComponentConversion -ff -te $adjacentFaces`; $adjacentEdges = `filterExpand -ex 1 -fp 1 -sm 32 $adjacentEdges`; string $someEdges[]; for($i=0;$i<`size><$intersections;$i++)><`size><$splitvertexcount;$i++)> 1 && $separateShells == 1) { $return = `polySeparate -ch $keepHistory $selection[0]`; $return = (`listRelatives -c -f -type mesh $return`); for($node in $return) { int $verticesInMesh[] = `polyEvaluate -v $node`; polyMergeVertex -d 0 -ch $keepHistory ($node + ".vtx[0:" + ($verticesInMesh[0] - 1) + "]"); }; $return = `stringArrayCatenate {"1"} $return`; } else if($succes) { $return = `polyListComponentConversion -fv -te -in $splitVertexName`; $return = `stringArrayCatenate {"2"} $return`; } else $return = {"3",$selection[0]}; clear $intersectingEdges $evalSplit $evalCurves; print ($parentName[0] + ": time: " + `timerX -startTime $timer` + " sec\n"); } else { print($parentName[0] + ": time: " + `timerX -startTime $timer` + " sec / no intersections found -> skipped\n"); $return = {"0",$selection[0]}; }; return $return; }; global proc string[] polyNurbsIntersect(int $subdivisions, int $useMaxEdgeLength, int $useCurvature, int $iterations, int $separateShells, int $separateBySide, int $createIntersectionCurves, int $keepHistory, float $maxEdgeLength, float $maxAngle, string $selection[]) { $timer = `timerX`; int $errors = 0; string $message[] = {"mesh was not","meshes were not"}; string $meshes[] = {"","mesh","meshes"}; string $output[] = {}; string $polySurface[] = {}; string $selectionChilds[] = `listRelatives -allDescendents -fullPath $selection`; for($node in $selectionChilds) { if(`nodeType $node` == "mesh" && !`getAttr ($node + ".intermediateObject")`) $polySurface[`size $polySurface`] = $node; }; string $nurbsSurface[] = `filterExpand -ex 1 -fp 1 -sm 10 $selection`; if(!`size $nurbsSurface` && `size $polySurface` < 2) { error("wrong number/types of items selected / use: mesh(es) cutted by nurbsSurface or mesh(es) cutted by mesh\n"); } else { string $normalPlus[], $normalMinus[], $noCut[], $cpos, $posi; if(`size $nurbsSurface`) { $cpos = `createNode closestPointOnSurface`; $posi = `createNode pointOnSurfaceInfo`; connectAttr -f ($nurbsSurface[0] + ".worldSpace[0]") ($cpos + ".inputSurface"); connectAttr -f ($nurbsSurface[0] + ".worldSpace[0]") ($posi + ".inputSurface"); connectAttr -f ($cpos + ".result.parameterU") ($posi + ".parameterU"); connectAttr -f ($cpos + ".result.parameterV") ($posi + ".parameterV"); } else { loadPlugin -quiet "nearestPointOnMesh"; if(! `pluginInfo -query -loaded "nearestPointOnMesh"`) { error("unable to load nearestPointOnMesh.mll"); return {}; }; $cpos = `createNode nearestPointOnMesh`; connectAttr -f ($polySurface[size($polySurface) - 1] + ".worldMesh") ($cpos + ".inMesh"); $posi = $cpos; $polySurface = `stringArrayRemove {$polySurface[size($polySurface) - 1]} $polySurface`; }; for($node in $polySurface) { string $tempOutput[] = `intersect $subdivisions $useMaxEdgeLength $useCurvature $iterations $separateShells $createIntersectionCurves $keepHistory $maxEdgeLength $maxAngle {$node,$nurbsSurface[0]} {$cpos,$posi}`; int $state = int($tempOutput[0]); $tempOutput = `stringArrayRemove {$tempOutput[0]} $tempOutput`; if($separateShells == 1 && $separateBySide == 1) { if($state == 2 || $state == 3) $noCut = `stringArrayCatenate $noCut $tempOutput`; else { for($mesh in $tempOutput) { vector $pointPosition = `pointPosition ($mesh + ".vtx[0]")`; setAttr ($cpos + ".inPosition") ($pointPosition.x) ($pointPosition.y) ($pointPosition.z); vector $surfacePoint = getAttr($cpos + ".position"); vector $normalDirection = getAttr($posi + ".normal"); float $angle = angle(($pointPosition - $surfacePoint),$normalDirection); if($angle < 1.570796) $normalPlus[`size $normalPlus`] = $mesh; else $normalMinus[`size $normalMinus`] = $mesh; }; }; } else $output = `stringArrayCatenate $output $tempOutput`; if($state == 3) { print("// Warning: polySplit did not work on " + $node + ". Try lower subdivision values.\n"); $errors++; }; }; delete $cpos $posi; if($separateShells == 1 && $separateBySide == 1) $output = {(`stringArrayToString $normalPlus " "`),(`stringArrayToString $normalMinus " "`),(`stringArrayToString $noCut " "`)}; if(`size $polySurface` > 1) print ("calculation time for " + `size $polySurface` + " " + $meshes[int(clamp(0,2,(`size $polySurface`)))] + ": " + `timerX -startTime $timer` + " sec\n"); if($errors) warning($errors + " " + $message[($errors - 1)] + " splittet correctly. See the Script Editor for details.\n"); }; return $output; };
    Report
  • roboguy

    roboguy said over 13 years ago:

    Thanks for you response, I basically have to clean up a lot of intersection geometry into one mesh at work all the time, so I'm experimenting with ways to save time. I tried the script but get, loads of error, probably because of the formatting in the post. Could you please put it in a gist, pastebin or something similar. Thanks,
    Report

Post a comment:

Sign in