omaremad, about your importer modification

Post your questions, suggestions and experiences regarding to Image manipulation, 3d modeling and level editing for the Irrlicht engine here.
vermeer
Posts: 2017
Joined: Wed Jan 21, 2004 3:22 pm
Contact:

omaremad, about your importer modification

Post by vermeer »

..of wings files into blender. I thought I was doing wrong being off topic in that other thread .

Hey, thanks a million again, but it is giving an error (Blender 2.48a)...I don't want to waste your time, as I can rebuild hard edges once in Blender after all.. But I felt as polite to report you what I found, for if you are curious :

( indeed, I just read in the comment of the intro that this plugin does not import materials or UV textures, so one would be forced to uv map inside Blender, and loose all hard worked material asignments...other reason why imho better not put your effort in it...heck, it could be as well that I am using latest Wings 3D 0.99.06 and Wings 3D 0.99.53 )


- with an averagely complex game model am doing (for some very little bucks) , it did not put back the hard edges, once imported...set as smooth...add edges split modifier, unmark by angle (by angle is selected by default) .It adds some weird hard edges in unwanted places, and none of the wanted. If add first the modifier, then set as smooth, then unmark angle, leave sharp...neither...

-The thing is console gives an error, maybe is some weird character from unix due to win copy paste....

line 282
SyntaxError: Non-ASCII character '\xc4' in file C:\Documents and Settings...\.blender\scripts\wings_import.py on line 282, but no encoding declared; see http://www.python.org/peps/pep-
0263.html for details

SyntaxError: Non-ASCII character '\xc4' in file C:\Documents and Settings... Blender\.blender\scripts\wings_import.py on line 212, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

first case probably it is not liking this character ? Ä
and second, maybe an intro not well traslated when pasted in win...
the Ä I can't change for test if it is...

Then more errors, like (or probably is not errors, but what dumps after an error..):

Traceback (most recent call last):
File "C:\Documents and Settings\.....\Blender Founda
tion\Blender\.blender\scripts\wings_import.py", line 367, in fs_callback
read(filename)
File "C:\Documents and Settings\...\Blender Founda
tion\Blender\.blender\scripts\wings_import.py", line 328, in read
edge_table = read_edges(data)
Finally making games again!
http://www.konekogames.com
vermeer
Posts: 2017
Joined: Wed Jan 21, 2004 3:22 pm
Contact:

Post by vermeer »

update.
the model is composed of several objects, when export only one (can be others have probs, or that can only import one at a time, should be no big issue if keeps offset) it then gives no error (blender 2.48a(latest stable), Wings 3D 0.99.53 (latest dev(quite stable)))

But I can't make it work as should, I mean, hard edges appear where they should not, and where they should, they don't.

But as I said in some line above, please, don't use more time of yours in this, as the original script I see does not import UVs nor materials, so defeats the purpose... (of most of us wingers uvmapping in Wings or Ultimate Unwrap...and using wings very fast selection system to create materials )
Finally making games again!
http://www.konekogames.com
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Sorry about getting your hopes up with the exporter, it seems it does the triangleation by itself so the meshes if complex end up with diffrent edge and traingle orders, it also seems it was dropped for other bugs? I dont fully understand the code of the old plugins, my mod works fine for some shapes but fails on cylinders in the same way you described.

Now good news...

Anyway seems this has bothered people and a wings3d user moded the obj loader to take care of hard edges, (it makes them as creases though which work for subsurf only), so i added Sharp edges, it also adds a subsurf on the object but i left that as it is.

http://nendowingsmirai.yuku.com/topic/5 ... error.html

http://nendowingsmirai.yuku.com/topic/5693

sharp edge version

Code: Select all

#!BPY
 
"""
Name: 'Wavefront Wings3D (.obj)...'
Blender: 245
Group: 'Import'
Tooltip: 'Load a Wavefront OBJ File exported from Wings3D.'
"""

__author__= "Turbanov Vladislav"
__url__= ["vladius.fanatic.ru"]
__version__= "1.0"

__bpydoc__= """\
This script imports a Wavefront OBJ files to Blender that were exported from Wings3D(with creased edges).

Usage:
Run this script from "File->Import" menu and then load the desired OBJ file exported from Wings3D.
"""

from Blender import *
import BPyMesh
import BPyImage
import BPyMessages

try:		import os
except:		os = False

from sets import Set
from sets import ImmutableSet

def get_float_func(filepath):
	'''
	find the float function for this obj file
	- weather to replace commas or not
	'''
	file= open(filepath, 'r')
	for line in file.xreadlines():
		if line.startswith('v'): # vn vt v 
			if ',' in line:
				return lambda f: float(f.replace(',', '.'))
			elif '.' in line:
				return float

				
			
class OBJ_Vertex:
	x=0
	y=0
	z=0
	def __init__(self,x1,y1,z1):
		self.x=x1
		self.y=y1
		self.z=z1
	def dump(self):
		print 'x:%.4f y:%.4f z:%.4f' % (self.x, self.y, self.z)
	def getList(self):
		return [self.x,self.y,self.z]
			
class OBJ_Face:
	vertexIndexes=[]
	normalIndexes=[]
	
	def __init__(self):
		self.vertexIndexes=[]
		self.normalIndexes=[]
		
		
	def dump(self):
		i=0
		while i < len(self.vertexIndexes):
			print self.vertexIndexes[i],"//",self.normalIndexes[i]
			i+=1
			
	def getVertexList(self):
		list=[]
		for index in self.vertexIndexes:
			list.append(index)
		return list
			
class OBJ_Group:
	name=None
	faces=[]
	material=None
	def __init__(self):
		name=None
		self.faces=[]
		material=None
	
	def dump(self):
		print 'group %s; total faces: %i' % (self.name, len(self.faces))
		for face in self.faces:
			face.dump()
			
	def getFaceList(self):
		list=[]
		for face in self.faces:
			if (len(face.vertexIndexes)<=4):
				list.append(face.getVertexList())
		return list
		
	def getMaterials(self):
		list=[]
		for face in self.faces:
			if (len(face.vertexIndexes)<=4):
				list.append(self.material)
		return list
	
class OBJ_Object:
	offset=1
	name=None
	vertices=[]
	normals=[]
	groups=[]
	def __init__(self):
		name=None
		offset=1
		normalOffset=1
		self.vertices=[]
		self.normals=[]
		self.groups=[]
		
	def getCreasedEdges(self):
		edges={}
		creasedEdges=Set()
		vertDict={}
		
		# Create edges
		for group in self.groups:
			for face in group.faces:
				i=0
				while i < len(face.vertexIndexes):
					ni=(i+1)%len(face.vertexIndexes)
					vertexIndex=face.vertexIndexes[i]
					nextVertexIndex=face.vertexIndexes[ni]
					

					edge=ImmutableSet([vertexIndex-self.offset,nextVertexIndex-self.offset])
					if edge not in edges:
						if (vertexIndex<nextVertexIndex):
							edges[edge]=tuple([face.normalIndexes[i],face.normalIndexes[ni]])
						else:
							edges[edge]=tuple([face.normalIndexes[ni],face.normalIndexes[i]])
					else:
					
						normalIndexes=ImmutableSet([face.normalIndexes[i],face.normalIndexes[ni]])
						if len(Set(edges[edge]).union(normalIndexes))==4:
							# Now check if normals actually differ
							storedNormalIndexes=edges[edge]
							storedNormals=tuple([self.normals[storedNormalIndexes[0]-self.normalOffset],\
							                     self.normals[storedNormalIndexes[1]-self.normalOffset]])
							normals=None
							if (vertexIndex<nextVertexIndex):
								normals=tuple([self.normals[face.normalIndexes[i]-self.normalOffset], \
											self.normals[face.normalIndexes[ni]-self.normalOffset]])
							else:
								normals=tuple([self.normals[face.normalIndexes[ni]-self.normalOffset], \
											   self.normals[face.normalIndexes[i]-self.normalOffset]])
							
							
							
							if (storedNormals[0]!=normals[0]) or (storedNormals[1]!=normals[1]):
								creasedEdges.add(edge)
					i+=1
		#print edges
		creasedEdgesList=[]
		for edge in creasedEdges:
			creasedEdgesList.append(tuple(edge))
		
		return creasedEdgesList
		
						
		
	
	def dump(self):
		print "object %s" % self.name
		print "vertices:"
		for vertex in self.vertices:
			vertex.dump()
		print "groups:"
		for group in self.groups:
			group.dump()
			
	def getFaceList(self):
		list=[]
		for group in self.groups:
			list.extend(group.getFaceList())
		# Apply offset
		i=0
		while i < len(list):
			j=0
			while j < len(list[i]):
				list[i][j]-=self.offset
				j+=1
			i+=1
		return list
	
	def getMaterials(self):
		list=[]
		for group in self.groups:
			list.extend(group.getMaterials())
		return list
	
objects=[]
				
def load_obj(filepath):
	'''
	Called by the user interface or another script.
	load_obj(path) - should give acceptable results.
	This function passes the file and sends the data off
		to be split into objects and then converted into mesh objects
	'''
	print '\nimporting obj "%s"' % filepath
	
	time_main= sys.time()
	
	
	# Get the string to float conversion func for this file- is 'float' for almost all files.
	float_func= get_float_func(filepath)
	
	currentObject=None
	currentGroup=None
	currentOffset=1
	currentNormalOffset=1
	
	
	print '\tparsing obj file "%s"...' % filepath,
	time_sub= sys.time()
	file= open(filepath, 'r')
	for line in file.xreadlines():
	
		line_split=line.split()
		
		if line.startswith('v '):
			currentObject.vertices.append( OBJ_Vertex(float(line_split[1]),float(line_split[2]),float(line_split[3])) )
			currentOffset+=1
		elif line.startswith('vn '):
			currentObject.normals.append((float(line_split[1]),float(line_split[2]),float(line_split[3])))
			currentNormalOffset+=1
			pass
		
		elif line.startswith('vt '):
			pass
		elif line.startswith('f'):
			face=OBJ_Face()
			for pair in line_split[1:]:
				indexes=pair.split("/")
				face.vertexIndexes.append(int(indexes[0]))
				face.normalIndexes.append(int(indexes[-1]))
			currentGroup.faces.append(face)
			
		elif line.startswith('s'):
			pass
		
		elif line.startswith('o'):
			currentObject=OBJ_Object()
			objects.append(currentObject)
			currentObject.name=line_split[1]
			currentObject.offset=currentOffset
			currentObject.normalOffset=currentNormalOffset
			
			
			
		elif line.startswith('g'):
			currentGroup=OBJ_Group()
			currentGroup.name=line_split[1]
			currentObject.groups.append(currentGroup)
		
		elif line.startswith('usemtl'):
			currentGroup.material=line_split[1]
		elif line.startswith('mtllib'): # usemap or usemat
			pass
		
		''' # How to use usemap? depricated?
		elif line.startswith('usema'): # usemap or usemat
			context_image= line_value(line.split())
		'''
	
	file.close()
	time_new= sys.time()
	print '%.4f sec' % (time_new-time_sub)

	print 'Total objects: %i' % len(objects)
	#for object in objects:
	#	object.dump()
	
	# deselect all
	Scene.GetCurrent().objects.selected = []
	new_objects= [] # put new objects here
	scene= Scene.GetCurrent()
	
	materialNames=[]
	for material in Material.Get():
		materialNames.append(material.getName())
		
	objectNames={}
	for object in scene.objects:
		objectNames[object.getName()]=object
		
	for obj_object in objects:
		mesh= Mesh.New(obj_object.name+"_mesh")
		for obj_vert in obj_object.vertices:
			mesh.verts.extend([[obj_vert.x,obj_vert.y,obj_vert.z]])
		
		mesh.faces.extend(obj_object.getFaceList())
		obj_materials=obj_object.getMaterials()
		obj_materialDict={}
		currentMaterialID=0
		




		i=0
		for obj_material in obj_materials:
			mesh.faces[i].smooth=1
			if obj_material in obj_materialDict:
				mesh.faces[i].mat=obj_materialDict[obj_material]
			else:
				material=None
				if obj_material in materialNames:
					material=Material.Get(obj_material)
				else:
					material=Material.New(obj_material)
				mesh.materials+=[material]
				obj_materialDict[obj_material]=currentMaterialID
				mesh.faces[i].mat=currentMaterialID
				currentMaterialID+=1
			i+=1

		creasedEdges=obj_object.getCreasedEdges()
		
		if (len(creasedEdges)!=0):
			if (len(creasedEdges)==1):
				mesh.edges[mesh.findEdges(creasedEdges)].crease=255
				mesh.edges[edgeIndex].flag=Mesh.EdgeFlags.SHARP 
			else:
				
				
				for edgeIndex in mesh.findEdges(creasedEdges):
					if edgeIndex != None:
						mesh.edges[edgeIndex].crease=255
						mesh.edges[edgeIndex].flag=Mesh.EdgeFlags.SHARP 
				
		object=None
		if (obj_object.name in objectNames):
			scene.objects.unlink(objectNames[obj_object.name])
			
		object=Object.New('Mesh',obj_object.name)
		mod = object.modifiers.append(Modifier.Type.SUBSURF) # add a new subsurf modifier
		mod[Modifier.Settings.LEVELS] = 1
		mod[Modifier.Settings.RENDLEVELS] = 3
		
		object.link(mesh)
		scene.objects.link(object)
		


def load_obj_ui(filepath, BATCH_LOAD= False):
	if BPyMessages.Error_NoFile(filepath):
		return

	Window.WaitCursor(1)

	load_obj(filepath)
	
	Window.WaitCursor(0)


def load_obj_ui_batch(file):
	load_obj_ui(file, True)


if __name__=='__main__':
	Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj')
I hope this restores your euphoria :wink:
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

His exporter doesnt import uv's ill try and add that inf a few secs.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Hmmm his exporter only implements the .obj properties exported by wings, so it only loads wings objs and fails on others. I guess that would make adding uv's useless ince wings cant uv, and the exporter is wings only. Locking you to blender uving.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

I guess that would make adding uv's useless ince wings cant uv
I don't know if Wings exports UVs to obj format but it certainly does UV. It also imports UV from obj.
vermeer
Posts: 2017
Joined: Wed Jan 21, 2004 3:22 pm
Contact:

Post by vermeer »

Sorry, been with no connection...

wings absolutely exports OBJs with UVs :) Indeed, exports UVs in most formats supporting that. What is more, OBJ format handling improved vastly since the old bad days of it: today you only need to care not to leave open holes if want to import again into wings.
Finally making games again!
http://www.konekogames.com
vermeer
Posts: 2017
Joined: Wed Jan 21, 2004 3:22 pm
Contact:

Post by vermeer »

Sorry about getting your hopes up with the exporter,
It's my own bad: I get hopes high often, myself ;) (Which is not bad in every case ;) )
it seems it does the triangleation by itself so the meshes if complex end
Aha! That explains evrything.
up with diffrent edge and traingle orders, it also seems it was dropped for other bugs?
If was added to oficial releases, maybe the author did not end it, or found a bug he couldn't fix...
I dont fully understand the code of the old plugins, my mod works fine for some shapes but fails on cylinders in the same way you described.
I am a bit lost there... Well, you quite know better which is the best route to take... :)
Now good news...
And sound pretty good (I know, getting my hopes high again ;))
Anyway seems this has bothered people and a wings3d user moded the obj loader to take care of hard edges, (it makes them as creases though which work for subsurf only), so i added Sharp edges, it also adds a subsurf on the object but i left that as it is.
I think I made my tries on that one: usually aware on most things wings or blender related, but my tests failed in many ways, was unable to use that with success...and as sounded like the author was not going to continue, guessed the importer would stop working in future releases...

Heck, if you make this thing work correctly, I'll be sure (asking permission to you, only doing if you allow) to ask the only close to developers (never know who are really developes) that I have spoken to privately, to see if he can push to add it somehow to blender releases...I have a low percentage of chance to be heard, 'cause they decide I guess all in common, is a lot of people, have to many things going on, etc...
But would worth my try.

His exporter doesnt import uv's ill try and add that inf a few secs.
Amazing :shock:
Indeed...has a reason there's no UV import... I remember the guy and artwork..he made an extremely good model of a wolf metal (kind of head-mask) head, very detailed, he made the surface only with material and vetex colors, using lots of mesh detail...crazy workflow in general but very good solution for that model. As he used no uv textures, I guess didnt add them, but hard edges were important for him.
The factis, hard edge is a must for Blender if wanted to work in collaboration with other tools (modelers, uvmappers, etc) in a team with different pipelines. I mean, if things had some sense.. The OBJ importer improve you are making should be of the interest of devrs...
Hmmm his exporter only implements the .obj properties exported by wings, so it only loads wings objs and fails on others. I guess that would make adding uv's useless ince wings cant uv, and the exporter is wings only. Locking you to blender uving.
ehm...Nono...Wings has a great AutoUv, having LSCM auto mapping much before than Blender had it... It imports uv mapped models perfectly, exports uv mapped models in several formats, an I confirm OBJ has the i/o of UVs working.

What can be happening is that in that ascii format that OBj is, some slight details that some tools writein export, make other loaders don't understand it, but are often very simple things, like if no "o" (object) tags existes, or no s tags exists, or how many decimals are taking in account in the coords, or if works with smooth groups (s tag) , or vertex normals (vn, I think, and vt coords I think is how UV info is stored) , or both. Or if coords are negative or not for depending on some factors I don't know because I don't jknow programming. But what I am used to see, is that those issues are pretty faster fixed than in any other format...probably cause is not a very complex format...

In my tests, and teted quite, simply blender can't load hard edges from any OBJ of any tool, and that's a very big lowdown...I only can explain it for a combination of maybe it's a tool historically focused to work independently and have it all, besides hard edges have been looked at more indepth not so long ago... Remember Blender was initially hi res tool, mainly...in movies tools is more subdives and subdivision creases features, than lowpol accurateness tools...

It is so important for games... I'll be sure to contact someone if you fix it..But can only hope they hear me and add it to releases...

For now, I will check if the already made second script, will load obj with hard edges in blender 2.48a...

Imho is more important than perhaps they are thinking... because I have found, simply , none of the release included import formats, any that leaves you with a model i n the viewport that after some modifier adding, gives your hard worked hard edges...

One way or the other, many thanks, Omaremad; you are benefiting the wingers here, as for those loving it, and wanting to put animated models into irrlicht, have a quite powerful way doing the rig and anim stuff in blender... (and then export to x, b3d, etc...) But also ppl using it to import meshes into blender for levels for some feature neeed (wings->irrlicht should suffice for that, but it depends. )
Finally making games again!
http://www.konekogames.com
vermeer
Posts: 2017
Joined: Wed Jan 21, 2004 3:22 pm
Contact:

Post by vermeer »

last note: is thousands times better if you go the OBJ route. I am pretty sure the XSI exported , which I checked in my side have vertex normals pretty similar to wings and maya vertex normals (because campbell made support for importing smoothgroups, but I guess that only works with max and poser... I mean, not even just smooth groups, but of the kind of those two tools, I have some reason to suspect that...and probably is doing a very diferent thing, related to groups in blender, not handling really vertex normals) ..those xsi etc obj models will loose that info to.

Is better obj because then wont matter if is milkshape, xsi, maya, wings, whatever where the OBJ comes from, it wont loose hard edges with the help of the modifier added or whatever needed.

And with a character is quite a pain, but imagen a whole city with hand made hard edges...Or large assets done as obj in many other tools...just can't go adding those manually again... (not that I have "assets", just mentioning only some of the issues of that not being there...)
Finally making games again!
http://www.konekogames.com
vermeer
Posts: 2017
Joined: Wed Jan 21, 2004 3:22 pm
Contact:

Post by vermeer »

yehaw!

This works!

Imports a simple torus from wings (an obj)
it appears subdivided for the subdiv modifier you mentioned. I deactivate it (can delete it , no issues, even) ..I just go adding split edges modifier...set smooth button in general editing buttons...hard edges supported...

if Uvs+materials asigned (*.mtl info) added, way to perfection, but you did enough a lot already... heck, even if they don't add it to oficial, one could only leave the today's 2.48a oficial for conversions, lol...
Finally making games again!
http://www.konekogames.com
vermeer
Posts: 2017
Joined: Wed Jan 21, 2004 3:22 pm
Contact:

Post by vermeer »

uh...now no worky anymore, my bad surely...
it all time says (when just hitting the button that script generates to import an obj file)

Code: Select all

Compiled with Python version 2.5.2.
Checking for installed Python... got it!
Characters '*?:|"<>\/' are illegal in a filename.
Characters '*?:|"<>\/' are illegal in a filename.


Some issue with sth. But i have tested the things works :)
Finally making games again!
http://www.konekogames.com
vermeer
Posts: 2017
Joined: Wed Jan 21, 2004 3:22 pm
Contact:

Post by vermeer »

..problem probably triggered when importing by mental flaw of my self going to import obj in blender's file menu...is like it'd leave a permanent weird value in a file name variable..
Finally making games again!
http://www.konekogames.com
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Ok... i found out why my uv export code didnt work, wings doesnt export even empty uv's if there was no uvmapping done.


Vermeer if the exporter manages to import wings->ultimate unwrap objs, ill try and code the rest of the uv loader. Can you provide me with a uvmapped mesh? Wings3d uvmapping is very hard (lol im tooo addicted to blender)
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

Try this-

http://dump.bitplane.net/chair_external_image.zip

It has a UV map and also a mixture of hard and soft edges :)

higher quality diffuse:
Image
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Thanks Vermeer and bitplane, here is a present to you wings fans. UV AND SHARP export!

Code: Select all

#!BPY
 
"""
Name: 'Wavefront Wings3D (.obj)...'
Blender: 245
Group: 'Import'
Tooltip: 'Load a Wavefront OBJ File exported from Wings3D.'
"""

__author__= "Turbanov Vladislav"
__url__= ["vladius.fanatic.ru"]
__version__= "1.0"

__bpydoc__= """\
This script imports a Wavefront OBJ files to Blender that were exported from Wings3D(with creased edges).

Usage:
Run this script from "File->Import" menu and then load the desired OBJ file exported from Wings3D.
"""

from Blender import *
import BPyMesh
import BPyImage
import BPyMessages

try:		import os
except:		os = False

from sets import Set
from sets import ImmutableSet

def get_float_func(filepath):
	'''
	find the float function for this obj file
	- weather to replace commas or not
	'''
	file= open(filepath, 'r')
	for line in file.xreadlines():
		if line.startswith('v'): # vn vt v 
			if ',' in line:
				return lambda f: float(f.replace(',', '.'))
			elif '.' in line:
				return float

				
			
class OBJ_Vertex:
	x=0
	y=0
	z=0

	def __init__(self,x1,y1,z1):
		self.x=x1
		self.y=y1
		self.z=z1
	
	def dump(self):
		print 'x:%.4f y:%.4f z:%.4f' % (self.x, self.y, self.z)
	def getList(self):
		return [self.x,self.y,self.z]
			
class OBJ_Face:
	vertexIndexes=[]
	normalIndexes=[]
	uvIndexes=[]
	
	def __init__(self):
		self.vertexIndexes=[]
		self.normalIndexes=[]
		self.uvIndexes=[]
		
		
	def dump(self):
		i=0
		while i < len(self.vertexIndexes):
			print self.vertexIndexes[i],"//",self.normalIndexes[i]
			i+=1
			
	def getVertexList(self):
		list=[]
		for index in self.vertexIndexes:
			list.append(index)
		return list
			
class OBJ_Group:
	name=None
	faces=[]
	material=None
	def __init__(self):
		name=None
		self.faces=[]
		material=None
	
	def dump(self):
		print 'group %s; total faces: %i' % (self.name, len(self.faces))
		for face in self.faces:
			face.dump()
			
	def getFaceList(self):
		list=[]
		for face in self.faces:
			if (len(face.vertexIndexes)<=4):
				list.append(face.getVertexList())
		return list
		
	def getMaterials(self):
		list=[]
		for face in self.faces:
			if (len(face.vertexIndexes)<=4):
				list.append(self.material)
		return list
	
class OBJ_Object:
	offset=1
	name=None
	vertices=[]
	normals=[]
	uvs=[]
	groups=[]
	def __init__(self):
		name=None
		offset=1
		normalOffset=1
		self.vertices=[]
		self.normals=[]
		self.groups=[]
		
	def getCreasedEdges(self):
		edges={}
		creasedEdges=Set()
		vertDict={}
		
		# Create edges
		for group in self.groups:
			for face in group.faces:
				i=0
				while i < len(face.vertexIndexes):
					ni=(i+1)%len(face.vertexIndexes)
					vertexIndex=face.vertexIndexes[i]
					nextVertexIndex=face.vertexIndexes[ni]
					

					edge=ImmutableSet([vertexIndex-self.offset,nextVertexIndex-self.offset])
					if edge not in edges:
						if (vertexIndex<nextVertexIndex):
							edges[edge]=tuple([face.normalIndexes[i],face.normalIndexes[ni]])
						else:
							edges[edge]=tuple([face.normalIndexes[ni],face.normalIndexes[i]])
					else:
						normalIndexes=ImmutableSet([face.normalIndexes[i],face.normalIndexes[ni]])
						if len(Set(edges[edge]).union(normalIndexes))==4:
							# Now check if normals actually differ
							storedNormalIndexes=edges[edge]
							storedNormals=tuple([self.normals[storedNormalIndexes[0]-self.normalOffset],\
							                     self.normals[storedNormalIndexes[1]-self.normalOffset]])
							normals=None
							if (vertexIndex<nextVertexIndex):
								normals=tuple([self.normals[face.normalIndexes[i]-self.normalOffset], \
											self.normals[face.normalIndexes[ni]-self.normalOffset]])
							else:
								normals=tuple([self.normals[face.normalIndexes[ni]-self.normalOffset], \
											   self.normals[face.normalIndexes[i]-self.normalOffset]])
							
							
							
							if (storedNormals[0]!=normals[0]) or (storedNormals[1]!=normals[1]):
								creasedEdges.add(edge)
					i+=1
		#print edges
		creasedEdgesList=[]
		for edge in creasedEdges:
			creasedEdgesList.append(tuple(edge))
		
		return creasedEdgesList
		
						
		
	
	def dump(self):
		print "object %s" % self.name
		print "vertices:"
		for vertex in self.vertices:
			vertex.dump()
		print "groups:"
		for group in self.groups:
			group.dump()
			
	def getFaceList(self):
		list=[]
		for group in self.groups:
			list.extend(group.getFaceList())
		# Apply offset
		i=0
		while i < len(list):
			j=0
			while j < len(list[i]):
				list[i][j]-=self.offset
				j+=1
			i+=1
		return list
	
	def getMaterials(self):
		list=[]
		for group in self.groups:
			list.extend(group.getMaterials())
		return list
	
objects=[]
				
def load_obj(filepath):
	'''
	Called by the user interface or another script.
	load_obj(path) - should give acceptable results.
	This function passes the file and sends the data off
		to be split into objects and then converted into mesh objects
	'''
	print '\nimporting obj "%s"' % filepath
	
	time_main= sys.time()
	
	
	# Get the string to float conversion func for this file- is 'float' for almost all files.
	float_func= get_float_func(filepath)
	
	currentObject=None
	currentGroup=None
	currentOffset=1
	currentNormalOffset=1
	
	
	print '\tparsing obj file "%s"...' % filepath,
	time_sub= sys.time()
	file= open(filepath, 'r')
	for line in file.xreadlines():
	
		line_split=line.split()
		
		if line.startswith('v '):
			currentObject.vertices.append( OBJ_Vertex(float(line_split[1]),float(line_split[2]),float(line_split[3])) )
			currentOffset+=1
		elif line.startswith('vn '):
			currentObject.normals.append((float(line_split[1]),float(line_split[2]),float(line_split[3])))
			currentNormalOffset+=1
			pass
		
		elif line.startswith('vt '):
			currentObject.uvs.append((float(line_split[1]),float(line_split[2])))
			pass
		elif line.startswith('f'):
			face=OBJ_Face()
			
			for pair in line_split[1:]:
				
				indexes=pair.split("/")
			
				if indexes[1]:
					print indexes
					print indexes[0]
					print indexes[1]
					print indexes[2]
					print "end"
					face.uvIndexes.append(int(indexes[1]))
				else:
					face.uvIndexes.append(1)
				face.vertexIndexes.append(int(indexes[0]))
				face.normalIndexes.append(int(indexes[2]))
			currentGroup.faces.append(face)
			
		elif line.startswith('s'):
			pass
		
		elif line.startswith('o'):
			currentObject=OBJ_Object()
			objects.append(currentObject)
			currentObject.name=line_split[1]
			currentObject.offset=currentOffset
			currentObject.normalOffset=currentNormalOffset
			
			
			
		elif line.startswith('g'):
			currentGroup=OBJ_Group()
			currentGroup.name=line_split[1]
			currentObject.groups.append(currentGroup)
		
		elif line.startswith('usemtl'):
			currentGroup.material=line_split[1]
		elif line.startswith('mtllib'): # usemap or usemat
			pass
		
		''' # How to use usemap? depricated?
		elif line.startswith('usema'): # usemap or usemat
			context_image= line_value(line.split())
		'''
	
	file.close()
	time_new= sys.time()
	print '%.4f sec' % (time_new-time_sub)

	print 'Total objects: %i' % len(objects)
	#for object in objects:
	#	object.dump()
	
	# deselect all
	Scene.GetCurrent().objects.selected = []
	new_objects= [] # put new objects here
	scene= Scene.GetCurrent()
	
	materialNames=[]
	for material in Material.Get():
		materialNames.append(material.getName())
		
	objectNames={}
	for object in scene.objects:
		objectNames[object.getName()]=object
		
	for obj_object in objects:
		mesh= Mesh.New(obj_object.name+"_mesh")
		for obj_vert in obj_object.vertices:
			mesh.verts.extend([[obj_vert.x,obj_vert.y,obj_vert.z]])
		
		mesh.faces.extend(obj_object.getFaceList())
		mesh.faceUV=1
		fcount=0
		vcount=0
		for g in obj_object.groups:
			for f in mesh.faces:
				vcount=0
				for uvcoord in f.uv:
					
					flist=obj_object.getFaceList()
					indexx=g.faces[fcount].uvIndexes[vcount]-1
					indexy=g.faces[fcount].uvIndexes[vcount]
					
					uvcoord[0]=obj_object.uvs[indexx][0]
					uvcoord[1]=obj_object.uvs[indexx][1]
					vcount+=1
				fcount+=1
				
		obj_materials=obj_object.getMaterials()
		obj_materialDict={}
		currentMaterialID=0
		




		i=0
		for obj_material in obj_materials:
			mesh.faces[i].smooth=1
			if obj_material in obj_materialDict:
				mesh.faces[i].mat=obj_materialDict[obj_material]
			else:
				material=None
				if obj_material in materialNames:
					material=Material.Get(obj_material)
				else:
					material=Material.New(obj_material)
				mesh.materials+=[material]
				obj_materialDict[obj_material]=currentMaterialID
				mesh.faces[i].mat=currentMaterialID
				currentMaterialID+=1
			i+=1

		creasedEdges=obj_object.getCreasedEdges()
		
		if (len(creasedEdges)!=0):
			if (len(creasedEdges)==1):
				mesh.edges[mesh.findEdges(creasedEdges)].crease=255
				mesh.edges[edgeIndex].flag=Mesh.EdgeFlags.SHARP 
			else:
				for edgeIndex in mesh.findEdges(creasedEdges):
					if edgeIndex != None:
						mesh.edges[edgeIndex].crease=255
						mesh.edges[edgeIndex].flag=Mesh.EdgeFlags.SHARP 
				
		object=None
		if (obj_object.name in objectNames):
			scene.objects.unlink(objectNames[obj_object.name])
			
		object=Object.New('Mesh',obj_object.name)
		
		object.link(mesh)
		scene.objects.link(object)
		


def load_obj_ui(filepath, BATCH_LOAD= False):
	if BPyMessages.Error_NoFile(filepath):
		return

	Window.WaitCursor(1)

	load_obj(filepath)
	
	Window.WaitCursor(0)


def load_obj_ui_batch(file):
	load_obj_ui(file, True)


if __name__=='__main__':
	Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj')
EDIT:
as usual triangulate in wings before exporting, blender can turn them back into quads if you need to.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
Post Reply