## popup message -A disappearing message def popupMessage(function_name): """ Displays an in-view message indicating that a function has been copied to the clipboard. :param function_name: #The name of the function that has been copied. :return: """ mc.inViewMessage(amg="Copied!!\nFunction name '{0}' has been copied to the clipboard.".format(function_name), pos='midCenter', fade=True) # Test function is provided to test main function popupMessage def test_popupMessage(): popupMessage(function_name='exampleFunction') # Since mc.inViewMessage affects the UI, manual verification is required. print("popupMessage executed successfully.") test_popupMessage()
top of page

โœจ๐ŸŽฏ ๐˜ฟ๐™–๐™ฎ12 -100-๐˜ฟ๐™–๐™ฎ๐™จ ๐˜พ๐™ค๐™™๐™š ๐˜พ๐™ค๐™™๐™š ๐˜พ๐™๐™–๐™ก๐™ก๐™š๐™ฃ๐™œ๐™š ๐Ÿš€๐ŸŽจ

Writer's picture: Subbu AddankiSubbu Addanki

Updated: Oct 31, 2024

โœจ๐ŸŽฌ ๐™‰๐™š๐™ฌ ๐™๐™ค๐™ค๐™ก ๐™„๐™ฃ๐™ฉ๐™ง๐™ค: "๐˜ฟ๐™ช๐™ฅ๐™ก๐™ž๐™˜๐™–๐™ฉ๐™š๐˜ผ๐™ก๐™ค๐™ฃ๐™œ๐˜พ๐™ช๐™ง๐™ซ๐™š" โžฐ

Hello VFX & Animation Professionals! ๐Ÿ‘‹

I'm thrilled to introduce a powerful addition to your Maya toolkitโ€”DuplicateAlongCurve! ๐ŸŒŸ

Placing multiple instances of an object along a path can be time-consuming when done manually. DuplicateAlongCurve automates this process, allowing you to duplicate objects along a selected curve with customizable parameters.


๐˜ž๐˜ฉ๐˜ข๐˜ต ๐˜ฟ๐™ช๐™ฅ๐™ก๐™ž๐™˜๐™–๐™ฉ๐™š๐˜ผ๐™ก๐™ค๐™ฃ๐™œ๐˜พ๐™ช๐™ง๐™ซ๐™š Offers:

  • Automation: Instantly duplicate objects along any curve.

  • Customization: Control the number of duplicates and alignment options.

  • User-Friendly Interface:ย Simplifies complex setups, saving you time.

๐Ÿ› ๏ธ ๐˜ฟ๐™ช๐™ฅ๐™ก๐™ž๐™˜๐™–๐™ฉ๐™š๐˜ผ๐™ก๐™ค๐™ฃ๐™œ๐˜พ๐™ช๐™ง๐™ซ๐™š โžฐ (๐™ข๐™–๐™ฎ๐™–.๐™˜๐™ข๐™™๐™จ ๐™‘๐™š๐™ง๐™จ๐™ž๐™ค๐™ฃ):



import maya.cmds as mc

def duplicateAlongCurve(object_name, curve_name, num_copies=10, align=True):
ย ย ย ย """
ย ย ย ย Duplicates an object along a NURBS curve.

ย ย ย ย :param object_name: <str> The name of the object to duplicate.
ย ย ย ย :param curve_name: <str> The name of the NURBS curve.
ย ย ย ย :param num_copies: <int> Number of duplicates to create along the curve.
ย ย ย ย :param align: <bool> Whether to align duplicates to the curve's tangent.
ย ย ย ย :return: <None>
ย ย ย ย """
ย ย ย ย # Validate object existence
ย ย ย ย if not mc.objExists(object_name):
ย ย ย ย ย ย ย ย mc.warning("Object '{}' does not exist.".format(object_name))
ย ย ย ย ย ย ย ย return

ย ย ย ย # Validate curve existence
ย ย ย ย if not mc.objExists(curve_name):
ย ย ย ย ย ย ย ย mc.warning("Curve '{}' does not exist.".format(curve_name))
ย ย ย ย ย ย ย ย return

ย ย ย ย # Ensure the curve is a NURBS curve and retrieve its shape node
ย ย ย ย if mc.nodeType(curve_name) != 'nurbsCurve':
ย ย ย ย ย ย ย ย curve_shapes = mc.listRelatives(curve_name, shapes=True, type='nurbsCurve')
ย ย ย ย ย ย ย ย if not curve_shapes:
ย ย ย ย ย ย ย ย ย ย ย ย mc.warning("'{}' is not a NURBS curve.".format(curve_name))
ย ย ย ย ย ย ย ย ย ย ย ย return
ย ย ย ย ย ย ย ย curve_shape = curve_shapes[0]
ย ย ย ย else:
ย ย ย ย ย ย ย ย curve_shape = curve_name

ย ย ย ย # Get the parameter range of the curve
ย ย ย ย try:
ย ย ย ย ย ย ย ย min_param = mc.getAttr(curve_shape + ".minValue")
ย ย ย ย ย ย ย ย max_param = mc.getAttr(curve_shape + ".maxValue")
ย ย ย ย except Exception as e:
ย ย ย ย ย ย ย ย mc.warning("Failed to get 'minValue' or 'maxValue' for '{}': {}".format(curve_shape, e))
ย ย ย ย ย ย ย ย return

ย ย ย ย # Handle edge cases for num_copies
ย ย ย ย if num_copies < 1:
ย ย ย ย ย ย ย ย mc.warning("Number of copies must be at least 1.")
ย ย ย ย ย ย ย ย return
ย ย ย ย elif num_copies == 1:
ย ย ย ย ย ย ย ย params = [(min_param + max_param) / 2.0]
ย ย ย ย else:
ย ย ย ย ย ย ย ย step = (max_param - min_param) / float(num_copies - 1)
ย ย ย ย ย ย ย ย params = [min_param + (step * i) for i in range(num_copies)]

ย ย ย ย duplicates = []

ย ย ย ย for i, param in enumerate(params):
ย ย ย ย ย ย ย ย try:
ย ย ย ย ย ย ย ย ย ย ย ย # Get position on curve at parameter
ย ย ย ย ย ย ย ย ย ย ย ย point = mc.pointOnCurve(curve_name, pr=param, p=True)

ย ย ย ย ย ย ย ย ย ย ย ย # Duplicate the object
ย ย ย ย ย ย ย ย ย ย ย ย # Use the 'n' flag instead of 'name' for better compatibility
ย ย ย ย ย ย ย ย ย ย ย ย dup = mc.duplicate(object_name, n="{}_dup{}".format(object_name, i+1))[0]

ย ย ย ย ย ย ย ย ย ย ย ย # Move duplicate to the point on the curve
ย ย ย ย ย ย ย ย ย ย ย ย mc.move(point[0], point[1], point[2], dup, absolute=True)

ย ย ย ย ย ย ย ย ย ย ย ย if align:
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย # Get the tangent at the parameter
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย tangent = mc.pointOnCurve(curve_name, pr=param, nt=True)

ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย # Aim the duplicate's Y-axis to align with the tangent
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย aim_constraint = mc.aimConstraint(
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย curve_name,
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย dup,
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย aimVector=(tangent[0], tangent[1], tangent[2]),
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย upVector=(0, 1, 0),
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย worldUpType="vector",
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย worldUpVector=(0, 1, 0)
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย )

ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย # Delete the constraint and bake the rotation
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย mc.delete(aim_constraint)
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย mc.makeIdentity(dup, apply=True, rotate=True)

ย ย ย ย ย ย ย ย ย ย ย ย duplicates.append(dup)

ย ย ย ย ย ย ย ย except Exception as e:
ย ย ย ย ย ย ย ย ย ย ย ย mc.warning("Failed to duplicate along curve at parameter {}: {}".format(param, e))

ย ย ย ย print("Duplicated '{}' along '{}' with {} copies.".format(object_name, curve_name, num_copies))


def test_duplicateAlongCurve():
ย ย ย ย """
ย ย ย ย Tests the duplicateAlongCurve function by:
ย ย ย ย 1. Creating a test object (sphere).
ย ย ย ย 2. Creating a test curve.
ย ย ย ย 3. Running duplicateAlongCurve with various parameters.
ย ย ย ย 4. Verifying the duplicates.
ย ย ย ย 5. Optionally cleaning up the test scene.
ย ย ย ย """
ย ย ย ย # Step 1: Create a test object (sphere)
ย ย ย ย test_object = 'testSphere'
ย ย ย ย if mc.objExists(test_object):
ย ย ย ย ย ย ย ย mc.delete(test_object)
ย ย ย ย test_object = mc.polySphere(name=test_object)[0]
ย ย ย ย mc.move(0, 0, 0, test_object)  # Ensure it's at the origin

ย ย ย ย # Step 2: Create a test curve (simple NURBS curve)
ย ย ย ย test_curve = 'testCurve'
ย ย ย ย if mc.objExists(test_curve):
ย ย ย ย ย ย ย ย mc.delete(test_curve)
ย ย ย ย # Correctly create a degree 3 NURBS curve with appropriate number of CVs
ย ย ย ย # For degree=3, n CVs, number of knots=k = n + degree + 1
ย ย ย ย # Here, n=4 CVs to have k=8 knots (auto-generated by Maya)
ย ย ย ย test_curve = mc.curve(
ย ย ย ย ย ย ย ย name=test_curve,
ย ย ย ย ย ย ย ย d=3,
ย ย ย ย ย ย ย ย p=[(0, 0, 0), (5, 5, 0), (10, 0, 0), (15, -5, 0)]
ย ย ย ย ย ย ย ย # Let Maya auto-generate the knot vector by not specifying 'k'
ย ย ย ย )

ย ย ย ย # Step 3: Run duplicateAlongCurve with default parameters
ย ย ย ย print("\nTest 1: Duplicate with default parameters (num_copies=10, align=True)")
ย ย ย ย duplicateAlongCurve(test_object, test_curve)

ย ย ย ย # Step 4: Verify duplicates are created
ย ย ย ย duplicates = mc.ls('{}_dup*'.format(test_object), type='transform')
ย ย ย ย expected_copies = 10
ย ย ย ย actual_copies = len(duplicates)
ย ย ย ย assert actual_copies == expected_copies, "Test 1 Failed: Expected {} duplicates, found {}".format(expected_copies, actual_copies)
ย ย ย ย print("Test 1 Passed: Correct number of duplicates created.")

ย ย ย ย print("\nAll tests completed successfully.")


# Run the test function
test_duplicateAlongCurve()

๐Ÿ› ๏ธ ๐˜ฟ๐™ช๐™ฅ๐™ก๐™ž๐™˜๐™–๐™ฉ๐™š๐˜ผ๐™ก๐™ค๐™ฃ๐™œ๐˜พ๐™ช๐™ง๐™ซ๐™š โžฐ (๐™‹๐™ฎ๐™Ž๐™ž๐™™๐™š2 ๐™‘๐™š๐™ง๐™จ๐™ž๐™ค๐™ฃ):



[Todayโ€™s Challenge is to take this simple code to next level.. I am sharing images of these advanced codes...]



๐Ÿ” ๐™’๐™๐™–๐™ฉ ๐˜ฟ๐™ช๐™ฅ๐™ก๐™ž๐™˜๐™–๐™ฉ๐™š๐˜ผ๐™ก๐™ค๐™ฃ๐™œ๐˜พ๐™ช๐™ง๐™ซ๐™š Offers:

  • Efficiency: Quickly duplicate objects along a curve without manual placement.

  • Precision: Align duplicates accurately to the curve's path and orientation.

  • Flexibility:ย Customize the number of duplicates and alignment options.

๐Ÿ”ง ๐™†๐™š๐™ฎ ๐˜ฝ๐™š๐™ฃ๐™š๐™›๐™ž๐™ฉ๐™จ:

โ€ข ๐Ÿš€ Boost Productivity:ย Save time on repetitive placement tasks.

โ€ข ๐Ÿ› ๏ธ Enhance Modeling Workflow:ย Ideal for creating objects like chains, ropes, or any repeated elements along a path.

โ€ข ๐Ÿ“ˆ Improve Accuracy:ย Ensures consistent spacing and alignment of duplicates.

โ€ข ๐Ÿ’ก User-Friendly Interface:ย Intuitive UI suitable for artists of all levels.

โœจ Ready to Streamline Your Duplication Process?

Try out DuplicateAlongCurveย today and elevate your Maya workflow! Feel free to reach out or comment below to see it in action. Letโ€™s enhance our Maya scripting together! ๐Ÿ’ช๐ŸŽ‰

๐™Ž๐™ช๐™—๐™—๐™ช'๐™จ ๐™‡๐™ž๐™ฃ๐™ ๐™จ :

๐Ÿ› ๏ธ๐˜ผ๐™™๐™™๐™ž๐™ฉ๐™ž๐™ค๐™ฃ๐™–๐™ก ๐™๐™ž๐™ฅ๐™จ:

  • Error Handling:ย The scripts include checks for object and curve existence to prevent errors.

  • Customization:ย Extend the tool to include scaling or rotating duplicates for more complex setups.

  • Integration:ย Incorporate this tool into your existing scripts or Maya shelf for quick access.

9 views0 comments

Comments


bottom of page