PyCharm – Enabling Scroll Zoom

Software:
PyCharm Community 2019.1

Unlike many popular text/programming editors and IDE’s, PyCharm doesn’t by default let you change the font size by pressing Ctrl + Scrolling the mouse wheel.

To enable scroll-zoom in PyCharm:

  1. Go to File > Settings to open the Settings dialog
  2. In the Settings dialog, navigate to Editor > General
  3. Check the Change font size (Zoom) with Ctrl + Mouse Wheel option.

Untitled-1

Advertisements

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

Python for 3ds max – replace selected objects with a merged object

Software:
3ds max 2019

merge

The following Python for 3ds max snippet replaces all selected objects with an object merged from an external 3ds max file.

Notes:

  1. The ‘model_path’ string variable should be set to the path of the 3ds max file containing the replacement model.
  2. This example takes into account that the merged file contains only a single object, otherwise the first of the merged objects will be used.
  3. The script actually replaces the Object node of the selected objects with the Object node of the merged model (creating instances), assigning them the merged material giving them the merged object’s name appended with numbers.
from MaxPlus import FileManager
from MaxPlus import SelectionManager

model_path = r"D:\Google Drive\CG-Lion_Studio\Asset_Library\3D_Models\Furniture\Home\Bar_Stool_A.max"

place_holders = []
for o in SelectionManager.Nodes:
     place_holders.append(o)

FileManager.Merge(model_path,True,True)

model = SelectionManager.GetNode(0)

for i in range(len(place_holders)):
     place_holders[i].SetObject(model.GetObject())
     place_holders[i].SetMaterial(model.GetMaterial())
     place_holders[i].SetName(model.Name + "_" + str(i))

model.Delete()

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

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

Python – Listing the files in a directory

Language:
Python 2.7

The following example uses functions from the os library to list the files in a given directory:

from os import listdir
from os.path import isfile, join
dir = "D:\\"
files = [f for f in listdir(dir) if isfile(join(dir, f))]
for f in files:
	print join(dir, f)

In the next example the script has been modified to list only files with the name extension ‘jpg’:

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

 

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

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 – list scene objects

Software:
3ds max 2019

Iterating through a list of all of an object’s hierarchy or all of the objects in the scene is a very common requirement for scripted tools and utilities in 3D animation software.
Coming from a MaxScript background, I was used to just have to write the word ‘objects‘ to reference a list of all of the objects in the scene.

Unless I’m missing something obvious,
There isn’t a shortcut like this available in the 3ds max Python API.

In order to list all the objects in the scene you need to use a recursive function that will return a list of all of a node’s children, and children’s children, etc.

In the following example, the function ‘list_children()’ will return a list all of the objects in the supplied node’s hierarchy, and when given the scene’s root node via MaxPlus.Core.GetRootNode() it will return a list of all the objects in the scene.
Wrapping ‘list_children()’ within the ‘scene_objects()’ function, provides a convenient way get a list of all the objects in the scene just by calling ‘scene_objects()’.

def scene_objects():
    def list_children(node):
       list = []
       for c in node.Children:
           list.append(c)
           list = list + list_children(c)
       return list
    return list_children(MaxPlus.Core.GetRootNode())


for o in scene_objects():
    print o.Name

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