Skip to content

Commit

Permalink
Fix issue #135, where Edge Lists where not being generated for OGRE >…
Browse files Browse the repository at this point in the history
… 1.9
  • Loading branch information
sercero committed Feb 19, 2023
1 parent 6f73e4e commit 0cc1425
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 56 deletions.
3 changes: 1 addition & 2 deletions io_ogre/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ def draw(self, context):
layout.prop(self, "SHADER_PROGRAMS")

def register():
#logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format='[%(levelname)5s] %(message)s', datefmt='%H:%M:%S')
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='[%(levelname)5s] %(message)s', datefmt='%H:%M:%S')

logging.info('Starting io_ogre %s', bl_info["version"])

Expand Down
4 changes: 2 additions & 2 deletions io_ogre/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@

# Logging
'ENABLE_LOGGING' : False,
#'DEBUG_LOGGING' : False,
'SHOW_LOG_NAME' : False,
'DEBUG_LOGGING' : False,
#'SHOW_LOG_NAME' : False,

# Import
'IMPORT_NORMALS' : True,
Expand Down
17 changes: 10 additions & 7 deletions io_ogre/ogre/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,15 +737,17 @@ def duplicate_object(scene, name, copyobj):
doc.end_tag('animations')
logger.info('- Done at %s seconds' % timer_diff_str(start))

## Clean up and save
if ob.modifiers != None:
#bpy.context.collection.objects.unlink(copy)
## If we made a copy of the object, clean it up
if ob != copy:
#bpy.context.collection.objects.unlink(copy) # Blender 2.7x
#bpy.context.scene.collection.objects.unlink(copy) # Blender 2.8+
copy.user_clear()
logger.debug("Removing temporary object: %s" % copy.name)
bpy.data.objects.remove(copy)
del copy

# Reenable disabled modifiers
# Reenable disabled modifiers
if ob.modifiers != None:
for mod in ob.modifiers:
if mod.type in disable_mods and mod.show_viewport == False:
logger.debug("Enabling Modifier: %s" % mod.name)
Expand Down Expand Up @@ -779,10 +781,11 @@ def replaceInplace(f,searchExp,replaceExp):

logger.info('- Created %s.mesh in total time %s seconds' % (obj_name, timer_diff_str(start)))

# If requested by the user, generate LOD levels through OgreMeshUpgrader
if config.get('LOD_LEVELS') > 0 and config.get('LOD_MESH_TOOLS') == True:
# If requested by the user, generate LOD levels / Edge Lists / Vertex buffer optimization through OgreMeshUpgrader
if ((config.get('LOD_LEVELS') > 0 and config.get('LOD_MESH_TOOLS') == True) or
(config.get('GENERATE_EDGE_LISTS') == True)):
target_mesh_file = os.path.join(path, '%s.mesh' % obj_name )
util.lod_create(target_mesh_file)
util.mesh_upgrade_tool(target_mesh_file)

# Note that exporting the skeleton does not happen here anymore
# It was moved to the function dot_skeleton in its own module (skeleton.py)
Expand Down
39 changes: 21 additions & 18 deletions io_ogre/ui/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def draw(self, context):
"Armature" : "ARMATURE_DATA", "Mesh" : "MESH_DATA", "LOD" : "LATTICE_DATA", "Shape Animation" : "POSE_HLT",
"Logging" : "TEXT"
}

# Options associated with each section
section_options = {
"General" : ["EX_SWAP_AXIS", "EX_V2_MESH_TOOL_VERSION", "EX_XML_DELETE"],
Expand All @@ -111,9 +111,9 @@ def draw(self, context):
"Mesh" : ["EX_MESH", "EX_MESH_OVERWRITE", "EX_ARRAY", "EX_V1_EXTREMITY_POINTS", "EX_Vx_GENERATE_EDGE_LISTS", "EX_GENERATE_TANGENTS", "EX_Vx_OPTIMISE_ANIMATIONS", "EX_V2_OPTIMISE_VERTEX_BUFFERS", "EX_V2_OPTIMISE_VERTEX_BUFFERS_OPTIONS"],
"LOD" : ["EX_LOD_LEVELS", "EX_LOD_DISTANCE", "EX_LOD_PERCENT", "EX_LOD_MESH_TOOLS"],
"Shape Animation" : ["EX_SHAPE_ANIMATIONS", "EX_SHAPE_NORMALS"],
"Logging" : ["EX_Vx_ENABLE_LOGGING"]
"Logging" : ["EX_Vx_ENABLE_LOGGING", "EX_Vx_DEBUG_LOGGING"]
}

for section in sections:
row = layout.row()
box = row.box()
Expand All @@ -130,7 +130,7 @@ def draw(self, context):
box.prop(self, prop)
elif prop.startswith('EX_'):
box.prop(self, prop)

def execute(self, context):
# Add warinng about missing XML converter
Report.reset()
Expand All @@ -155,32 +155,38 @@ def execute(self, context):
config.update(**kw)

print ("_" * 80,"\n")

target_path, target_file_name = os.path.split(os.path.abspath(self.filepath))
target_file_name = clean_object_name(target_file_name)
target_file_name_no_ext = os.path.splitext(target_file_name)[0]

file_handler = None

# Add a file handler to all Logger instances
if config.get('ENABLE_LOGGING') == True:
log_file = ("%s/blender2ogre.log" % target_path)
logger.info("* Writing log file to: %s" % log_file)

file_handler = logging.FileHandler(filename=log_file, mode='w', encoding='utf-8', delay=False)

# Show the python file name from where each log message originated
SHOW_LOG_NAME = False

if SHOW_LOG_NAME:
file_formatter = logging.Formatter(fmt='%(asctime)s %(name)9s.py [%(levelname)5s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
else:
file_formatter = logging.Formatter(fmt='%(asctime)s [%(levelname)5s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S')

file_handler.setFormatter(file_formatter)

if config.get('DEBUG_LOGGING') == True:
level = logging.DEBUG
else:
level = logging.INFO

for logger_name in logging.Logger.manager.loggerDict.keys():
logging.getLogger(logger_name).addHandler(file_handler)
logging.getLogger(logger_name).setLevel(level)

logger.info("* Target path: %s" % target_path)
logger.info("* Target file name: %s" % target_file_name)
Expand All @@ -201,10 +207,7 @@ def execute(self, context):
# Flush and close all logging file handlers
if config.get('ENABLE_LOGGING') == True:
for logger_name in logging.Logger.manager.loggerDict.keys():
logger_instance = logging.getLogger(logger_name)

# Remove handlers
logger_instance.handlers.clear()
logging.getLogger(logger_name).handlers.clear()

file_handler.flush()
file_handler.close()
Expand Down Expand Up @@ -356,8 +359,8 @@ def execute(self, context):
min=0, max=65536,
default=config.get('EXTREMITY_POINTS')) = {}
EX_Vx_GENERATE_EDGE_LISTS : BoolProperty(
name="Edge Lists",
description="Generate edge lists (for stencil shadows)",
name="Generate Edge Lists",
description="Generate Edge Lists (for Stencil Shadows)",
default=config.get('GENERATE_EDGE_LISTS')) = {}
EX_GENERATE_TANGENTS : EnumProperty(
items=config.TANGENT_MODES,
Expand Down Expand Up @@ -423,10 +426,10 @@ def execute(self, context):
default=config.get('ENABLE_LOGGING')) = {}

# It seems that it is not possible to exclude DEBUG when selecting a log level
#EX_Vx_DEBUG_LOGGING : BoolProperty(
# name="Debug Logging",
# description="Whether to show DEBUG log messages",
# default=config.get('DEBUG_LOGGING')) = {}
EX_Vx_DEBUG_LOGGING : BoolProperty(
name="Debug Logging",
description="Whether to show DEBUG log messages",
default=config.get('DEBUG_LOGGING')) = {}

# It was decided to make this an option that is not user-facing
#EX_Vx_SHOW_LOG_NAME : BoolProperty(
Expand Down
84 changes: 57 additions & 27 deletions io_ogre/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,28 @@ def mesh_tool_parameters():
def mesh_tool_version():
return mesh_tool_parameters()[1]

# Calls OgreMeshUpgrader to generate the LOD levels
def lod_create(infile):
# Calls OgreMeshUpgrader to perform:
# - Edge List / LOD generation
# - Optimize vertex buffers for shaders
def mesh_upgrade_tool(infile):
exe = config.get('OGRETOOLS_MESH_UPGRADER')

# OgreMeshUpgrader only works in tandem with OgreXMLConverter, which are both Ogre v1.x tools.
# For Ogre v2.x we will use OgreMeshTool to generate the LODs
# For Ogre v2.x we will use OgreMeshTool, which can perform the same operations
if detect_converter_type() != "OgreXMLConverter":
return

output_path, filename = os.path.split(infile)

if not os.path.exists(infile):
logger.warn("Cannot find file mesh file: %s, unable to generate LOD" % filename)
Report.warnings.append("OgreMeshUpgrader failed, LODs will not be generated for this mesh: %s" % filename)
logger.warn("Cannot find file mesh file: %s, unable run OgreMeshUpgrader" % filename)

if config.get('LOD_MESH_TOOLS') == True:
Report.warnings.append("OgreMeshUpgrader failed, LODs will not be generated for this mesh: %s" % filename)

if config.get('GENERATE_EDGE_LISTS') == True:
Report.warnings.append("OgreMeshUpgrader failed, Edge Lists will not be generated for this mesh: %s" % filename)

return

# Extract converter type from its output
Expand All @@ -91,25 +99,27 @@ def lod_create(infile):
output = output.decode('utf-8')
except:
output = ""

# Check to see if the executable is actually OgreMeshUpgrader
if output.find("OgreMeshUpgrader") == -1:
logger.warn("Cannot find suitable OgreMeshUpgrader executable, unable to generate LOD")
logger.warn("Cannot find suitable OgreMeshUpgrader executable, unable to generate LODs / Edge Lists / Vertex buffer optimization")
return

cmd = [exe]

cmd.append('-l')
cmd.append(str(config.get('LOD_LEVELS')))

cmd.append('-d')
cmd.append(str(config.get('LOD_DISTANCE')))
if config.get('LOD_LEVELS') > 0 and config.get('LOD_MESH_TOOLS') == True:
cmd.append('-l')
cmd.append(str(config.get('LOD_LEVELS')))

cmd.append('-d')
cmd.append(str(config.get('LOD_DISTANCE')))

cmd.append('-p')
cmd.append(str(config.get('LOD_PERCENT')))
cmd.append('-p')
cmd.append(str(config.get('LOD_PERCENT')))

# Edge lists should be generated (or not) by mesh.py, not OgreMeshUpgrader
cmd.append('-e')
# Don't generate Edge Lists (-e = DON'T generate edge lists (for stencil shadows))
if config.get('GENERATE_EDGE_LISTS') == False:
cmd.append('-e')

# Put logfile into output directory
use_logger = False
Expand All @@ -124,10 +134,15 @@ def lod_create(infile):
# Finally, specify input file
cmd.append(infile)

logger.info("* Generating %s LOD levels for mesh: %s" % (config.get('LOD_LEVELS'), filename))
if config.get('LOD_LEVELS') > 0 and config.get('LOD_MESH_TOOLS') == True:
logger.info("* Generating %s LOD levels for mesh: %s" % (config.get('LOD_LEVELS'), filename))

if config.get('GENERATE_EDGE_LISTS') == True:
logger.info("* Generating Edge Lists for mesh: %s" % filename)

# First try to execute with the -log option
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
logger.debug("%s" % " ".join(cmd))
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
output, error = proc.communicate()

if use_logger == False:
Expand All @@ -136,13 +151,23 @@ def lod_create(infile):
log.write(output)

if proc.returncode != 0:
logger.warn("OgreMeshUpgrader failed, LODs will not be generated for this mesh: %s" % filename)
Report.warnings.append("OgreMeshUpgrader failed, LODs will not be generated for this mesh: %s" % filename)
logger.warn("OgreMeshUpgrader failed, LODs / Edge Lists / Vertex buffer optimizations will not be generated for this mesh: %s" % filename)

if config.get('LOD_LEVELS') > 0 and config.get('LOD_MESH_TOOLS') == True:
Report.warnings.append("OgreMeshUpgrader failed, LODs will not be generated for this mesh: %s" % filename)

if config.get('GENERATE_EDGE_LISTS') == True:
Report.warnings.append("OgreMeshUpgrader failed, Edge Lists will not be generated for this mesh: %s" % filename)

if error != None:
logger.error(error)
logger.warn(output)
else:
logger.info("- Generated %s LOD levels for mesh: %s" % (config.get('LOD_LEVELS'), filename))
if config.get('LOD_LEVELS') > 0 and config.get('LOD_MESH_TOOLS') == True:
logger.info("- Generated %s LOD levels for mesh: %s" % (config.get('LOD_LEVELS'), filename))

if config.get('GENERATE_EDGE_LISTS') == True:
logger.info("- Generated Edge Lists for mesh: %s" % filename)


def detect_converter_type():
Expand Down Expand Up @@ -218,6 +243,7 @@ def mesh_convert(infile):
# OgreMeshTool must be run from its own directory (so setting cwd accordingly)
# otherwise it will complain about missing render system (missing plugins_tools.cfg)
exe_path, name = os.path.split(exe)
logger.debug("%s" % " ".join(cmd))
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, cwd=exe_path)
output, error = proc.communicate()

Expand Down Expand Up @@ -261,9 +287,10 @@ def xml_convert(infile, has_uvs=False):
cmd.append('-x')
cmd.append(config.get('EXTREMITY_POINTS'))

if version < (1,10,0) or converter_type == "OgreMeshTool":
if not config.get('GENERATE_EDGE_LISTS'):
cmd.append('-e')
# OgreMeshTool (OGRE v2): -e = DON'T generate edge lists (for stencil shadows)
# OgreXMLConverter (OGRE < 1.10): -e = DON'T generate edge lists (for stencil shadows)
if config.get('GENERATE_EDGE_LISTS') == False and (version < (1,10,0) or converter_type == "OgreMeshTool"):
cmd.append('-e')

if config.get('GENERATE_TANGENTS') != "0" and converter_type == "OgreMeshTool":
cmd.append('-t')
Expand Down Expand Up @@ -293,16 +320,18 @@ def xml_convert(infile, has_uvs=False):
# Finally, specify input file
cmd.append(infile)

ret = subprocess.call(cmd)
logger.debug("%s" % " ".join(cmd))
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
output, error = proc.communicate()

# Instead of asserting, report an error
if ret != 0:
if proc.returncode != 0:
logger.error("OgreXMLConverter returned with non-zero status, check OgreXMLConverter.log")
logger.info(" ".join(cmd))
Report.errors.append("OgreXMLConverter finished with non-zero status converting mesh: (%s), it might not have been properly generated" % name)

# Clean up .xml file after successful conversion
if ret == 0 and config.get('XML_DELETE') == True:
if proc.returncode == 0 and config.get('XML_DELETE') == True:
logger.info("Removing generated xml file after conversion: %s" % infile)
os.remove(infile)

Expand Down Expand Up @@ -330,6 +359,7 @@ def xml_convert(infile, has_uvs=False):
# OgreMeshTool must be run from its own directory (so setting cwd accordingly)
# otherwise it will complain about missing render system (missing plugins_tools.cfg)
exe_path, name = os.path.split(exe)
logger.debug("%s" % " ".join(cmd))
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, cwd=exe_path)
output, error = proc.communicate()

Expand Down

0 comments on commit 0cc1425

Please sign in to comment.