Deletion Effectors

Here is three simple deletion effectors I made for fun. Perhaps they might be sometimes pretty useful. These effectors hides clones completely, they does not scale them to zero.

Delete by scale effector

Hides clones (visibility) based on clone’s scale parameter (not size). This helps to get rid off too tiny or too big clones when you are randomizing clones’ scale with e.g. random effector.

delete_by_scale_effector.c4d

Delete random effector

Hides clones randomly. You can change seed to randomize which clones are deleted, change amount of deleted clones and invert the final output.

delete_random_effector.c4d

Delete by index effector

Hides clones by given index number or range. Indexes are separated with commas (,) and ranges are pointed with dashes (-). You can also invert the final output.

delete_by_index_effector.c4d

Updated 24/04/2019:
> Effectors now supports already hidden clones
> Fixed ‘Delete by scale Effector’ does not calculate only x scale but scale vector average

Cinema 4D, Effector, MoGraph, Python

Fusion version up script

This script is for Blackmagic Fusion. With this script you can easily view different versions. You can load newer version, older version, latest version or custom given version. You need to install Python 2.7 64-bit version to use this script with Fusion. The script scans folder so it can jump over versions that are missing (e.g. from v02 to v05).

Place the script to comp folder:
“C:\Users\[USER]\AppData\Roaming\Blackmagic Design\Fusion\Scripts\Comp”

Script uses “_v” as a version delimiter.

Your filepath should be something like this:
“..\Versions\MyProject_v001\Passes\MyProject_v001_diffuselighting_####.exr”
So next version path looks like this:
“..\Versions\MyProject_v002\Passes\MyProject_v002_diffuselighting_####.exr”

Path structure is very important. It should not change.

AR_VersionUp.py

Fusion, Python

Colorise plug-in

This is my first Cinema 4D plug-in. It is made for Xpresso heavy users. This plug-in makes changing node’s color easy. Just select nodes and click what color you want to use. You can also load and save custom color palettes.

You can also colorise objects and and add objects to layers. Works also with Redshift shader graph editor!

> Keep in mind that your xpresso tag has to be selected, otherwise plug-in wont work when you are changing node’s color!

> If you use Redshift shader graph editor, the material has to be selected when you are changing color!

Place the plugin to your appdata plug-in folder to make it work properly (avoid permission errors).
Win: “C:\Users\[USER]\AppData\Roaming\MAXON\Cinema 4D R[VERSION]\plugins\”
Mac: “/Users/[USER]/Library/Preferences/MAXON/CINEMA 4D R[VERSION]/plugins”

Updated 06/08/2018 (v0.3)
> Redshift node-editor support added
> Colorise objects and nulls
> Shift+color add to layer
> Ctrl+color group objects under the colorised null and add  objects to layer
> Added reset palette to default colors button (D)
> Added reset item to default color button (X)
> Shift+X button removes object’s layer
> You can now undo

Updated 07/08/2018 (v0.4.1)
> Supports now polygon, spline, voronoi, joint, hair, motion tracker, lod and camera objects

Updated 10/08/2018 (v0.4.2)
> Cleaner GUI
> New palette menu: load, save, reset and set as default color palette
> Preset menu system (Put preset files to colorise/presets folder)
> Updated grouping function (Ctrl+color)
> Added doodle tool support (Objects needs to be unselected)

Updated 29/08/2018 (v0.4.3)
> Added support for creating swatches and loading palette from selected swatches
> Random colors from palette to selected objects (Alt+X)
> More presets

Updated 03/09/2018 (v0.4.4)
> Option to change between horizontal and vertical layout
> Fixed default color bug

Updated 25/09/2018 (v0.4.5)
> Select colored objects (Alt+color)
> Add to selection colored objects (Alt+Shift+color)
> Select objects by layer color (Alt+Ctrl+color)
> Fixed layer bug
> Custom version for C4D R20

Updated 25/09/2019 (v0.4.6)
> Fixed bug that couldn’t colorise some objects
> C4D R19 support dropped

Thanks to @BachtellDesign and @_james_owen_ for new feature ideas.

N.B. In R20 Maxon added annoying color picker next to color field. Hopefully they will update their Python API, so we can get rid of that color picker. Otherwise I’ll have to build completely custom button.

colorise_v0.4.6_r20.zip

Cinema 4D, Plug-in, Python, Redshift, Xpresso

Pile Up Effector

This is simple Python Effector that piles clones top of each other. It supports random effectors scale y parameter. It uses clone’s original object’s bounding box to get correct height. It needs primitive or polygon object to work. You should use it only with cloner. Pile Up Effector does not support rotation.

Updated 19/04/2018
>
Now it works if object is scaled in coordinates tab.

Updated 02/05/2019
> Now you can change axis.

pile_up_effector.c4d

Cinema 4D, Effector, MoGraph, Python

Take Control Effector

Take Control Effector takes control over selected clone. Select clone ID and then clone is linked to the Effector. When you move the Effector, clone moves with it in Effector’s coordinate space.

Besides changing PSR, you can also modify clone (works only with Cloner object), set custom clone weight, or change clone color. Take Control Effector works properly with Cloner object when ‘Fix Clone’ checkbox is ticked. There is also checkboxes to activate/deactivate position, scale and rotation linking in ‘Matrix’ group.

There is handy ‘Go To Origin’ button that moves effector to clone’s original position (before this effector is calculated).

Warning! There is a bug in C4D (at least in R20.059) with Fracture Object. You can fix this putting Plain Effector before Take Control Effector to Fracture Object and then adjusting ‘Weight Transform’ parameter (just drag it around). After that you can delete Plain Effector.

Updated 26/04/2019
> Complete rebuild

Updated 30/05/2019
> Changed ‘Visible’ option

take_control_effector.c4d

Cinema 4D, Effector, MoGraph, Python

Import and play obj sequences in c4d

I’m currently working with one project where I mess with OBJ sequences (recorded with Brekel Pro PointCloud), so I created a script that loads OBJ files from a folder and a Python Tag that plays through objects making them visible and invisible depending the current frame.

Import obj folder

import c4d, os
from c4d import storage as s
def main():
    extensions = ["obj"] # File extensions that will be imported
    folder = s.LoadDialog(c4d.FILESELECTTYPE_ANYTHING,'Select folder to import',c4d.FILESELECT_DIRECTORY,'') # Load folder
    if not folder: return # If there is no folder, stop the script
    files = os.listdir(folder) # Get files
    for f in files: # Loop through files
        ext = f.rsplit(".",1) # Get file extension
        if ext[1] in extensions: # If extension matches
            c4d.documents.MergeDocument(doc, folder+'\\'+f, 1) # Merge file to current project
    c4d.EventAdd() # Update Cinema 4D
if __name__=='__main__':
    main()

OBJ Sequence Player

This is Python Tag with some custom constrols on it. You can change starting frame, reverse sequence and animate manually with custom mode. Controls are in Python Tag.

import c4d

def main():
    frame = doc[c4d.DOCUMENT_TIME].GetFrame(doc[c4d.DOCUMENT_FPS]) # Get current frame
    obj = op.GetObject() # Get object
    children = obj.GetChildren() # Get children
    index = 0 # Initialize index variable
    run = 0 # Initialize run variable

    rev = op[c4d.ID_USERDATA,2] # User data: Reverse sequence
    start = op[c4d.ID_USERDATA,3] # User data: Starting frame
    holdf = op[c4d.ID_USERDATA,4] # User data: Hold first frame
    holdl = op[c4d.ID_USERDATA,5] # User data: Hold last frame
    manon = op[c4d.ID_USERDATA,7] # User data: Activate manual mode
    manfr = op[c4d.ID_USERDATA,8] # User data: Set manual frame

    if manon == False: # If manual mode is off
        if rev == False: # If reverse mode is off
            for child in children: # Loop through children
                if frame == index+start: # If index maches with current frame
                    child[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 2 # Default
                    child[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 2 # Default
                    run = 1 # Sequence is running
                else: # Otherwise
                    child[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 1 # Off
                    child[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 1 # Off
                index = index + 1 # Increase index
        else: # Otherwise
            for child in reversed(children): # Loop through reversed children
                if frame == index+start:
                    child[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 2
                    child[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 2
                    run = 1
                else: # Otherwise
                    child[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 1
                    child[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 1
                index = index + 1

        if holdf == True and run == 0: # If hold start frame is on
            if frame < len(children)+start: if rev == True: children[-1][c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 2 children[-1][c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 2 else: children[0][c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 2 children[0][c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 2 if holdl == True and run == 0: # If hold last frame is on if frame >= len(children)+start:
                if rev == True:
                    children[0][c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 2
                    children[0][c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 2
                else:
                    children[-1][c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 2
                    children[-1][c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 2
    else: # Manual mode is on
        for i, child in enumerate(children): # Loop through children
            if i == manfr: # If index is same as custom frame
                children[manfr][c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 2
                children[manfr][c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 2
            else: # Otherwise
                child[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 1
                child[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 1

Updated 31/03/2019

obj_sequence_player.c4d

Asset, Cinema 4D, Python

Load custom c4d asset with a script

I use a lot of custom assets in every single project. Those assets can be very big MoGraph setups, Xpresso rigs, Python Generators or whatever. That’s why I had an idea to make a little script that merges your asset from absolute file path to your existing project.

Instead searching your asset every time in folders or content browser, you can simply create custom asset with this script and place it to Cinema 4D’s layout.

import c4d

def main():
    doc.StartUndo() # Start recording undos
    path = "C:\\c4d-assets\\my-asset.c4d" # Your asset file path, change this
    flags = c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS | c4d.SCENEFILTER_MERGESCENE # Merge objects and materials
    c4d.documents.MergeDocument(doc, path, flags) # Merge asset to active project
    c4d.EventAdd() # Refresh Cinema 4D
    doc.EndUndo() # Stop recording undos
if __name__=='__main__':
    main()

You can also use this to load models (obj, abc, fbx) or different c4d projects into your active document.
If you use Mac, use “/” instead “\\” (line 5)

Updated 26/03/2019

Cinema 4D, Python

Messing with After Effects and subtitles

Nowadays many clients wants to burn subtitles straight into video so they can put video to social media etc. so I made two scripts that makes working with After Effects and subtitles a little bit easier.

With the first script you can import srt files and the script makes automatically text layers from that subtitle file. I wanted to make text layers instead of keyframed sourceText since individual layers gives better control and are sometimes also lighter to process.

  1. Make composition or use current one, but there needs to be a open composition.
  2. Run the script (File > Scripts > Run Script File…)
  3. Select the srt-file to import
  4. Text layers are generated

AR_ImportSRT.jsx

With second script you can export text layers to srt file. Your text layers should look something like in the image: use ascending layer stacking.

AR_ExportSRT.jsx

After Effects, JavaScript

FolderLink

FolderLink is asset made with Xpresso and Python that allows you to select folder which includes specific file types. You can decide which kind of file types you are looking for by typing file extensions (separated with comma). FolderLink will scan selected folder (top level) and collects approved files to dropdown menu.

Then you can link easily and quickly browse between different files with dropdown menu and link selected file’s file path to whatever you like, for example to textures or HDRIs.

import c4d, os # Import necessary libraries

def main():
    global path # Output file path
    string = search # Get extensions string
    string = search.replace(" ","") # Remove spaces
    extensions = string.split(",") # Split to list
    c = 0 # Initialize iteration variable
    names = [] # Initialize list for file names
    obj = doc.SearchObject("FolderLink")
    cycle = c4d.BaseContainer() # Initialize base container
    bc = c4d.GetCustomDatatypeDefault(c4d.DTYPE_LONG) # Integer
    bc.SetString(c4d.DESC_NAME, "File") # Set user data name
    bc.SetInt32(c4d.DESC_CUSTOMGUI, c4d.CUSTOMGUI_CYCLE) # Set user data gui
    try: # Try to execute following code
        if folder != "": # If there is folder
            files = os.listdir(folder) # Get files from folder
            for f in files: # Iterate through files
                ext = f.rsplit(".",1) # Get file extension
                if ext[1] in extensions: # If file extension matches
                    c += 1 # Increase iteration
                    cycle.SetString(c, f) # Add item to user data cycle
                    names.append(f) # Add file name to list
            bc.SetContainer(c4d.DESC_CYCLE, cycle) # Set container
            obj.SetUserDataContainer([c4d.ID_USERDATA, 5], bc) # Update user data
            path = folder+"\\"+names[select-1] # Return file path
        else: # Else
            path = "" # Return empty string
    except IndexError: # If something went wrong
        path = "" # Return empty string

If you use Mac OS X you might have to change line 26 “\\” to “/”.
I updated the file so now it’s possible to filter files by filename extension. Thanks to @lasse_lauch for this suggestion.

folderlink.c4d

Asset, Cinema 4D, Python, Xpresso