[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27295] trunk/blender: re-project: operators for projecting from a view screenshot rather then a camera.

Campbell Barton ideasman42 at gmail.com
Sat Mar 6 20:46:21 CET 2010


Revision: 27295
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27295
Author:   campbellbarton
Date:     2010-03-06 20:46:21 +0100 (Sat, 06 Mar 2010)

Log Message:
-----------
re-project: operators for projecting from a view screenshot rather then a camera.
 - new mode for projecting an image with the view matrix saved in the image id-properties rather then using the camera matrix.
 - operator to screenshot the view and create a new image with the view matrix stored in the image.

these will be used for better re-project integration and are not immediately very useful.

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/space_view3d_toolbar.py
    trunk/blender/source/blender/editors/include/ED_view3d.h
    trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_intern.h
    trunk/blender/source/blender/editors/sculpt_paint/paint_ops.c
    trunk/blender/source/blender/editors/sculpt_paint/sculpt.c
    trunk/blender/source/blender/editors/space_view3d/view3d_view.c

Modified: trunk/blender/release/scripts/ui/space_view3d_toolbar.py
===================================================================
--- trunk/blender/release/scripts/ui/space_view3d_toolbar.py	2010-03-06 18:21:57 UTC (rev 27294)
+++ trunk/blender/release/scripts/ui/space_view3d_toolbar.py	2010-03-06 19:46:21 UTC (rev 27295)
@@ -909,7 +909,7 @@
 
         sub = col.column()
         col.operator("image.save_dirty", text="Save Edited")
-        col.operator("paint.camera_project")
+        col.operator("paint.project_image")
 
 
 class VIEW3D_MT_tools_projectpaint_clone(bpy.types.Menu):

Modified: trunk/blender/source/blender/editors/include/ED_view3d.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_view3d.h	2010-03-06 18:21:57 UTC (rev 27294)
+++ trunk/blender/source/blender/editors/include/ED_view3d.h	2010-03-06 19:46:21 UTC (rev 27295)
@@ -98,6 +98,7 @@
 void viewline(struct ARegion *ar, struct View3D *v3d, float mval[2], float ray_start[3], float ray_end[3]);
 void viewray(struct ARegion *ar, struct View3D *v3d, float mval[2], float ray_start[3], float ray_normal[3]);
 
+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, 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]);

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image.c	2010-03-06 18:21:57 UTC (rev 27294)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image.c	2010-03-06 19:46:21 UTC (rev 27295)
@@ -64,6 +64,7 @@
 #include "DNA_windowmanager_types.h"
 
 #include "BKE_context.h"
+#include "BKE_idprop.h"
 #include "BKE_object.h"
 #include "BKE_brush.h"
 #include "BKE_global.h"
@@ -76,6 +77,7 @@
 #include "BKE_DerivedMesh.h"
 #include "BKE_report.h"
 #include "BKE_depsgraph.h"
+#include "BKE_library.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
@@ -186,8 +188,13 @@
 #define PROJ_FACE_NOSEAM4	1<<7
 
 #define PROJ_SRC_VIEW		1
-#define PROJ_SRC_CAM		2
+#define PROJ_SRC_IMAGE_CAM	2
+#define PROJ_SRC_IMAGE_VIEW	3
 
+#define PROJ_VIEW_DATA_ID "view_data"
+#define PROJ_VIEW_DATA_SIZE (4*4 + 4*4 + 3) /* viewmat + winmat + clipsta + clipend + is_ortho */
+
+
 /* a slightly scaled down face is used to get fake 3D location for edge pixels in the seams
  * as this number approaches  1.0f the likelihood increases of float precision errors where
  * it is occluded by an adjacent face */
@@ -293,6 +300,7 @@
 	float clipsta, clipend;
 	
 	/* reproject vars */
+	Image *reproject_image;
 	ImBuf *reproject_ibuf;
 
 
@@ -2770,6 +2778,19 @@
 #endif
 }
 
+static int project_paint_view_clip(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend)
+{
+	int orth= get_view3d_cliprange(v3d, rv3d, clipsta, clipend);
+
+	if (orth) { /* only needed for ortho */
+		float fac = 2.0f / ((*clipend) - (*clipsta));
+		*clipsta *= fac;
+		*clipend *= fac;
+	}
+
+	return orth;
+}
+
 /* run once per stroke before projection painting */
 static void project_paint_begin(ProjPaintState *ps)
 {	
@@ -2806,8 +2827,8 @@
 	/* paint onto the derived mesh */
 	
 	/* Workaround for subsurf selection, try the display mesh first */
-	if (ps->source==PROJ_SRC_CAM) {
-		/* using render mesh */
+	if (ps->source==PROJ_SRC_IMAGE_CAM) {
+		/* using render mesh, assume only camera was rendered from */
 		ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->v3d->customdata_mask | CD_MASK_MTFACE);
 		ps->dm_release= TRUE;
 	}
@@ -2882,13 +2903,13 @@
 	ps->viewDir[2] = 1.0f;
 	
 	{
-		rctf viewplane;
 		float viewmat[4][4];
 		float viewinv[4][4];
 
 		invert_m4_m4(ps->ob->imat, ps->ob->obmat);
 
 		if(ps->source==PROJ_SRC_VIEW) {
+			/* normal drawing */
 			ps->winx= ps->ar->winx;
 			ps->winy= ps->ar->winy;
 
@@ -2897,47 +2918,55 @@
 
 			view3d_get_object_project_mat(ps->rv3d, ps->ob, ps->projectMat);
 
-			ps->is_ortho= get_view3d_viewplane(ps->v3d, ps->rv3d, ps->winx, ps->winy, &viewplane, &ps->clipsta, &ps->clipend, NULL);
-
-			//printf("%f %f\n", ps->clipsta, ps->clipend);
-			if (ps->is_ortho) { /* only needed for ortho */
-				float fac = 2.0f / (ps->clipend - ps->clipsta);
-				ps->clipsta *= fac;
-				ps->clipend *= fac;
-			}
-			else {
-				/* TODO - can we even adjust for clip start/end? */
-			}
+			ps->is_ortho= project_paint_view_clip(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend);
 		}
-		else if (ps->source==PROJ_SRC_CAM) {
-			Object *camera= ps->scene->camera;
-			rctf viewplane;
+		else {
+			/* reprojection */
 			float winmat[4][4];
 			float vmat[4][4];
 
-			/* dont actually use these */
-			float _viewdx, _viewdy, _ycor, _lens=0.0f;
-
-
 			ps->winx= ps->reproject_ibuf->x;
 			ps->winy= ps->reproject_ibuf->y;
 
-			/* viewmat & viewinv */
-			copy_m4_m4(viewinv, ps->scene->camera->obmat);
-			normalize_m4(viewinv);
-			invert_m4_m4(viewmat, viewinv);
+			if (ps->source==PROJ_SRC_IMAGE_VIEW) {
+				/* image stores camera data, tricky */
+				IDProperty *idgroup= IDP_GetProperties(&ps->reproject_image->id, 0);
+				IDProperty *view_data= IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID);
 
-			/* camera winmat */
-			object_camera_matrix(&ps->scene->r, camera, ps->winx, ps->winy, 0,
-					winmat, &viewplane, &ps->clipsta, &ps->clipend,
-					&_lens, &_ycor, &_viewdx, &_viewdy);
+				float *array= (float *)IDP_Array(view_data);
 
+				/* use image array, written when creating image */
+				memcpy(winmat, array, sizeof(winmat)); array += sizeof(winmat)/sizeof(float);
+				memcpy(viewmat, array, sizeof(viewmat)); array += sizeof(viewmat)/sizeof(float);
+				ps->clipsta= array[0];
+				ps->clipend= array[1];
+				ps->is_ortho= array[2] ? 1:0;
 
+				invert_m4_m4(viewinv, viewmat);
+			}
+			else if (ps->source==PROJ_SRC_IMAGE_CAM) {
+				Object *camera= ps->scene->camera;
+
+				/* dont actually use these */
+				float _viewdx, _viewdy, _ycor, _lens=0.0f;
+				rctf _viewplane;
+
+				/* viewmat & viewinv */
+				copy_m4_m4(viewinv, ps->scene->camera->obmat);
+				normalize_m4(viewinv);
+				invert_m4_m4(viewmat, viewinv);
+
+				/* camera winmat */
+				object_camera_matrix(&ps->scene->r, camera, ps->winx, ps->winy, 0,
+						winmat, &_viewplane, &ps->clipsta, &ps->clipend,
+						&_lens, &_ycor, &_viewdx, &_viewdy);
+
+				ps->is_ortho= (ps->scene->r.mode & R_ORTHO) ? 1 : 0;
+			}
+
 			/* same as view3d_get_object_project_mat */
 			mul_m4_m4m4(vmat, ps->ob->obmat, viewmat);
 			mul_m4_m4m4(ps->projectMat, vmat, winmat);
-
-			ps->is_ortho= (ps->scene->r.mode & R_ORTHO) ? 1 : 0;
 		}
 
 
@@ -3016,7 +3045,7 @@
 		CLAMP(ps->screenMax[1], -ps->brush->size, ps->winy + ps->brush->size);
 #endif
 	}
-	else if (ps->source==PROJ_SRC_CAM) {
+	else { /* reprojection, use bounds */
 		ps->screenMin[0]= 0;
 		ps->screenMax[0]= ps->winx;
 
@@ -3449,7 +3478,7 @@
 		ps->context_bucket_x = ps->bucketMin[0];
 		ps->context_bucket_y = ps->bucketMin[1];
 	}
-	else { /* PROJ_SRC_CAM */
+	else { /* reproject: PROJ_SRC_* */
 		ps->bucketMin[0]= 0;
 		ps->bucketMin[1]= 0;
 
@@ -3476,7 +3505,7 @@
 			/* use bucket_bounds for project_bucket_isect_circle and project_bucket_init*/
 			project_bucket_bounds(ps, ps->context_bucket_x, ps->context_bucket_y, bucket_bounds);
 			
-			if (	(ps->source==PROJ_SRC_CAM) ||
+			if (	(ps->source != PROJ_SRC_VIEW) ||
 					project_bucket_isect_circle(ps->context_bucket_x, ps->context_bucket_y, mval, ps->brush->size * ps->brush->size, bucket_bounds)
 			) {
 				*bucket_index = ps->context_bucket_x + (ps->context_bucket_y * ps->buckets_x);
@@ -3701,7 +3730,7 @@
 			project_bucket_init(ps, thread_index, bucket_index, &bucket_bounds);
 		}
 
-		if(ps->source==PROJ_SRC_CAM) {
+		if(ps->source != PROJ_SRC_VIEW) {
 
 			/* Re-Projection, simple, no brushes! */
 			
@@ -5331,6 +5360,8 @@
 	Scene *scene= CTX_data_scene(C);
 	ProjPaintState ps;
 	int orig_brush_size;
+	IDProperty *idgroup;
+	IDProperty *view_data= NULL;
 
 	memset(&ps, 0, sizeof(ps));
 
@@ -5351,7 +5382,9 @@
 		return OPERATOR_CANCELLED;
 	}
 
+	ps.reproject_image= image;
 	ps.reproject_ibuf= BKE_image_get_ibuf(image, NULL);
+
 	if(ps.reproject_ibuf==NULL || ps.reproject_ibuf->rect==NULL) {
 		BKE_report(op->reports, RPT_ERROR, "Image data could not be found.");
 		return OPERATOR_CANCELLED;
@@ -5363,10 +5396,28 @@
 	orig_brush_size= ps.brush->size;
 	ps.brush->size= 32; /* cover the whole image */
 
-	ps.tool= PAINT_TOOL_DRAW;
+	ps.tool= PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */
 
-	ps.source= PROJ_SRC_CAM;
+	idgroup= IDP_GetProperties(&image->id, 0);
+	if(idgroup) {
+		view_data= IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID);
 
+		/* type check to make sure its ok */
+		if(view_data->len != PROJ_VIEW_DATA_SIZE || view_data->type != IDP_ARRAY || view_data->subtype != IDP_FLOAT) {
+			BKE_report(op->reports, RPT_ERROR, "Image project data invalid.");
+			return OPERATOR_CANCELLED;
+		}
+	}
+
+
+	if(view_data) {
+		/* image has stored view projection info */
+		ps.source= PROJ_SRC_IMAGE_VIEW;
+	}
+	else {
+		ps.source= PROJ_SRC_IMAGE_CAM;
+	}
+
 	scene->toolsettings->imapaint.flag |= IMAGEPAINT_DRAWING;
 
 	undo_paint_push_begin(UNDO_PAINT_IMAGE, "Image Paint",
@@ -5405,13 +5456,13 @@
 	return OPERATOR_FINISHED;
 }
 
-void PAINT_OT_camera_project(wmOperatorType *ot)
+void PAINT_OT_project_image(wmOperatorType *ot)
 {
 	PropertyRNA *prop;
 
 	/* identifiers */
-	ot->name= "Camera Project";
-	ot->idname= "PAINT_OT_camera_project";
+	ot->name= "Project Image";
+	ot->idname= "PAINT_OT_project_image";
 	ot->description= "Project an edited render from the active camera back onto the object";
 
 	/* api callbacks */
@@ -5425,3 +5476,81 @@
 	RNA_def_enum_funcs(prop, RNA_image_itemf);
 	ot->prop= prop;
 }
+
+static Image *ED_region_image(ARegion *ar, char *filename)
+{
+	int x= ar->winrct.xmin;
+	int y= ar->winrct.ymin;
+	int w= ar->winrct.xmax-x;
+	int h= ar->winrct.ymax-y;
+
+	if (h && w) {
+		float color[] = {0, 0, 0, 1};
+		Image *image = BKE_add_image_size(w, h, filename, 0, 0, color);
+		ImBuf *ibuf= BKE_image_get_ibuf(image, NULL);
+
+		glReadBuffer(GL_FRONT);
+		glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+		glFinish();

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list