Category Archives: Hobbies

Other things about the stuff I like to do.

MPCNC Post Processor

Published by:

This is my MPCNC post processor, it works for me. Use it at your own risk!

Your mileage may vary!

 

 
# -*- coding: utf-8 -*-
# ***************************************************************************
# * *
# * (c) sliptonic (shopinthewoods@gmail.com) 2014 *
# * (c) Gauthier Briere - 2018, 2019 *
# * (c) Schildkroet - 2019-2020 *
# * (c) Ian Jobson - 2020 - 2021 *
# * *
# * This file is not yet part of the FreeCAD CAx development system. *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Lesser General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with FreeCAD; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************/

import FreeCAD
from FreeCAD import Units
import PathScripts.PostUtils as PostUtils
import argparse
import datetime
import shlex
import PathScripts.PathUtil as PathUtil

TOOLTIP = '''
Generate g-code from a Path that is compatible with the MPCNC Marlin controller.
import mpcnc_post
mpcnc_post.export(object, "/path/to/file.gcode")
'''

# ***************************************************************************
# * Globals set customization preferences
# ***************************************************************************

# Default values for command line arguments:
NUMBERTOOL = 1 # there has to be one tool to start with
PAUSE_FIRST_TOOL = False # should we create an M0 for the first tool
OUTPUT_COMMENTS = True # default output of comments in output gCode file
OUTPUT_HEADER = True # default output header in output gCode file
OUTPUT_LINE_NUMBERS = False # default doesn't output line numbers in output gCode file
OUTPUT_BCNC = False # default doesn't add bCNC operation block headers in output gCode file
SHOW_EDITOR = True # default show the resulting file dialog output in GUI
PRECISION = 3 # Default precision for metric (see http://linuxcnc.org/docs/2.7/html/gcode/overview.html#_g_code_best_practices)
TRANSLATE_DRILL_CYCLES = False # If true, G81, G82 & G83 are translated in G0/G1 moves
PREAMBLE = '''G90
G21
''' # default preamble text will appear at the beginning of the gCode output file.
POSTAMBLE = '''M117 Job End
''' # default postamble text will appear following the last operation.

SPINDLE_WAIT = 0 # no waiting after M3 / M4 by default
RETURN_TO = ("0","0",) # no movements after end of program

# Customisation with no command line argument
MODAL = False # if true commands are suppressed if the same as previous line.
LINENR = 100 # line number starting value
LINEINCR = 10 # line number increment
OUTPUT_TOOL_CHANGE = True # default output M0 tool changes pause the machine until the resume is hit
DRILL_RETRACT_MODE = 'G98' # Default value of drill retractations (CURRENT_Z) other possible value is G99
MOTION_MODE = 'G90' # G90 for absolute moves, G91 for relative
UNITS = 'G21' # G21 for metric, G20 for us standard
UNIT_FORMAT = 'mm'
UNIT_SPEED_FORMAT = 'mm/min'
PRE_OPERATION = '''''' # Pre operation text will be inserted before every operation
POST_OPERATION = '''''' # Post operation text will be inserted after every operation
TOOL_CHANGE = '''M0
''' # Tool Change commands will be inserted before a tool change

# ***************************************************************************
# * End of customization
# ***************************************************************************

# Parser arguments list & definition
parser = argparse.ArgumentParser(prog='grbl', add_help=False)
parser.add_argument('--comments', action='store_true', help='output comment (default)')
parser.add_argument('--no-comments', action='store_true', help='suppress comment output')
parser.add_argument('--header', action='store_true', help='output headers (default)')
parser.add_argument('--no-header', action='store_true', help='suppress header output')
parser.add_argument('--line-numbers', action='store_true', help='prefix with line numbers')
parser.add_argument('--no-line-numbers', action='store_true', help='don\'t prefix with line numbers (default)')
parser.add_argument('--show-editor', action='store_true', help='pop up editor before writing output (default)')
parser.add_argument('--no-show-editor', action='store_true', help='don\'t pop up editor before writing output')
parser.add_argument('--precision', default='3', help='number of digits of precision, default=3')
parser.add_argument('--translate_drill', action='store_true', help='translate drill cycles G81, G82 & G83 in G0/G1 movements')
parser.add_argument('--no-translate_drill', action='store_true', help='don\'t translate drill cycles G81, G82 & G83 in G0/G1 movements (default)')
parser.add_argument('--preamble', help='set commands to be issued before the first command, default="G17 G90"')
parser.add_argument('--postamble', help='set commands to be issued after the last command, default="M5\nG17 G90\n;M2"')
parser.add_argument('--inches', action='store_true', help='Convert output for US imperial mode (G20)')
parser.add_argument('--tool-change', action='store_true', help='Insert M0 for all tool changes')
parser.add_argument('--wait-for-spindle', type=int, default=0, help='Wait for spindle to reach desired speed after M3 / M4, default=0')
parser.add_argument('--return-to', default='', help='Move to the specified coordinates at the end, e.g. --return-to=0,0')
parser.add_argument('--bcnc', action='store_true', help='Add Job operations as bCNC block headers. Consider suppressing existing comments: Add argument --no-comments')
parser.add_argument('--no-bcnc', action='store_true', help='suppress bCNC block header output (default)')
TOOLTIP_ARGS = parser.format_help()

# ***************************************************************************
# * Internal global variables
# ***************************************************************************
MOTION_COMMANDS = ['G0', 'G00', 'G1', 'G01', 'G2', 'G02', 'G3', 'G03'] # Motion gCode commands definition
RAPID_MOVES = ['G0', 'G00'] # Rapid moves gCode commands definition
SUPPRESS_COMMANDS = [] # These commands are ignored by commenting them out
COMMAND_SPACE = " "
# Global variables storing current position
CURRENT_X = 0
CURRENT_Y = 0
CURRENT_Z = 0

# ***************************************************************************
# * to distinguish python built-in open function from the one declared below
if open.__module__ in ['__builtin__', 'io']:
pythonopen = open

def processArguments(argstring):

global NUMBERTOOL
global PAUSE_FIRST_TOOL
global OUTPUT_HEADER
global OUTPUT_COMMENTS
global OUTPUT_LINE_NUMBERS
global SHOW_EDITOR
global PRECISION
global PREAMBLE
global POSTAMBLE
global UNITS
global UNIT_SPEED_FORMAT
global UNIT_FORMAT
global TRANSLATE_DRILL_CYCLES
global OUTPUT_TOOL_CHANGE
global SPINDLE_WAIT
global RETURN_TO
global OUTPUT_BCNC

try:
args = parser.parse_args(shlex.split(argstring))
if args.no_header:
OUTPUT_HEADER = False
if args.header:
OUTPUT_HEADER = True
if args.no_comments:
OUTPUT_COMMENTS = False
if args.comments:
OUTPUT_COMMENTS = True
if args.no_line_numbers:
OUTPUT_LINE_NUMBERS = False
if args.line_numbers:
OUTPUT_LINE_NUMBERS = True
if args.no_show_editor:
SHOW_EDITOR = False
if args.show_editor:
SHOW_EDITOR = True
PRECISION = args.precision
if args.preamble is not None:
PREAMBLE = args.preamble
if args.postamble is not None:
POSTAMBLE = args.postamble
if args.no_translate_drill:
TRANSLATE_DRILL_CYCLES = False
if args.translate_drill:
TRANSLATE_DRILL_CYCLES = True
if args.inches:
UNITS = 'G20'
UNIT_SPEED_FORMAT = 'in/min'
UNIT_FORMAT = 'in'
PRECISION = 4
if args.tool_change:
OUTPUT_TOOL_CHANGE = True
if args.wait_for_spindle > 0:
SPINDLE_WAIT = args.wait_for_spindle
if args.return_to != '':
RETURN_TO = [int(v) for v in args.return_to.split(',')]
if len(RETURN_TO) != 2:
RETURN_TO = None
print("--return-to coordinates must be specified as ,, ignoring")
if args.bcnc:
OUTPUT_BCNC = True
if args.no_bcnc:
OUTPUT_BCNC = False

except Exception as e:
return False

return True

# For debug...
def dump(obj):
for attr in dir(obj):
print("obj.%s = %s" % (attr, getattr(obj, attr)))

def export(objectslist, filename, argstring):

if not processArguments(argstring):
return None

global UNITS
global UNIT_FORMAT
global UNIT_SPEED_FORMAT
global MOTION_MODE
global SUPPRESS_COMMANDS

print("Post Processor: " + __name__ + " postprocessing...")
gcode = ""

# write header
if OUTPUT_HEADER:
gcode += linenumber() + ";Exported by FreeCAD\n"
gcode += linenumber() + ";Post Processor: " + __name__ + "\n"
gcode += linenumber() + ";Output Time:" + str(datetime.datetime.now()) + "\n"

# Check canned cycles for drilling
if TRANSLATE_DRILL_CYCLES:
if len(SUPPRESS_COMMANDS) == 0:
SUPPRESS_COMMANDS = ['G98', 'G80']
else:
SUPPRESS_COMMANDS += ['G98', 'G80']

# Write the preamble
if OUTPUT_COMMENTS:
gcode += linenumber() + ";Begin preamble\n"
for line in PREAMBLE.splitlines(True):
gcode += linenumber() + line
# verify if PREAMBLE have changed MOTION_MODE or UNITS
if 'G90' in PREAMBLE:
MOTION_MODE = 'G90'
elif 'G91' in PREAMBLE:
MOTION_MODE = 'G91'
else:
gcode += linenumber() + MOTION_MODE + "\n"
if 'G21' in PREAMBLE:
UNITS = 'G21'
UNIT_FORMAT = 'mm'
UNIT_SPEED_FORMAT = 'mm/min'
elif 'G20' in PREAMBLE:
UNITS = 'G20'
UNIT_FORMAT = 'in'
UNIT_SPEED_FORMAT = 'in/min'
else:
gcode += linenumber() + UNITS + "\n"

for obj in objectslist:
# Debug...
# print("\n" + "*"*70)
# dump(obj)
# print("*"*70 + "\n")
if not hasattr(obj, "Path"):
print("The object " + obj.Name + " is not a path. Please select only path and Compounds.")
return

# Skip inactive operations
if PathUtil.opProperty(obj, 'Active') is False:
continue

# do the pre_op
if OUTPUT_BCNC:
gcode += linenumber() + "(Block-name: " + obj.Label + ")\n"
gcode += linenumber() + "(Block-expand: 0)\n"
gcode += linenumber() + "(Block-enable: 1)\n"
if OUTPUT_COMMENTS:
gcode += linenumber() + ";Begin operation: " + obj.Label + "\n"
for line in PRE_OPERATION.splitlines(True):
gcode += linenumber() + line

# get coolant mode
coolantMode = 'None'
if hasattr(obj, "CoolantMode") or hasattr(obj, 'Base') and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode

# turn coolant on if required
if OUTPUT_COMMENTS:
if not coolantMode == 'None':
gcode += linenumber() + ';(Coolant On:' + coolantMode + ')\n'
if coolantMode == 'Flood':
gcode += linenumber() + 'M8' + '\n'
if coolantMode == 'Mist':
gcode += linenumber() + 'M7' + '\n'

# Parse the op
gcode += parse(obj)

# do the post_op
if OUTPUT_COMMENTS:
gcode += linenumber() + ";Finish operation: " + obj.Label + "\n"
for line in POST_OPERATION.splitlines(True):
gcode += linenumber() + line

# turn coolant off if required
if not coolantMode == 'None':
if OUTPUT_COMMENTS:
gcode += linenumber() + ';(Coolant Off:' + coolantMode + ')\n'
gcode += linenumber() +'M9' + '\n'

# do the post_amble
if OUTPUT_BCNC:
gcode += linenumber() + "(Block-name: post_amble)\n"
gcode += linenumber() + "(Block-expand: 0)\n"
gcode += linenumber() + "(Block-enable: 1)\n"
if OUTPUT_COMMENTS:
gcode += linenumber() + ";Begin postamble\n"
for line in POSTAMBLE.splitlines(True):
gcode += linenumber() + line

if RETURN_TO:
gcode += linenumber() + "G0 X%s Y%s" % tuple(RETURN_TO)

# show the gCode result dialog
if FreeCAD.GuiUp and SHOW_EDITOR:
dia = PostUtils.GCodeEditorDialog()
dia.editor.setText(gcode)
result = dia.exec_()
if result:
final = dia.editor.toPlainText()
else:
final = gcode
else:
final = gcode

print("Done postprocessing.")

# write the file
gfile = pythonopen(filename, "w")
gfile.write(final)
gfile.close()

def linenumber():
global LINENR
global LINEINCR
if OUTPUT_LINE_NUMBERS:
s = "N" + str(LINENR) + " "
LINENR += LINEINCR
return s
return ""

def format_outstring(strTbl):
global COMMAND_SPACE
# construct the line for the final output
s = ""
for w in strTbl:
s += w + COMMAND_SPACE
s = s.strip()
return s

def parse(pathobj):

global DRILL_RETRACT_MODE
global MOTION_MODE
global CURRENT_X
global CURRENT_Y
global CURRENT_Z
global NUMBERTOOL
global TOOL_CHANGE

out = ""
lastcommand = None

precision_string = '.' + str(PRECISION) + 'f'

params = ['X', 'Y', 'Z', 'A', 'B', 'C', 'U', 'V', 'W', 'I', 'J', 'K', 'F', 'S', 'T', 'Q', 'R', 'L', 'P']

if hasattr(pathobj, "Group"): # We have a compound or project.
if OUTPUT_COMMENTS:
out += linenumber() + ";(Compound: " + pathobj.Label + ")\n"
for p in pathobj.Group:
out += parse(p)
return out

else: # parsing simple path
if not hasattr(pathobj, "Path"): # groups might contain non-path things like stock.
return out
if OUTPUT_COMMENTS:
out += linenumber() + ";Path: " + pathobj.Label + "\n"
for c in pathobj.Path.Commands:
outstring = []
command = c.Name
######################################################################
# Intercept the command here and modify it to insert the comment char
######################################################################
message = command
#print(message)
message_start = message[0]
#print(message_start)
if message_start == '(':
message = message.replace(message_start, ';' + message_start)
#print(message)
command = message
message_start = message[0:2]
#print(message_start + "---From Message[0:2]")
if message_start == 'M6':
TOOL_CHANGE = TOOL_CHANGE.rstrip("\n")
if NUMBERTOOL == 1 and PAUSE_FIRST_TOOL == False :
message = message.replace(message_start, ';' + TOOL_CHANGE)
NUMBERTOOL += 1

else:
message = message.replace(message_start, TOOL_CHANGE)
NUMBERTOOL += 1

#print(message)
#print (NUMBERTOOL)
#print ("^^^is the tool number")
command = message
#######################################################################
# End of Intercept mods
#######################################################################
outstring.append(command)

# if modal: only print the command if it is not the same as the last one
if MODAL:
if command == lastcommand:
outstring.pop(0)

# Now add the remaining parameters in order
for param in params:
if param in c.Parameters:
if param == 'F':
if command not in RAPID_MOVES:
speed = Units.Quantity(c.Parameters['F'], FreeCAD.Units.Velocity)
if speed.getValueAs(UNIT_SPEED_FORMAT) > 0.0:
outstring.append(param + format(float(speed.getValueAs(UNIT_SPEED_FORMAT)), precision_string))
elif param in ['T', 'H', 'D', 'S', 'P', 'L']:
outstring.append(param + str(c.Parameters[param]))
elif param in ['A', 'B', 'C']:
outstring.append(param + format(c.Parameters[param], precision_string))
else: # [X, Y, Z, U, V, W, I, J, K, R, Q] (Conversion eventuelle mm/inches)
pos = Units.Quantity(c.Parameters[param], FreeCAD.Units.Length)
outstring.append(param + format(float(pos.getValueAs(UNIT_FORMAT)), precision_string))

# store the latest command
lastcommand = command

# Memorizes the current position for calculating the related movements and the withdrawal plan
if command in MOTION_COMMANDS:
if 'X' in c.Parameters:
CURRENT_X = Units.Quantity(c.Parameters['X'], FreeCAD.Units.Length)
if 'Y' in c.Parameters:
CURRENT_Y = Units.Quantity(c.Parameters['Y'], FreeCAD.Units.Length)
if 'Z' in c.Parameters:
CURRENT_Z = Units.Quantity(c.Parameters['Z'], FreeCAD.Units.Length)

if command in ('G98', 'G99'):
DRILL_RETRACT_MODE = command

if command in ('G90', 'G91'):
MOTION_MODE = command

if TRANSLATE_DRILL_CYCLES:
if command in ('G81', 'G82', 'G83'):
out += drill_translate(outstring, command, c.Parameters)
# Erase the line we just translated
del(outstring[:])
outstring = []

if SPINDLE_WAIT > 0:
if command in ('M3', 'M03', 'M4', 'M04'):
out += linenumber() + format_outstring(outstring) + "\n"
out += linenumber() + format_outstring(['G4', 'P%s' % SPINDLE_WAIT]) + "\n"
del(outstring[:])
outstring = []

# Check for Tool Change:
if command in ('M6', 'M06'):
if OUTPUT_COMMENTS:
out += linenumber() + ";Begin toolchange\n"
if not OUTPUT_TOOL_CHANGE:
outstring[0] = "(" + outstring[0]
outstring[-1] = outstring[-1] + ")"
else:
for line in TOOL_CHANGE.splitlines(True):
out += linenumber() + line

if command == "message":
if OUTPUT_COMMENTS is False:
out = []
else:
outstring.pop(0) # remove the command

if command in SUPPRESS_COMMANDS:
outstring[0] = ";(" + outstring[0]
outstring[-1] = outstring[-1] + ")"

# prepend a line number and append a newline
if len(outstring) >= 1:
out += linenumber() + format_outstring(outstring) + "\n"

return out

def drill_translate(outstring, cmd, params):
global DRILL_RETRACT_MODE
global MOTION_MODE
global CURRENT_X
global CURRENT_Y
global CURRENT_Z
global UNITS
global UNIT_FORMAT
global UNIT_SPEED_FORMAT

strFormat = '.' + str(PRECISION) + 'f'

trBuff = ""

if OUTPUT_COMMENTS: # Comment the original command
outstring[0] = ";" + outstring[0]
outstring[-1] = outstring[-1] + "!"
trBuff += linenumber() + format_outstring(outstring) + "\n"

# Conversion du cycle
# Pour l'instant, on gere uniquement les cycles dans le plan XY (G17)
# les autres plans ZX (G18) et YZ (G19) ne sont pas traites : Calculs sur Z uniquement.
if MOTION_MODE == 'G90': # Deplacements en coordonnees absolues
drill_X = Units.Quantity(params['X'], FreeCAD.Units.Length)
drill_Y = Units.Quantity(params['Y'], FreeCAD.Units.Length)
drill_Z = Units.Quantity(params['Z'], FreeCAD.Units.Length)
RETRACT_Z = Units.Quantity(params['R'], FreeCAD.Units.Length)
else: # G91 Deplacements relatifs
drill_X = CURRENT_X + Units.Quantity(params['X'], FreeCAD.Units.Length)
drill_Y = CURRENT_Y + Units.Quantity(params['Y'], FreeCAD.Units.Length)
drill_Z = CURRENT_Z + Units.Quantity(params['Z'], FreeCAD.Units.Length)
RETRACT_Z = CURRENT_Z + Units.Quantity(params['R'], FreeCAD.Units.Length)

if DRILL_RETRACT_MODE == 'G98' and CURRENT_Z >= RETRACT_Z:
RETRACT_Z = CURRENT_Z

# Recupere les valeurs des autres parametres
drill_Speed = Units.Quantity(params['F'], FreeCAD.Units.Velocity)
if cmd == 'G83':
drill_Step = Units.Quantity(params['Q'], FreeCAD.Units.Length)
elif cmd == 'G82':
drill_DwellTime = params['P']

if MOTION_MODE == 'G91':
trBuff += linenumber() + "G90" + "\n" # Force des deplacements en coordonnees absolues pendant les cycles

# Mouvement(s) preliminaire(s))
if CURRENT_Z < RETRACT_Z: trBuff += linenumber() + 'G0 Z' + format(float(RETRACT_Z.getValueAs(UNIT_FORMAT)), strFormat) + "\n" trBuff += linenumber() + 'G0 X' + format(float(drill_X.getValueAs(UNIT_FORMAT)), strFormat) + ' Y' + format(float(drill_Y.getValueAs(UNIT_FORMAT)), strFormat) + "\n" if CURRENT_Z > RETRACT_Z:
trBuff += linenumber() + 'G0 Z' + format(float(CURRENT_Z.getValueAs(UNIT_FORMAT)), strFormat) + "\n"

# Mouvement de percage
if cmd in ('G81', 'G82'):
trBuff += linenumber() + 'G1 Z' + format(float(drill_Z.getValueAs(UNIT_FORMAT)), strFormat) + ' F' + format(float(drill_Speed.getValueAs(UNIT_SPEED_FORMAT)), '.2f') + "\n"
# Temporisation eventuelle
if cmd == 'G82':
trBuff += linenumber() + 'G4 P' + str(drill_DwellTime) + "\n"
# Sortie de percage
trBuff += linenumber() + 'G0 Z' + format(float(RETRACT_Z.getValueAs(UNIT_FORMAT)), strFormat) + "\n"
else: # 'G83'
next_Stop_Z = RETRACT_Z - drill_Step
while 1:
if next_Stop_Z > drill_Z:
trBuff += linenumber() + 'G1 Z' + format(float(next_Stop_Z.getValueAs(UNIT_FORMAT)), strFormat) + ' F' + format(float(drill_Speed.getValueAs(UNIT_SPEED_FORMAT)), '.2f') + "\n"
trBuff += linenumber() + 'G0 Z' + format(float(RETRACT_Z.getValueAs(UNIT_FORMAT)), strFormat) + "\n"
next_Stop_Z -= drill_Step
else:
trBuff += linenumber() + 'G1 Z' + format(float(drill_Z.getValueAs(UNIT_FORMAT)), strFormat) + ' F' + format(float(drill_Speed.getValueAs(UNIT_SPEED_FORMAT)), '.2f') + "\n"
trBuff += linenumber() + 'G0 Z' + format(float(RETRACT_Z.getValueAs(UNIT_FORMAT)), strFormat) + "\n"
break

if MOTION_MODE == 'G91':
trBuff += linenumber() + 'G91' # Restore le mode de deplacement relatif

return trBuff

print(__name__ + ": GCode postprocessor loaded.")

MPCNC inlays

Published by:

Iron Man

I am still working on creating a flawless inlay. I have found some wood that I can use but now I have to find a good subject. I am starting to get a feel for the type of graphic that would make a good inlay candidate.

 

Take a look at this page MPCNC vcarve inlay technique it should give you a good idea of where I am with this.

I have created some videos on the subject you can find them here YouTube video

Blender 2.8 Video Green Screen

Published by:

Using Blender 2.8 it is possible to create a “green screen” video. Essentially you record a video in front of a green screen then superimpose that video over another background. To do this in Blender is fairly simple but you have to know what you are doing. It’s certainly not intuitive.

This picture shows the compositor window it’s important to understand that Blender has many different work benches in which you can manipulate “things” The compositor window allows us to take the source and apply nodes making it possible to filter out the green screen. This blog is just showing the very basic process of making a green screen video. It’s not intended to be perfect and much of the “tweaking” will depend on the final video used.

Here you can see three work benches are open the video editing, the rendering, and the compositing. You can switch between these work benches but for now it’s only necessary to use the compositing work bench. If the compositing work bench is not open, click on the + to the right and select compositing.

When you check the use nodes box (see previous picture) you will be presented with a rendering node and a composite node. You can delete the rendering node as we are not working a rendering as our source. To delete it, right click on the rendering node and select delete.  Instead we are working with our green screen movie. Click add then input from the menu and insert a Movie Clip node. To place the node just move the mouse and left click in the position you want it to stay. It doesn’t really matter where you put it but input is usually left to right. At the bottom of the node you  can see a file search box. Click that and select your green screen video. Of course at this point the green screen video is just something in front of a green screen that you can see, no magic has been applied.
Now add a keying node. You can find that under the Matte menu item. You will see that the keying node will allow you to select many different adjustment factors. More on this later.
Now connect the image output of the green screen movie clip node to the image input of the keying node. Don’t adjust anything yet, there are more nodes to add that will make the adjustment easier. Now add an Alpha Over node, you will find it under the color menu. Connect the image output of the keying node to lower image input of the Alpha Over node. You will see why later.
Finally add viewer node now connect the image out from the alpha over to the image input of both the composite node and the viewer node. This will show you the green screen picture in the background. You can adjust this image to make the green screen disappear. To start you will need to go back to the keying node.

Here you can see an item called Key Color. Click on the color and choose the color picker (pipet) and select a darker portion of the green screen in the video image. This will set the key color so that Blender will try to remove it. Now you can tweak all the settings in the keying node to try and make the green screen disappear. – You should wait for the change to render before you try another tweak. Eventually you may add other nodes to assist with removing the green screen but for now, let’s keep it very simple. Once you have the green screen removed (in my example it’s not quite gone but I don’t want to be perfect here just get the principle worked out.Now we can add a second movie clip node, this will be our background. It can be a static image or another video. The choice is yours. Once you have added the node use the file selector to insert the media you want to use. Make sure that it is large enough to fill the background. If it is not adjust it before you use it.

Once you have the media loaded in the second movie clip node just connect the output of that movie clip node directly to the upper image input of the Alpha Over node. This should put your image in the background.Before you render the video you need to make sure you have everything set up properly. The output should look like the picture above. Select an output folder and ensure you have ffmpeg video selected or it will just render frames. Select RGB for color output and an MPEG4 container. Make sure your end Frame is the end of the video you want, too short and you won’t get it all, too long and you will have a lot of black. And finally, and most importantly. Blender will by default render the sequencer (video editing work bench) you need to select just compositing in the post processing. Then just render the animation. I normally render the image first just to make sure it’s rendering what you want to see. Rendering takes a while, go get a drink and come back later and you should have a video in the output folder that you selected. You can take that video into the video editing work bench and manipulate it like any other video.

NOTES:

If you want to use a box matte to remove areas of the video that are not on the green screen. Ensure you connect to the garbage input on the keying node. The box matte node should connect right after the movie clip node and before the keying node.

Home Automation

Published by:

Openhab

As you may have seen I have the Amazon Echo at home. I liked the potential to make the echo the hub for home automation. The first step is to get something you can control so I set out to find something that works with Alexa natively so there would be no issues with integration. I searched Amazon for the a switchable plug that I could plug my living room light in to. I found the TP-LINK HS100.打印

This is a wifi enabled smart plug. You plug it in and from an Android app set it up on your wi-fi network. Once it’s set up you just ask Alexa to look for new devices and it will find the smart plug. Through the set up you designate a name for the device so now you can say something like “Alexa turn on the living room light” and it will switch it on and say “OK”. This is cool and how I work my living room light today. Of course the light is just one thing you can turn any item on that is plugged in to the smart plug. It is just a simple way to power on and power off. This is the beginning of automating the home of course, the smart plug is about $30 so this could be an expensive way to avoid turning a light switch. I will admit that I got mine a lot cheaper than that, it was on sale and I had a gift card from a survey so I ended up paying about $4 out of pocket.  Since we have had that light operated by Alexa we have wished that we had one for the bedroom light so that it would be on when we go upstairs. Now imagine, instead of saying “Alexa turn off the living room light” at the end of the day we could say “Alexa its bed time” and have her turn off the living room light, turn off the tv and the tuner, turn on the bedroom light, set the alarm, check the garage door is closed, and start the sounds of the sea music. – Well, this is possible if you introduce something like Openhab. What is this you ask, here’s a brief description of Openhab

Continue reading

The Amazon Echo

Published by:

I saw the Amazon Echo online and thought that it looked like a cool device, it’s essentially a smart blue tooth speaker. How is it smart you ask? Well, it can understand some of your spoken questions/commands. Take a look at the Amazon page here Amazon Echo

Or simply search for Echo on Amazon.com – I was intrigued by the capability and wanted to see how hard it was to build an “Alexa” skill so I researched a little and it turns out that you build a skill from a template. Although that sounds simple, it’s anything but simple. There are several parts to the creation and publishing. I decided to create one that could provide some car insurance facts. The template gives you all the code that you need you just need to carefully follow the instructions and replace the key words and facts with the data you want to share. Having done that I was able to successfully publish my first Alexa skill and it is now available from the ever growing skills library on Alexa.

feature-setupYou can ask Alexa things like, “what’s the weather today?” or “give me an update” and it will give you whatever it can. You can also ask it to add things to your shopping list which can see on your phone when you are at the store. It’s very cool that way. Where it really falls down is it’s not linked to a regular search engine so if you ask it something that you think Google can answer you may stump Alexa! It is improving daily, there are more “skills” being added daily. I am very interested to see where this technology goes. I suspect that Amazon is going to integrate Alexa into many other devices.

One of the other cool features of Amazon Echo involves home automation. You can use “Alexa” to automate things at home check out my page on home automation.

Cool Guitars

Published by:

Going to work on a new project Albatross DIY Guitar it’s a Les Paul style that needs to be built from the kit. I will start out by selecting a finish for the guitar then working on that, once I have the finish I will work on the body. Then, I will decide what the headstock shape should look like. I will fashion the headstock to that shape then finish that too. Once I have completed all the preliminary finishing I will assemble the guitar and put all the pieces together.KitGuitar

So here’s my kit before we get started. There are pictures of everything in the box (note, no instructions whatsoever!)

20160106_202759

This is the box with all the parts in it. I looked at the body and there are definitely some areas that need some filler. I am going to research the best way to fill it. Obviously if I use some filler I can’t use stain to color the body as the filled areas will show up like sore thumb.

20160106_202931

This is the back of it, you can clearly see that we do not have a one piece solid body but, keep in mind you can’t expect a $2,000 guitar. This is a cheap kit and so far looks like a good kit as long as you keep your expectations in check.

20160106_202804

 

This is a little closer on the body. I like the look of it even though it’s a very thin veneer. I tried a few of the pieces together and they seem to fit reasonably well. I like what they have done so far but on the right hand side where the neck meets the body the binding is sticking up above the body and interfering with the neck. I need to file that down to prevent it from interfering with the neck position.

Continue reading

Line6 Amplifi FX100

Published by:

AMPLIFi FX100

AMPLIFi FX100

Just received a Line6 Amplifi FX100 as a gift, it’s a multi-effects pedal on steroids. – It has man built in AMPs and Cabinets plus all the pedals I could possibly want/need. It is a piece of hardware that has a bluetooth connection to and Android or iOS device.

I am using it with my Nexus7 and setting up the FX100 so I can play Rocksmith songs and use the pedal to play the tones that I need to sound like the song. – I have already created a couple of custom tones based on the Rocksmith tones, they are pretty analogous if you use your judgement to select similar amp, cabinet and pedals. There are some things you need to know to get the FX100 working and the documentation is pretty sparse but once you figure out the basics it’s lots of fun.

I will work on documenting some of it here when I get the time but for now, I think it’s very cool.

One of the ideas I had is to use the FX100 to find a tone for the CDLC I am creating then use that a basis to create a new custom tone for my own CDLC. It should be fun to try. – I just wish I had more time to do that.

I was able to set up a few tones, load them on the hardware and the navigate using the foot switches to the bank (25) that has my tones in it then navigate through the tones using foot switch A through D. It works pretty well, if you have the Nexus on the screen showing that bank, clicking the foot switch will change the current tone on the Nexus, it’s pretty slick. I have already uploaded one tone to the Line 6 tone cloud and expect to get a little more prolific with that.

Screen shots helping to create CDLC for Rocksmith2014

Published by:

To create a new song there are many steps to take, the order of  things is important to get a working song:

  1. Open Editor On Fire (EOF) and click file/new to start a new song.
  2. Rocksmith_63 Dec. 08 12.36It will prompt you to pick your music file (usually an mp3 file) Remember that you can make an mp3 from a YouTube video if you are hunting for a music track.Rocksmith_64 Dec. 08 12.38
  3. There will be a dialog that asks you some music information fill in the appropriate fields.Rocksmith_65 Dec. 08 12.38
  4. Once you have the song loaded you will see this screen. Of course you can’t see your song wave yet because you haven’t switched it on.Rocksmith_66 Dec. 08 12.40
  5. Select song/waveform graph/showRocksmith_67 Dec. 08 12.40
  6. Now add a leading silence to the song before you start modifying anything. You need this so the song doesn’t start too quickly in Rocksmith.Rocksmith_68 Dec. 08 12.41
  7. About 3 seconds will do the trick. The EOF will update the ogg file to add the silence.Rocksmith_69 Dec. 08 12.41
  8. Now under beat update the bpm. If you don’t know the bpm you have to figure it out. This is critical to getting the timing right. If you don’t have the right bpm your song tab won’t line up.Rocksmith_70 Dec. 08 12.41
  9. Now we need to set the track to which track we are creating. You can use part real_guitar for the lead or the rhythm you just have to keep track of what you assign where.  If you don’t select part real_guitar or real_guitar_22 you may not be able to modify Rocksmith specific features. Also, you won’t be able to import the guitar pro tab.Rocksmith_71 Dec. 08 12.42
  10. From the file menu you can import the guitar pro tab (Guitar Pro Import)Rocksmith_72 Dec. 08 12.42
  11. Select your guitar pro tab for the song. If you don’t have the tab you are going to need it or you will be entering all the notes manually. You can edit and create guitar pro 5 tab in Tux Guitar. It will allow you to play the tune and hear how the tab will sound. Remember that all of the component parts are very important. If your song doesn’t play the exact tab you have selected then you will have to modify to make it work in Rocksmith2014.Rocksmith_73 Dec. 08 12.48
  12. When you import the guitar pro file it will ask you if you want to use the time signature and other setting from the guitar pro file, it is up to you. Do what is best for the final outcome.Rocksmith_74 Dec. 08 12.49
  13. When you import you may have multiple tracks in the file. You can import the one that you want for this track, you can always import the others later. (The one in the picture only has one track “Guitar” so that’s what was imported).Rocksmith_75 Dec. 08 12.49
  14. Once you have imported it, you will see the notes from the tab and the wave form together. It’s obvious from this that the notes start too early in the file. To change that you can drag the beat marker to the beginning of the wave form.Rocksmith_76 Dec. 08 12.49
  15. Once you do this, if (a big if) all the notes line up with the music in the wave form, you are in great shape. Chances are they won’t and you will have to do lots of manual manipulation to the file in EOF. Take your time here as the final outcome will only be as good as your EOF file and its timing, song to notes and how they play. You can review the notes in EOF an see how they line up whilst you listen to the music in the wave form.Rocksmith_77 Dec. 08 12.49
  16. As you advance the music, you will see the notes in the 3D view lining up with the timing markers. You can check to see if the notes are going to be presented at the exact time that you they should be played. Remember in EOF you can fine tune the tab by adding, removing and adjusting individual notes and chords.Rocksmith_78 Dec. 08 12.50
  17. Once you have lined everything up you can import your lyric file, this will display the lyrics in time with the music. If you don’t have an lrc file you will need to make one. It’s quite time consuming to line up the words with their timing markers but it will make a much better final product if you do it. You can use UltraStar Creator to create a lrc file that will work with EOF.Rocksmith_79 Dec. 08 12.50
  18. Now you have your file set up, you can add sections to break it up in Rocksmith and allow the dynamic difficulty to be added later. Just try to break the song into sections that make sense. Intro, Verse, Chorus, Outro etc. These are going to be important for riff repeater use too.
  19. Finally, save the file and open up wwise so you can make the ogg vorbis files and the wem that you will need to create the usable psarc file.Rocksmith_80 Dec. 08 12.51
  20. Click on new to start a new project in Wwise. Once you have filled in all the required boxes you will have created some project files in it’s own Wwise folder.Rocksmith_82 Dec. 08 13.18
  21. Right click on the Default work unit and select Import Audio Files….Rocksmith_83 Dec. 08 13.19
  22. Select the happy birthday files from EOF then click on source setting on the right hand side of the screen.Rocksmith_84 Dec. 08 13.20
    Click on Override parent then select Factory Conversion Settings/Vorbis/Vorbis High Qualtity. Then select Edit…Rocksmith_85 Dec. 08 13.20
  23. Make sure you have selected stereo then click Edit… here.Rocksmith_86 Dec. 08 13.21
  24. Change the seek table granularity to 16384 and click OKRocksmith_87 Dec. 08 13.21
  25. Click convert and it will create the Ogg Vorbis file that you need. Do this same process for the song preview that you created in EOF. That will give you the files that you need to make the psarc with the Rocksmith Creator Toolkit.Rocksmith_88 Dec. 08 13.21 Rocksmith_89 Dec. 08 13.21
  26. In the creator you are going to create your Dynamic Difficulty first, this will create new xml files that you need. Select the DDC tab and click Add.Rocksmith_90 Dec. 08 13.49
  27. Add your guitar part xml file. This is the xml file you created in EOF.Rocksmith_91 Dec. 08 13.50
  28. Now select ddc_8_max_levels under options. Set the phrase length to 4 and click Generate DD. This will make a new XML file that DD in the name. It contains the information required for Rocksmith to use dynamic difficulty.Rocksmith_92 Dec. 08 13.51
  29. Now in Platform make sure you have only selected the platforms you want to create. In my case just PC. Then fill out the information for the song you are creating. Select a song in the drop down box that you already own the DLC for. It can be any song as long as you own it already.Rocksmith_98 Dec. 08 13.55Rocksmith_93 Dec. 08 13.51
  30. Under files select the wem button to choose your wem file that you created with Wwise.Rocksmith_94 Dec. 08 13.52
  31. You can select the file you want then when you create the song it will ask you about the preview file too.Rocksmith_95 Dec. 08 13.53
  32. Select the album art that you have for your song. If you don’t have something, you can go on google and under images select something that has exact size 512×512. This will give you the best result.Rocksmith_97 Dec. 08 13.54
  33. Double check you have everything filled in correctly and that your game version is RS2014Rocksmith_96 Dec. 08 13.53
  34. Under the arrangements click add. In the pop up box you can select the XML file for the arrangement you are adding.Rocksmith_100 Dec. 08 14.14
  35. Select the DDC_Part which is the XML with the dynamic difficulty in it.Rocksmith_101 Dec. 08 14.14
  36. Here is where you can select Lead or Rhythm as the arrangement. You can also select the appropriate tones. If you have your own or you just want to use one from another song. Rocksmith_102 Dec. 08 14.22
  37. Do the same thing for the vocals then, click generate. It will ask you where you want to save the psarc file. Once you have the psarc file (for the appropriate platform) you can copy it to your Rocksmith DLC folder. It is in c:\windows\Program Files(x86)\Steam\Steamapps\Rocksmith2014\dlc folder.
  38. Rocksmith_103 Dec. 08 14.36Start Rocksmith and your new song should appear in the appropriate area (Lead, Rhythm etc). You should be able to play the song, see the dynamic difficult and enjoy!