您当前的位置: 首页 > 
  • 3浏览

    0关注

    157博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

BlenderGIS 2.2.6导入数据NoneType 解决

牙膏上的小苏打2333 发布时间:2022-05-22 19:47:00 ,浏览量:3

BlenderGIS
  • 🎃问题描述
  • 🎳解决方案

🎃问题描述

🎈在BlenderGIS中导入tif、png、jpg等格式的数据时会有报错的情况发生,如果遇到了以下情况可以按本文的方案修改~

在这里插入图片描述

🎳解决方案

按提示的路径打开对应的脚本(推荐用VS Code) 在这里插入图片描述 🎁 用一下内容覆盖保存后重启Blender即可!

# -*- coding:utf-8 -*-

# This file is part of BlenderGIS

#  ***** GPL LICENSE BLOCK *****
#
#  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 3 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, see .
#  All rights reserved.
#  ***** GPL LICENSE BLOCK *****

import os
import numpy as np
import bpy, bmesh
import math

import logging
log = logging.getLogger(__name__)

from ...core.georaster import GeoRaster


def _exportAsMesh(georaster, dx=0, dy=0, step=1, buildFaces=True, flat=False, subset=False, reproj=None):
	'''Numpy test'''

	if subset and georaster.subBoxGeo is None:
		subset = False

	if not subset:
		georef = georaster.georef
	else:
		georef = georaster.getSubBoxGeoRef()

	x0, y0 = georef.origin #pxcenter
	pxSizeX, pxSizeY = georef.pxSize.x, georef.pxSize.y
	w, h = georef.rSize.x, georef.rSize.y

	#adjust against step
	w, h = math.ceil(w/step), math.ceil(h/step)
	pxSizeX, pxSizeY = pxSizeX * step, pxSizeY * step

	x = np.array([(x0 + (pxSizeX * i)) - dx for i in range(0, w)])
	y = np.array([(y0 + (pxSizeY * i)) - dy for i in range(0, h)])
	xx, yy = np.meshgrid(x, y)
	#TODO reproj

	if flat:
		zz = np.zeros((h, w))
	else:
		zz = georaster.readAsNpArray(subset=subset).data[::step,::step] #TODO raise error if multiband

	verts = np.column_stack((xx.ravel(), yy.ravel(), zz.ravel()))
	if buildFaces:
		faces = [(x+y*w, x+y*w+1, x+y*w+1+w, x+y*w+w) for x in range(0, w-1) for y in range(0, h-1)]
	else:
		faces = []
	mesh = bpy.data.meshes.new("DEM")
	mesh.from_pydata(verts, [], faces)
	mesh.update()
	return mesh


def exportAsMesh(georaster, dx=0, dy=0, step=1, buildFaces=True, subset=False, reproj=None, flat=False):
	if subset and georaster.subBoxGeo is None:
		subset = False

	if not subset:
		georef = georaster.georef
	else:
		georef = georaster.getSubBoxGeoRef()

	if not flat:
		img = georaster.readAsNpArray(subset=subset)
		#TODO raise error if multiband
		data = img.data

	x0, y0 = georef.origin #pxcenter
	pxSizeX, pxSizeY = georef.pxSize.x, georef.pxSize.y
	w, h = georef.rSize.x, georef.rSize.y

	#Build the mesh (Note : avoid using bmesh because it's very slow with large mesh, use from_pydata instead)
	verts = []
	faces = []
	nodata = []
	idxMap = {}
	for py in range(0, h, step):
		for px in range(0, w, step):
			x = x0 + (pxSizeX * px)
			y = y0 + (pxSizeY * py)

			if reproj is not None:
				x, y = reproj.pt(x, y)

			#shift
			x -= dx
			y -= dy

			if flat:
				z = 0
			else:
				z = data[py, px]

			#vertex index
			v1 = px + py * w #bottom right

			#Filter nodata
			if z == georaster.noData:
				nodata.append(v1)
			else:
				verts.append((x, y, z))
				idxMap[v1] = len(verts) - 1

				#build face from bottomright to topright (using only points already created)
				if buildFaces and px > 0 and py > 0: #filter first row and column
					v2 = v1 - step #bottom left
					v3 = v2 - w * step #topleft
					v4 = v3 + step #topright
					f = [v4, v3, v2, v1] #anticlockwise --> face up
					if not any(v in f for v in nodata): #TODO too slow ?
						f = [idxMap[v] for v in f]
						faces.append(f)

	mesh = bpy.data.meshes.new("DEM")
	mesh.from_pydata(verts, [], faces)
	mesh.update()

	return mesh


def rasterExtentToMesh(name, rast, dx, dy, pxLoc='CORNER', reproj=None, subdivise=False):
	'''Build a new mesh that represent a georaster extent'''
	#create mesh
	bm = bmesh.new()
	if pxLoc == 'CORNER':
		pts = [(pt[0], pt[1]) for pt in rast.corners]#shift coords
	elif pxLoc == 'CENTER':
		pts = [(pt[0], pt[1]) for pt in rast.cornersCenter]
	#Reprojection
	if reproj is not None:
		pts = reproj.pts(pts)
	#build shifted flat 3d vertices
	pts = [bm.verts.new((pt[0]-dx, pt[1]-dy, 0)) for pt in pts]#upper left to botton left (clockwise)
	pts.reverse()#bottom left to upper left (anticlockwise --> face up)
	bm.faces.new(pts)
	#Create mesh from bmesh
	mesh = bpy.data.meshes.new(name)
	bm.to_mesh(mesh)
	bm.free()
	return mesh

def geoRastUVmap(obj, uvLayer, rast, dx, dy, reproj=None):
	'''uv map a georaster texture on a given mesh'''
	mesh = obj.data
	#Assign uv coords
	loc = obj.location
	for pg in mesh.polygons:
		for i in pg.loop_indices:
			vertIdx = mesh.loops[i].vertex_index
			pt = list(mesh.vertices[vertIdx].co)
			#adjust coords against object location and shift values to retrieve original point coords
			pt = (pt[0] + loc.x + dx, pt[1] + loc.y + dy)
			if reproj is not None:
				pt = reproj.pt(*pt)
			#Compute UV coords --> pourcent from image origin (bottom left)
			dx_px, dy_px = rast.pxFromGeo(pt[0], pt[1], reverseY=True, round2Floor=False)
			u = dx_px / rast.size[0]
			v = dy_px / rast.size[1]
			#Assign coords
			#uvLoop = uvLoopLayer.data[i]
			#uvLoop.uv = [u,v]
			if(hasattr(uvLayer,data)):
					uvLayer.data[i].uv = [u,v]

def setDisplacer(obj, rast, uvTxtLayer, mid=0, interpolation=False):
	#Config displacer
	displacer = obj.modifiers.new('DEM', type='DISPLACE')
	demTex = bpy.data.textures.new('demText', type = 'IMAGE')
	demTex.image = rast.bpyImg
	demTex.use_interpolation = interpolation
	demTex.extension = 'CLIP'
	demTex.use_clamp = False #Needed to get negative displacement with float32 texture
	displacer.texture = demTex
	displacer.texture_coords = 'UV'
	displacer.uv_layer = uvTxtLayer.name
	displacer.mid_level = mid #Texture values below this value will result in negative displacement
	#Setting the displacement strength :
	#displacement = (texture value - Midlevel) * Strength
	#>> Strength = displacement / texture value (because mid=0)
	#If DEM non scaled then
	#	*displacement = alt max - alt min = delta Z
	#	*texture value = delta Z / (2^depth-1)
	#		(because in Blender, pixel values are normalized between 0.0 and 1.0)
	#>> Strength = delta Z / (delta Z / (2^depth-1))
	#>> Strength = 2^depth-1
	if rast is None ==False and rast.depth  32767, -(65536-a), a)
			'''
		if not subset:
			return a
		else:
			# Get overlay extent (in pixels)
			subBoxPx = self.subBoxPx
			# Get subset data (min and max pixel number are both include)
			a = a[subBoxPx.ymin:subBoxPx.ymax+1, subBoxPx.xmin:subBoxPx.xmax+1] #topleft to bottomright
			return a


	def flattenPixelsArray(self, px):
		'''
		Flatten a 3d array of pixels to match the shape of bpy.pixels
		[ [[rgba], [rgba]...], [lines2], [lines3]...] >> [r,g,b,a,r,g,b,a,r,g,b,a, ... ]
		If the submited array contains only one band, then the band will be duplicate
		and an alpha band will be added to get all rgba values.
		'''
		shape = px.shape
		if len(shape) == 2:
			px = np.expand_dims(px, axis=2)
			px = np.repeat(px, 3, axis=2)
			alpha = np.ones(shape)
			alpha = np.expand_dims(alpha, axis=2)
			px = np.append(px, alpha, axis=2)
		#px = px.swapaxes(0,1)
		px = np.flipud(px)
		px = px.flatten()
		return px

关注
打赏
1664520285
查看更多评论
立即登录/注册

微信扫码登录

0.0547s