Python for 3ds max – Mesh manipulation

Software:
3ds max 2019

An example of creating a mesh ripple deformation using Python for 3ds max:

mesh_manipulation.gif

Script steps:

  1. Define the effect intensity and a helper point object that will serve as the effect center.
  2. Collapse the object to an Editable-Mesh so its vertices will be accessible by Python.
    Note that the Node‘s Object has to be cast as a TriObject, to access the object’s Mesh data.
  3.  Loop through the Mesh’s vertices, get their world position, and set a new Z position as a sine function of the distance from the effect center.
import math
from MaxPlus import Factory
from MaxPlus import ClassIds
from MaxPlus import INode
from MaxPlus import TriObject
from MaxPlus import Matrix3
from MaxPlus import Point3

# Intensity:
effecr_mult = 1.0

# Effect center:
effector = INode.GetINodeByName('Point001')
effect_pos = effector.GetWorldPosition()

# Prepare object and eccess it's mesh data:
node = INode.GetINodeByName('Teapot001')
new_edit_mesh_mod = Factory.CreateObjectModifier(ClassIds.Edit_Mesh)
node.AddModifier(new_edit_mesh_mod)
node.Collapse(True)
node_tm = node.GetWorldTM()
node_pos = node.GetWorldPosition()
obj = node.GetObject()
triobj = TriObject._CastFrom(obj)
mesh = triobj.GetMesh()

# Process the object's vertices:
for i in range(mesh.GetNumVertices()):
     # Get vertex in world space
     vert_pos = mesh.GetVertex(i)
     vert_world_pos = node_tm.VectorTransform(vert_pos)
     vert_world_pos = vert_world_pos + node_pos
     # Get vertex distance from effect center:
     diff_vec = vert_world_pos - effect_pos 
     diff_vec.Z = 0
     dist = diff_vec.GetLength()
     # Set new vertex position:
     mesh.SetVert(i,vert_pos.X,vert_pos.Y,vert_pos.Z + math.sin(dist)*effecr_mult)

* note that when copying and pasting a script from this example, the indentation may not be pasted correctly.

Related Post:
Python for 3ds max – Animated Mesh

Advertisements

UE4 – Python – Importing assets

Software:
Unreal Engine 4.20

Untitled-1

Importing assets into a project is done using the import_asset_tasks() function which is a member of the unreal.AssetTools class.
A reference to the AssetTools class is created by calling the get_asset_tools() function which is a member of the unreal.AssetToolHelpers class.
The import_asset_tasks() function requires a list of unreal.AssetImportTask objects as an argument, each unreal.AssetImportTask object in the supplied list represents the import action of a single asset, and contains properties needed for the import operation.
Asset import properties are set using the set_editor_property() function which is called through the AssetImportTask object.
Available asset import properties are listed here:
https://api.unrealengine.com/INT/PythonAPI/class/AssetImportTask.html

In the following example a specified texture file is imported into the project and stored in the Content(Game) > Textures folder.
* If the folder doesn’t exist it will be created.

import unreal
AssetTools = unreal.AssetToolsHelpers.get_asset_tools()
AssetImportTask = unreal.AssetImportTask()
AssetImportTask.set_editor_property('filename', "D:\Wood_Red_A.jpg")
AssetImportTask.set_editor_property('destination_path', '/Game/Textures')
AssetTools.import_asset_tasks([AssetImportTask])

The following example imports all the JPG files from folder: D:\ into the project, stores the new assets in Content(Game)\Textures folder and saves them:

from os import listdir
from os.path import isfile, join
import unreal
dir = "D:\\"
files = [f for f in listdir(dir) if isfile(join(dir, f)) and f[-3:]=='jpg']
AssetTools = unreal.AssetToolsHelpers.get_asset_tools()

import_tasks = []
for f in files:
     print join(dir, f)
     AssetImportTask = unreal.AssetImportTask()
     AssetImportTask.set_editor_property('filename', join(dir, f))
     AssetImportTask.set_editor_property('destination_path', '/Game/Textures')
     AssetImportTask.set_editor_property('save', True)
     import_tasks.append(AssetImportTask)

AssetTools.import_asset_tasks(import_tasks)

* note that when copying and pasting a script from this example, the indentation may not be pasted correctly.

Get started with Python in UE4

UE4 – Python Scripting – how to start

Software:
Unreal Engine 4.20

  1. Go to:
    Edit > Plugins > Scripting
    And enable the Python Editor Script Plugin.
    * also recommended to enable Editor Scripting Utilities,
    And Sequencer Scripting plugins
    Untitled-2
  2. Restart the UE4 Editor.
  3. Open:
    Window > Developer Tools > Output Log
    Untitled-1
  4. Switch the command-line mode from Cmd to Python, write Python commands and press Enter to execute them:
    Untitled-3
  5. Or in Cmd mode, write ‘py‘ with a path to a Python script file, and hit Enter to execute the script:
    Untitled-4.jpg

 

Links:

  1. Scripting the Editor using Python:
    https://docs.unrealengine.com/en-us/Editor/ScriptingAndAutomation/Python
  2. UE4 Python API reference:
    https://api.unrealengine.com/INT/PythonAPI/

Python for 3ds max – Animated Mesh

Software:
3ds max 2019

This is an example of procedurally animating a mesh’s vertices via Python script.

Vert_Anim.gif

Notes:
1. The model has to be converted to Editable Mesh before the script is run.
* unless the scrip will be extended to do it.
2. The model must be selected for the script to work.

import MaxPlus
import math
from MaxPlus import INode
from MaxPlus import TriObject
from MaxPlus import SelectionManager
from MaxPlus import Factory
from MaxPlus import Animation
from MaxPlus import Point3
from MaxPlus import Control

ticks_frame = 160

#Selection
sel = []
for n in SelectionManager.Nodes:
    sel.append(n)
node = sel[0]

#Setup Controllers
obj = node.GetObject()
Tri = TriObject._CastFrom(obj)
mesh = Tri.GetMesh()
num_verts = mesh.GetNumVertices()
mesh_anim = obj.GetSubAnim(0)
pnt_ctrl = Factory.CreateDefaultMasterPointController()
node.AssignController(pnt_ctrl,1)
for i in range(num_verts):
    bezp3 = Factory.CreateDefaultPoint3Controller()
    bezp3.SetPoint3Value(mesh.GetVertex(i))
    mesh_anim.AssignController(bezp3,i)

#Animation
Animation.SetAnimateButtonState(True)
for t in range(100):
    time = t * ticks_frame
    Animation.SetTime(time)
    mesh_anim.AddNewKey(time,0)
    for i in range(num_verts):
        vert_anim = mesh_anim.GetSubAnim(i)
        vert_ctrl = Control._CastFrom(vert_anim)
        vert_val = mesh.GetVertex(i)
        vert_val.SetZ(vert_val.GetZ() + math.sin(((Animation.GetTime()*0.5)/(ticks_frame))+i))
        vert_ctrl.SetPoint3Value(vert_val)
Animation.SetAnimateButtonState(False)

* note that when copying and pasting a script from this example, the indentation may not be pasted correctly.

Related:
Python for 3ds max – Mesh manipulation

Blender Python – Make an unselectable object local so it can be selected..

Software:
Blender 2.79

If you happen to link an external object that was made unselectable in the original blend file, You will have no interactive way to make it selectable again, or local, or even delete it from the current blend file.

The good news is that it can easily be done by a very short Python script:

import bpy

obj = bpy.data.objects['the_untouchable_object']
obj.make_local()

It should also be very easy script a loop that will find all those linked objects,
I will post an example when I’ll have a minute to breathe… 😀

Notepad++ – Show White Space and TAB

Software:
Notepad++ 7.5.9

A lot of Python debugging frustration can be avoided by activating the ‘Show White Space and TAB’ option from the View > Show Symbol menu.

This view option displays yellow dots for White Spaces and yellow arrows for TAB indents in the script, and can save precious time locating places where the indentation is wrong.

Untitled-1.jpg

Maya Python scripting – Getting an object’s transform matrix relative to another object’s coordinates

Software:
Maya 2018

How to get an object transformation matrix relative to another object’s coordinates:
* The following script requires selecting 2 objects, the function will return the transform matrix of the first object relative to the transform matrix of the second.

from maya.api.OpenMaya import MVector, MMatrix, MPoint
import maya.cmds as cmds

def get_relative_transform (node,coordinate_space_node):
    node_matrix = MMatrix(cmds.xform(node, q=True, matrix=True, ws=True))
    parent_matrix = MMatrix(cmds.xform(coordinate_space_node, q=True, matrix=True, ws=True))
    return (node_matrix * parent_matrix.inverse())

node_a = (cmds.ls(sl=1,sn=True))[0]
node_b = (cmds.ls(sl=1,sn=True))[1]

print (get_relative_transform(node_a,node_b))

Untitled-1