static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObject *args) { PyObject *ret; VectorObject *plane_a_co, *plane_a_no, *plane_b_co, *plane_b_no; float isect_co[3]; float isect_no[3]; if (!PyArg_ParseTuple(args, "O!O!O!O!|i:intersect_plane_plane", &vector_Type, &plane_a_co, &vector_Type, &plane_a_no, &vector_Type, &plane_b_co, &vector_Type, &plane_b_no)) { return NULL; } if (BaseMath_ReadCallback(plane_a_co) == -1 || BaseMath_ReadCallback(plane_a_no) == -1 || BaseMath_ReadCallback(plane_b_co) == -1 || BaseMath_ReadCallback(plane_b_no) == -1) { return NULL; } if (ELEM4(2, plane_a_co->size, plane_a_no->size, plane_b_co->size, plane_b_no->size)) { PyErr_SetString(PyExc_ValueError, "geometry.intersect_plane_plane(...): " " can't use 2D Vectors"); return NULL; } isect_plane_plane_v3(isect_co, isect_no, plane_a_co->vec, plane_a_no->vec, plane_b_co->vec, plane_b_no->vec); normalize_v3(isect_no); ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_co, 3, Py_NEW, NULL)); PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(isect_no, 3, Py_NEW, NULL)); return ret; }
/* only valid for perspective cameras */ int camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3]) { float shift[2]; float plane_tx[4][3]; float rot_obmat[3][3]; const float zero[3]= {0,0,0}; CameraViewFrameData data_cb; unsigned int i; camera_view_frame(scene, camera_ob->data, data_cb.frame_tx); copy_m3_m4(rot_obmat, camera_ob->obmat); normalize_m3(rot_obmat); for (i= 0; i < 4; i++) { /* normalize so Z is always 1.0f*/ mul_v3_fl(data_cb.frame_tx[i], 1.0f/data_cb.frame_tx[i][2]); } /* get the shift back out of the frame */ shift[0]= (data_cb.frame_tx[0][0] + data_cb.frame_tx[1][0] + data_cb.frame_tx[2][0] + data_cb.frame_tx[3][0]) / 4.0f; shift[1]= (data_cb.frame_tx[0][1] + data_cb.frame_tx[1][1] + data_cb.frame_tx[2][1] + data_cb.frame_tx[3][1]) / 4.0f; for (i= 0; i < 4; i++) { mul_m3_v3(rot_obmat, data_cb.frame_tx[i]); } for (i= 0; i < 4; i++) { normal_tri_v3(data_cb.normal_tx[i], zero, data_cb.frame_tx[i], data_cb.frame_tx[(i + 1) % 4]); } /* initialize callback data */ data_cb.dist_vals[0]= data_cb.dist_vals[1]= data_cb.dist_vals[2]= data_cb.dist_vals[3]= FLT_MAX; data_cb.tot= 0; /* run callback on all visible points */ BKE_scene_foreach_display_point(scene, v3d, BA_SELECT, camera_to_frame_view_cb, &data_cb); if (data_cb.tot <= 1) { return FALSE; } else { float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3]; float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3]; float plane_isect_pt_1[3], plane_isect_pt_2[3]; /* apply the dist-from-plane's to the transformed plane points */ for (i= 0; i < 4; i++) { mul_v3_v3fl(plane_tx[i], data_cb.normal_tx[i], data_cb.dist_vals[i]); } isect_plane_plane_v3(plane_isect_1, plane_isect_1_no, plane_tx[0], data_cb.normal_tx[0], plane_tx[2], data_cb.normal_tx[2]); isect_plane_plane_v3(plane_isect_2, plane_isect_2_no, plane_tx[1], data_cb.normal_tx[1], plane_tx[3], data_cb.normal_tx[3]); add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no); add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no); if (isect_line_line_v3(plane_isect_1, plane_isect_1_other, plane_isect_2, plane_isect_2_other, plane_isect_pt_1, plane_isect_pt_2) == 0) { return FALSE; } else { float cam_plane_no[3]= {0.0f, 0.0f, -1.0f}; float plane_isect_delta[3]; float plane_isect_delta_len; mul_m3_v3(rot_obmat, cam_plane_no); sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1); plane_isect_delta_len= len_v3(plane_isect_delta); if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) { copy_v3_v3(r_co, plane_isect_pt_1); /* offset shift */ normalize_v3(plane_isect_1_no); madd_v3_v3fl(r_co, plane_isect_1_no, shift[1] * -plane_isect_delta_len); } else { copy_v3_v3(r_co, plane_isect_pt_2); /* offset shift */ normalize_v3(plane_isect_2_no); madd_v3_v3fl(r_co, plane_isect_2_no, shift[0] * -plane_isect_delta_len); } return TRUE; } } }
static bool camera_frame_fit_calc_from_data( CameraParams *params, CameraViewFrameData *data, float r_co[3], float *r_scale) { float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][3]; unsigned int i; if (data->tot <= 1) { return false; } if (params->is_ortho) { const float *cam_axis_x = data->camera_rotmat[0]; const float *cam_axis_y = data->camera_rotmat[1]; const float *cam_axis_z = data->camera_rotmat[2]; float dists[CAMERA_VIEWFRAME_NUM_PLANES]; float scale_diff; /* apply the dist-from-plane's to the transformed plane points */ for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) { dists[i] = sqrtf_signed(data->dist_vals_sq[i]); } if ((dists[0] + dists[2]) > (dists[1] + dists[3])) { scale_diff = (dists[1] + dists[3]) * (BLI_rctf_size_x(¶ms->viewplane) / BLI_rctf_size_y(¶ms->viewplane)); } else { scale_diff = (dists[0] + dists[2]) * (BLI_rctf_size_y(¶ms->viewplane) / BLI_rctf_size_x(¶ms->viewplane)); } *r_scale = params->ortho_scale - scale_diff; zero_v3(r_co); madd_v3_v3fl(r_co, cam_axis_x, (dists[2] - dists[0]) * 0.5f + params->shiftx * scale_diff); madd_v3_v3fl(r_co, cam_axis_y, (dists[1] - dists[3]) * 0.5f + params->shifty * scale_diff); madd_v3_v3fl(r_co, cam_axis_z, -(data->dist_to_cam - 1.0f - params->clipsta)); return true; } else { float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3]; float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3]; float plane_isect_pt_1[3], plane_isect_pt_2[3]; /* apply the dist-from-plane's to the transformed plane points */ for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) { mul_v3_v3fl(plane_tx[i], data->normal_tx[i], sqrtf_signed(data->dist_vals_sq[i])); } if ((!isect_plane_plane_v3(plane_isect_1, plane_isect_1_no, plane_tx[0], data->normal_tx[0], plane_tx[2], data->normal_tx[2])) || (!isect_plane_plane_v3(plane_isect_2, plane_isect_2_no, plane_tx[1], data->normal_tx[1], plane_tx[3], data->normal_tx[3]))) { return false; } add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no); add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no); if (isect_line_line_v3(plane_isect_1, plane_isect_1_other, plane_isect_2, plane_isect_2_other, plane_isect_pt_1, plane_isect_pt_2) != 0) { float cam_plane_no[3]; float plane_isect_delta[3]; float plane_isect_delta_len; float shift_fac = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y) / params->lens; /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */ negate_v3_v3(cam_plane_no, data->camera_rotmat[2]); sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1); plane_isect_delta_len = len_v3(plane_isect_delta); if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) { copy_v3_v3(r_co, plane_isect_pt_1); /* offset shift */ normalize_v3(plane_isect_1_no); madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac); } else { copy_v3_v3(r_co, plane_isect_pt_2); /* offset shift */ normalize_v3(plane_isect_2_no); madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac); } return true; } } return false; }