Skip to content

Commit

Permalink
added mmpldinfo, shell integration for MMPLD
Browse files Browse the repository at this point in the history
  • Loading branch information
reinago committed Apr 4, 2018
1 parent de9088e commit 5a2c020
Show file tree
Hide file tree
Showing 9 changed files with 324 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ build-linux/
.gitmodules

*.orig

utils/MMPLD/mmpld\.bat

utils/MMPLD/mmpld\.reg
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ endif()
###############################
add_subdirectory(plugins)

###############################
# utils
###############################
add_subdirectory(utils)

# Check dependencies and throw error
foreach(d ${DEP_LIST})
string(REGEX REPLACE " +" ";" SINGLE_LIST "${d}")
Expand Down
8 changes: 8 additions & 0 deletions utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

file(GLOB utils RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ *)
foreach(util ${utils})
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${util}/CMakeLists.txt)
add_subdirectory(${util})
endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${util}/CMakeLists.txt)
endforeach(util ${utils})

25 changes: 25 additions & 0 deletions utils/MMPLD/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
if (UNIX)

#configure_file(mmpld.sh.input mmpld.sh @ONLY)
#execute_process(COMMAND "cp" "${CMAKE_CURRENT_BINARY_DIR}/mmpld.bat" "${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE out_var RESULT_VARIABLE res_var ERROR_VARIABLE err_var)

else()
string(REPLACE "/" "\\" THEBIN "${CMAKE_CURRENT_BINARY_DIR}")
string(APPEND THEBIN "\\")

string(REPLACE "/" "\\" THESRC "${CMAKE_SOURCE_DIR}")
string(APPEND THESRC "\\")

string(REPLACE "/" "\\" CURSRC "${CMAKE_CURRENT_SOURCE_DIR}")
string(APPEND CURSRC "\\")

configure_file(mmpld.bat.input mmpld.bat @ONLY)
execute_process(COMMAND "cmd" "/c" "copy" "${THEBIN}mmpld.bat" "${CURSRC}" OUTPUT_VARIABLE out_var RESULT_VARIABLE res_var ERROR_VARIABLE err_var)

string(REPLACE "/" "\\\\" CURSRC "${CMAKE_CURRENT_SOURCE_DIR}")
string(APPEND CURSRC "\\\\")

configure_file(mmpld.reg.input mmpld.reg @ONLY)
execute_process(COMMAND "cmd" "/c" "copy" "${THEBIN}mmpld.reg" "${CURSRC}" OUTPUT_VARIABLE out_var RESULT_VARIABLE res_var ERROR_VARIABLE err_var)

endif()
Binary file added utils/MMPLD/MegaMol_File.ico
Binary file not shown.
35 changes: 35 additions & 0 deletions utils/MMPLD/mmpld.bat.input
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@echo off
SET MEGAMOLDIR=@THESRC@
SET MEGAMOLBINDIR=%MEGAMOLDIR%bin\
SET MMPLDINFODIR=%MEGAMOLDIR%utils\MMPLD\

if a%2a == aa GOTO ERROR
if /i "%1" == "render" GOTO RENDER
if /i "%1" == "info" GOTO INFO

GOTO ERROR

:RENDER
TITLE MMPLD Render - %2
cd /d %MEGAMOLBINDIR%
mmconsole.exe -p %MMPLDINFODIR%mmpld.mmprj -i mmpldview inst -v inst::data::filename %2
GOTO END

:INFO
TITLE MMPLD Info - %2
for %%X in (python.exe) do (set FOUND=%%~$PATH:X)
if not defined FOUND GOTO :PYERROR
cd /d %MMPLDINFODIR%
python mmpldinfo.py -v %2
GOTO END

:ERROR
echo usage: mmpld.bat (info^|render) ^<filename^>
GOTO END

:PYERROR
echo cannot find python.exe in path!
GOTO END

:END
pause
10 changes: 10 additions & 0 deletions utils/MMPLD/mmpld.mmprj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<MegaMol type="project" version="1.0">
<view name="mmpldview" viewmod="view">
<module class="MMPLDDataSource" name="data" confpos="{X=727,Y=141}" />
<module class="View3D" name="view" confpos="{X=84,Y=86}" />
<module class="SimpleSphereRenderer" name="SimpleSphereRenderer1" confpos="{X=396,Y=136}" />
<call class="MultiParticleDataCall" from="SimpleSphereRenderer1::getdata" to="data::getdata" />
<call class="CallRender3D" from="view::rendering" to="SimpleSphereRenderer1::rendering" />
</view>
</MegaMol>
22 changes: 22 additions & 0 deletions utils/MMPLD/mmpld.reg.input
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\MegaMol.mmpld]
@="MegaMol Particle List Data"

[HKEY_CLASSES_ROOT\MegaMol.mmpld\DefaultIcon]
@="@CURSRC@MegaMol_File.ico"

[HKEY_CLASSES_ROOT\MegaMol.mmpld\shell]

[HKEY_CLASSES_ROOT\MegaMol.mmpld\shell\info]
@="Show Data Info"

[HKEY_CLASSES_ROOT\MegaMol.mmpld\shell\info\command]
@="\"@[email protected]\" info \"%1\""

[HKEY_CLASSES_ROOT\MegaMol.mmpld\shell\view]
@="Render in MegaMol"

[HKEY_CLASSES_ROOT\MegaMol.mmpld\shell\view\command]
@="\"@[email protected]\" render \"%1\""

215 changes: 215 additions & 0 deletions utils/MMPLD/mmpldinfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# MMPLDinfo - MegaMol Particle List Data File Information Utility
# Copyright 2014, 2016 (C) by
# S. Grottel, TU Dresden, Germany and G. Reina, University of Stuttgart
# All rights reserved. Alle Rechte vorbehalten.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# - Neither the name of S. Grottel, TU Dresden, nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY S. GROTTEL AS IS AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL S. GROTTEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import sys
import os
import struct
import argparse

def getUShort(file):
stuff = file.read(2)
return struct.unpack("<H", stuff)[0]

def getUInt(file):
stuff = file.read(4)
return struct.unpack("<I", stuff)[0]

def getFloat(file):
stuff = file.read(4)
return struct.unpack("<f", stuff)[0]

def getUInt64(file):
stuff = file.read(8)
return struct.unpack("<Q", stuff)[0]

def getByte(file):
return file.read(1)[0]

def pluralTuple(thingy):
return thingy, "s" if (thingy != 1) else ""

def listFramedata(parseResult, frame):
return parseResult.v and (parseResult.v > 1) or (parseResult.v == 1 and frame == 0)

vertexSizes = [0, 12, 16, 5]
vertexNames = ["VERTDATA_NONE", "VERTDATA_FLOAT_XYZ", "VERTDATA_FLOAT_XYZR", "VERTDATA_SHORT_XYZ"]
colorSizes = [0, 3, 4, 4, 12, 16]
colorNames = ["COLDATA_NONE", "COLDATA_UINT8_RGB", "COLDATA_UINT8_RGBA", "COLDATA_FLOAT_I", "COLDATA_FLOAT_RGB", "COLDATA_FLOAT_RGBA"]

print("")
print("MMPLDinfo (v.: 1.2) - MegaMol Particle List Data File Information Utility")
print("Copyright 2014-2018 (C) by")
print("S. Grottel, TU Dresden, Germany and G. Reina, University of Stuttgart")
print("All rights reserved. Alle Rechte vorbehalten.")
print("")

parser = argparse.ArgumentParser(description='display information about .mmpld file(s)')
parser.add_argument('inputfiles', metavar='file', nargs='+', help='file to get info about')
parser.add_argument('-v', action='count', help='show verbose frame info (add another v for more verbosity)')
parseResult = parser.parse_args()

for filename in parseResult.inputfiles:
print("")
print("File: " + (filename))
print("-" * (6 + len(filename)))

if not os.path.isfile(filename):
print("error: cannot open file.")
continue

with open(filename, "rb") as f:
magic = f.read(6)
if (magic != b'MMPLD\x00'):
print("this is not an mmpld file!")
exit(1)
version = getUShort(f)
if (version == 100):
print("mmpld version 1.0")
elif (version == 101):
print("mmpld version 1.1")
elif (version == 102):
print("mmpld version 1.2")
else:
print("unsupported mmpld version " + str(version / 100) + "." + str(version % 100))
exit(1)

frameCount = getUInt(f)
print("Number of frames: " + str(frameCount))

box = [getFloat(f) for x in range(6)]
print("Bounding box: (%f, %f, %f) - (%f, %f, %f)" % (tuple(box)))
box = [getFloat(f) for x in range(6)]
print("Clipping box: (%f, %f, %f) - (%f, %f, %f)" % (tuple(box)))

if (frameCount <= 0):
print("out of data")
exit(1)

frameTable = []
for x in range(frameCount + 1):
frameTable.append(getUInt64(f))

if (f.tell() != frameTable[0]):
print("warning: dead data trailing header")

f.seek(0, os.SEEK_END)
if (f.tell() < frameTable[frameCount]):
print("warning: file truncated")
if (f.tell() > frameTable[frameCount]):
print("warning: dead data trailing body")

for x in range(frameCount):
if (frameTable[x + 1] <= frameTable[x]):
print("frame table corrupted at frame " + str(x))

minNumLists = 0
maxNumLists = 0
minNumParts = 0
maxNumParts = 0
frameNumParts = 0
listNumParts = 0
accumulatedParts = 0

for fi in range(frameCount):
f.seek(frameTable[fi], os.SEEK_SET)
timeStampString = ""
if (version == 102):
timestamp = getFloat(f)
timeStampString = "(%f)" % timestamp
numLists = getUInt(f)
listFramedata(parseResult, fi) and (sys.stdout.write("Frame # %u %s" % (fi, timeStampString)), print("- %u list%s" % pluralTuple(numLists)))
if (fi == 0):
minNumLists = maxNumLists = numLists
else:
if (minNumLists > numLists):
minNumLists = numLists
if (maxNumLists < numLists):
maxNumLists = numLists
frameNumParts = 0
for li in range(numLists):
vertType = getByte(f)
if (vertType >= len(vertexNames)):
vertType = 0
colType = getByte(f)
if (colType >= len(colorNames)):
colType = 0
if (vertType == 0):
colType = 0

listFramedata(parseResult, fi) and print(" #%u: %s, %s" % (li, vertexNames[vertType], colorNames[colType]))
stride = vertexSizes[vertType] + colorSizes[colType]
listFramedata(parseResult, fi) and print(" %u byte%s per particle" % pluralTuple(stride))

globalRad = 0.05
if (vertType == 1 or vertType == 3):
globalRad = getFloat(f)
listFramedata(parseResult, fi) and print(" global radius: %f" % (globalRad))

if (colType == 0):
col = [getByte(f) for x in range(4)]
listFramedata(parseResult, fi) and print(" global color: (%u, %u, %u, %u)" % (tuple(col)))
elif (colType == 3):
intensity = [getFloat(f) for x in range(2)]
listFramedata(parseResult, fi) and print(" intensity color range: [%f, %f]" % (tuple(intensity)))

listNumParts = getUInt64(f)
#listFramedata and print(" %Q particle%s" % countPlural(listNumParts))
listFramedata(parseResult, fi) and print(" {0} particle{1}".format(*pluralTuple(listNumParts)))
frameNumParts += listNumParts

f.seek(listNumParts * stride, os.SEEK_CUR)

if (f.tell() != frameTable[fi + 1]):
print("warning: trailing data after frame %u or frame table corrupted" % (fi))
if (fi == 0):
minNumParts = maxNumParts = frameNumParts
else:
if (minNumParts > frameNumParts):
minNumParts = frameNumParts
if (maxNumParts < frameNumParts):
maxNumParts = frameNumParts
accumulatedParts += frameNumParts

accumulatedParts /= frameCount

print("Data Summary")
print(" %u time frame%s" % pluralTuple(frameCount))
if (minNumLists == maxNumLists):
print(" %u particle list%s per frame" % pluralTuple(minNumLists))
else:
sys.stdout.write(" %u" % minNumLists)
print(" .. %u particle list%s per frame" % pluralTuple(maxNumLists))

if (minNumParts == maxNumParts):
print(" {0} particle{1} per frame".format(*pluralTuple(minNumParts)))
else:
sys.stdout.write(" {0}".format(minNumParts))
print(" .. {0} particle{1} per frame".format(*pluralTuple(maxNumParts)))
print(" {0} particles on average".format(int(accumulatedParts)))

#input()

0 comments on commit 5a2c020

Please sign in to comment.