[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20310] trunk/blender: fix for [#18772] c3d_import script crashes

Campbell Barton ideasman42 at gmail.com
Thu May 21 01:31:59 CEST 2009


Revision: 20310
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20310
Author:   campbellbarton
Date:     2009-05-21 01:31:58 +0200 (Thu, 21 May 2009)

Log Message:
-----------
fix for [#18772] c3d_import script crashes
Patch from Roger Wickes update to 2.48 sFrame, eFrame, fps.


[#18794] GE API conversion script: 2.48 -> 2.49
patch from Alex Fraser (z0r), will test further in the next few days.
 --- 
This is text plug in and standalone script that updates Blender 2.48 Game Engine scripts to be compatible with the 2.49
API.

The script contains a mapping of attribute names to functions that do the conversion. Most of the mappings were extracted
from the documentation in GameTypes.py. Where the conversion is ambiguous, the script will not change the source except
to insert a warning as a comment. This means that the script does not completely automate the conversion process, but
will do a lot of the work.

The script still needs a fair bit of testing. Many of the mappings have not been tested and could result in broken scripts.
I'm submitting this patch now to start the review process early. I think I might need help if it is to be included in
2.49.

Modified Paths:
--------------
    trunk/blender/release/scripts/c3d_import.py
    trunk/blender/source/gameengine/PyDoc/GameTypes.py

Added Paths:
-----------
    trunk/blender/release/scripts/textplugin_convert_ge.py

Modified: trunk/blender/release/scripts/c3d_import.py
===================================================================
--- trunk/blender/release/scripts/c3d_import.py	2009-05-20 21:34:50 UTC (rev 20309)
+++ trunk/blender/release/scripts/c3d_import.py	2009-05-20 23:31:58 UTC (rev 20310)
@@ -527,9 +527,10 @@
 	if VideoFrameRate>120: VideoFrameRate=120
 	# set up anim panel for them
 	context=scn.getRenderingContext() 
-	context.startFrame(StartFrame)
-	context.endFrame(EndFrame)
-	context.framesPerSec(int(VideoFrameRate))
+	context.sFrame=StartFrame
+	context.eFrame=EndFrame
+	context.fps=int(VideoFrameRate)
+	
 	Blender.Set("curframe",StartFrame)
 	Blender.Redraw()
 	return

Added: trunk/blender/release/scripts/textplugin_convert_ge.py
===================================================================
--- trunk/blender/release/scripts/textplugin_convert_ge.py	                        (rev 0)
+++ trunk/blender/release/scripts/textplugin_convert_ge.py	2009-05-20 23:31:58 UTC (rev 20310)
@@ -0,0 +1,677 @@
+#!BPY
+"""
+Name: 'Convert BGE 2.49'
+Blender: 246
+Group: 'TextPlugin'
+Shortcut: ''
+Tooltip: 'Attemps to update deprecated usage of game engine API.'
+"""
+
+#
+# Copyright 2009 Alex Fraser <alex at phatcore.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import string
+import re
+
+COMMENTCHAR = '#'
+
+class ParseError(Exception): pass
+class ConversionError(Exception): pass
+
+def findBalancedParens(lines, row, col, openChar = '(', closeChar = ')'):
+	"""Finds a balanced pair of parentheses, searching from lines[row][col].
+	The opening parenthesis must be on the starting line.
+	
+	Returns a 4-tuple containing the row and column of the opening paren, and
+	the row and column of the matching paren.
+	
+	Throws a ParseError if the first character is not openChar, or if a matching
+	paren cannot be found."""
+	
+	#
+	# Find the opening coordinates.
+	#
+	oRow = row
+	oCol = col
+	line = lines[oRow]
+	while oCol < len(line):
+		if line[oCol] == openChar:
+			break
+		elif line[oCol] == COMMENTCHAR:
+			break
+		oCol = oCol + 1
+	
+	if oCol >= len(line) or line[oCol] != openChar or not re.match(r'^\s*$', line[col:oCol]):
+		raise ParseError, "Can't find opening parenthesis. '%s'" % openChar
+	
+	#
+	# Find the closing coordinates.
+	#
+	eRow = oRow
+	eCol = oCol + 1
+	level = 1
+	while eRow < len(lines) and level > 0:
+		line = lines[eRow]
+		while eCol < len(line) and level > 0:
+			c = line[eCol]
+			if c == openChar:
+				# Found a nested paren.
+				level = level + 1
+			elif c == closeChar:
+				# Exiting one level of nesting.
+				level = level - 1
+				if level == 0:
+					# Back to top level!
+					return (oRow, oCol), (eRow, eCol)
+			elif c == COMMENTCHAR:
+				# Comment. Skip the rest of the line.
+				break
+			eCol = eCol + 1
+		eRow = eRow + 1
+		eCol = 0
+	raise ParseError, "Couldn't find closing parenthesis."
+
+def findLastAssignment(lines, row, attrName):
+	"""Finds the most recent assignment of `attrName' before `row'. Returns
+	everything after the '=' sign or None, if there was no match."""
+	contRegex = re.compile(r'[^#]*?' +      # Don't search in comments.
+	                       attrName  +
+	                       r'\s*=\s*(.*)')  # Assignment
+	
+	cRow = row - 1
+	while cRow >= 0:
+		match = contRegex.search(lines[cRow])
+		if match:
+			return match.group(1)
+		cRow = cRow - 1
+	return None
+
+def replaceSubstr(s, start, end, newSubStr):
+	"""Replace the contents of `s' between `start' and `end' with
+	`newSubStr'."""
+	return s[:start] + newSubStr + s[end:]
+
+def replaceNextParens(lines, row, colStart, newOpenChar, newCloseChar,
+                      oldOpenChar = '(', oldCloseChar = ')'):
+	"""Replace the next set of parentheses with different characters. The
+	opening parenthesis must be located on line `row', and on or after
+	`colStart'. The closing parenthesis may be on the same line or any following
+	line. The strings are edited in-place.
+	
+	Throws a ParseError if the set of parentheses can't be found. In this case,
+	the strings in `lines' will be untouched."""
+	try:
+		pOpen, pClose = findBalancedParens(lines, row, colStart, oldOpenChar,
+		                                   oldCloseChar)
+	except ParseError:
+		raise
+	
+	# Replacement may change string length. Replace closing paren first.
+	r, c = pClose
+	lines[r] = replaceSubstr(lines[r], c, c + 1, newCloseChar)
+	# Replace opening paren.
+	r, c = pOpen
+	lines[r] = replaceSubstr(lines[r], c, c + 1, newOpenChar)
+
+def replaceSimpleGetter(lines, row, colStart, colEnd, newName):
+	"""Replace a call to a simple getter function with a reference to a
+	property, e.g. foo.getBar() -> foo.bar
+	
+	The function identifier being replaced must be on line `row' and
+	between `colStart' and `colEnd'. The opening parenthesis must follow
+	immediately (whitespace is allowed). The closing parenthesis may be on the
+	same or following lines.
+	
+	Throws a ConversionError if the parentheses can't be found. In this case
+	the content of `lines' will be untouched."""
+	try:
+		replaceNextParens(lines, row, colEnd, newOpenChar = '', newCloseChar = '')
+	except ParseError:
+		raise ConversionError, ("Deprecated function reference.")
+	
+	lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName)
+
+def replaceSimpleSetter(lines, row, colStart, colEnd, newName):
+	"""Replace a call to a simple setter function with a reference to a
+	property, e.g. foo.setBar(baz) -> foo.bar = baz
+	
+	The function identifier being replaced must be on line `row' and
+	between `colStart' and `colEnd'. The opening parenthesis must follow
+	immediately (whitespace is allowed). The closing parenthesis may be on the
+	same or following lines.
+	
+	Throws a ConversionError if the parentheses can't be found. In this case
+	the content of `lines' will be untouched."""
+	try:
+		replaceNextParens(lines, row, colEnd, newOpenChar = '', newCloseChar = '')
+	except ParseError:
+		raise ConversionError, ("Deprecated function reference.")
+	
+	lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName + ' = ')
+
+def replaceKeyedGetter(lines, row, colStart, colEnd, newName):
+	"""Replace a call to a keyed getter function with a reference to a
+	property, e.g. foo.getBar(baz) -> foo.bar[baz]
+	
+	The function identifier being replaced must be on line `row' and
+	between `colStart' and `colEnd'. The opening parenthesis must follow
+	immediately (whitespace is allowed). The closing parenthesis may be on the
+	same or following lines.
+	
+	Throws a ConversionError if the parentheses can't be found. In this case
+	the content of `lines' will be untouched."""
+	try:
+		replaceNextParens(lines, row, colEnd, newOpenChar = '[', newCloseChar = ']')
+	except ParseError:
+		raise ConversionError, ("Deprecated function reference.")
+	
+	lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName)
+ 
+def replaceGetXYPosition(lines, row, colStart, colEnd, axis):
+	'''SCA_MouseSensor.getXPosition; SCA_MouseSensor.getYPosition.
+	This is like a keyed getter, but the key is embedded in the attribute
+	name.
+	
+	Throws a ConversionError if the parentheses can't be found. In this case
+	the content of `lines' will be untouched.'''
+	try:
+		(openRow, openCol), (closeRow, closeCol) = findBalancedParens(lines,
+			row, colEnd)
+	except ParseError:
+		raise ConversionError, "Deprecated function reference."
+	if closeRow != row:
+		raise ConversionError, "Can't modify multiple lines."
+	
+	lines[row] = replaceSubstr(lines[row], openCol, closeCol + 1,
+		"[%s]" % axis)
+	
+	lines[row] = replaceSubstr(lines[row], colStart, colEnd, 'position')
+
+def replaceRename(lines, row, colStart, colEnd, newName):
+	"""Replace an identifier with another, e.g. foo.getBar() -> foo.getBaz()
+	
+	The identifier being replaced must be on line `row' and between `colStart'
+	and `colEnd'."""
+	lines[row] = replaceSubstr(lines[row], colStart, colEnd, newName)
+
+def replaceAddActiveActuator(lines, row, colStart, colEnd, closure):
+	'''Extra work needs to be done here to find out the name of the controller,
+	and whether the actuator should be activated or deactivated.
+	
+	Throws a ConversionError if the actuator, controller or condition can't be
+	found. In this case the content of `lines' will be untouched.'''
+	try:
+		(openRow, openCol), (closeRow, closeCol) = findBalancedParens(lines, row, colEnd)
+	except ParseError:
+		ConversionError, "Can't find arguments."
+	
+	if closeRow != openRow:
+		raise ConversionError, ("Can't perform conversion: arguments span multiple lines.")
+	
+	args = lines[row][openCol + 1:closeCol]
+	match = re.search(r'([a-zA-Z_]\w*)'       # Actuator identifier
+	                  r',\s*'
+	                  r'([0-9a-zA-Z_]\w*)',      # Condition (boolean)
+					  args)
+	if not match:
+		raise ConversionError, "Can't find arguments."
+	
+	actuator = match.group(1)
+	condition = match.group(2)
+	controller = None
+	
+	assn = findLastAssignment(lines, row, actuator)
+	if assn:
+		match = re.search(r'([a-zA-Z_]\w*)'           # Controller identifier
+		                  r'\s*\.\s*'                 # Dot
+		                  r'(actuators\s*\[|getActuator\s*\()', # Dictionary/getter identifier
+		                  assn)
+		if match:
+			controller = match.group(1)
+	
+	if not controller:
+		raise ConversionError, "Can't find actuator's controller."
+	
+	gameLogicStart = lines[row].rfind("GameLogic", 0, colStart)
+	if gameLogicStart < 0:
+		raise ConversionError, "Can't find GameLogic identifier."
+	
+	newExpr = None
+	if condition in ['1', 'True']:
+		newExpr = "%s.activate(%s)" % (controller, actuator)
+	elif condition in ['0', 'False']:
+		newExpr = "%s.deactivate(%s)" % (controller, actuator)
+	else:
+		newExpr = "(lambda: %s and (%s.activate(%s) or True) or %s.deactivate(%s))()" % (
+				condition, controller, actuator, controller, actuator)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list