# How to calculate intersection between two planes

I'm dipping my feet at Blender SDK, and I'm trying to calculate intersection between two planes: Created a default plane in center, duplicated, rotated second, scaled first, applied transforms; but I'm failing for apparently no reason. The script:

import bpy
import bmesh
import mathutils

# https://docs.blender.org/api/2.79/mathutils.geometry.html

# Get the active mesh

center1 = 0
normal1 = 0
center2 = 0
normal2 = 0

# get the selected object
# me = bpy.context.object.data

me = bpy.data.objects['Plane'].data

# for i in range(1,objs+1):

# Get a BMesh representation
bm = bmesh.new()   # create an empty BMesh
bm.from_mesh(me)   # fill it in from a Mesh

print('bmesh:', bm)
# Modify the BMesh, can do anything here...

# get obj geom
for f in bm.faces:
print('face index:', f.index ,' and face normal:', f.normal)

center1 = f.calc_center_median_weighted()
normal1 = f.normal

# Finish up, write the bmesh back to the mesh
# bm.to_mesh(me)
# free and prevent further access
bm.free()

mz = bpy.data.objects['Plane.001'].data

# for i in range(1,objs+1):

# Get a BMesh representation
bz = bmesh.new()   # create an empty BMesh
bz.from_mesh(mz)   # fill it in from a Mesh

print('bmesh:', bz)
# Modify the BMesh, can do anything here...

# get obj geom
for f in bz.faces:
print('face index:', f.index ,' and face normal:', f.normal)

center2 = f.calc_center_median_weighted()
normal2 = f.normal

# Finish up, write the bmesh back to the mesh
# bm.to_mesh(me)
# free and prevent further access
bz.free()

# calc

print('center1:', center1)
print('normal1:', normal1)
print('center2:', center2)
print('normal2:', normal2)

intersect_line = mathutils.geometry.intersect_plane_plane(center1, normal1, center2, normal2)

print('Point:', intersect_line ,' Vector:', intersect_line)

# mathutils.geometry.intersect_plane_plane(plane_a_co, plane_a_no, plane_b_co, plane_b_no)


it should be straightforward, but clearly I'm missing something...

the blend

EDIT: console print

bmesh: <BMesh(0x10a6d6008), totvert=4, totedge=4, totface=1, totloop=4>
face index: 0  and face normal: <Vector (0.0000, 0.0000, 1.0000)>
bmesh: <BMesh(0x10a6d6008), totvert=4, totedge=4, totface=1, totloop=4>
face index: 0  and face normal: <Vector (0.9426, -0.1969, 0.2696)>
center1: <Vector (0.0000, -1.0000, 0.0000)>
normal1: <Vector (0.9426, -0.1969, 0.2696)>
center2: <Vector (0.0000, 0.0000, -0.0000)>
normal2: <Vector (0.9426, -0.1969, 0.2696)>
Point: None  Vector: None


EDIT2: better script

import bpy
import bmesh
import mathutils

# https://docs.blender.org/api/2.79/mathutils.geometry.html

# Get the active mesh

def intersect_faces () :

center1 = mathutils.Vector([0.0,0.0,0.0])
normal1 = mathutils.Vector([0.0,0.0,0.0])
center2 = mathutils.Vector([0.0,0.0,0.0])
normal2 = mathutils.Vector([0.0,0.0,0.0])

face_pn1 = [center1,normal1]
face_pn2 = [center2,normal2]

face_pn = [face_pn1,face_pn2]

me = bpy.context.selectable_objects.data

# for i in range(1,objs+1):

# Get a BMesh representation
bm = bmesh.new()   # create an empty BMesh
bm.from_mesh(me)   # fill it in from a Mesh

print('Start')
print('bmesh:', bm)
# Modify the BMesh, can do anything here...

# get obj geom
for f in bm.faces:
print('face index:', f.index ,' and face normal:', f.normal)

center1 = f.calc_center_median_weighted()
normal1 = f.normal.copy()

print('center1:', center1)
print('normal1:', normal1)

face_pn1=center1
face_pn1=normal1

# Finish up, write the bmesh back to the mesh
# bm.to_mesh(me)
# free and prevent further access
bm.free()

# mz = bpy.data.objects['Plane.001'].data

mz = bpy.context.selectable_objects.data

# for i in range(1,objs+1):

# Get a BMesh representation
bz = bmesh.new()   # create an empty BMesh
bz.from_mesh(mz)   # fill it in from a Mesh

print('bmesh:', bz)
# Modify the BMesh, can do anything here...

# get obj geom
for g in bz.faces:
print('face index:', g.index ,' and face normal:', g.normal)

center2 = g.calc_center_median_weighted()
normal2 = g.normal.copy()

print('center2:', center2)
print('normal2:', normal2)

face_pn2=center2
face_pn2=normal2

# Finish up, write the bmesh back to the mesh
# bm.to_mesh(me)
# free and prevent further access
bz.free()

return face_pn

# check

face_pn = intersect_faces()

center1 = face_pn
normal1 = face_pn
center2 = face_pn
normal2 = face_pn

# calc
print('final values')
print('center1:', center1)
print('normal1:', normal1)
print('center2:', center2)
print('normal2:', normal2)

intersect_line = mathutils.geometry.intersect_plane_plane(center1, normal1, center2, normal2)

print('Point:', intersect_line ,' Vector:', intersect_line)

# mathutils.geometry.intersect_plane_plane(plane_a_co, plane_a_no, plane_b_co, plane_b_no)


anyway, result is strange... if you run it, say 100 times, sometimes it works and sometimes it doesn't... I start suspecting a bug.

EDIT3: script modified with normal.copy as suggested by kheetor. This solves the problem

• How are your prints looking? The centers and normals in mesh data are in object space, which means if you rotated objects in object mode instead of edit mode the normals are identical and you can't calculate intersection. – kheetor Apr 10 '18 at 16:53
• Normal appear correct in the first part of the script; while in the last part (after "calc") are overwritten. Maybe something "pythonesque"? – Kabu Apr 10 '18 at 20:01
• I added .copy() in the end of normal assignments and it worked "normal1 = f.normal.copy()". Something pythonesque indeed, you were still referencing the "normal" variabled stored in the "f" iterator instead of a new Vector3 like you should. – kheetor Apr 11 '18 at 12:10
• I have already told you what the problem is ^ – kheetor Apr 11 '18 at 15:49
• You are right. Still I have to grasp this pythoneque thing well... Post the answer so I can accept it – Kabu Apr 11 '18 at 19:41

I think this is something like you need.

import bpy
import bmesh
import mathutils

def objects_return(obj):

mat = obj.matrix_world
v0 = mat *obj.data.vertices.co
v1 = mat *obj.data.vertices.co
v2 = mat *obj.data.vertices.co

normal = mathutils.geometry.normal(v0,v1,v2)

r = [v0,normal]

return r

def new_object(verts, edges):

mesh = bpy.data.meshes.new(name="new line")
mesh.from_pydata(verts, [], [])

print("#"*15)
p1 = bpy.data.objects['Plane']
p2 = bpy.data.objects['Plane.001']

a = objects_return(p1)
b = objects_return(p2)

c = mathutils.geometry.intersect_plane_plane(a, a, b, b)

bpy.context.scene.cursor_location = c
vertices = [tuple(c),tuple(c)]
edges = [tuple(c),tuple(c)]

new_object(vertices, edges)