This commit is contained in:
Brecht Van Lommel
2011-05-19 12:37:26 +00:00
27 changed files with 433 additions and 223 deletions

View File

@@ -135,7 +135,7 @@ def resolve_ncase(path):
filename = os.path.basename(path) # filename may be a directory or a file
dirpath = os.path.dirname(path)
suffix = ""
suffix = path[:0] # "" but ensure byte/str match
if not filename: # dir ends with a slash?
if len(dirpath) < len(path):
suffix = path[:len(path) - len(dirpath)]

View File

@@ -36,12 +36,17 @@ def region_2d_to_vector_3d(region, rv3d, coord):
"""
from mathutils import Vector
dx = (2.0 * coord[0] / region.width) - 1.0
dy = (2.0 * coord[1] / region.height) - 1.0
viewvec = rv3d.view_matrix.inverted()[2].xyz.normalized()
viewvec = rv3d.view_matrix.inverted()[2].to_3d().normalized()
perspinv_x, perspinv_y = rv3d.perspective_matrix.inverted().to_3x3()[0:2]
return ((perspinv_x * dx + perspinv_y * dy) - viewvec).normalized()
if rv3d.is_perspective:
dx = (2.0 * coord[0] / region.width) - 1.0
dy = (2.0 * coord[1] / region.height) - 1.0
persmat = rv3d.perspective_matrix.copy()
perspinv_x, perspinv_y = persmat.inverted().to_3x3()[0:2]
return ((perspinv_x * dx + perspinv_y * dy) - viewvec).normalized()
else:
return viewvec
def region_2d_to_location_3d(region, rv3d, coord, depth_location):
@@ -62,10 +67,28 @@ def region_2d_to_location_3d(region, rv3d, coord, depth_location):
:return: normalized 3d vector.
:rtype: :class:`Vector`
"""
from mathutils import Vector
from mathutils.geometry import intersect_point_line
origin_start = rv3d.view_matrix.inverted()[3].to_3d()
origin_end = origin_start + region_2d_to_vector_3d(region, rv3d, coord)
return intersect_point_line(depth_location, origin_start, origin_end)[0]
persmat = rv3d.perspective_matrix.copy()
coord_vec = region_2d_to_vector_3d(region, rv3d, coord)
depth_location = Vector(depth_location)
if rv3d.is_perspective:
from mathutils.geometry import intersect_line_plane
origin_start = rv3d.view_matrix.inverted()[3].to_3d()
origin_end = origin_start + coord_vec
view_vec = rv3d.view_matrix.inverted()[2]
return intersect_line_plane(origin_start, origin_end, depth_location, view_vec, 1)
else:
dx = (2.0 * coord[0] / region.width) - 1.0
dy = (2.0 * coord[1] / region.height) - 1.0
persinv = persmat.inverted()
viewinv = rv3d.view_matrix.inverted()
origin_start = (persinv[0].xyz * dx) + (persinv[1].xyz * dy) + viewinv[3].xyz
origin_end = origin_start + coord_vec
return intersect_point_line(depth_location, origin_start, origin_end)[0]
def location_3d_to_region_2d(region, rv3d, coord):

View File

@@ -752,7 +752,7 @@ class USERPREF_PT_file(bpy.types.Panel):
from bl_ui.space_userpref_keymap import InputKeyMapPanel
class USERPREF_PT_input(InputKeyMapPanel):
class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Input"

View File

@@ -138,7 +138,7 @@ class USERPREF_MT_keyconfigs(bpy.types.Menu):
bpy.types.Menu.draw_preset(self, context)
class InputKeyMapPanel(bpy.types.Panel):
class InputKeyMapPanel:
bl_space_type = 'USER_PREFERENCES'
bl_label = "Input"
bl_region_type = 'WINDOW'

View File

@@ -52,6 +52,7 @@ struct Icon
typedef struct Icon Icon;
struct PreviewImage;
struct ID;
void BKE_icons_init(int first_dyn_id);
@@ -74,11 +75,14 @@ void BKE_icon_changed(int icon_id);
/* free all icons */
void BKE_icons_free(void);
/* free the preview image for use in list */
void BKE_previewimg_freefunc(void *link);
/* free the preview image */
void BKE_previewimg_free(struct PreviewImage **prv);
/* free the preview image belonging to the id */
void BKE_previewimg_free_id(ID *id);
void BKE_previewimg_free_id(struct ID *id);
/* create a new preview image */
struct PreviewImage* BKE_previewimg_create(void) ;
@@ -87,6 +91,6 @@ struct PreviewImage* BKE_previewimg_create(void) ;
struct PreviewImage* BKE_previewimg_copy(struct PreviewImage *prv);
/* retrieve existing or create new preview image */
PreviewImage* BKE_previewimg_get(ID *id);
struct PreviewImage* BKE_previewimg_get(struct ID *id);
#endif /* BKE_ICONS_H */

View File

@@ -132,18 +132,26 @@ struct PreviewImage* BKE_previewimg_create(void)
return prv_img;
}
void BKE_previewimg_freefunc(void *link)
{
PreviewImage *prv = (PreviewImage *)link;
if (prv) {
int i;
for (i=0; i<NUM_ICON_SIZES;++i) {
if (prv->rect[i]) {
MEM_freeN(prv->rect[i]);
prv->rect[i] = NULL;
}
}
MEM_freeN(prv);
}
}
void BKE_previewimg_free(PreviewImage **prv)
{
if(prv && (*prv)) {
int i;
for (i=0; i<NUM_ICON_SIZES;++i) {
if ((*prv)->rect[i]) {
MEM_freeN((*prv)->rect[i]);
(*prv)->rect[i] = NULL;
}
}
MEM_freeN((*prv));
BKE_previewimg_freefunc(*prv);
*prv = NULL;
}
}

View File

@@ -871,7 +871,8 @@ Lamp *copy_lamp(Lamp *la)
if(la->nodetree)
lan->nodetree= ntreeCopyTree(la->nodetree);
if (la->preview) lan->preview = BKE_previewimg_copy(la->preview);
if(la->preview)
lan->preview = BKE_previewimg_copy(la->preview);
return lan;
}

View File

@@ -135,7 +135,8 @@ World *copy_world(World *wrld)
if(wrld->nodetree)
wrldn->nodetree= ntreeCopyTree(wrld->nodetree);
if (wrld->preview) wrldn->preview = BKE_previewimg_copy(wrld->preview);
if(wrld->preview)
wrldn->preview = BKE_previewimg_copy(wrld->preview);
return wrldn;
}

View File

@@ -96,6 +96,18 @@ int isect_line_line_strict_v3(const float v1[3], const float v2[3],
int isect_ray_plane_v3(float p1[3], float d[3], float v0[3],
float v1[3], float v2[3], float *lambda, int clip);
/**
* Intersect line/plane, optionally treat line as directional (like a ray) with the no_flip argument.
* @param out The intersection point.
* @param l1 The first point of the line.
* @param l2 The second point of the line.
* @param plane_co A point on the plane to intersect with.
* @param plane_no The direction of the plane (does not need to be normalized).
* @param no_flip When true, the intersection point will always be from l1 to l2, even if this is not on the plane.
*/
int isect_line_plane_v3(float out[3], const float l1[3], const float l2[3],
const float plane_co[3], const float plane_no[3], const short no_flip);
/* line/ray triangle */
int isect_line_tri_v3(const float p1[3], const float p2[3],
const float v0[3], const float v1[3], const float v2[3], float *lambda, float uv[2]);

View File

@@ -37,7 +37,7 @@
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
static float lambda_cp_line(const float p[3], const float l1[3], const float l2[3]);
/********************************** Polygons *********************************/
@@ -640,6 +640,48 @@ int isect_ray_tri_threshold_v3(const float p1[3], const float d[3], const float
return 1;
}
int isect_line_plane_v3(float out[3], const float l1[3], const float l2[3], const float plane_co[3], const float plane_no[3], const short no_flip)
{
float l_vec[3]; /* l1 -> l2 normalized vector */
float p_no[3]; /* 'plane_no' normalized */
float dot;
sub_v3_v3v3(l_vec, l2, l1);
normalize_v3(l_vec);
normalize_v3_v3(p_no, plane_no);
dot= dot_v3v3(l_vec, p_no);
if(dot == 0.0f) {
return 0;
}
else {
float l1_plane[3]; /* line point aligned with the plane */
float dist; /* 'plane_no' aligned distance to the 'plane_co' */
/* for pradictable flipping since the plane is only used to
* define a direction, ignore its flipping and aligned with 'l_vec' */
if(dot < 0.0f) {
dot= -dot;
negate_v3(p_no);
}
add_v3_v3v3(l1_plane, l1, p_no);
dist = lambda_cp_line(plane_co, l1, l1_plane);
/* treat line like a ray, when 'no_flip' is set */
if(no_flip && dist < 0.0f) {
dist= -dist;
}
mul_v3_fl(l_vec, dist / dot);
add_v3_v3v3(out, l1, l_vec);
return 1;
}
}
/* Adapted from the paper by Kasper Fauerby */
/* "Improved Collision detection and Response" */
@@ -1075,16 +1117,14 @@ float closest_to_line_v2(float cp[2],const float p[2], const float l1[2], const
return lambda;
}
#if 0
/* little sister we only need to know lambda */
static float lambda_cp_line(float p[3], float l1[3], float l2[3])
static float lambda_cp_line(const float p[3], const float l1[3], const float l2[3])
{
float h[3],u[3];
sub_v3_v3v3(u, l2, l1);
sub_v3_v3v3(h, p, l1);
return(dot_v3v3(u,h)/dot_v3v3(u,u));
}
#endif
/* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */
void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2], const float pt[2], float *uv)

View File

@@ -49,6 +49,8 @@ struct SpaceFile;
struct SpaceImaSel;
struct UserDef;
struct bContext;
struct BHead;
struct FileData;
typedef struct BlendHandle BlendHandle;
@@ -225,6 +227,8 @@ struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh
int BLO_library_append_named_part(const struct bContext *C, struct Main *mainl, BlendHandle** bh, const char *idname, int idcode, short flag);
void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag);
void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname);
/* deprecated */
#if 1
void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Main *mainvar, struct Scene *scene, struct ReportList *reports);

View File

@@ -148,15 +148,14 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
LinkNode *previews= NULL;
BHead *bhead;
int looking=0;
int npreviews = 0;
PreviewImage* prv = NULL;
PreviewImage* new_prv = NULL;
int tot= 0;
for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
if (bhead->code==ofblocktype) {
ID *id= (ID*) (bhead+1);
switch(GS(id->name))
char *idname= bhead_id_name(fd, bhead);
switch(GS(idname))
{
case ID_MA: /* fall through */
case ID_TE: /* fall through */
@@ -174,31 +173,29 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
} else if (bhead->code==DATA) {
if (looking) {
if (bhead->SDNAnr == DNA_struct_find_nr(fd->filesdna, "PreviewImage") ) {
prv = (PreviewImage*) (bhead+1);
npreviews = 0;
memcpy(new_prv, prv, sizeof(PreviewImage));
if (prv->rect[0]) {
unsigned int *rect = NULL;
// int rectlen = 0;
new_prv->rect[0] = MEM_callocN(new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int), "prvrect");
bhead= blo_nextbhead(fd, bhead);
rect = (unsigned int*)(bhead+1);
// rectlen = new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int);
memcpy(new_prv->rect[0], rect, bhead->len);
} else {
new_prv->rect[0] = NULL;
}
if (prv->rect[1]) {
unsigned int *rect = NULL;
// int rectlen = 0;
new_prv->rect[1] = MEM_callocN(new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int), "prvrect");
bhead= blo_nextbhead(fd, bhead);
rect = (unsigned int*)(bhead+1);
// rectlen = new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int);
memcpy(new_prv->rect[1], rect, bhead->len);
} else {
new_prv->rect[1] = NULL;
prv = BLO_library_read_struct(fd, bhead, "PreviewImage");
if (prv) {
memcpy(new_prv, prv, sizeof(PreviewImage));
if (prv->rect[0]) {
unsigned int *rect = NULL;
new_prv->rect[0] = MEM_callocN(new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int), "prvrect");
bhead= blo_nextbhead(fd, bhead);
rect = (unsigned int*)(bhead+1);
memcpy(new_prv->rect[0], rect, bhead->len);
} else {
new_prv->rect[0] = NULL;
}
if (prv->rect[1]) {
unsigned int *rect = NULL;
new_prv->rect[1] = MEM_callocN(new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int), "prvrect");
bhead= blo_nextbhead(fd, bhead);
rect = (unsigned int*)(bhead+1);
memcpy(new_prv->rect[1], rect, bhead->len);
} else {
new_prv->rect[1] = NULL;
}
MEM_freeN(prv);
}
}
}

View File

@@ -4169,7 +4169,7 @@ static void direct_link_object(FileData *fd, Object *ob)
bActuator *act;
int a;
/* weak weak... this was only meant as draw flag, now is used in give_base too */
/* weak weak... this was only meant as draw flag, now is used in give_base_to_objects too */
ob->flag &= ~OB_FROMGROUP;
/* loading saved files with editmode enabled works, but for undo we like
@@ -12789,12 +12789,22 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is
int do_it= 0;
if(ob->id.us==0)
if(ob->id.us==0) {
do_it= 1;
else if(ob->id.us==1 && lib)
if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0)
}
else if (lib==NULL) { /* appending */
if(object_in_any_scene(mainvar, ob)==0) {
/* when appending, make sure any indirectly loaded objects
* get a base else they cant be accessed at all [#27437] */
do_it= 1;
}
}
else if(ob->id.us==1 && lib) {
if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0) {
do_it= 1;
}
}
if(do_it) {
base= MEM_callocN( sizeof(Base), "add_ext_base");
BLI_addtail(&(sce->base), base);
@@ -13064,6 +13074,9 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in
give_base_to_objects(mainvar, scene, NULL, 0);
}
}
else {
printf("library_append_end, scene is NULL (objects wont get bases)\n");
}
/* has been removed... erm, why? s..ton) */
/* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
/* 20041208: put back. It only linked direct, not indirect objects (ton) */
@@ -13084,6 +13097,11 @@ void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle**
*bh= (BlendHandle*)fd;
}
void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname)
{
return read_struct(fd, bh, blockname);
}
/* ************* READ LIBRARY ************** */
static int mainvar_count_libread_blocks(Main *mainvar)

View File

@@ -2498,8 +2498,8 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *e
ARegion *ar;
View3D *v3d;
RegionView3D *rv3d;
float dx, dy, fz, *fp = NULL, dvec[3], oldcurs[3];
int mx, my, mval[2];
float *fp = NULL, tvec[3], oldcurs[3];
int mx, my;
int retv;
scene= CTX_data_scene(C);
@@ -2513,27 +2513,9 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *e
mx= event->x - ar->winrct.xmin;
my= event->y - ar->winrct.ymin;
project_int_noclip(ar, fp, mval);
initgrabz(rv3d, fp[0], fp[1], fp[2]);
if(mval[0]!=IS_CLIPPED) {
window_to_3d_delta(ar, dvec, mval[0]-mx, mval[1]-my);
sub_v3_v3v3(fp, fp, dvec);
}
else {
dx= ((float)(mx-(ar->winx/2)))*rv3d->zfac/(ar->winx/2);
dy= ((float)(my-(ar->winy/2)))*rv3d->zfac/(ar->winy/2);
fz= rv3d->persmat[0][3]*fp[0]+ rv3d->persmat[1][3]*fp[1]+ rv3d->persmat[2][3]*fp[2]+ rv3d->persmat[3][3];
fz= fz/rv3d->zfac;
fp[0]= (rv3d->persinv[0][0]*dx + rv3d->persinv[1][0]*dy+ rv3d->persinv[2][0]*fz)-rv3d->ofs[0];
fp[1]= (rv3d->persinv[0][1]*dx + rv3d->persinv[1][1]*dy+ rv3d->persinv[2][1]*fz)-rv3d->ofs[1];
fp[2]= (rv3d->persinv[0][2]*dx + rv3d->persinv[1][2]*dy+ rv3d->persinv[2][2]*fz)-rv3d->ofs[2];
}
window_to_3d(ar, tvec, fp, mx, my);
copy_v3_v3(fp, tvec);
/* extrude to the where new cursor is and store the operation result */
retv= armature_click_extrude_exec(C, op);

View File

@@ -365,7 +365,7 @@ static EnumPropertyItem prop_gpencil_convertmodes[] = {
/* convert the coordinates from the given stroke point into 3d-coordinates
* - assumes that the active space is the 3D-View
*/
static void gp_strokepoint_convertcoords (bContext *C, bGPDstroke *gps, bGPDspoint *pt, float p3d[3])
static void gp_strokepoint_convertcoords (bContext *C, bGPDstroke *gps, bGPDspoint *pt, float p3d[3], rctf *subrect)
{
Scene *scene= CTX_data_scene(C);
View3D *v3d= CTX_wm_view3d(C);
@@ -377,41 +377,44 @@ static void gp_strokepoint_convertcoords (bContext *C, bGPDstroke *gps, bGPDspoi
}
else {
float *fp= give_cursor(scene, v3d);
float dvec[3];
int mval[2];
int mx, my;
float mx, my;
/* get screen coordinate */
if (gps->flag & GP_STROKE_2DSPACE) {
int mxi, myi;
View2D *v2d= &ar->v2d;
UI_view2d_view_to_region(v2d, pt->x, pt->y, &mx, &my);
UI_view2d_view_to_region(v2d, pt->x, pt->y, &mxi, &myi);
mx= mxi;
my= myi;
}
else {
mx= (int)(pt->x / 100 * ar->winx);
my= (int)(pt->y / 100 * ar->winy);
if(subrect) {
mx= (((float)pt->x/100.0f) * (subrect->xmax - subrect->xmin)) + subrect->xmin;
my= (((float)pt->y/100.0f) * (subrect->ymax - subrect->ymin)) + subrect->ymin;
}
else {
mx= (float)pt->x / 100.0f * ar->winx;
my= (float)pt->y / 100.0f * ar->winy;
}
}
mval[0]= mx;
mval[1]= my;
/* convert screen coordinate to 3d coordinates
* - method taken from editview.c - mouse_cursor()
*/
project_int_noclip(ar, fp, mval);
window_to_3d(ar, dvec, mval[0]-mx, mval[1]-my);
sub_v3_v3v3(p3d, fp, dvec);
window_to_3d(ar, p3d, fp, mx, my);
}
}
/* --- */
/* convert stroke to 3d path */
static void gp_stroke_to_path (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu)
static void gp_stroke_to_path (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect)
{
bGPDspoint *pt;
Nurb *nu;
BPoint *bp;
int i;
/* create new 'nurb' within the curve */
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_path(nurb)");
@@ -428,7 +431,7 @@ static void gp_stroke_to_path (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cur
float p3d[3];
/* get coordinates to add at */
gp_strokepoint_convertcoords(C, gps, pt, p3d);
gp_strokepoint_convertcoords(C, gps, pt, p3d, subrect);
copy_v3_v3(bp->vec, p3d);
/* set settings */
@@ -440,8 +443,27 @@ static void gp_stroke_to_path (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cur
BLI_addtail(&cu->nurb, nu);
}
static int gp_camera_view_subrect(bContext *C, rctf *subrect)
{
Scene *scene= CTX_data_scene(C);
View3D *v3d= CTX_wm_view3d(C);
ARegion *ar= CTX_wm_region(C);
if (v3d) {
RegionView3D *rv3d= ar->regiondata;
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
view3d_calc_camera_border(scene, ar, NULL, v3d, subrect, -1); /* negative shift */
return 1;
}
}
return 0;
}
/* convert stroke to 3d bezier */
static void gp_stroke_to_bezier (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu)
static void gp_stroke_to_bezier (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect)
{
bGPDspoint *pt;
Nurb *nu;
@@ -463,9 +485,9 @@ static void gp_stroke_to_bezier (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, C
/* get initial coordinates */
pt=gps->points;
if (tot) {
gp_strokepoint_convertcoords(C, gps, pt, p3d_cur);
gp_strokepoint_convertcoords(C, gps, pt, p3d_cur, subrect);
if (tot > 1) {
gp_strokepoint_convertcoords(C, gps, pt+1, p3d_next);
gp_strokepoint_convertcoords(C, gps, pt+1, p3d_next, subrect);
}
}
@@ -493,7 +515,7 @@ static void gp_stroke_to_bezier (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, C
copy_v3_v3(p3d_cur, p3d_next);
if (i + 1 < tot) {
gp_strokepoint_convertcoords(C, gps, pt+1, p3d_next);
gp_strokepoint_convertcoords(C, gps, pt+1, p3d_next, subrect);
}
}
@@ -512,7 +534,10 @@ static void gp_layer_to_curve (bContext *C, bGPdata *gpd, bGPDlayer *gpl, short
bGPDstroke *gps;
Object *ob;
Curve *cu;
/* camera framing */
rctf subrect, *subrect_ptr= NULL;
/* error checking */
if (ELEM3(NULL, gpd, gpl, gpf))
return;
@@ -521,6 +546,11 @@ static void gp_layer_to_curve (bContext *C, bGPdata *gpd, bGPDlayer *gpl, short
if (gpf->strokes.first == NULL)
return;
/* initialize camera framing */
if(gp_camera_view_subrect(C, &subrect)) {
subrect_ptr= &subrect;
}
/* init the curve object (remove rotation and get curve data from it)
* - must clear transforms set on object, as those skew our results
*/
@@ -538,10 +568,10 @@ static void gp_layer_to_curve (bContext *C, bGPdata *gpd, bGPDlayer *gpl, short
for (gps= gpf->strokes.first; gps; gps= gps->next) {
switch (mode) {
case GP_STROKECONVERT_PATH:
gp_stroke_to_path(C, gpl, gps, cu);
gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr);
break;
case GP_STROKECONVERT_CURVE:
gp_stroke_to_bezier(C, gpl, gps, cu);
gp_stroke_to_bezier(C, gpl, gps, cu, subrect_ptr);
break;
}
}
@@ -564,8 +594,6 @@ static int gp_convert_layer_exec (bContext *C, wmOperator *op)
bGPdata *gpd= gpencil_data_get_active(C);
bGPDlayer *gpl= gpencil_layer_getactive(gpd);
Scene *scene= CTX_data_scene(C);
View3D *v3d= CTX_wm_view3d(C);
float *fp= give_cursor(scene, v3d);
int mode= RNA_enum_get(op->ptr, "type");
/* check if there's data to work with */
@@ -574,9 +602,6 @@ static int gp_convert_layer_exec (bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* initialise 3d-cursor correction globals */
initgrabz(CTX_wm_region_view3d(C), fp[0], fp[1], fp[2]);
/* handle conversion modes */
switch (mode) {
case GP_STROKECONVERT_PATH:

View File

@@ -80,9 +80,9 @@ typedef struct ViewDepths {
float *give_cursor(struct Scene *scene, struct View3D *v3d);
int initgrabz(struct RegionView3D *rv3d, float x, float y, float z);
void window_to_3d(struct ARegion *ar, float out[3], const int mx, const int my);
void window_to_3d_delta(struct ARegion *ar, float out[3], const int mx, const int my);
void window_to_3d_vector(struct ARegion *ar, float out[3], const int mx, const int my);
void window_to_3d(struct ARegion *ar, float out[3], const float depth_pt[3], const float mx, const float my);
void window_to_3d_delta(struct ARegion *ar, float out[3], const float mx, const float my);
void window_to_3d_vector(struct ARegion *ar, float out[3], const float mx, const float my);
void view3d_unproject(struct bglMats *mats, float out[3], const short x, const short y, const float z);
/* Depth buffer */
@@ -112,7 +112,6 @@ void viewray(struct ARegion *ar, struct View3D *v3d, float mval[2], float ray_st
void get_object_clip_range(struct Object *ob, float *lens, float *clipsta, float *clipend);
int get_view3d_cliprange(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend);
int get_view3d_viewplane(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend, float *pixsize);
int get_view3d_ortho(struct View3D *v3d, struct RegionView3D *rv3d);
void view3d_get_object_project_mat(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
void view3d_project_float(struct ARegion *a, const float vec[3], float adr[2], float mat[4][4]);
void view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct RegionView3D *rv3d, struct View3D *v3d, struct rctf *viewborder_r, short do_shift);

View File

@@ -419,7 +419,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
}
}
else if(subtype == PROP_DIRECTION) {
uiDefButR(block, BUT_NORMAL, 0, name, x, y, 100, 100, ptr, RNA_property_identifier(prop), 0, 0, 0, -1, -1, NULL);
uiDefButR(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X*3, UI_UNIT_Y*3, ptr, RNA_property_identifier(prop), 0, 0, 0, -1, -1, NULL);
}
else {
if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand)

View File

@@ -72,41 +72,6 @@ typedef struct ScreenshotData {
int dumpsx, dumpsy;
} ScreenshotData;
static int screenshot_exec(bContext *C, wmOperator *op)
{
ScreenshotData *scd= op->customdata;
if(scd) {
if(scd->dumprect) {
Scene *scene= CTX_data_scene(C);
ImBuf *ibuf;
char path[FILE_MAX];
RNA_string_get(op->ptr, "filepath", path);
strcpy(G.ima, path);
BLI_path_abs(path, G.main->name);
/* BKE_add_image_extension() checks for if extension was already set */
if(scene->r.scemode & R_EXTENSION)
if(strlen(path)<FILE_MAXDIR+FILE_MAXFILE-5)
BKE_add_image_extension(path, scene->r.imtype);
ibuf= IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0);
ibuf->rect= scd->dumprect;
BKE_write_ibuf(ibuf, path, scene->r.imtype, scene->r.subimtype, scene->r.quality);
IMB_freeImBuf(ibuf);
MEM_freeN(scd->dumprect);
}
MEM_freeN(scd);
op->customdata= NULL;
}
return OPERATOR_FINISHED;
}
/* get shot from frontbuffer */
static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy, int fscreen)
{
@@ -140,8 +105,8 @@ static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy, int fscre
return dumprect;
}
static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
/* call from both exec and invoke */
static int screenshot_data_create(bContext *C, wmOperator *op)
{
unsigned int *dumprect;
int dumpsx, dumpsy;
@@ -154,7 +119,68 @@ static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)
scd->dumpsy= dumpsy;
scd->dumprect= dumprect;
op->customdata= scd;
return TRUE;
}
else {
op->customdata= NULL;
return FALSE;
}
}
static void screenshot_data_free(wmOperator *op)
{
ScreenshotData *scd= op->customdata;
if(scd) {
if(scd->dumprect)
MEM_freeN(scd->dumprect);
MEM_freeN(scd);
op->customdata= NULL;
}
}
static int screenshot_exec(bContext *C, wmOperator *op)
{
ScreenshotData *scd= op->customdata;
if(scd == NULL) {
/* when running exec directly */
screenshot_data_create(C, op);
scd= op->customdata;
}
if(scd) {
if(scd->dumprect) {
Scene *scene= CTX_data_scene(C);
ImBuf *ibuf;
char path[FILE_MAX];
RNA_string_get(op->ptr, "filepath", path);
strcpy(G.ima, path);
BLI_path_abs(path, G.main->name);
/* BKE_add_image_extension() checks for if extension was already set */
if(scene->r.scemode & R_EXTENSION)
if(strlen(path)<FILE_MAXDIR+FILE_MAXFILE-5)
BKE_add_image_extension(path, scene->r.imtype);
ibuf= IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0);
ibuf->rect= scd->dumprect;
BKE_write_ibuf(ibuf, path, scene->r.imtype, scene->r.subimtype, scene->r.quality);
IMB_freeImBuf(ibuf);
}
}
screenshot_data_free(op);
return OPERATOR_FINISHED;
}
static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
if(screenshot_data_create(C, op)) {
if(RNA_property_is_set(op->ptr, "filepath"))
return screenshot_exec(C, op);
@@ -169,14 +195,7 @@ static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)
static int screenshot_cancel(bContext *UNUSED(C), wmOperator *op)
{
ScreenshotData *scd= op->customdata;
if(scd) {
if(scd->dumprect)
MEM_freeN(scd->dumprect);
MEM_freeN(scd);
op->customdata= NULL;
}
screenshot_data_free(op);
return OPERATOR_CANCELLED;
}

View File

@@ -59,6 +59,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_icons.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BLO_readfile.h"
@@ -999,7 +1000,7 @@ static int groupname_to_code(char *group)
return BKE_idcode_from_name(buf);
}
void filelist_from_library(struct FileList* filelist)
{
LinkNode *l, *names, *previews;
@@ -1086,7 +1087,7 @@ void filelist_from_library(struct FileList* filelist)
}
BLI_linklist_free(names, free);
if (previews) BLI_linklist_free(previews, (void(*)(void*)) MEM_freeN);
if (previews) BLI_linklist_free(previews, BKE_previewimg_freefunc);
filelist_sort(filelist, FILE_SORT_ALPHA);

View File

@@ -366,7 +366,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
}
else {
/* draw with lights in the scene otherwise */
Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, get_view3d_ortho(v3d, rv3d));
Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
}
obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);

View File

@@ -383,7 +383,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
if((vod->use_dyn_ofs=view_autodist(CTX_data_scene(C), vod->ar, vod->v3d, event->mval, vod->dyn_ofs))) {
if (rv3d->persp==RV3D_PERSP || (rv3d->persp==RV3D_CAMOB && (vod->v3d->flag2 & V3D_LOCK_CAMERA))) {
if (rv3d->is_persp) {
float my_origin[3]; /* original G.vd->ofs */
float my_pivot[3]; /* view */
float dvec[3];
@@ -1074,7 +1074,7 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
float tvec[3];
float tpos[3];
float new_dist;
short vb[2], mouseloc[2];
int vb[2], mouseloc[2];
mouseloc[0]= mx - ar->winrct.xmin;
mouseloc[1]= my - ar->winrct.ymin;
@@ -1087,7 +1087,7 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
/* Project cursor position into 3D space */
initgrabz(rv3d, tpos[0], tpos[1], tpos[2]);
window_to_3d_delta(ar, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
window_to_3d_delta(ar, dvec, mouseloc[0]-vb[0]/2.0f, mouseloc[1]-vb[1]/2.0f);
/* Calculate view target position for dolly */
add_v3_v3v3(tvec, tpos, dvec);

View File

@@ -507,7 +507,7 @@ void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float
float vec[4];
int a;
if(!get_view3d_ortho(v3d, rv3d)) {
if(rv3d->is_persp) {
vec[0]= 2.0f * mval[0] / ar->winx - 1;
vec[1]= 2.0f * mval[1] / ar->winy - 1;
vec[2]= -1.0f;
@@ -598,26 +598,39 @@ int initgrabz(RegionView3D *rv3d, float x, float y, float z)
return flip;
}
/* always call initgrabz */
void window_to_3d(ARegion *ar, float out[3], const int mx, const int my)
void window_to_3d(ARegion *ar, float out[3], const float depth_pt[3], const float mx, const float my)
{
RegionView3D *rv3d= ar->regiondata;
float dx= ((float)(mx-(ar->winx/2)))*rv3d->zfac/(ar->winx/2);
float dy= ((float)(my-(ar->winy/2)))*rv3d->zfac/(ar->winy/2);
float fz= rv3d->persmat[0][3]*out[0]+ rv3d->persmat[1][3]*out[1]+ rv3d->persmat[2][3]*out[2]+ rv3d->persmat[3][3];
fz= fz/rv3d->zfac;
out[0]= (rv3d->persinv[0][0]*dx + rv3d->persinv[1][0]*dy+ rv3d->persinv[2][0]*fz)-rv3d->ofs[0];
out[1]= (rv3d->persinv[0][1]*dx + rv3d->persinv[1][1]*dy+ rv3d->persinv[2][1]*fz)-rv3d->ofs[1];
out[2]= (rv3d->persinv[0][2]*dx + rv3d->persinv[1][2]*dy+ rv3d->persinv[2][2]*fz)-rv3d->ofs[2];
float line_sta[3];
float line_end[3];
if(rv3d->is_persp) {
float mousevec[3];
copy_v3_v3(line_sta, rv3d->viewinv[3]);
window_to_3d_vector(ar, mousevec, mx, my);
add_v3_v3v3(line_end, line_sta, mousevec);
if(isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) {
/* highly unlikely to ever happen, mouse vec paralelle with view plane */
zero_v3(out);
}
}
else {
const float dx= (2.0f * (float)mx / (float)ar->winx) - 1.0f;
const float dy= (2.0f * (float)my / (float)ar->winy) - 1.0f;
line_sta[0]= (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
line_sta[1]= (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
line_sta[2]= (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2];
add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]);
closest_to_line_v3(out, depth_pt, line_sta, line_end);
}
}
/* always call initgrabz */
/* only to detect delta motion */
void window_to_3d_delta(ARegion *ar, float out[3], const int mx, const int my)
void window_to_3d_delta(ARegion *ar, float out[3], const float mx, const float my)
{
RegionView3D *rv3d= ar->regiondata;
float dx, dy;
@@ -633,22 +646,27 @@ void window_to_3d_delta(ARegion *ar, float out[3], const int mx, const int my)
/* doesn't rely on initgrabz */
/* for perspective view, get the vector direction to
* the mouse cursor as a normalized vector */
void window_to_3d_vector(ARegion *ar, float out[3], const int mx, const int my)
void window_to_3d_vector(ARegion *ar, float out[3], const float mx, const float my)
{
RegionView3D *rv3d= ar->regiondata;
float dx, dy;
float viewvec[3];
dx= (2.0f * mx / ar->winx) - 1.0f;
dy= (2.0f * my / ar->winy) - 1.0f;
if(rv3d->is_persp) {
float dx, dy;
float viewvec[3];
/* normalize here so vecs are proportional to eachother */
normalize_v3_v3(viewvec, rv3d->viewinv[2]);
dx= (2.0f * mx / ar->winx) - 1.0f;
dy= (2.0f * my / ar->winy) - 1.0f;
out[0]= (rv3d->persinv[0][0]*dx + rv3d->persinv[1][0]*dy) - viewvec[0];
out[1]= (rv3d->persinv[0][1]*dx + rv3d->persinv[1][1]*dy) - viewvec[1];
out[2]= (rv3d->persinv[0][2]*dx + rv3d->persinv[1][2]*dy) - viewvec[2];
/* normalize here so vecs are proportional to eachother */
normalize_v3_v3(viewvec, rv3d->viewinv[2]);
out[0]= (rv3d->persinv[0][0]*dx + rv3d->persinv[1][0]*dy) - viewvec[0];
out[1]= (rv3d->persinv[0][1]*dx + rv3d->persinv[1][1]*dy) - viewvec[1];
out[2]= (rv3d->persinv[0][2]*dx + rv3d->persinv[1][2]*dy) - viewvec[2];
}
else {
copy_v3_v3(out, rv3d->viewinv[2]);
}
normalize_v3(out);
}
@@ -890,29 +908,6 @@ void project_float_noclip(ARegion *ar, const float vec[3], float adr[2])
}
}
int get_view3d_ortho(View3D *v3d, RegionView3D *rv3d)
{
Camera *cam;
if(rv3d->persp==RV3D_CAMOB) {
if(v3d->camera && v3d->camera->type==OB_CAMERA) {
cam= v3d->camera->data;
if(cam && cam->type==CAM_ORTHO)
return 1;
else
return 0;
}
else
return 0;
}
if(rv3d->persp==RV3D_ORTHO)
return 1;
return 0;
}
/* copies logic of get_view3d_viewplane(), keep in sync */
int get_view3d_cliprange(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend)
{
@@ -1082,6 +1077,8 @@ void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect) /* rect: for pick
int orth;
orth= get_view3d_viewplane(v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend, NULL);
rv3d->is_persp= !orth;
// printf("%d %d %f %f %f %f %f %f\n", winx, winy, viewplane.xmin, viewplane.ymin, viewplane.xmax, viewplane.ymax, clipsta, clipend);
x1= viewplane.xmin;
y1= viewplane.ymin;

View File

@@ -391,7 +391,7 @@ struct ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags)
if (png_get_valid (png_ptr, info_ptr, PNG_INFO_pHYs)) {
int unit_type;
unsigned int xres, yres;
png_uint_32 xres, yres;
if(png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type))
if(unit_type == PNG_RESOLUTION_METER) {

View File

@@ -97,10 +97,13 @@ typedef struct RegionView3D {
float zfac; /* initgrabz() result */
float camdx, camdy; /* camera view offsets, 1.0 = viewplane moves entire width/height */
float pixsize; /* runtime only */
float ofs[3]; /* view center & orbit pivot, negative of worldspace location */
float ofs[3]; /* view center & orbit pivot, negative of worldspace location,
* also matches -viewinv[3][0:3] in ortho mode.*/
short camzoom;
short twdrawflag;
int pad;
char is_persp; /* check if persp/ortho view, since 'persp' cant be used for this since
* it can have cameras assigned as well. (only set in setwinmatrixview3d) */
char pad[3];
short rflag, viewlock;
short persp;

View File

@@ -1458,6 +1458,11 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rv3d_persp_items);
RNA_def_property_ui_text(prop, "Perspective", "View Perspective");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
prop= RNA_def_property(srna, "is_perspective", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "is_persp", 1);
RNA_def_property_ui_text(prop, "Is Perspective", "");
RNA_def_property_flag(prop, PROP_EDITABLE);
prop= RNA_def_property(srna, "view_location", PROP_FLOAT, PROP_TRANSLATION);
#if 0

View File

@@ -1674,7 +1674,7 @@ static PyObject *Matrix_getColSize(MatrixObject *self, void *UNUSED(closure))
return PyLong_FromLong((long) self->col_size);
}
static PyObject *Matrix_getMedianScale(MatrixObject *self, void *UNUSED(closure))
static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closure))
{
float mat[3][3];
@@ -1692,7 +1692,7 @@ static PyObject *Matrix_getMedianScale(MatrixObject *self, void *UNUSED(closure)
return PyFloat_FromDouble(mat3_to_scale(mat));
}
static PyObject *Matrix_getIsNegative(MatrixObject *self, void *UNUSED(closure))
static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure))
{
if(BaseMath_ReadCallback(self) == -1)
return NULL;
@@ -1708,6 +1708,21 @@ static PyObject *Matrix_getIsNegative(MatrixObject *self, void *UNUSED(closure))
}
}
static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closure))
{
if(BaseMath_ReadCallback(self) == -1)
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->col_size == 4 && self->row_size == 4)
return PyBool_FromLong(is_orthogonal_m4((float (*)[4])self->contigPtr));
else if(self->col_size == 3 && self->row_size == 3)
return PyBool_FromLong(is_orthogonal_m3((float (*)[3])self->contigPtr));
else {
PyErr_SetString(PyExc_AttributeError, "Matrix.is_orthogonal: inappropriate matrix size - expects 3x3 or 4x4 matrix");
return NULL;
}
}
/*****************************************************************************/
/* Python attributes get/set structure: */
@@ -1715,8 +1730,9 @@ static PyObject *Matrix_getIsNegative(MatrixObject *self, void *UNUSED(closure))
static PyGetSetDef Matrix_getseters[] = {
{(char *)"row_size", (getter)Matrix_getRowSize, (setter)NULL, (char *)"The row size of the matrix (readonly).\n\n:type: int", NULL},
{(char *)"col_size", (getter)Matrix_getColSize, (setter)NULL, (char *)"The column size of the matrix (readonly).\n\n:type: int", NULL},
{(char *)"median_scale", (getter)Matrix_getMedianScale, (setter)NULL, (char *)"The average scale applied to each axis (readonly).\n\n:type: float", NULL},
{(char *)"is_negative", (getter)Matrix_getIsNegative, (setter)NULL, (char *)"True if this matrix results in a negative scale, 3x3 and 4x4 only, (readonly).\n\n:type: bool", NULL},
{(char *)"median_scale", (getter)Matrix_median_scale_get, (setter)NULL, (char *)"The average scale applied to each axis (readonly).\n\n:type: float", NULL},
{(char *)"is_negative", (getter)Matrix_is_negative_get, (setter)NULL, (char *)"True if this matrix results in a negative scale, 3x3 and 4x4 only, (readonly).\n\n:type: bool", NULL},
{(char *)"is_orthogonal", (getter)Matrix_is_orthogonal_get, (setter)NULL, (char *)"True if this matrix is orthogonal, 3x3 and 4x4 only, (readonly).\n\n:type: bool", NULL},
{(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL},
{(char *)"owner",(getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */

View File

@@ -497,6 +497,60 @@ static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObj
}
static char M_Geometry_intersect_line_plane_doc[] =
".. function:: intersect_line_plane(line_a, line_b, plane_co, plane_no, no_flip=False)\n"
"\n"
" Takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None.\n"
"\n"
" :arg line_a: First point of the first line\n"
" :type line_a: :class:`mathutils.Vector`\n"
" :arg line_b: Second point of the first line\n"
" :type line_b: :class:`mathutils.Vector`\n"
" :arg plane_co: A point on the plane\n"
" :type plane_co: :class:`mathutils.Vector`\n"
" :arg plane_no: The direction the plane is facing\n"
" :type plane_no: :class:`mathutils.Vector`\n"
" :arg no_flip: Always return an intersection on the directon defined bt line_a -> line_b\n"
" :type no_flip: :boolean\n"
" :return: The point of intersection or None when not found\n"
" :rtype: :class:`mathutils.Vector` or None\n"
;
static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObject* args)
{
VectorObject *line_a, *line_b, *plane_co, *plane_no;
int no_flip= 0;
float isect[3];
if(!PyArg_ParseTuple(args, "O!O!O!O!|i:intersect_line_line_2d",
&vector_Type, &line_a,
&vector_Type, &line_b,
&vector_Type, &plane_co,
&vector_Type, &plane_no,
&no_flip)
) {
return NULL;
}
if( BaseMath_ReadCallback(line_a) == -1 ||
BaseMath_ReadCallback(line_b) == -1 ||
BaseMath_ReadCallback(plane_co) == -1 ||
BaseMath_ReadCallback(plane_no) == -1
) {
return NULL;
}
if(ELEM4(2, line_a->size, line_b->size, plane_co->size, plane_no->size)) {
PyErr_SetString(PyExc_RuntimeError, "geometry.intersect_line_plane(...) can't use 2D Vectors");
return NULL;
}
if(isect_line_plane_v3(isect, line_a->vec, line_b->vec, plane_co->vec, plane_no->vec, no_flip) == 1) {
return newVectorObject(isect, 3, Py_NEW, NULL);
}
else {
Py_RETURN_NONE;
}
}
static char M_Geometry_intersect_point_line_doc[] =
".. function:: intersect_point_line(pt, line_p1, line_p2)\n"
"\n"
@@ -860,6 +914,7 @@ static PyMethodDef M_Geometry_methods[]= {
{"intersect_point_quad_2d", (PyCFunction) M_Geometry_intersect_point_quad_2d, METH_VARARGS, M_Geometry_intersect_point_quad_2d_doc},
{"intersect_line_line", (PyCFunction) M_Geometry_intersect_line_line, METH_VARARGS, M_Geometry_intersect_line_line_doc},
{"intersect_line_line_2d", (PyCFunction) M_Geometry_intersect_line_line_2d, METH_VARARGS, M_Geometry_intersect_line_line_2d_doc},
{"intersect_line_plane", (PyCFunction) M_Geometry_intersect_line_plane, METH_VARARGS, M_Geometry_intersect_line_plane_doc},
{"interpolate_bezier", (PyCFunction) M_Geometry_interpolate_bezier, METH_VARARGS, M_Geometry_interpolate_bezier_doc},
{"area_tri", (PyCFunction) M_Geometry_area_tri, METH_VARARGS, M_Geometry_area_tri_doc},
{"normal", (PyCFunction) M_Geometry_normal, METH_VARARGS, M_Geometry_normal_doc},