vrml2 import for blender-

The interface, modeling, 3d editing tools, import/export, feature requests, etc

Moderators: jesterKing, stiv

Post Reply
ideasman
Posts: 0
Joined: Tue Feb 25, 2003 2:37 pm

vrml2 import for blender-

Post by ideasman » Wed Aug 18, 2004 4:43 am

This is no where near finished- was just mucking around with different ways to pass files.

With this one the VRML2 is converted into a dictionary and then evaled-

its cool in the way that all the data is in the dict- and the passer dosnt even know what the variables mean.
Its crudddy that the passer is way to slow.

Once the VRML2 its passed its then imported.

Code: Select all

#!BPY
 
"""
Name: 'VRML 2 (.wrl)...'
Blender: 232
Group: 'Import'
Tooltip: 'Load a VRML2 File'
"""

from Blender import *

def printDict(dictString):
  dictString = dictString.split('}')
  dictString = '\n}\n'.join(dictString)
  dictString = dictString.split('{')
  dictString = '\n{\n'.join(dictString)
  dictString = dictString.split('\n')
  ind = 2
  for l in dictString:
    
    if l == '{':
      ind+=2
      print (ind* ' '), l
    elif l == '}':
      print (ind* ' '), l
      ind-=2
      
    else:
      print (ind* ' '), l
NUM = "0123456789-.,"
BRC = ':{}[]' # () are omitted since I have never seen them in a VRML2 file.

# tells us weather a string can be evaluates as a number
# returns 1/0
#def isNum(string):
#  for ch in string:
#    if ch not in NUM:
#      return 0
#  return 1
def isNum(string):
  if string[0] not in NUM:
    return 0
  return 1


def vrml2dict(file):
  data = open(file, 'r').readlines()
  data = ['{'] + data + ['}']
  # Pass the File
  
  
  # Add invertex commas to strings.
  lIdx = 0
  while lIdx < len(data):
    
    # Add dict braces
    
    
    # Make all lower case- Just for simplisity sake.
    data[lIdx] = data[lIdx].lower()
    
    # Remove commenting
    if '#' in data[lIdx]:
      data[lIdx] = data[lIdx][ :data[lIdx].index('#') ]
    
    # Make sure there are spaced between brackets
    # This is a bit pedantic but Im doing it so there.
    #data[lIdx] = ' [ '.join(data[lIdx].split('['))
    #data[lIdx] = ' ] '.join(data[lIdx].split(']'))
    data[lIdx] = ' { '.join(data[lIdx].split('['))
    data[lIdx] = ' } '.join(data[lIdx].split(']'))
    data[lIdx] = ' } '.join(data[lIdx].split('}'))
    data[lIdx] = ' { '.join(data[lIdx].split('{'))
    data[lIdx] = ''.join(data[lIdx].split(','))
    data[lIdx] = ''.join(data[lIdx].split('"'))
    
    data[lIdx] = '1'.join(data[lIdx].split('true'))
    data[lIdx] = '0'.join(data[lIdx].split('false'))
    
    
    # There should always be a space after a comma.
    
    lIdx += 1

  # Join all this into 1 line.
  data = ' '.join(data)
  
  data = data.split() # split by spaces
  
  quoteOpen = 0
  wIdx = 0 # Word in the list
  while wIdx < len(data):
  
    if data[wIdx] in BRC:
      if quoteOpen:
        data[wIdx-1] = data[wIdx-1] + '" :'
        quoteOpen = 0
      pass
    # If the first char a number?
    # it may be better to test every char
    # but its a standard in many planes that if the first letter is a number
    # then expect the rest to be.
    elif isNum(data[wIdx]):
      if quoteOpen:
        data[wIdx-1] = data[wIdx-1] + '" :'
        quoteOpen = 0
      pass
    elif quoteOpen == 0: # We have a string
      data[wIdx] = '"' + data[wIdx] 
      quoteOpen = wIdx + 1
    
    
    
    wIdx += 1
  
  # Add " to the last string. This makes a long key for the dict to use.
  if quoteOpen:
    data[lIdx][wIdx-1] = data[lIdx][wIdx-1] + '" :'
  
  # Join the words into a line again.
  data = ' '.join(data)
  
  # Add brackets around numbers
  # this converts all number lists into flat number lists.
  # Spaces and commas are treated the same way.
  # This may become a problem mater on- for eg-
  # if you dont know how many items chould be in each chunk.
  # Add invertex commas to strings.
  data = data.split()
  
  remDictBrace = 0 # weather a brace has been removed at the start
  
  numOpen = 0
  wIdx = 0
  while wIdx < len(data):
    print wIdx
    if isNum(data[wIdx]):
      if numOpen == 0:
      
        if data[wIdx-1] == '{':
          data = data[:wIdx-1] + ['('] +  data[wIdx:]
          numOpen = 1
          remDictBrace = 1
          wIdx-=1
        else:
          data = data[:wIdx] + ['('] +  data[wIdx:]
          numOpen = 1
      else:
        data = data[:1+wIdx] + [','] +  data[1+wIdx:]
        wIdx+=1
    else:
      if numOpen == 1:
        data = data[:wIdx] + ['),'] +  data[remDictBrace+wIdx:]
        numOpen = 0 
        remDictBrace = 0
    
    wIdx += 1
    
  data = ' '.join(data)
  
  
  data = ' : "" }'.join(data.split(' : } '))
  data = '} , "'.join(data.split('} "'))
  data = '"'.join(data.split('" '))
  
  # printDict(data)
  
  return eval(data)


def load_vrml(file):
  vrmlData = vrml2dict(file)
  global flatData
  flatData = []
  def dictBrowse(dict, depth):
    global flatData
    for x in dict.keys():
      if type(dict[x]) == type({}):
        # depth +=1
        flatData.append((x, None))
        #print depth, x
        dictBrowse(dict[x], depth)
      else:
        flatData.append((x, dict[x]))
        #print depth, x, dict[x]
  
  dictBrowse(vrmlData, 0)
  # print flatData
  
  mesh = NMesh.GetRaw()
  
  
  dIdx = 0
  while dIdx < len(flatData):
    
    if flatData[dIdx][0] == 'geometry indexedfaceset':
      while flatData[dIdx][0] != 'point':
        dIdx += 1
    
      vIdx = 0
      while vIdx < len(flatData[dIdx][1]):
        mesh.verts.append(NMesh.Vert(flatData[dIdx][1][vIdx], flatData[dIdx][1][vIdx+1], flatData[dIdx][1][vIdx+2]))
        vIdx += 3
        print 'dsd'
      
      while flatData[dIdx][0] != 'coordindex':
        
        dIdx += 1
      
      vIdx = 0
      while vIdx < len(flatData[dIdx][1]):
        f = NMesh.Face()
        f.v.append(mesh.verts[flatData[dIdx][1][vIdx]])
        f.v.append(mesh.verts[flatData[dIdx][1][vIdx+1]])
        f.v.append(mesh.verts[flatData[dIdx][1][vIdx+2]])
        # Tri
        if flatData[dIdx][1][vIdx+2] == -1:
          vIdx += 4
        else: # Quad
          f.v.append(mesh.verts[flatData[dIdx][1][vIdx+3]])
          vIdx += 5
        mesh.faces.append(f)
        # mesh.faces.append(NMesh.Face(flatData[dIdx][1][vIdx], flatData[dIdx][1][vIdx+1], flatData[dIdx][1][vIdx+2]))
        
        print 'daaaaad'

    
    dIdx+=1
    
  NMesh.PutRaw(mesh)
  
  
  
#print vrml2dict (sys.argv[-1])
#for l in vrml2dict ('/ex3.wrl'):
#  print l
Window.FileSelector(load_vrml, 'Import VRML2')



ElBarto
Posts: 0
Joined: Fri Jun 11, 2004 3:24 pm
Location: Berlin
Contact:

Post by ElBarto » Wed Aug 18, 2004 9:30 am

Cool. I renembered there is a project about an VRML importer by Flo: http://projects.blender.org/projects/vrmlimportexp/

You should contact him he needed help.

ideasman
Posts: 0
Joined: Tue Feb 25, 2003 2:37 pm

Post by ideasman » Wed Aug 18, 2004 10:43 am

Id prefer to write my own and base it on my OBJ importer.
- Cam

Monkeyboi
Posts: 251
Joined: Tue Nov 26, 2002 1:24 pm
Location: Copenhagen, Denmark
Contact:

Post by Monkeyboi » Wed Aug 18, 2004 11:42 pm

Couldn't get it to work with a VRML 2 file created from Wings 3D. No N-gons or anything. Here is the file so you can test: http://www.shadeless.dk/files/shape.wrl

It prints this in the console:

Code: Select all

2044
2046
2048
2050
2052
2054
2056
2058
2060
2062
2064
2066
2068

(...)

dsd
dsd
dsd
dsd
dsd
dsd
dsd

(...)

Traceback (most recent call last):
  File "<string>", line 206, in load_vrml
IndexError: list index out of range


PS
Did you code the Paths import for Blender 2.34? I just noticed it, whoa! Brilliant!

ideasman
Posts: 0
Joined: Tue Feb 25, 2003 2:37 pm

Post by ideasman » Thu Aug 19, 2004 1:15 am

Hi MonkiBoi, I didnt know VRML2 did NGons- Ill rewrite the importer and include support for them.

Im a little confused as to how VRML2 treats white space???- sometimes its very ambiguous.

If sombody is keen you can post some VRML specs....

The problem with VRML is you cant cound on line breaks etc.. because it can be hand coded, some TAGS give braces, others dont. It seems sloppy to me. (couldent they have come up with somthing better?)

Monkeyboi
Posts: 251
Joined: Tue Nov 26, 2002 1:24 pm
Location: Copenhagen, Denmark
Contact:

Post by Monkeyboi » Thu Aug 19, 2004 1:33 am

Er... I think you misunderstood... I don't think VRML2 supports N-gons (though I'm not sure). What I mean was that the file I tried to import didn't have N-gons, so it should be fine, but it doesn't work unfortunately.

Post Reply