JMS Updates the script, and I did some fixes too. now works with more models.
This commit is contained in:
@@ -1,15 +1,16 @@
|
|||||||
#!BPY
|
#!BPY
|
||||||
|
|
||||||
""" Registration info for Blender menus: <- these words are ignored
|
""" Registration info for Blender menus: <- these words are ignored
|
||||||
Name: 'Google Map Model (KMZ/KML)'
|
Name: 'Google Map Model (KMZ/KML)'
|
||||||
Blender: 241
|
Blender: 241
|
||||||
Group: 'Import'
|
Group: 'Import'
|
||||||
Tip: 'Import Google earth models'
|
Tip: 'Import a Google earth model'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = "Jean-Michel Soler (jms)"
|
__author__ = "Jean-Michel Soler (jms)"
|
||||||
__url__ = ("Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/py_import_kml-kmz.htm",
|
__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")
|
"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
|
||||||
__version__ = "0.1.5, june, 04, 2006"
|
__version__ = "0.1.6, june, 05, 2006"
|
||||||
|
|
||||||
__bpydoc__ = """\
|
__bpydoc__ = """\
|
||||||
To open .kmz file this script needs zipfile.py from the complete python
|
To open .kmz file this script needs zipfile.py from the complete python
|
||||||
@@ -35,13 +36,30 @@ __bpydoc__ = """\
|
|||||||
|
|
||||||
import Blender
|
import Blender
|
||||||
from Blender import Window
|
from Blender import Window
|
||||||
from Blender import Mathutils
|
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):
|
def split(pathname):
|
||||||
if pathname.find(Blender.sys.sep)!=-1:
|
if pathname.find(os.sep)!=-1:
|
||||||
k0=pathname.split(Blender.sys.sep)
|
k0=pathname.split(os.sep)
|
||||||
else:
|
else:
|
||||||
if Blender.sys.sep=='/':
|
if os.sep=='/':
|
||||||
k0=pathname.split('\\')
|
k0=pathname.split('\\')
|
||||||
else:
|
else:
|
||||||
k0=pathname.split('/')
|
k0=pathname.split('/')
|
||||||
@@ -51,7 +69,11 @@ def split(pathname):
|
|||||||
return directory, Name
|
return directory, Name
|
||||||
|
|
||||||
def join(l0,l1):
|
def join(l0,l1):
|
||||||
return l0+Blender.sys.sep+l1
|
return l0+os.sep+l1
|
||||||
|
|
||||||
|
os.isdir=isdir
|
||||||
|
os.split=split
|
||||||
|
os.join=join
|
||||||
|
|
||||||
def fonctionSELECT(nom):
|
def fonctionSELECT(nom):
|
||||||
scan_FILE(nom)
|
scan_FILE(nom)
|
||||||
@@ -62,16 +84,18 @@ def filtreFICHIER(nom):
|
|||||||
in : string nom , filename
|
in : string nom , filename
|
||||||
out : string t , if correct filecontaint
|
out : string t , if correct filecontaint
|
||||||
"""
|
"""
|
||||||
if nom.upper().find('.KMZ')!=-1:
|
if nom.upper().endswith('.KMZ'):
|
||||||
from zipfile import ZipFile, ZIP_DEFLATED
|
from zipfile import ZipFile, ZIP_DEFLATED
|
||||||
tz=ZipFile(nom,'r',ZIP_DEFLATED)
|
tz=ZipFile(nom,'r',ZIP_DEFLATED)
|
||||||
t = tz.read(tz.namelist()[0])
|
t = tz.read(tz.namelist()[0])
|
||||||
tz.close()
|
tz.close()
|
||||||
|
t=t.replace('<br>','')
|
||||||
return t
|
return t
|
||||||
elif nom.upper().find('.KML')!=-1:
|
elif nom.upper().endswith('.KML')!=-1:
|
||||||
tz=open(nom,'r')
|
tz=open(nom,'r')
|
||||||
t = tz.read()
|
t = tz.read()
|
||||||
tz.close()
|
tz.close()
|
||||||
|
t=t.replace('<br>','')
|
||||||
return t
|
return t
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
@@ -81,7 +105,7 @@ SC = None #Blender.Scene.GetCurrent() # link object to current scene
|
|||||||
#SC.link(OB)
|
#SC.link(OB)
|
||||||
ME= None#OB.getData(mesh=1)
|
ME= None#OB.getData(mesh=1)
|
||||||
|
|
||||||
|
POLYGON_NUMBER= 0
|
||||||
DOCUMENTORIGINE= []
|
DOCUMENTORIGINE= []
|
||||||
UPDATE_V= []
|
UPDATE_V= []
|
||||||
UPDATE_F= []
|
UPDATE_F= []
|
||||||
@@ -101,14 +125,16 @@ def cree_POLYGON(ME,TESSEL):
|
|||||||
print 'Pgon: ', npoly, 'verts:',[len(T) for T in TESSEL]
|
print 'Pgon: ', npoly, 'verts:',[len(T) for T in TESSEL]
|
||||||
|
|
||||||
if npoly %250 == 1 :
|
if npoly %250 == 1 :
|
||||||
Blender.Window.RedrawAll()
|
#Blender.Window.Redraw(Blender.Window.Types.VIEW3D) #Blender.Window.RedrawAll()
|
||||||
g2= Blender.sys.time()-gt1
|
g2= Blender.sys.time()-gt1
|
||||||
print int(g2/60),':',int(g2%60)
|
print int(g2/60),':',int(g2%60)
|
||||||
|
|
||||||
if len(TESSEL)==1 and len(TESSEL[0]) in [3,4] :
|
if len(TESSEL)==1 and len(TESSEL[0]) in (3,4):
|
||||||
if UPDATE_F==[]:
|
if UPDATE_F==[]:
|
||||||
POS=len(ME.verts)
|
POS=len(ME.verts)
|
||||||
|
|
||||||
|
#for VE in TESSEL[0]:
|
||||||
|
# UPDATE_V.append(VE)
|
||||||
UPDATE_V.extend(TESSEL[0])
|
UPDATE_V.extend(TESSEL[0])
|
||||||
|
|
||||||
if len(TESSEL[0])==3:
|
if len(TESSEL[0])==3:
|
||||||
@@ -118,7 +144,7 @@ def cree_POLYGON(ME,TESSEL):
|
|||||||
UPDATE_F.append([POS,POS+1,POS+2,POS+3])
|
UPDATE_F.append([POS,POS+1,POS+2,POS+3])
|
||||||
POS+=4
|
POS+=4
|
||||||
else :
|
else :
|
||||||
if UPDATE_V: ME.verts.extend(UPDATE_V)
|
if len(UPDATE_V): ME.verts.extend(UPDATE_V)
|
||||||
FACES=[]
|
FACES=[]
|
||||||
if UPDATE_F:
|
if UPDATE_F:
|
||||||
for FE in UPDATE_F:
|
for FE in UPDATE_F:
|
||||||
@@ -145,9 +171,13 @@ def cree_POLYGON(ME,TESSEL):
|
|||||||
ME.edges.extend(EDGES)
|
ME.edges.extend(EDGES)
|
||||||
ME.fill()
|
ME.fill()
|
||||||
if npoly %500 == 1 :
|
if npoly %500 == 1 :
|
||||||
|
#for v in ME.verts:
|
||||||
|
# v.sel=1
|
||||||
ME.sel= True
|
ME.sel= True
|
||||||
ME.remDoubles(0.0)
|
ME.remDoubles(0.0)
|
||||||
|
|
||||||
|
#for v in ME.verts:
|
||||||
|
# v.sel=0
|
||||||
ME.sel= False
|
ME.sel= False
|
||||||
|
|
||||||
def cree_FORME(v,TESSEL):
|
def cree_FORME(v,TESSEL):
|
||||||
@@ -178,8 +208,9 @@ def active_FORME():
|
|||||||
UPDATE_F=[]
|
UPDATE_F=[]
|
||||||
POS=0
|
POS=0
|
||||||
|
|
||||||
if ME.verts:
|
if len(ME.verts)>0:
|
||||||
ME.sel= True
|
for v in ME.verts:
|
||||||
|
v.sel=1
|
||||||
ME.remDoubles(0.0)
|
ME.remDoubles(0.0)
|
||||||
|
|
||||||
def wash_DATA(ndata):
|
def wash_DATA(ndata):
|
||||||
@@ -192,8 +223,8 @@ def wash_DATA(ndata):
|
|||||||
ndata=ndata[1:]
|
ndata=ndata[1:]
|
||||||
while ndata[-1]==' ':
|
while ndata[-1]==' ':
|
||||||
ndata=ndata[:-1]
|
ndata=ndata[:-1]
|
||||||
if ndata[0]==',':ndata.pop(0)
|
if ndata[0]==',':ndata=ndata[1:]
|
||||||
if ndata[-1]==',':ndata.pop()
|
if ndata[-1]==',':ndata=ndata[:-1]
|
||||||
ndata=ndata.replace(',,',',')
|
ndata=ndata.replace(',,',',')
|
||||||
ndata=ndata.replace(' ',',')
|
ndata=ndata.replace(' ',',')
|
||||||
ndata=ndata.split(',')
|
ndata=ndata.split(',')
|
||||||
@@ -221,15 +252,15 @@ def collecte_ATTRIBUTS(data):
|
|||||||
|
|
||||||
def contruit_HIERARCHIE(t):
|
def contruit_HIERARCHIE(t):
|
||||||
global DOCUMENTORIGINE, OB , ME, SC
|
global DOCUMENTORIGINE, OB , ME, SC
|
||||||
global NUMBER, PLACEMARK
|
global NUMBER, PLACEMARK, POLYGON_NUMBER
|
||||||
vv=[]
|
|
||||||
TESSEL=[]
|
TESSEL=[]
|
||||||
# De select all
|
for OB in SC.getChildren(): OB.sel= False
|
||||||
for O in SC.getChildren(): O.sel= False
|
|
||||||
OB = Blender.Object.New('Mesh')
|
OB = Blender.Object.New('Mesh')
|
||||||
SC.link(OB)
|
SC.link(OB)
|
||||||
ME= OB.getData(mesh=1)
|
ME= OB.getData(mesh=1)
|
||||||
OB.sel= True
|
#[O.select(0) for O in Blender.Object.Get()]
|
||||||
|
OB.select(1)
|
||||||
|
|
||||||
t=t.replace('\t',' ')
|
t=t.replace('\t',' ')
|
||||||
while t.find(' ')!=-1:
|
while t.find(' ')!=-1:
|
||||||
@@ -238,7 +269,8 @@ def contruit_HIERARCHIE(t):
|
|||||||
t0=t1=0
|
t0=t1=0
|
||||||
baliste=[]
|
baliste=[]
|
||||||
balisetype=['?','?','/','/','!','!']
|
balisetype=['?','?','/','/','!','!']
|
||||||
BALISES=['D', #DECL_TEXTE',
|
BALISES=[\
|
||||||
|
'D', #DECL_TEXTE',
|
||||||
'D', #DECL_TEXTE',
|
'D', #DECL_TEXTE',
|
||||||
'F', #FERMANTE',
|
'F', #FERMANTE',
|
||||||
'E', #ELEM_VIDE',
|
'E', #ELEM_VIDE',
|
||||||
@@ -276,20 +308,9 @@ def contruit_HIERARCHIE(t):
|
|||||||
if t[t0+2]=='-':
|
if t[t0+2]=='-':
|
||||||
b=balisetype.index(t[t0+1])+1
|
b=balisetype.index(t[t0+1])+1
|
||||||
balise=BALISES[b]
|
balise=BALISES[b]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# FIXME - JMS WHY IS STACK[-1] None Sometimes?
|
|
||||||
try:
|
|
||||||
if b==2 and t[t0:t1].find(STACK[-1])>-1:
|
|
||||||
parent=STACK.pop()
|
|
||||||
except:
|
|
||||||
#print 'ERROR'
|
|
||||||
#print b
|
|
||||||
#print STACK
|
#print STACK
|
||||||
#raise "Error"
|
if b==2 and t[t0:t1].find(STACK[-1])>-1:
|
||||||
STACK.pop() # Remove the None value
|
parent=STACK.pop(-1)
|
||||||
|
|
||||||
elif t[t1-1] in balisetype:
|
elif t[t1-1] in balisetype:
|
||||||
balise=BALISES[balisetype.index(t[t1-1])+1]
|
balise=BALISES[balisetype.index(t[t1-1])+1]
|
||||||
else:
|
else:
|
||||||
@@ -302,21 +323,27 @@ def contruit_HIERARCHIE(t):
|
|||||||
else:
|
else:
|
||||||
balise=BALISES[-2]
|
balise=BALISES[-2]
|
||||||
if balise=='E' or balise=='O':
|
if balise=='E' or balise=='O':
|
||||||
if NOM not in TAGS and NOM!='a':
|
if NOM not in TAGS :
|
||||||
|
if NOM not in ['a','b','table','tr','td','div','hr']:
|
||||||
TAGS.append(NOM)
|
TAGS.append(NOM)
|
||||||
|
else :
|
||||||
|
t0=t.find('</'+NOM,t0)
|
||||||
|
t1=t.find('>',t0)
|
||||||
|
if t0==-1 and t1==-1:
|
||||||
|
break
|
||||||
if balise=='O' and NOM in TAGS:
|
if balise=='O' and NOM in TAGS:
|
||||||
STACK.append(NOM)
|
STACK.append(NOM)
|
||||||
if not PLACEMARK :
|
if not PLACEMARK :
|
||||||
if NOM.startswith('Style'):
|
if NOM.startswith('Style'):
|
||||||
proprietes=collecte_ATTRIBUTS(t[t0:t1+ouvrante])
|
proprietes=collecte_ATTRIBUTS(t[t0:t1+ouvrante])
|
||||||
elif NOM.startswith('PolyStyle'):
|
if NOM.startswith('PolyStyle'):
|
||||||
GETMAT=1
|
GETMAT=1
|
||||||
elif NOM.startswith('color') and GETMAT:
|
if NOM.startswith('color') and GETMAT:
|
||||||
COLOR=t[t2+1:t.find('</color',t2)]
|
COLOR=t[t2+1:t.find('</color',t2)]
|
||||||
print COLOR
|
#print COLOR
|
||||||
COLOR=[eval('0x'+COLOR[0:2]), eval('0x'+COLOR[2:4]), eval('0x'+COLOR[4:6]), eval('0x'+COLOR[6:])]
|
COLOR=[eval('0x'+COLOR[0:2]), eval('0x'+COLOR[2:4]), eval('0x'+COLOR[4:6]), eval('0x'+COLOR[6:])]
|
||||||
print COLOR
|
#print COLOR
|
||||||
if 'id' in proprietes.keys() and proprietes['id'] not in MATERIALS:
|
if 'id' in proprietes.iterkeys() and proprietes['id'] not in MATERIALS:
|
||||||
MAT=Blender.Material.New(proprietes['id'])
|
MAT=Blender.Material.New(proprietes['id'])
|
||||||
MAT.rgbCol = [COLOR[3]/255.0,COLOR[2]/255.0,COLOR[1]/255.0]
|
MAT.rgbCol = [COLOR[3]/255.0,COLOR[2]/255.0,COLOR[1]/255.0]
|
||||||
MAT.setAlpha(COLOR[0]/255.0)
|
MAT.setAlpha(COLOR[0]/255.0)
|
||||||
@@ -324,18 +351,21 @@ def contruit_HIERARCHIE(t):
|
|||||||
GETMAT=0
|
GETMAT=0
|
||||||
if NOM.find('Polygon')>-1:
|
if NOM.find('Polygon')>-1:
|
||||||
VAL=t[t2+2:t.find('</Polygon',t2)]
|
VAL=t[t2+2:t.find('</Polygon',t2)]
|
||||||
|
#POLYGON_NUMBER-=1
|
||||||
|
#if POLYGON_NUMBER<10 :
|
||||||
|
# print STACK
|
||||||
n=VAL.count('<outerBoundaryIs>')+VAL.count('<innerBoundaryIs>')
|
n=VAL.count('<outerBoundaryIs>')+VAL.count('<innerBoundaryIs>')
|
||||||
if NUMBER and NOM.find('Placemark')>-1 :
|
if NUMBER and NOM.find('Placemark')>-1 :
|
||||||
PLACEMARK=1
|
PLACEMARK=1
|
||||||
if t[t2:t.find('</Placemark',t2)].find('Polygon')>-1 and len(ME.verts)>0:
|
if t[t2:t.find('</Placemark',t2)].find('Polygon')>-1 and ME.verts:
|
||||||
active_FORME()
|
active_FORME()
|
||||||
OB.sel= False
|
OB.select(0)
|
||||||
#[O.select(0) for O in Blender.Object.Get()]
|
#[O.select(0) for O in Blender.Object.Get()]
|
||||||
OB = Blender.Object.New('Mesh') # link mesh to an object
|
OB = Blender.Object.New('Mesh') # link mesh to an object
|
||||||
SC = Blender.Scene.GetCurrent() # link object to current scene
|
SC = Blender.Scene.GetCurrent() # link object to current scene
|
||||||
SC.link(OB)
|
SC.link(OB)
|
||||||
ME=OB.getData(mesh=1)
|
ME=OB.getData(mesh=1)
|
||||||
OB.sel= True
|
OB.select(1)
|
||||||
if NOM.find('styleUrl')>-1:
|
if NOM.find('styleUrl')>-1:
|
||||||
material= t[t2+2:t.find('</styleUrl',t2)]
|
material= t[t2+2:t.find('</styleUrl',t2)]
|
||||||
if material in MATERIALS :
|
if material in MATERIALS :
|
||||||
@@ -348,15 +378,15 @@ def contruit_HIERARCHIE(t):
|
|||||||
n-=1
|
n-=1
|
||||||
TESSEL.append([])
|
TESSEL.append([])
|
||||||
VAL=wash_DATA(VAL)
|
VAL=wash_DATA(VAL)
|
||||||
vv=[[float(VAL[a+ii]) for ii in xrange(3)] for a in xrange(0,len(VAL),3)]
|
for a in xrange(0,len(VAL),3):
|
||||||
if vv: [cree_FORME(v,TESSEL[-1]) for v in vv]
|
cree_FORME([float(VAL[a]), float(VAL[a+1]), float(VAL[a+2])], TESSEL[-1])
|
||||||
|
|
||||||
del VAL
|
del VAL
|
||||||
if n==0:
|
if n==0:
|
||||||
cree_POLYGON(ME,TESSEL)
|
cree_POLYGON(ME,TESSEL)
|
||||||
TESSEL= []
|
TESSEL= []
|
||||||
|
#elif balise=='O' :
|
||||||
elif balise=='O' :
|
# STACK.append('None')
|
||||||
STACK.append(None)
|
|
||||||
D=[]
|
D=[]
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
@@ -364,7 +394,7 @@ def contruit_HIERARCHIE(t):
|
|||||||
t0= t1
|
t0= t1
|
||||||
|
|
||||||
def scan_FILE(nom):
|
def scan_FILE(nom):
|
||||||
global NUMBER, PLACEMARK, SC, OB, ME
|
global NUMBER, PLACEMARK, SC, OB, ME, POLYGON_NUMBER
|
||||||
|
|
||||||
dir,name= split(nom)
|
dir,name= split(nom)
|
||||||
name= name.split('.')
|
name= name.split('.')
|
||||||
@@ -379,7 +409,7 @@ def scan_FILE(nom):
|
|||||||
print '# Sorry the script can\'t find any geometry in this'
|
print '# Sorry the script can\'t find any geometry in this'
|
||||||
print '# file .'
|
print '# file .'
|
||||||
print '#----------------------------------------------'
|
print '#----------------------------------------------'
|
||||||
Blender.Window.RedrawAll()
|
#Blender.Window.RedrawAll()
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
|
||||||
@@ -396,5 +426,4 @@ def scan_FILE(nom):
|
|||||||
gt2=Blender.sys.time()-gt1
|
gt2=Blender.sys.time()-gt1
|
||||||
print int(gt2/60),':',int(gt2%60)
|
print int(gt2/60),':',int(gt2%60)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
Blender.Window.FileSelector (fonctionSELECT, 'SELECT a .KMZ FILE')
|
Blender.Window.FileSelector (fonctionSELECT, 'SELECT a .KMZ FILE')
|
||||||
Reference in New Issue
Block a user