Added support for EXTERNPROTO's and fixed a bug where relative Inline URL's that included a path didn't load
This commit is contained in:
@@ -258,6 +258,10 @@ def is_nodeline(i, words):
|
|||||||
if lines[i].startswith('PROTO'):
|
if lines[i].startswith('PROTO'):
|
||||||
words[:] = lines[i].split()
|
words[:] = lines[i].split()
|
||||||
return NODE_NORMAL, i+1 # TODO - assumes the next line is a '[\n', skip that
|
return NODE_NORMAL, i+1 # TODO - assumes the next line is a '[\n', skip that
|
||||||
|
if lines[i].startswith('EXTERNPROTO'):
|
||||||
|
words[:] = lines[i].split()
|
||||||
|
return NODE_ARRAY, i+1 # TODO - assumes the next line is a '[\n', skip that
|
||||||
|
|
||||||
'''
|
'''
|
||||||
proto_type, new_i = is_protoline(i, words, proto_field_defs)
|
proto_type, new_i = is_protoline(i, words, proto_field_defs)
|
||||||
if new_i != -1:
|
if new_i != -1:
|
||||||
@@ -437,6 +441,17 @@ class vrmlNode(object):
|
|||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def findSpecRecursive(self, spec):
|
||||||
|
self_real = self.getRealNode()
|
||||||
|
if spec == self_real.getSpec():
|
||||||
|
return self
|
||||||
|
|
||||||
|
for child in self_real.children:
|
||||||
|
if child.findSpecRecursive(spec):
|
||||||
|
return child
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def getPrefix(self):
|
def getPrefix(self):
|
||||||
if self.id:
|
if self.id:
|
||||||
return self.id[0]
|
return self.id[0]
|
||||||
@@ -454,6 +469,9 @@ class vrmlNode(object):
|
|||||||
def getProtoName(self):
|
def getProtoName(self):
|
||||||
return self.getSpecialTypeName('PROTO')
|
return self.getSpecialTypeName('PROTO')
|
||||||
|
|
||||||
|
def getExternprotoName(self):
|
||||||
|
return self.getSpecialTypeName('EXTERNPROTO')
|
||||||
|
|
||||||
def getChildrenBySpec(self, node_spec): # spec could be Transform, Shape, Appearance
|
def getChildrenBySpec(self, node_spec): # spec could be Transform, Shape, Appearance
|
||||||
self_real = self.getRealNode()
|
self_real = self.getRealNode()
|
||||||
# using getSpec functions allows us to use the spec of USE children that dont have their spec in their ID
|
# using getSpec functions allows us to use the spec of USE children that dont have their spec in their ID
|
||||||
@@ -496,15 +514,20 @@ class vrmlNode(object):
|
|||||||
# where the parent of this object is not the real parent
|
# where the parent of this object is not the real parent
|
||||||
# - In this case we have added the proto as a child to a node instancing it.
|
# - In this case we have added the proto as a child to a node instancing it.
|
||||||
# This is a bit arbitary, but its how Proto's are done with this importer.
|
# This is a bit arbitary, but its how Proto's are done with this importer.
|
||||||
if child.getProtoName() == None:
|
if child.getProtoName() == None and child.getExternprotoName() == None:
|
||||||
child.getSerialized(results, ancestry)
|
child.getSerialized(results, ancestry)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if DEBUG: print 'getSerialized() is proto:', child.getProtoName(), self.getSpec()
|
if DEBUG: print 'getSerialized() is proto:', child.getProtoName(), child.getExternprotoName(), self.getSpec()
|
||||||
if child.getProtoName()==self.getSpec():
|
|
||||||
|
self_spec = self.getSpec()
|
||||||
|
|
||||||
|
if child.getProtoName() == self_spec or child.getExternprotoName() == self_spec:
|
||||||
if DEBUG: "FoundProto!"
|
if DEBUG: "FoundProto!"
|
||||||
child.getSerialized(results, ancestry)
|
child.getSerialized(results, ancestry)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def searchNodeTypeID(self, node_spec, results):
|
def searchNodeTypeID(self, node_spec, results):
|
||||||
@@ -869,19 +892,52 @@ class vrmlNode(object):
|
|||||||
|
|
||||||
# print self.id, self.getFilename()
|
# print self.id, self.getFilename()
|
||||||
|
|
||||||
# If we were an inline then try load the file
|
# Check if this node was an inline or externproto
|
||||||
|
|
||||||
|
url_ls = []
|
||||||
|
|
||||||
if self.node_type == NODE_NORMAL and self.getSpec() == 'Inline':
|
if self.node_type == NODE_NORMAL and self.getSpec() == 'Inline':
|
||||||
|
|
||||||
|
|
||||||
ancestry = [] # Warning! - PROTO's using this wont work at all.
|
ancestry = [] # Warning! - PROTO's using this wont work at all.
|
||||||
url = self.getFieldAsString('url', None, ancestry)
|
url = self.getFieldAsString('url', None, ancestry)
|
||||||
|
if url:
|
||||||
|
url_ls = [(url, None)]
|
||||||
del ancestry
|
del ancestry
|
||||||
|
|
||||||
if url != None:
|
elif self.getExternprotoName():
|
||||||
|
# externproto
|
||||||
|
url_ls = []
|
||||||
|
for f in self.fields:
|
||||||
|
|
||||||
|
if type(f)==str:
|
||||||
|
f = [f]
|
||||||
|
|
||||||
|
for ff in f:
|
||||||
|
for f_split in ff.split('"'):
|
||||||
|
# print f_split
|
||||||
|
# "someextern.vrml#SomeID"
|
||||||
|
if '#' in f_split:
|
||||||
|
|
||||||
|
f_split, f_split_id = f_split.split('#') # there should only be 1 # anyway
|
||||||
|
|
||||||
|
url_ls.append( (f_split, f_split_id) )
|
||||||
|
else:
|
||||||
|
url_ls.append( (f_split, None) )
|
||||||
|
|
||||||
|
|
||||||
|
# Was either an Inline or an EXTERNPROTO
|
||||||
|
if url_ls:
|
||||||
|
|
||||||
|
# print url_ls
|
||||||
|
|
||||||
|
for url, extern_key in url_ls:
|
||||||
|
print url
|
||||||
urls = []
|
urls = []
|
||||||
urls.append( url )
|
urls.append( url )
|
||||||
urls.append( BPySys.caseInsensitivePath(urls[-1]) )
|
urls.append( BPySys.caseInsensitivePath(urls[-1]) )
|
||||||
|
|
||||||
|
urls.append( dirName(self.getFilename()) + url )
|
||||||
|
urls.append( BPySys.caseInsensitivePath(urls[-1]) )
|
||||||
|
|
||||||
urls.append( dirName(self.getFilename()) + baseName(url) )
|
urls.append( dirName(self.getFilename()) + baseName(url) )
|
||||||
urls.append( BPySys.caseInsensitivePath(urls[-1]) )
|
urls.append( BPySys.caseInsensitivePath(urls[-1]) )
|
||||||
|
|
||||||
@@ -918,7 +974,7 @@ class vrmlNode(object):
|
|||||||
lines.insert(0, 'root_node____')
|
lines.insert(0, 'root_node____')
|
||||||
lines.append('}')
|
lines.append('}')
|
||||||
'''
|
'''
|
||||||
ff = open('/root/test.txt', 'w')
|
ff = open('/tmp/test.txt', 'w')
|
||||||
ff.writelines([l+'\n' for l in lines])
|
ff.writelines([l+'\n' for l in lines])
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@@ -926,10 +982,29 @@ class vrmlNode(object):
|
|||||||
child.setRoot(url) # initialized dicts
|
child.setRoot(url) # initialized dicts
|
||||||
child.parse(0)
|
child.parse(0)
|
||||||
|
|
||||||
|
# if self.getExternprotoName():
|
||||||
|
|
||||||
|
if not extern_key: # if none is spesified - use the name
|
||||||
|
extern_key = self.getSpec()
|
||||||
|
|
||||||
|
if extern_key:
|
||||||
|
|
||||||
|
self.children.remove(child)
|
||||||
|
child.parent = None
|
||||||
|
|
||||||
|
extern_child = child.findSpecRecursive(extern_key)
|
||||||
|
|
||||||
|
if extern_child:
|
||||||
|
self.children.append(extern_child)
|
||||||
|
extern_child.parent = self
|
||||||
|
|
||||||
|
if DEBUG: print "\tEXTERNPROTO ID found!:", extern_key
|
||||||
|
else:
|
||||||
|
print "\tEXTERNPROTO ID not found!:", extern_key
|
||||||
|
|
||||||
# Watch it! - restore lines
|
# Watch it! - restore lines
|
||||||
lines[:] = lines_old
|
lines[:] = lines_old
|
||||||
|
|
||||||
|
|
||||||
return new_i
|
return new_i
|
||||||
|
|
||||||
def __parse(self, i, IS_PROTO_DATA=False):
|
def __parse(self, i, IS_PROTO_DATA=False):
|
||||||
@@ -967,6 +1042,8 @@ class vrmlNode(object):
|
|||||||
self.getDefDict()[ key ] = self
|
self.getDefDict()[ key ] = self
|
||||||
|
|
||||||
key = self.getProtoName()
|
key = self.getProtoName()
|
||||||
|
if not key: key = self.getExternprotoName()
|
||||||
|
|
||||||
proto_dict = self.getProtoDict()
|
proto_dict = self.getProtoDict()
|
||||||
if key != None:
|
if key != None:
|
||||||
proto_dict[ key ] = self
|
proto_dict[ key ] = self
|
||||||
@@ -1167,11 +1244,11 @@ def vrml_parse(path):
|
|||||||
lines.append('}')
|
lines.append('}')
|
||||||
# Use for testing our parsed output, so we can check on line numbers.
|
# Use for testing our parsed output, so we can check on line numbers.
|
||||||
|
|
||||||
|
'''
|
||||||
ff = open('/tmp/test.txt', 'w')
|
ff = open('/tmp/test.txt', 'w')
|
||||||
ff.writelines([l+'\n' for l in lines])
|
ff.writelines([l+'\n' for l in lines])
|
||||||
ff.close()
|
ff.close()
|
||||||
|
'''
|
||||||
|
|
||||||
# Now evaluate it
|
# Now evaluate it
|
||||||
node_type, new_i = is_nodeline(0, [])
|
node_type, new_i = is_nodeline(0, [])
|
||||||
|
|||||||
Reference in New Issue
Block a user