The rules have been updated, read them now: Rules!

Pepakura .PBO to Metasequoia .MQO Conversion Script

Post questions about game models here, or help out others!
User avatar
gwlogan
beginner
Posts: 24
Joined: Mon May 12, 2008 9:23 am
Location: Earth, well most of the time...
Has thanked: 9 times
Been thanked: 4 times

Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by gwlogan » Tue Jul 26, 2011 3:45 am

I've got a script written for Python 2.6 that supposedly converts Pepakura (.PBO) models to Metasequoia (.MQO) models. The problem is I can't get the script to run without getting a bunch of syntax errors! I did not write this script and I have no python programing knowledge.
I hope someone who knows Python scripting can fix the errors.
I'd love to see how well this script works. Any and all help would be much appreciated!

Code: Select all

# pepakura3 (.PDO) to metasequoia (.MQO) converter
# by MrPotatoHead using python 2.6

# You must specify the imput file with the full directory
# You must also specify the output directory AND filename (no extension)
# Also remember to change the scale

# I couldn't be bothered to invert the face orientation
# Just select all the faces in your cad program and invert them

import struct
import zlib
import codecs
from array import array
import sys
#saveout = sys.stdout
#outfile = open('C:/output.txt', 'w')
#sys.stdout = outfile

h1=codecs.decode('424d','hex')
h2=codecs.decode('000000003600000028000000','hex')
h3=codecs.decode('010018000000000000000000120B0000120B00000000000000000000','hex')
h4=codecs.decode('0000','hex')

#***** Change the Scale here *****
scale = 1
#*********************************


f = open("C:/testfile.pdo", "rb")
outputname = "testfile"
outputdirectory = "C:/temp/"


metafile = outputdirectory+outputname
of = open(metafile+".mqo", 'w')

of.write("Metasequoia Document\n")
of.write("Format Text Ver 1.0\n")
of.write("\n")
of.write("Scene {\n")
of.write("pos -30.5374 -301.0406 878.7299\n")
of.write("lookat 0.0000 0.0000 0.0000\n")
of.write("head -6.8400\n")
of.write("pich 0.1908\n")
of.write("ortho 0\n")
of.write("zoom2 10.0094\n")
of.write("amb 0.490 0.490 0.490\n")
of.write("}\n")



try:
   dump = f.read(148)
   print ("dump")
   nobj = f.read(4)
   numobj = struct.unpack("i", nobj)
   kk1 = numobj[0]
   print ("number of objects =" ,kk1)
   if kk1 > 10000: kk1=1
   #loop number of objects
   for i in range(0,kk1):
      dump = f.read(4)
      namelen = struct.unpack("i", dump)
      dump = f.read(namelen[0])
      dump = f.read(1)
      dump = f.read(4)
      numvert = struct.unpack("i", dump)
      kk2 = numvert[0]
      if kk2 > 10000: kk2 = 0
      #loop number of vertices
      for j in range(0, kk2):
         x = f.read(8)
         y = f.read(8)

         z = f.read(8)
      dump = f.read(4)
      numfaces = struct.unpack("i", dump)
      kk3 = numfaces[0]
      if kk3 > 10000: kk3 = 0
      #loop number of faces
      for j in range(0, kk3):
         dump = f.read(40)
         nvif = f.read(4)
         numvif = struct.unpack("i", nvif)
         kk4 = numvif[0]
         if kk4 > 10: kk4 = 0
         #loop number of verticies in face
         for k in range(0, kk4):
            vnum = f.read(4)
            vnumber = struct.unpack("i", vnum)
            dump = f.read(8)
            dump = f.read(8)
            u1 = f.read(8)
            uu = struct.unpack("d", u1)
            v1 = f.read(8)
            vv = struct.unpack("d", v1)
            dump = f.read(49)
      dump = f.read(4)
      numlines = struct.unpack("i", dump)
      kk5 = numlines[0]
      print ("number of lines", kk5)
      if kk5 > 20000: kk5 = 0
      for l in range(0, kk5):
         dump = f.read(22)
      position = f.tell();

   #now get materials
   print ("position")
   dump = f.read(4)
   numtx = struct.unpack("i", dump)

   numtex = numtx[0]
   tstr1 = ("Material"+str(numtex)+" {\n")
   of.write(tstr1)
   for m in range(0, numtex):
      print ("processing material", m+1, "of", numtex)
      tstr1 = "\"mat"+str(m+1)+"\" shader(3) col("
      of.write(tstr1)
      dump = f.read(4)
      nameln = struct.unpack("i", dump)
      namelen = nameln[0]
      dump = f.read(namelen)
      dump = f.read(4)
      rrrr = struct.unpack("f", dump)
      dump = f.read(4)
      gggg = struct.unpack("f", dump)
      dump = f.read(4)
      bbbb = struct.unpack("f", dump)
      dump = f.read(4)
      aaaa = struct.unpack("f", dump)
      tstr1 = ("%.3f" % rrrr)+" "+("%.3f" % gggg)+" "+("%.3f" % bbbb)+" "+("%.3f" % aaaa)
      tstr1 += ") dif(0.800) amb(0.600) emi(0.160) spc(0.000) power(5.00)"
      of.write(tstr1)
      dump = f.read(64)
      dump = f.read(1)
      d2 = struct.unpack("B", dump[0])
      print ("d2[0]")
      if d2[0] == 1:
         tstr1 = "text(\""+outputname+str(m)+"tex.bmp\")"
         of.write(tstr1)
         print ("texture found")
         dump = f.read(4)
         bmpw = struct.unpack("i", dump)
         bmpwidth = bmpw[0]
         dump = f.read(4)
         bmph = struct.unpack("i", dump)


         bmpheight = bmph[0]
         dump = f.read(4)
         zlibl = struct.unpack("i", dump)
         zliblen = zlib[0]
         numpixels = bmpwidth*bmpheight
         print ("numpixels")
         #decompress zlib data
         dump = f.read(zliblen)
      of.write("\n")



except EOFError:
   print ("oops")

finally:
   f.seek(0,0);


#just to make sure
f.seek(0,0);
of.write("}\n")
out_str = ""
try:
   dump = f.read(148)
   nobj - f.read(4)
   numobj = struct.unpack("i", nobj)
   #print numobj[0]
   kk1 = numobj[0]
   if kk1 > 10000: kk1 = 1
   for i in range(0, kk1):
      dump = f.read(4)
      namelen = struct.unpack("i", dump)
      dump = f.read(namelen[0])
      dump = f.read(1)
      print ("processing object", i+1)
      name = "obj"+str(i+1)
      of.write("Object \""+name+"\" {\n")

      of.write(" depth 0\n")
      of.write(" folding 0\n")
      of.write(" scale 1.000000 1.000000 1.000000\n")
      of.write(" rotation 0.000000 0.000000 0.000000\n")
      of.write(" translation 0.000000 0.000000 0.000000\n")
      of.write(" visible 15\n")
      of.write(" locking 0\n")
      of.write(" shading 1\n")
      of.write(" facet 59.5\n")
      of.write(" color 0.000 0.000 0.000\n")
      of.write(" color_type 0\n")
      of.write(" verex ")
      dump = f.read(4)
      numvert = struct.unpack("i", dump)
      of.write(str(numvert[0])),
      of.write("{\n")
      kk2 = numvert[0]
      if kk2 > 10000: kk2 = 0
      for j in range(0, kk2):
         x = f.read(8)
         y = f.read(8)
         z = f.read(8)
         outx = struct.unpack("d",x)
         outy = struct.unpack("d",y)
         outz = struct.unpack("d",z)
         ox = outx[0] * scale
         oy = outy[0] * scale
         oz = outz[0] * scale
         tmpstr = "\t"+("%.4f" % ox)+" "+("%.4f" % oy)+" "+("%.4f" % oz)
         of.write(tmpstr+"\n")
      of.write(" }\n")
      dump = f.read(4)
      numfaces = struct.unpack("i", dump)
      tmpstr = "\t face"+" "+str(numfaces[0])+" {\n"
      of.write(tmpstr)
      kk3 = numfaces[0]

      if kk3 > 10000: kk3 = 0
      for j in range(0, kk3):
         mtid = f.read(4)
         matid = struct.unpack("i", mtid)
         matid2 = matid[0]
         matstr = ""
         if matid2 != -1:
            matstr = "M("+str(matid2)+")"
         dump = f.read(36)
         nvif = f.read(4)
         numvif = struct.unpack("i", nvif)
         tmpstr = str(numvif[0])+" V("
         of.write(tmpstr)
         kk4 = numvif[0]
         if kk4 > 10: kk4 = 0
         #redo this to reverse the faces: either 3 or 4
         for k in range(0, kk4):
            vnum = f.read(4)
            vnumber = struct.unpack("i", vnum)
            of.write(str(vnumber[0])+" "),
            dump = f.read(8)
            dump = f.read(8)
            u1 = f.read(8)
            uu = struct.unpack("d", u1)
            out_str += ("%.5f" % uu[0])
            out_str += " "
            v1 = f.read(8)
            vv = struct.unpack("d", v1)
            out_str += ("%.5f" % vv[0])
            out_str += " "
            dump = f.read(49)
         of.write(")"+matstr+" UV( "+out_str+" )\n")
         out_str = ""
      of.write("}\n")
      of.write("}\n")
      dump = f.read(4)

      numlines = struct.unpack("i", dump)
      kk5 = numlines[0]
      if kk5 > 20000: kk5 = 0
      for l in range(0, kk5):
         dump = f.read(22)
      position = f.tell();
   of.write("Eof\n")
   of.close()
   #read number of materials
   dump = f.read(4)
   numtx = struct.unpack("i", dump)
   numtex = numtx[0]
   #for k = 1 to numtex do
   for m in range(0, numtex):
      print ("processing materials",m)
      dump = f.read(4)
      nameln = struct.unpack("i", dump)
      namelen = nameln[0]
      dump = f.read(nameln)
      dump = f.read(80)
      dump = f.read(1)
      d2 = struct.unpack("B", dump[0])
      print ("d2[0]")
      if d2[0] == 1:
         print ("doing bitmap")
         dump = f.read(4)
         bmpw = struct.unpack("i", dump)
         bmpwidth = bmpw[0]
         dump = f.read(4)
         bmph = struct.unpack("i", dump)
         bmpheight = bmph[0]
         dump = f.read(4)
         zlibl = struct.unpack("i", dump)
         zliblen = zlib[0]
         numpixels = bmpwidth*bmpheight
         print ("numpixels")

         #decompress zlib data
         dump = f.read(zliblen)
         out = zlib.decompress(dump)
         out = out[::-1]
         out2 = ""
         for n in range(0, bmpheight):
            pstart = int(n*bmpwidth*3)
            pend = int((pstart)+(bmpwidth*3))
            tout = out[pstart:pend]
            outk = ""
            for knn in range(0, bmpwidth):
               myoutk = ""
               kstart = (knn*3)
               kend = (knn*3)+3
               myoutk = tout[kstart:kend]
               outk += myoutk[::-1]
            out2 += outk[::-1]
         print ("n")
         #write bitmap image to file
         of2name = metafile+str(m)+"tex.bmp"
         of2 = open(of2name, 'wb')
         of2.write(h1)
         bmpfilesize = "%08x" % ((bmpwidth*bmpheight*3)+56)
         print ("bmpfilesize, bmpwidth, bmpheight")
         bmpfs = codecs.decode(bmpfilesize,'hex')
         bmpfs = bmpfs[::-1]
         of2.write(bmpfs)
         of2.write(h2)
         bmpws = "%08x" % (bmpwidth)
         bmpws2 = codecs.decode(bmpws,'hex')
         bmpws2 = bmpws2[::-1]
         of2.write(str(bmpws2))
         bmphs = "%08x" % (bmpheight)
         bmphs2 = codecs.decode(bmphs,'hex')
         bmphs2 = bmphs2[::-1]
         of2.write(str(bmphs2))

         of2.write(h3)
         of2.write(out2)
         of2.write(h4)
         of2.close()

except EOFError:
   print ("oops")

finally:
   f.close()

print ("finished")
Last edited by gwlogan on Tue Jul 26, 2011 5:28 pm, edited 3 times in total.

finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 300 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by finale00 » Tue Jul 26, 2011 4:00 am

Upload some samples to test against.

EDIT: I found this http://www.tamasoft.co.jp/pepakura-en/d ... index.html
Guess these are samples.

Though, I can't follow his code lol :|

User avatar
gwlogan
beginner
Posts: 24
Joined: Mon May 12, 2008 9:23 am
Location: Earth, well most of the time...
Has thanked: 9 times
Been thanked: 4 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by gwlogan » Tue Jul 26, 2011 8:40 am

Here is a place to download some free models:
http://www.swpm.tym.sk/index.files/alliance.htm
The web is full of free Pepakura models so finding some to test with shouldn't be too hard.

User avatar
porimac
VIP member
VIP member
Posts: 109
Joined: Wed Sep 08, 2010 4:46 pm
Location: Japan,Kanagawa
Has thanked: 63 times
Been thanked: 13 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by porimac » Tue Jul 26, 2011 12:55 pm

I tried running script.
error messaged "Invalid syntax @ line 158".
but i have no idea sorry :cry:
You do not have the required permissions to view the files attached to this post.

finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 300 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by finale00 » Tue Jul 26, 2011 1:51 pm

I don't think you're supposed to run it through metaseq script editor.
Just run it through command-line, seeing how it's writing out mqo files.

Anyways I ran it through command-line and it was running into a bunch of odd errors that shouldn't occur in tested code

1: strings not ended properly (missing quotes, extra quotes)

Code: Select all

  for j in range(0, kk2):
         x = f.read(8)
         y = f.read(8)
         z = f.read(8)
         outx = struct.unpack("d", x")
         outy = struct.unpack("d", y")
         outz = struct.unpack("d", z")
         ox = outx[0] * scale
         oy = outy[0] * scale
         oz = outz[0] * scale
2: hardcoded input file (some people would probably have no idea what's wrong)

After making some attempt to fix it, it still doesn't work for the models I downloaded from the official site.
It tells me 0 objects were in the file and so everything fails.

Here's what I've made out of the version 3 binary format:

Code: Select all

#pepakura PDO version 3 format

Char_10 idstring (Version 3\n)
dword unk1
dword null
dword unk2

dword charLen
charLen keyboard
dword charLen
charLen encoding

dword null
dword charLen
charLen hash

dword_8 ???
dword numMesh

numMesh mesh {
   dword charLen
   charLen meshName
   
   byte unkByte
   dword unkCount
   #skip unkCount * 24 bytes
   dword numVerts
   
   numVerts vertex {
       299 bytes or 384 bytes
   }
   dword numFaces
}
From what I've written here, the code doesn't even look like it's going to get the right values.
Last edited by finale00 on Tue Jul 26, 2011 4:48 pm, edited 2 times in total.

alon
mega-veteran
mega-veteran
Posts: 160
Joined: Mon Nov 29, 2010 10:38 am
Has thanked: 32 times
Been thanked: 2 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by alon » Tue Jul 26, 2011 4:03 pm

Me too.
"Invalid syntax."

User avatar
gwlogan
beginner
Posts: 24
Joined: Mon May 12, 2008 9:23 am
Location: Earth, well most of the time...
Has thanked: 9 times
Been thanked: 4 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by gwlogan » Tue Jul 26, 2011 5:05 pm

Well after some further research I found this:
http://uppit.com/psx3tn8va1b8/Pdo2mqo.zip
This is the original Python code. How it works is you must open the pdo2mqo.pdo file in Pepakura Viewer (NOT Pepakura Designer), and view the model's texture to read the code. You then have to manually type out the lines of code text yourself into Python and save the script. What a headache! From what I've seen of the original code it looks to be meant to work with 3D Studio Max 7. Thanks for all the continued help here guys!

finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 300 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by finale00 » Tue Jul 26, 2011 5:30 pm

We might as well just figure out the format, post it up, and then let people write the respective importers :)
I looked around and it seemed some other members on other forums had some interest in the format for version 3, but couldn't figure it out.

I'm also have trouble just getting the faces section right (I can't find a solid pattern) and have no idea how the vertex is stored besides having 299 or 384 bytes depending on some unknown reason.

I believe the designer (or maybe the viewer) has an option to export to OBJ though.

Szkaradek123
mega-veteran
mega-veteran
Posts: 292
Joined: Wed May 05, 2010 8:21 pm
Location: Poland Głogów
Has thanked: 21 times
Been thanked: 612 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by Szkaradek123 » Tue Jul 26, 2011 7:01 pm

The contents of this post was deleted because of possible forum rules violation.

finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 300 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by finale00 » Tue Jul 26, 2011 7:39 pm

It looks like the ones from the official site are different; they didn't have the "pepakura designer 3" in their header. That makes sense then.

User avatar
gwlogan
beginner
Posts: 24
Joined: Mon May 12, 2008 9:23 am
Location: Earth, well most of the time...
Has thanked: 9 times
Been thanked: 4 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by gwlogan » Tue Jul 26, 2011 10:09 pm

The contents of this post was deleted because of possible forum rules violation.

finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 300 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by finale00 » Tue Jul 26, 2011 10:42 pm

Post up the ones you are having trouble with.

User avatar
gwlogan
beginner
Posts: 24
Joined: Mon May 12, 2008 9:23 am
Location: Earth, well most of the time...
Has thanked: 9 times
Been thanked: 4 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by gwlogan » Wed Jul 27, 2011 9:53 am

The contents of this post was deleted because of possible forum rules violation.

Ares722
veteran
Posts: 154
Joined: Thu Jul 15, 2010 2:15 pm
Has thanked: 24 times
Been thanked: 9 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by Ares722 » Wed Jul 27, 2011 7:18 pm

Szkaradek123 , you are great!!!

User avatar
youngmark
veteran
Posts: 145
Joined: Thu Sep 02, 2010 1:38 pm
Has thanked: 30 times
Been thanked: 5 times

Re: Pepakura .PBO to Metasequoia .MQO Conversion Script

Post by youngmark » Wed Mar 21, 2012 4:49 am

Image
Please help me.
This pdo file could not be converted
http://www.mediafire.com/?dkdas8shmhckk26
need someone to fix error on python script.

Post Reply