// =========================================================================== // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // =========================================================================== // // // Creation Date: July 17, 1998 // // Description: // This is the action for snap 2 points to 2 points. It takes any 2 // pair of point selections (curve point, surface point, edit point, poly // vertex, etc.) and uses these as a vector. The first 2 points must // be on the same object (i.e. it is the object to be transformed). The // second pair of points define the position to translate to and the // axis to rotate to. // // Note: the 2 points do not define a scale, just an axis for rotation. // // Input Arguments: // None. // // Return Value: // None. // proc string getObjectToMoveName( string $object ) // // Description: // Returns the transform name of the object with no components in the // string e.g. curve1.u[0.5] will return curve1 // { string $name; // get the string before any "." or "->" - this could be a shape name // string $buffer[]; int $numTokens = `tokenize $object ".->" $buffer`; if ( $numTokens >= 1 ) $name = $buffer[0]; return $name; } global proc snap2PointsTo2Points( int $moveParent, int $option ) { // $option = 1: left snap (pre 4.5 behaviour) // $option = 2: middle snap // $option = 3: right snap // $moveParent = 0: move the object defined by the first point // $moveParent = 1: move the parent of the object // $moveParent = 2: move the grandparent of the object // $moveParent = 3: move the great-grandparent of the object // Get the list of nurbs curves/surfaces selected. // global int $gSelectCVsBit; global int $gSelectMeshVerts; global int $gSelectLatticePoints; global int $gSelectParticles; global int $gSelectEditPointsBit; global int $gSelectCurveParmPointsBit; global int $gSelectSurfaceParmPointsBit; global int $gSelectMeshUVs; global int $gSelectRotatePivots; global int $gSelectScalePivots; global int $gSelectJointPivots; global int $gSelectSelectHandles; global int $gSelectDimensions; global int $gSelectUVLocators; global int $gSelectSubdivMeshPoints; global int $gSelectMeshEdge; string $polyEdges[] = `filterExpand -ex true -sm $gSelectMeshEdge`; int $numEdges = size($polyEdges); if (2 == $numEdges) { getVerts(); } else if (0 != $numEdges) { error (uiRes("m_snap2PointsTo2Points.kInvalidSelection")); } string $objectList[] = `filterExpand -ex true -sm $gSelectCVsBit -sm $gSelectMeshVerts -sm $gSelectLatticePoints -sm $gSelectParticles -sm $gSelectEditPointsBit -sm $gSelectSurfaceParmPointsBit -sm $gSelectCurveParmPointsBit -sm $gSelectMeshUVs -sm $gSelectRotatePivots -sm $gSelectScalePivots -sm $gSelectJointPivots -sm $gSelectSelectHandles -sm $gSelectDimensions -sm $gSelectUVLocators -sm $gSelectSubdivMeshPoints`; // make sure there are 4 objects selected // int $total = size($objectList); if ( $total == 0 ) { error (uiRes("m_snap2PointsTo2Points.kNoPointsSelected")); return; } else if ( $total < 4 ) { error (uiRes("m_snap2PointsTo2Points.kIncompleteSelection")); return; } else if ( $total > 4 ) { warning (uiRes("m_snap2PointsTo2Points.kTooManyPoints")); } string $obj1 = $objectList[$total-4]; string $obj2 = $objectList[$total-3]; string $obj3 = $objectList[$total-2]; string $obj4 = $objectList[$total-1]; // get the name of the object to move (with no component part). The first // 2 points should be on the same object? // string $objectToMove = getObjectToMoveName( $obj1 ); string $tmpToMove = getObjectToMoveName( $obj2 ); string $tmp1 = getObjectToMoveName( $obj3 ); string $tmp2 = getObjectToMoveName( $obj4 ); if ( $objectToMove == $tmp1 || $objectToMove == $tmp2 ) { error (uiRes("m_snap2PointsTo2Points.kErrorSameObject")); return; } else { string $fullPath1[] = `ls -l $objectToMove`; string $fullPath2[] = `ls -l $tmpToMove`; if ( strcmp($fullPath1[0], $fullPath2[0]) != 0 ) { error (uiRes("m_snap2PointsTo2Points.kErrorImproperSelection")); return; } } // If user wants to move a group, eg. he selects points on a // face of a cube and wants the entire cube (group) to move // $moveParent = 1: move the parent of the object // $moveParent = 2: move the grandparent of the object // $moveParent = 3: move the great-grandparent of the object // if( $moveParent > 0 ) { string $parent[]; string $obj = $objectToMove; for( $i = 0; $i < $moveParent; $i ++ ) { $parent = `listRelatives -parent $obj`; if( size($parent[0]) > 0 ) { $obj = $parent[0]; } } if( size($obj) > 0 ) { $objectToMove = $obj; } } // get the world space position of each selected point object // float $pos1[] = `pointPosition $obj1`; float $pos2[] = `pointPosition $obj2`; float $pos3[] = `pointPosition $obj3`; float $pos4[] = `pointPosition $obj4`; if ( $pos1[0] == $pos2[0] && $pos1[1] == $pos2[1] && $pos1[2] == $pos2[2] ) { error (uiRes("m_snap2PointsTo2Points.kDupedFirstPointSelection")); return; } if ( $pos3[0] == $pos4[0] && $pos3[1] == $pos4[1] && $pos3[2] == $pos4[2] ) { error (uiRes("m_snap2PointsTo2Points.kDupedSecondPointSelection")); return; } // Arrange the points accordingly, based on the options // float $tmpFloat; if (3 == $option) { // rightEdge snap.. // (Same as swapping pos3<=>pos4 and pos1<=>pos2) // $tmpFloat = $pos3[0]; $pos3[0] = $pos4[0]; $pos4[0] = $tmpFloat; $tmpFloat = $pos3[1]; $pos3[1] = $pos4[1]; $pos4[1] = $tmpFloat; $tmpFloat = $pos3[2]; $pos3[2] = $pos4[2]; $pos4[2] = $tmpFloat; $tmpFloat = $pos1[0]; $pos1[0] = $pos2[0]; $pos2[0] = $tmpFloat; $tmpFloat = $pos1[1]; $pos1[1] = $pos2[1]; $pos2[1] = $tmpFloat; $tmpFloat = $pos1[2]; $pos1[2] = $pos2[2]; $pos2[2] = $tmpFloat; } else if (2 == $option) { // midEdge snap.. // // (Same as using midpoints as the starting point of the vectors) // Push pos1 to the midpoint, and push pos3 to the midpoint.. // $pos1[0] = 0.5 * ($pos1[0] + $pos2[0]); $pos1[1] = 0.5 * ($pos1[1] + $pos2[1]); $pos1[2] = 0.5 * ($pos1[2] + $pos2[2]); $pos3[0] = 0.5 * ($pos3[0] + $pos4[0]); $pos3[1] = 0.5 * ($pos3[1] + $pos4[1]); $pos3[2] = 0.5 * ($pos3[2] + $pos4[2]); } // calculate the translation amount - the first point on each pair is the // point to use for translation // float $distance[]; $distance[0] = $pos3[0] - $pos1[0]; $distance[1] = $pos3[1] - $pos1[1]; $distance[2] = $pos3[2] - $pos1[2]; // move the first object by that amount // evalEcho("move -r " + $distance[0] + " " + $distance[1] + " " + $distance[2] + " " + $objectToMove); // define the two vectors for each pair of points // float $axis1[]; $axis1[0] = $pos2[0] - $pos1[0]; $axis1[1] = $pos2[1] - $pos1[1]; $axis1[2] = $pos2[2] - $pos1[2]; float $axis2[]; $axis2[0] = $pos4[0] - $pos3[0]; $axis2[1] = $pos4[1] - $pos3[1]; $axis2[2] = $pos4[2] - $pos3[2]; // get the angle (in radians) between the two vectors and the axis of // rotation // float $dotProduct = dotProduct( $axis1, $axis2, 1 ); $dotProduct = clamp(-1.0, 1.0, $dotProduct); float $angle = acos($dotProduct); float $crossProduct[] = crossProduct( $axis1, $axis2, 1, 1 ); // rotate the first object about the pivot point (the pivot is defined // by the first point from the second pair of points - i.e. point 3 from // the inputs above) // float $rotation[]; xyzRotation( $angle, $crossProduct, $rotation ); evalEcho("rotate -r -p " + $pos3[0] + " " + $pos3[1] + " " + $pos3[2] + " " + $rotation[0] + "rad " + $rotation[1] + "rad " + $rotation[2] + "rad " + $objectToMove); }