diff options
Diffstat (limited to 'Virtools')
-rw-r--r-- | Virtools/3dxml.py | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/Virtools/3dxml.py b/Virtools/3dxml.py index 149d9c6..a72cf54 100644 --- a/Virtools/3dxml.py +++ b/Virtools/3dxml.py @@ -5,7 +5,7 @@ bl_info={ "description":"Import 3D XML 3.0", "author":"Chris Xiong", "version":(0,1), - "blender":(2,79,0), + "blender":(2,82,0), "category":"Import-Export", "support":"TESTING" } @@ -36,7 +36,7 @@ bl_info={ ################################################################ import bpy,bmesh,bpy_extras,mathutils import xml.etree.ElementTree as etree -import pathlib,zipfile,time,os,tempfile +import pathlib,zipfile,time,os,tempfile,math NS="{http://www.3ds.com/xsd/3DXML}" @@ -56,11 +56,11 @@ def load_textures(tree): txp=[] if txd.is_dir(): txp=[i for i in txd.iterdir() if i.stem.lower()==txname.lower()] - if len(txp)<1 and tex.attrib["href"] is not None: + if len(txp)<1 and tex.attrib["href"] is not None and tex.attrib["href"] in texturefiles: txp=[texturefiles[tex.attrib["href"]]] - tx=bpy.data.textures.new(txname,'IMAGE') + tx=None try: - tx.image=bpy.data.images.load(str(txp[0]),True) + tx=bpy.data.images.load(str(txp[0]),check_existing=True) except IndexError: print(txname) textures[tex.attrib["id"]]=tx @@ -69,15 +69,20 @@ def load_materials(tree): for mat in tree.findall(f".//{NS}GraphicMaterial"): mname=mat.attrib["name"] m=bpy.data.materials.new(mname) - mslot=m.texture_slots.add() + m.use_nodes=True + for node in m.node_tree.nodes: + m.node_tree.nodes.remove(node) + bnode=m.node_tree.nodes.new(type="ShaderNodeBsdfPrincipled") + inode=m.node_tree.nodes.new(type="ShaderNodeTexImage") + mnode=m.node_tree.nodes.new(type="ShaderNodeOutputMaterial") try: - mslot.texture=textures[mat.attrib["texture"].split(":")[-1]] + inode.image=textures[mat.attrib["texture"].split(":")[-1]] except KeyError: pass - m.diffuse_color=[float(mat.find(f"{NS}Diffuse").attrib[i])for i in ["red","green","blue"]] - m.diffuse_intensity=float(mat.attrib["diffuseCoef"]) + m.node_tree.links.new(inode.outputs[0],bnode.inputs[0]) + m.node_tree.links.new(bnode.outputs[0],mnode.inputs[0]) + m.diffuse_color=[float(mat.find(f"{NS}Diffuse").attrib[i])for i in ["red","green","blue"]]+[float(mat.attrib["diffuseCoef"])] m.specular_color=[float(mat.find(f"{NS}Specular").attrib[i])for i in ["red","green","blue"]] - m.specular_alpha=float(mat.find(f"{NS}Specular").attrib["alpha"]) m.specular_intensity=float(mat.attrib["specularCoef"]) materials[mat.attrib["id"]]=m @@ -85,6 +90,7 @@ def load_meshes(tree): for rep in tree.findall(f".//{NS}Representation"): rid=rep.attrib["id"] verts=unflatten(rep.find(f".//{NS}Positions").text,float,3,unitfactor) + normals=unflatten(rep.find(f".//{NS}Normals").text,float,3) uvs=unflatten(rep.find(f".//{NS}TextureCoordinates").text,float,2) faces=[] facemat=[] @@ -111,15 +117,20 @@ def load_meshes(tree): faces.extend(unflatten(face.attrib["fans"],int,4)) facemat.extend([fmat]*len(unflatten(face.attrib["fans"],int,4))) meshmat[rid]=matslots - create_mesh(verts,faces,facemat,uvs,rid) + create_mesh(verts,faces,facemat,normals,uvs,rid) def load_objects(tree): rr=tree.findall(f".//{NS}ReferenceRep[@format='TESSELLATED']") - i3d=tree.findall(f".//{NS}Instance3D") + sr=set() + for ref in rr: + n=ref.attrib["name"] + sr.add(n[:n.rfind('_')]) + ti3d=tree.findall(f".//{NS}Instance3D") + i3d=[i3 for i3 in ti3d if i3.attrib["name"][:i3.attrib["name"].rfind('_')] in sr] for ref,i3 in zip(rr,i3d): meshid=ref.attrib["associatedFile"].split(":")[-1] objname=ref.attrib["name"] - objname=objname[0:objname.rfind('_')] + objname=objname[:objname.rfind('_')] mat=list(map(float,i3.find(f"./{NS}RelativeMatrix").text.split(' '))) obj=bpy.data.objects.new(objname,meshes[meshid]) _wmat=mathutils.Matrix() @@ -129,18 +140,19 @@ def load_objects(tree): obj.data.materials.append(materials[m]) obj.matrix_world=_wmat scn=bpy.context.scene - scn.objects.link(obj) - scn.objects.active=obj - obj.select=True - bpy.ops.object.shade_smooth() + scn.collection.objects.link(obj) + obj.select_set(True) -def create_mesh(verts,faces,facemat,uvs,meshidx): - if len(uvs)>len(verts): + bpy.ops.object.shade_smooth() + +def create_mesh(verts,faces,facemat,norms,uvs,meshidx): + if len(uvs)<len(verts): uvs.append([uvs[0]]*(len(verts)-len(uvs))) meshname=f"Mesh_{meshidx}" mesh=bmesh.new() - for i in verts: - mesh.verts.new(i) + for vert,norm in zip(verts,norms): + v=mesh.verts.new(vert) + v.normal=norm mesh.verts.ensure_lookup_table() mesh.verts.index_update() for i,m in zip(faces,facemat): @@ -155,8 +167,10 @@ def create_mesh(verts,faces,facemat,uvs,meshidx): for lp in face.loops: lp[uv].uv=mathutils.Vector(uvs[lp.vert.index]) msh=bpy.data.meshes.new(meshname) + if usesmooth: + msh.use_auto_smooth=True + msh.auto_smooth_angle=smoothangle mesh.to_mesh(msh) - msh.use_auto_smooth=True meshes[meshidx]=msh mesh.free() @@ -203,12 +217,16 @@ class ImportDialog(bpy.types.Operator,bpy_extras.io_utils.ImportHelper): filter_glob=bpy.props.StringProperty(default='*.3dxml',options={'HIDDEN'}) pt=bpy.props.StringProperty(name="Texture path",default=texdir) - uf=bpy.props.FloatProperty(name="Unit factor",default=unitfactor) + uf=bpy.props.FloatProperty(name="Unit factor",default=unitfactor,min=0) + us=bpy.props.BoolProperty(name="Use auto smooth instead of the normal data in the 3DXML file",default=False) + aa=bpy.props.FloatProperty(name="Auto smooth angle",min=0,max=180,default=90) def execute(self,context): - global texdir,unitfactor + global texdir,unitfactor,usesmooth,smoothangle texdir=self.pt unitfactor=self.uf + usesmooth=self.us + smoothangle=self.aa/180*math.pi read(self.filepath) return {'FINISHED'} @@ -229,11 +247,11 @@ def menu_func_import_tdxml(self,context): def register(): bpy.utils.register_class(ImportDialog) bpy.utils.register_class(_3DXMLImport) - bpy.types.INFO_MT_file_import.append(menu_func_import_tdxml) + bpy.types.TOPBAR_MT_file_import.append(menu_func_import_tdxml) def unregister(): bpy.utils.unregister_class(_3DXMLImport) - bpy.utils.unregister_class(ImportDialog) + bpy.utils.unrigister_class(ImportDialog) if __name__=="__main__": register() |