#!BPY """ Registration info for Blender menus: <- these words are ignored Name: 'Google Map Model (KMZ/KML)' Blender: 241 Group: 'Import' Tip: 'Import a Google earth model' """ __author__ = "Jean-Michel Soler (jms)" __url__ = ("Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/py_import_kml-kmz.htm", "Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender") __version__ = "0.1.6, june, 05, 2006" __bpydoc__ = """\ To open .kmz file this script needs zipfile.py from the complete python """ # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # # Copyright (C) 2006: jm soler, jmsoler_at_free.fr # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # -------------------------------------------------------------------------- import Blender from Blender import Window import sys try: import nt os=nt os.sep='\\' except: import posix os=posix os.sep='/' def isdir(path): try: st = os.stat(path) return 1 except: return 0 def split(pathname): if pathname.find(os.sep)!=-1: k0=pathname.split(os.sep) else: if os.sep=='/': k0=pathname.split('\\') else: k0=pathname.split('/') directory=pathname.replace(k0[len(k0)-1],'') Name=k0[len(k0)-1] return directory, Name def join(l0,l1): return l0+os.sep+l1 os.isdir=isdir os.split=split os.join=join def fonctionSELECT(nom): scan_FILE(nom) def filtreFICHIER(nom): """ Function filtreFICHIER in : string nom , filename out : string t , if correct filecontaint """ if nom.upper().endswith('.KMZ'): from zipfile import ZipFile, ZIP_DEFLATED tz=ZipFile(nom,'r',ZIP_DEFLATED) t = tz.read(tz.namelist()[0]) tz.close() t=t.replace('
','') return t elif nom.upper().endswith('.KML')!=-1: tz=open(nom,'r') t = tz.read() tz.close() t=t.replace('
','') return t else: return None OB = None #Blender.Object.New('Mesh') # link mesh to an object SC = None #Blender.Scene.GetCurrent() # link object to current scene #SC.link(OB) ME= None#OB.getData(mesh=1) POLYGON_NUMBER= 0 DOCUMENTORIGINE= [] UPDATE_V= [] UPDATE_F= [] POS= 0 NUMBER= 0 PLACEMARK= 0 eps= 0.0000001 npoly= 0 gt1= Blender.sys.time() def cree_POLYGON(ME,TESSEL): global OB, npoly, UPDATE_V, UPDATE_F, POS npoly+=1 for T in TESSEL: del T[-1] if npoly %100 == 1 : print 'Pgon: ', npoly, 'verts:',[len(T) for T in TESSEL] if npoly %250 == 1 : #Blender.Window.Redraw(Blender.Window.Types.VIEW3D) #Blender.Window.RedrawAll() g2= Blender.sys.time()-gt1 print int(g2/60),':',int(g2%60) if len(TESSEL)==1 and len(TESSEL[0]) in (3,4): if UPDATE_F==[]: POS=len(ME.verts) #for VE in TESSEL[0]: # UPDATE_V.append(VE) UPDATE_V.extend(TESSEL[0]) if len(TESSEL[0])==3: UPDATE_F.append([POS,POS+1,POS+2]) POS+=3 else : UPDATE_F.append([POS,POS+1,POS+2,POS+3]) POS+=4 else : if len(UPDATE_V): ME.verts.extend(UPDATE_V) FACES=[] if UPDATE_F: for FE in UPDATE_F: if len(FE)==3: FACES.append([ME.verts[FE[0]],ME.verts[FE[1]],ME.verts[FE[2]]]) else: FACES.append([ME.verts[FE[0]],ME.verts[FE[1]],ME.verts[FE[2]],ME.verts[FE[3]]]) if FACES: ME.faces.extend(FACES) FACES=[] UPDATE_F=[] UPDATE_V=[] EDGES=[] for T in TESSEL: ME.verts.extend(T) for t in xrange(len(T),1,-1): ME.verts[-t].sel=1 EDGES.append([ME.verts[-t],ME.verts[-t+1]]) ME.verts[-1].sel=1 EDGES.append([ME.verts[-1],ME.verts[-len(T)]]) ME.edges.extend(EDGES) ME.fill() if npoly %500 == 1 : #for v in ME.verts: # v.sel=1 ME.sel= True ME.remDoubles(0.0) #for v in ME.verts: # v.sel=0 ME.sel= False def cree_FORME(v,TESSEL): if 1 : VE=[(v[0]-DOCUMENTORIGINE[0])* 85331.2, (v[1]-DOCUMENTORIGINE[1])* 110976.0, (v[2]-DOCUMENTORIGINE[2]) ] TESSEL.append(VE) #return TESSEL def active_FORME(): global ME, UPDATE_V, UPDATE_F, POS, OB if len(UPDATE_V)>2 : #print UPDATE_V ME.verts.extend(UPDATE_V) FACES=[] #print UPDATE_F, len(UPDATE_F) for FE in UPDATE_F: #print FE if len(FE)<4: FACES.append([ME.verts[FE[0]],ME.verts[FE[1]],ME.verts[FE[2]]]) else : FACES.append([ME.verts[FE[0]],ME.verts[FE[1]],ME.verts[FE[2]],ME.verts[FE[3]]]) #if len(ME.faces)%200==1 : print len(ME.faces) if FACES: ME.faces.extend(FACES) UPDATE_V=[] UPDATE_F=[] POS=0 if len(ME.verts)>0: for v in ME.verts: v.sel=1 ME.remDoubles(0.0) def wash_DATA(ndata): if ndata!='': ndata=ndata.replace('\n',',') ndata=ndata.replace('\r','') while ndata[-1]==' ': ndata=ndata.replace(' ',' ') while ndata[0]==' ': ndata=ndata[1:] while ndata[-1]==' ': ndata=ndata[:-1] if ndata[0]==',':ndata=ndata[1:] if ndata[-1]==',':ndata=ndata[:-1] ndata=ndata.replace(',,',',') ndata=ndata.replace(' ',',') ndata=ndata.split(',') for n in ndata : if n=='' : ndata.remove(n) return ndata def collecte_ATTRIBUTS(data): data=data.replace(' ',' ') ELEM={'TYPE':data[1:data.find(' ')]} t1=len(data) t2=0 ct=data.count('="') while ct>0: t0=data.find('="',t2) t2=data.find(' ',t2)+1 id=data[t2:t0] t2=data.find('"',t0+2) if id!='d': exec "ELEM[id]=\"\"\"%s\"\"\""%(data[t0+2:t2].replace('\\','/')) else: exec "ELEM[id]=[%s,%s]"%(t0+2,t2) ct=data.count('="',t2) return ELEM def contruit_HIERARCHIE(t): global DOCUMENTORIGINE, OB , ME, SC global NUMBER, PLACEMARK, POLYGON_NUMBER TESSEL=[] for OB in SC.getChildren(): OB.sel= False OB = Blender.Object.New('Mesh') SC.link(OB) ME= OB.getData(mesh=1) #[O.select(0) for O in Blender.Object.Get()] OB.select(1) t=t.replace('\t',' ') while t.find(' ')!=-1: t=t.replace(' ',' ') n0=0 t0=t1=0 baliste=[] balisetype=['?','?','/','/','!','!'] BALISES=[\ 'D', #DECL_TEXTE', 'D', #DECL_TEXTE', 'F', #FERMANTE', 'E', #ELEM_VIDE', 'd', #DOC', 'R', #REMARQUES', 'C', #CONTENU', 'O' #OUVRANTE' ] TAGS = ['kml','Document','description','DocumentSource', 'DocumentOrigin','visibility','LookAt', 'Folder','name','heading','tilt','latitude', 'longitude','range','Style','LineStyle','color', 'Placemark','styleUrl','GeometryCollection', 'Polygon','LinearRing','outerBoundaryIs', 'altitudeMode','coordinates','LineString', 'fill','PolyStyle','outline','innerBoundaryIs', 'IconStyle', 'Icon', 'x','y' ,'w','href','h' ] STACK=[] latitude = float(t[t.find('')+len(''):t.find('')]) longitude = float(t[t.find('')+len(''):t.find('')]) DOCUMENTORIGINE=[longitude,latitude,0 ] GETMAT=0 MATERIALS=[M.getName() for M in Blender.Material.Get()] while t1-1 : t0=t.find('<',t0) t1=t.find('>',t0) ouvrante=0 if t0>-1 and t1>-1: if t[t0+1] in balisetype: b=balisetype.index(t[t0+1]) if t[t0+2]=='-': b=balisetype.index(t[t0+1])+1 balise=BALISES[b] #print STACK if b==2 and t[t0:t1].find(STACK[-1])>-1: parent=STACK.pop(-1) elif t[t1-1] in balisetype: balise=BALISES[balisetype.index(t[t1-1])+1] else: t2=t.find(' ',t0) if t2>t1: t2=t1 ouvrante=1 NOM=t[t0+1:t2] if t.find('-1: balise=BALISES[-1] else: balise=BALISES[-2] if balise=='E' or balise=='O': if NOM not in TAGS : if NOM not in ['a','b','table','tr','td','div','hr']: TAGS.append(NOM) else : t0=t.find('',t0) if t0==-1 and t1==-1: break if balise=='O' and NOM in TAGS: STACK.append(NOM) if not PLACEMARK : if NOM.startswith('Style'): proprietes=collecte_ATTRIBUTS(t[t0:t1+ouvrante]) if NOM.startswith('PolyStyle'): GETMAT=1 if NOM.startswith('color') and GETMAT: COLOR=t[t2+1:t.find('-1: VAL=t[t2+2:t.find('')+VAL.count('') if NUMBER and NOM.find('Placemark')>-1 : PLACEMARK=1 if t[t2:t.find('-1 and ME.verts: active_FORME() OB.select(0) #[O.select(0) for O in Blender.Object.Get()] OB = Blender.Object.New('Mesh') # link mesh to an object SC = Blender.Scene.GetCurrent() # link object to current scene SC.link(OB) ME=OB.getData(mesh=1) OB.select(1) if NOM.find('styleUrl')>-1: material= t[t2+2:t.find('-1: VAL=t[t2+2:t.find('') print 'Number of Placemark : ', PLACEMARK_NUMBER if PLACEMARK_NUMBER != POLYGON_NUMBER : NUMBER= 1 PLACEMARK= 0 if t!='false': contruit_HIERARCHIE(t) active_FORME() gt2=Blender.sys.time()-gt1 print int(gt2/60),':',int(gt2%60) Blender.Window.FileSelector (fonctionSELECT, 'SELECT a .KMZ FILE')