Everything related to Maxwell Render and general stuff that doesn't fit in other categories.
#395688
I need to make a time-lapse sky in an animation sequence. I can't do this from within my 3D application, so I need to replace the sky frame for frame (series of exported mxs files).

Can someone help me make a script that will automate this process? I will pay for your time on this.

Loop...

1. Open (next) mxs file "...0001.mxs" in Studio
2. Replace the HDRI sky image to the next in sequence
3. Save/close

Look forward to hear from someone that can help me out with this.

Thanks
Anders
#395697
You can use a python script. Do you know our pymaxwell tool?
Code: Select all
from pymaxwell import *
import os

def replaceHDRSky(scenepath,imagepath,outscenepath):
  if not os.path.exists(scenepath):
    print('Cannot find %s' % scenepath)
    return 0
  if not os.path.exists(imagepath):
    print('Cannot find %s' % imagepath)
    return 0

  mxs = Cmaxwell(mwcallback)

  if not mxs.readMXS('G:/scenes/sky-anim/knots_0001.mxs'):    
    print('Cannot open %s' % scenepath)
    return 0

  environment = mxs.getEnvironment()
  bitmapFileName,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset,ok = environment.getEnvironmentLayer(IBL_LAYER_BACKGROUND)
  environment.setEnvironmentLayer(IBL_LAYER_BACKGROUND,imagepath,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset)
  bitmapFileName,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset,ok = environment.getEnvironmentLayer(IBL_LAYER_ILLUMINATION)
  environment.setEnvironmentLayer(IBL_LAYER_ILLUMINATION,imagepath,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset)
  bitmapFileName,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset,ok = environment.getEnvironmentLayer(IBL_LAYER_REFLECTION)
  environment.setEnvironmentLayer(IBL_LAYER_REFLECTION,imagepath,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset)
  bitmapFileName,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset,ok = environment.getEnvironmentLayer(IBL_LAYER_REFRACTION)
  environment.setEnvironmentLayer(IBL_LAYER_REFRACTION,imagepath,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset)
  environment.enableEnvironment(True)
  
  if not mxs.writeMXS(outscenepath):
    print('Cannot save %s' % outscenepath)
    return 0

  print('%s saved' % outscenepath)
  return 1

if __name__ == "__main__":
  mxsDir       = 'G:/scenes/sky-anim'
  hdrDir       = 'G:/scenes/sky-anim/hdrs'
  mxsOutputDir = 'G:/scenes/sky-anim/output'
  
  if not os.path.exists(mxsOutputDir):
    os.mkdir(mxsOutputDir)

  mxss = getFilesFromPath(mxsDir,'mxs')
  hdrs = getFilesFromPath(hdrDir,'exr')
  mxss.sort()
  hdrs.sort()

  for mxs,sky in zip(mxss,hdrs):
    inmxs = os.path.join(mxsDir,mxs)
    outmxs = os.path.join(mxsOutputDir,mxs)
    sky = os.path.join(hdrDir,sky)
    replaceHDRSky(inmxs,sky,outmxs)
If you open pymaxwell.exe, paste this code, and replace mxsDir, hdrDir, mxsOutputDir and the HDR extension 'exr' by the proper ones, you will able to replace X HDR images in X mxs scenes.
#395700
Hehe... I was working on another one at the same time. :)
Code: Select all

#================= CHANGE THIS PATH AS REQUIRED =================

dir = 'C:/Users/<username>/Desktop/mxsfiles'

#=================  DON'T CHANGE ANYTHING ELSE  =================

import os
import sys
import re
from pymaxwell import *

print('### apply_hdris_to_frames.py')
dir = os.path.normpath(dir)
if not os.path.isdir(dir):
   print('ERROR: input dir not found: %s' % dir)
   sys.exit(1)

print('### dir: %s ' % dir)
def split_name(file):
   name,ext = os.path.splitext(file)
   m = re.search(r'[0-9]+$', name)
   if not m:
      print('WARNING: sequential part of name not found for %s' % name)
      return None, -1
   i = m.start()
   basename = name[:i]
   if not basename:
      print("WARNING: cannot find (non-sequential part of) name in '%s'." % file)
      return None, -1
   try:
      seqnum = int(name[i:])
   except ValueError:
      print("WARNING: cannot convert (sequential part of name) '%s' to integer." % name[i:])
      return None, -1
   return basename,seqnum

matches = {}

for file in os.listdir(dir):
   if file.startswith('mod_'):
      print('IGNORE: previously-sequenced MXS: %s' % file)
      continue
   basename,seqnum = split_name(file)
   if seqnum == -1:
      continue
   if seqnum not in matches.keys():
      matches[seqnum] = {'mxs': None, 'hdr': None}
   if file.lower().endswith('.mxs'):
      matches[seqnum]['mxs'] = os.path.join(dir, file)
   else:
      matches[seqnum]['hdr'] = os.path.join(dir, file)

def set_env_layer(env, hdr, type):
   layer = list(env.getEnvironmentLayer(type))[0:-1]
   layer[0] = hdr
   env.setEnvironmentLayer(type, *layer)

for k,v in matches.iteritems():
   mxs = v['mxs']
   hdr = v['hdr']
   mxsname = mxs and os.path.basename(mxs) or None
   hdrname = hdr and os.path.basename(hdr) or None
   if not mxsname:
      print('WARNING: no MXS file found for %s.' % hdrname)
      continue
   if not hdrname:
      print('WARNING: no HDR file found for %s.' % mxsname)
      continue
   mw = Cmaxwell(mwcallback)
   if not mw.readMXS(mxs):
      print('ERROR: Failed to read %s.' % mxs)
      mw.freeScene()
      continue
   env = mw.getEnvironment()
   set_env_layer(env, hdr, IBL_LAYER_BACKGROUND)
   set_env_layer(env, hdr, IBL_LAYER_REFLECTION)
   set_env_layer(env, hdr, IBL_LAYER_REFRACTION)
   set_env_layer(env, hdr, IBL_LAYER_ILLUMINATION)
   dirname = os.path.dirname(mxs)
   basename = os.path.basename(mxs)
   mxsout = os.path.join(dirname, 'mod_' + basename);
   if not mw.writeMXS( mxsout):
      print('ERROR: failed to write %s' % mxsout)
   else:
      print('OK: wrote sequenced MXS: %s (hdr: %s)' % (mxsname, hdrname))
   mw.freeScene()

print('### DONE.')

It works a little different. Enter the path to a directory containing mxs files with names ending in integers (e.g. mxsname00001.mxs), as well as any other files with names ending in integers, and it will match up the mxs files with the other files, if matches can be found. Then, it will write new mxs (with the associated hdrs assigned to IBL) files with "mod_" prepended to the filename, for any that were matched (if it is run again, it will skip any files beginning with "mod_", since they will just be overwritten).
#395702
hello
i worked on this last night and i will add it to maxwell tool ; before i extracted every parameters of the environment than i used the method of Brany ; more simple and save alot of lines
Code: Select all
from pymaxwell import *
import os

###########################################################################################################

def ibl():

    hdrFolder = 'F:/change ibl/hdr'      ######  new time-lapse hdr folder
    mxsFolder = 'F:/change ibl/anim'     ######  mxs sequence folder
    newfolder = 'F:/change ibl/animnew'  ######  folder to save new frames

#----------------------------------------------------------------------------------------------------------#

    list = os.listdir(hdrFolder)
    mxslist = getFilesFromPath(mxsFolder, 'mxs')
    lenlist = len(mxslist)
    scene = Cmaxwell(mwcallback)
    for i in range(lenlist):
        new = hdrFolder + '/' + list[i]       # name of the new hdr
        frame = mxsFolder + '/' + mxslist[i]  # name of mxs frame
        scene.readMXS(frame)
        env = scene.getEnvironment()

        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_BACKGROUND)
        env.setEnvironmentLayer(IBL_LAYER_BACKGROUND, new,par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)
        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_REFLECTION)
        env.setEnvironmentLayer(IBL_LAYER_REFLECTION, new, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)
        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_REFRACTION)
        env.setEnvironmentLayer(IBL_LAYER_REFRACTION, new, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)
        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_ILLUMINATION)
        env.setEnvironmentLayer(IBL_LAYER_ILLUMINATION, new, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)

        output = newfolder + '/' + mxslist[i]
        print output
        ok = scene.writeMXS(output)
        scene.freeScene()
        if ok == 1:
           print ('Scene Updated With : ' + new)


if __name__ == "__main__":

    if ibl():
        print 'OK'
#395705
Brany wrote:
Tue Oct 10, 2017 6:15 pm
You can use a python script. Do you know our pymaxwell tool?
Code: Select all
from pymaxwell import *
import os

def replaceHDRSky(scenepath,imagepath,outscenepath):
  if not os.path.exists(scenepath):
    print('Cannot find %s' % scenepath)
    return 0
  if not os.path.exists(imagepath):
    print('Cannot find %s' % imagepath)
    return 0

  mxs = Cmaxwell(mwcallback)

  if not mxs.readMXS('G:/scenes/sky-anim/knots_0001.mxs'):    
    print('Cannot open %s' % scenepath)
    return 0

  environment = mxs.getEnvironment()
  bitmapFileName,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset,ok = environment.getEnvironmentLayer(IBL_LAYER_BACKGROUND)
  environment.setEnvironmentLayer(IBL_LAYER_BACKGROUND,imagepath,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset)
  bitmapFileName,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset,ok = environment.getEnvironmentLayer(IBL_LAYER_ILLUMINATION)
  environment.setEnvironmentLayer(IBL_LAYER_ILLUMINATION,imagepath,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset)
  bitmapFileName,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset,ok = environment.getEnvironmentLayer(IBL_LAYER_REFLECTION)
  environment.setEnvironmentLayer(IBL_LAYER_REFLECTION,imagepath,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset)
  bitmapFileName,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset,ok = environment.getEnvironmentLayer(IBL_LAYER_REFRACTION)
  environment.setEnvironmentLayer(IBL_LAYER_REFRACTION,imagepath,state,sphericalMapping,interpolate,intensity,uTile,vTile,uTileOffset,vTileOffset)
  environment.enableEnvironment(True)
  
  if not mxs.writeMXS(outscenepath):
    print('Cannot save %s' % outscenepath)
    return 0

  print('%s saved' % outscenepath)
  return 1

if __name__ == "__main__":
  mxsDir       = 'G:/scenes/sky-anim'
  hdrDir       = 'G:/scenes/sky-anim/hdrs'
  mxsOutputDir = 'G:/scenes/sky-anim/output'
  
  if not os.path.exists(mxsOutputDir):
    os.mkdir(mxsOutputDir)

  mxss = getFilesFromPath(mxsDir,'mxs')
  hdrs = getFilesFromPath(hdrDir,'exr')
  mxss.sort()
  hdrs.sort()

  for mxs,sky in zip(mxss,hdrs):
    inmxs = os.path.join(mxsDir,mxs)
    outmxs = os.path.join(mxsOutputDir,mxs)
    sky = os.path.join(hdrDir,sky)
    replaceHDRSky(inmxs,sky,outmxs)
If you open pymaxwell.exe, paste this code, and replace mxsDir, hdrDir, mxsOutputDir and the HDR extension 'exr' by the proper ones, you will able to replace X HDR images in X mxs scenes.
Hi Branny

Thanks for helping out with this. I really appreciate it! I tried your script, but all I get is a bunch of "Cannot open('s)", for every .mxs file in the that folder.

Anders
#395706
JDHill wrote:
Tue Oct 10, 2017 9:15 pm
Hehe... I was working on another one at the same time. :)
Code: Select all

#================= CHANGE THIS PATH AS REQUIRED =================

dir = 'C:/Users/<username>/Desktop/mxsfiles'

#=================  DON'T CHANGE ANYTHING ELSE  =================

import os
import sys
import re
from pymaxwell import *

print('### apply_hdris_to_frames.py')
dir = os.path.normpath(dir)
if not os.path.isdir(dir):
   print('ERROR: input dir not found: %s' % dir)
   sys.exit(1)

print('### dir: %s ' % dir)
def split_name(file):
   name,ext = os.path.splitext(file)
   m = re.search(r'[0-9]+$', name)
   if not m:
      print('WARNING: sequential part of name not found for %s' % name)
      return None, -1
   i = m.start()
   basename = name[:i]
   if not basename:
      print("WARNING: cannot find (non-sequential part of) name in '%s'." % file)
      return None, -1
   try:
      seqnum = int(name[i:])
   except ValueError:
      print("WARNING: cannot convert (sequential part of name) '%s' to integer." % name[i:])
      return None, -1
   return basename,seqnum

matches = {}

for file in os.listdir(dir):
   if file.startswith('mod_'):
      print('IGNORE: previously-sequenced MXS: %s' % file)
      continue
   basename,seqnum = split_name(file)
   if seqnum == -1:
      continue
   if seqnum not in matches.keys():
      matches[seqnum] = {'mxs': None, 'hdr': None}
   if file.lower().endswith('.mxs'):
      matches[seqnum]['mxs'] = os.path.join(dir, file)
   else:
      matches[seqnum]['hdr'] = os.path.join(dir, file)

def set_env_layer(env, hdr, type):
   layer = list(env.getEnvironmentLayer(type))[0:-1]
   layer[0] = hdr
   env.setEnvironmentLayer(type, *layer)

for k,v in matches.iteritems():
   mxs = v['mxs']
   hdr = v['hdr']
   mxsname = mxs and os.path.basename(mxs) or None
   hdrname = hdr and os.path.basename(hdr) or None
   if not mxsname:
      print('WARNING: no MXS file found for %s.' % hdrname)
      continue
   if not hdrname:
      print('WARNING: no HDR file found for %s.' % mxsname)
      continue
   mw = Cmaxwell(mwcallback)
   if not mw.readMXS(mxs):
      print('ERROR: Failed to read %s.' % mxs)
      mw.freeScene()
      continue
   env = mw.getEnvironment()
   set_env_layer(env, hdr, IBL_LAYER_BACKGROUND)
   set_env_layer(env, hdr, IBL_LAYER_REFLECTION)
   set_env_layer(env, hdr, IBL_LAYER_REFRACTION)
   set_env_layer(env, hdr, IBL_LAYER_ILLUMINATION)
   dirname = os.path.dirname(mxs)
   basename = os.path.basename(mxs)
   mxsout = os.path.join(dirname, 'mod_' + basename);
   if not mw.writeMXS( mxsout):
      print('ERROR: failed to write %s' % mxsout)
   else:
      print('OK: wrote sequenced MXS: %s (hdr: %s)' % (mxsname, hdrname))
   mw.freeScene()

print('### DONE.')

It works a little different. Enter the path to a directory containing mxs files with names ending in integers (e.g. mxsname00001.mxs), as well as any other files with names ending in integers, and it will match up the mxs files with the other files, if matches can be found. Then, it will write new mxs (with the associated hdrs assigned to IBL) files with "mod_" prepended to the filename, for any that were matched (if it is run again, it will skip any files beginning with "mod_", since they will just be overwritten).
Thank you! This worked great. How will it work if an .exr have only been defined for the background and reflection. Will it replace just those?

Anders
#395707
seghier wrote:
Tue Oct 10, 2017 11:58 pm
hello
i worked on this last night and i will add it to maxwell tool ; before i extracted every parameters of the environment than i used the method of Brany ; more simple and save alot of lines
Code: Select all
from pymaxwell import *
import os

###########################################################################################################

def ibl():

    hdrFolder = 'F:/change ibl/hdr'      ######  new time-lapse hdr folder
    mxsFolder = 'F:/change ibl/anim'     ######  mxs sequence folder
    newfolder = 'F:/change ibl/animnew'  ######  folder to save new frames

#----------------------------------------------------------------------------------------------------------#

    list = os.listdir(hdrFolder)
    mxslist = getFilesFromPath(mxsFolder, 'mxs')
    lenlist = len(mxslist)
    scene = Cmaxwell(mwcallback)
    for i in range(lenlist):
        new = hdrFolder + '/' + list[i]       # name of the new hdr
        frame = mxsFolder + '/' + mxslist[i]  # name of mxs frame
        scene.readMXS(frame)
        env = scene.getEnvironment()

        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_BACKGROUND)
        env.setEnvironmentLayer(IBL_LAYER_BACKGROUND, new,par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)
        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_REFLECTION)
        env.setEnvironmentLayer(IBL_LAYER_REFLECTION, new, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)
        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_REFRACTION)
        env.setEnvironmentLayer(IBL_LAYER_REFRACTION, new, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)
        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_ILLUMINATION)
        env.setEnvironmentLayer(IBL_LAYER_ILLUMINATION, new, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)

        output = newfolder + '/' + mxslist[i]
        print output
        ok = scene.writeMXS(output)
        scene.freeScene()
        if ok == 1:
           print ('Scene Updated With : ' + new)


if __name__ == "__main__":

    if ibl():
        print 'OK'
Hi seghier

Thanks again. Your script does it's thing and it's nice to be able to define separate folders for .exr files and output. The order of the mxs files and the exr's being replaced seems a little random though...

.../output/hdri_test 8 View 1 1_0004.mxs
Scene Updated With : .../hdri_test_skies_b//sky_0024.exr
.../output/hdri_test 8 View 1 1_0010.mxs
Scene Updated With : .../hdri_test_skies_b//sky_0025.exr
.../output/hdri_test 8 View 1 1_0006.mxs
Scene Updated With : .../hdri_test_skies_b//sky_0019.exr

Best
Anders
#395708
try this:
Code: Select all
from pymaxwell import *
import os

###########################################################################################################

def ibl():

    hdrFolder = 'F:/change ibl/hdr'      ######  new time-lapse hdr folder
    mxsFolder = 'F:/change ibl/anim'     ######  mxs sequence folder
    newfolder = 'F:/change ibl/animnew'  ######  folder to save new frames

#----------------------------------------------------------------------------------------------------------#

    list = os.listdir(hdrFolder)
    list.sort()
    mxslist = getFilesFromPath(mxsFolder, 'mxs')
    mxslist.sort()
    lenlist = len(mxslist)
    scene = Cmaxwell(mwcallback)
    for i in range(lenlist):
        new = hdrFolder + '/' + list[i]       # name of the new hdr
        frame = mxsFolder + '/' + mxslist[i]  # name of mxs frame
        scene.readMXS(frame)
        env = scene.getEnvironment()

        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_BACKGROUND)
        env.setEnvironmentLayer(IBL_LAYER_BACKGROUND, new,par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)
        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_REFLECTION)
        env.setEnvironmentLayer(IBL_LAYER_REFLECTION, new, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)
        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_REFRACTION)
        env.setEnvironmentLayer(IBL_LAYER_REFRACTION, new, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)
        old, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h,ok = env.getEnvironmentLayer(IBL_LAYER_ILLUMINATION)
        env.setEnvironmentLayer(IBL_LAYER_ILLUMINATION, new, par_a, par_b, par_c, par_d, par_e, par_f, par_g, par_h)

        output = newfolder + '/' + mxslist[i]
        print output
        ok = scene.writeMXS(output)
        scene.freeScene()
        if ok == 1:
           print ('Scene Updated With : ' + new)


if __name__ == "__main__":

    if ibl():
        print 'OK'
#395709
Anders Peter Amsnæs wrote:
Wed Oct 11, 2017 9:04 am
How will it work if an .exr have only been defined for the background and reflection. Will it replace just those?
It will set all channels; if you want it to leave channels alone unless they already have a path defined, just change the set_env_layer function from this:
Code: Select all
def set_env_layer(env, hdr, type):
   layer = list(env.getEnvironmentLayer(type))[0:-1]
   layer[0] = hdr
   env.setEnvironmentLayer(type, *layer)
To this:
Code: Select all
def set_env_layer(env, hdr, type):
   layer = list(env.getEnvironmentLayer(type))[0:-1]
   if len(layer[0]):
      layer[0] = hdr
      env.setEnvironmentLayer(type, *layer)
#395724
Hi guys

I have been looking for a good solution for this for quite some time. It's great that you made it work so well and simple. One thing...

Would it possible to add a parameter that only advances the sky/exr for every x frames? If set to 1, everything would work as now. If set to 2, mxs_001 and mxs_002 would both be assigned sky_001, mxs_003 and mxs_004 would both be assigned sky_002 and so on. This would make it possible to make the sky move slower of cause.

Btw, Seghier, you mentioned "maxwell tool". What's that?

Best
Anders
#395725
If you want assign the same hdr to every
Two frames try to duplicate the frame 1 twice and rename them to 01 02 , and duplicate the frame 2 twice and rename them to 03 04 ...etc, in the same folder .
__
Or you can separate mxs frames in two folders , first one have 001 003 005 ...x frame.
The second 002 004 006 ...x frame.
And new hdr folder have the half hdr count of the original 001 002 003 ...x.
Than use the script .
About maxwell tool you can check sdk forum , it use to run some maxwell scripts like render animation , replace materials in animation ...and it is for windows only
Sketchup 2024 Released

Any idea of when the Maxwell Sketchup plugin will […]

Will there be a Maxwell Render 6 ?

Let's be realistic. What's left of NL is only milk[…]