Rhino 7 to Blender 2.9

Hello,
i recentely stummbled upon a script from “Jesterking” to open 3dm files in Blender. It works great but the camera dimensions arent being converted properly. I only found a short thread from 2018 about this but the problem still doesnt seem to be resolved.
Is there any fix or workaround to achieve the exact same camera settings in both programs ?
Thanks in advance for any information!

I don’t think there is a work-around other than fixing the code :slight_smile:

/jesterKing

Well? :slightly_smiling_face:

Definitely at some point

I wrote these two scripts to export named views from Rhino and import them into blender:

Rhino

import rhinoscriptsyntax as rs
import scriptcontext as sc
import json
import Rhino
import System.Environment

def ViewData():	
	view_port = sc.doc.Views.ActiveView.ActiveViewport
	
	if not view_port.IsPerspectiveProjection: return None
	
	width = view_port.Size.Width
	height = view_port.Size.Height
	
	fov = view_port.GetCameraAngle()[3]*2
	lens_length = view_port.Camera35mmLensLength
	
	camera_location = view_port.CameraLocation
	
	clipping_near = view_port.GetFrustumNearPlane()[1].Origin
	clipping_near = clipping_near.DistanceTo(camera_location)

	clipping_far = view_port.GetFrustumFarPlane()[1].Origin
	clipping_far = clipping_far.DistanceTo(camera_location)
	
	camera_rot_plane = Rhino.Geometry.Plane(
			Rhino.Geometry.Point3d.Origin,
			view_port.CameraX,
			view_port.CameraY)

	transformed_plane =  Rhino.Geometry.Plane.WorldXY
	rot_transform = Rhino.Geometry.Transform.ChangeBasis(camera_rot_plane, transformed_plane)

	camera_rotation = (Rhino.Geometry.Transform.GetYawPitchRoll(rot_transform)[1:])
	camera_rotation = (camera_rotation[2], camera_rotation[1], camera_rotation[0])
	camera_rotation = str(camera_rotation)
	camera_rotation = camera_rotation[1:-1]
	
	camera_data = [width, height, "Perspective", fov, lens_length, camera_location.ToString(), camera_rotation, clipping_near, clipping_far]
	
	return camera_data

sc.doc.Views.RedrawEnabled = False

cameraData = {}
for nv in sc.doc.NamedViews:
	
	sc.doc.Views.ActiveView.MainViewport.PushViewInfo(nv, False)
	
	data = ViewData()
	if data:
		entry = {
					"camera_width": data[0],
					"camera_height": data[1],
					"camera_lensType": data[2],
					"camera_fov": data[3],
					"camera_lensLength": data[4],
					"camera_location": data[5],
					"camera_rotation": data[6],
					"camera_clippingNear" : data[7],
					"camera_clippingFar" : data[8]
                  }
		cameraData[str(nv.Name)] = entry

desktop = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop)

doc_name = rs.DocumentName()[:-4]

folder = rs.BrowseForFolder(folder=desktop, message=None, title="Save Location")
if folder:
	json_filename = folder + '\\' + doc_name + '_BlenderCamera.json'
	print json_filename
	
	with open(json_filename, 'w') as f: json.dump({}, f)
	with open(json_filename, 'w') as f: json.dump(cameraData, f, indent = 4, sort_keys=True)
	
	sc.doc.Views.RedrawEnabled = True
	sc.doc.Views.Redraw()

Blender

import bpy
import os
import math
import json

pi = math.pi
scene = bpy.context.scene
scale = 1/1000
use_fov = False

def ReadData(filename):
    try:
        with open(filename, 'r') as f:
            datastore = json.load(f)
            return datastore
    except IOError:
        print ("Reading Failed")

def AddCamera(view):

    camera_loc = [float(l)*scale for l in d_camera[view]["camera_location"].split(",")]
    camera_rot = [float(l) for l in d_camera[view]["camera_rotation"].split(",")]

    bpy.ops.object.camera_add(enter_editmode=False, align='VIEW', location=camera_loc, rotation=camera_rot )

    currentCameraObj = bpy.data.objects[bpy.context.active_object.name]
    scene.camera = currentCameraObj

    currentCameraObj.name = view

    if use_fov:
        currentCameraObj.data.lens_unit = 'FOV'
        currentCameraObj.data.angle = float(d_camera[view]["camera_fov"])

    else:
        currentCameraObj.data.lens_unit = 'MILLIMETERS'
        currentCameraObj.data.sensor_width = 57.519
        currentCameraObj.data.lens = float(d_camera[view]["camera_lensLength"])

    #Align View to Main Camera
    area = next(area for area in bpy.context.screen.areas if area.type == 'VIEW_3D')
    area.spaces[0].region_3d.view_perspective = 'CAMERA'

    #Clipping
    clippingNear = float(d_camera[view]["camera_clippingNear"]) * scale
    clippingFar = float(d_camera[view]["camera_clippingFar"]) * scale
    currentCameraObj.data.clip_start = clippingNear
    currentCameraObj.data.clip_end = clippingFar

    bpy.context.scene.render.resolution_y = float(d_camera[view]["camera_height"])
    bpy.context.scene.render.resolution_x = float(d_camera[view]["camera_width"])

path = r'C:\\Users\\Alasdair\\Desktop\\'
json_filename = path + "Blender-Camera.json"

d_camera = ReadData(json_filename)
for view in d_camera:
    AddCamera(view)

Just replace the path with where you saved the named views.

Does this code still work with the latest Rhino 7? The json file is empty when I export from Rhino.

Have you not tried the import_3dm add-on yet?

1 Like