| 
									
										
										
										
											2011-09-18 12:16:03 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2012-08-05 15:04:10 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2011-09-18 12:16:03 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup edsculpt | 
					
						
							| 
									
										
										
										
											2011-02-27 20:29:51 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_mesh_types.h"
 | 
					
						
							|  |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							|  |  |  | #include "DNA_object_types.h"
 | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | #include "DNA_material_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | #include "DNA_scene_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-04 04:01:27 +00:00
										 |  |  | #include "DNA_brush_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | #include "BLI_math_color.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-08 06:07:10 +11:00
										 |  |  | #include "BLI_listbase.h"
 | 
					
						
							| 
									
										
										
										
											2012-07-12 08:31:23 +00:00
										 |  |  | #include "BLI_rect.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-16 17:32:01 +10:00
										 |  |  | #include "BLT_translation.h"
 | 
					
						
							| 
									
										
										
										
											2013-03-28 15:41:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-11 00:43:08 +00:00
										 |  |  | #include "BKE_brush.h"
 | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-25 15:21:40 +02:00
										 |  |  | #include "BKE_customdata.h"
 | 
					
						
							| 
									
										
										
										
											2014-04-13 17:20:06 +03:00
										 |  |  | #include "BKE_image.h"
 | 
					
						
							| 
									
										
										
										
											2015-01-09 18:03:42 +01:00
										 |  |  | #include "BKE_material.h"
 | 
					
						
							| 
									
										
										
										
											2018-10-09 17:31:04 +02:00
										 |  |  | #include "BKE_mesh_runtime.h"
 | 
					
						
							| 
									
										
										
										
											2009-08-16 19:50:00 +00:00
										 |  |  | #include "BKE_paint.h"
 | 
					
						
							| 
									
										
										
										
											2013-03-16 16:11:50 +00:00
										 |  |  | #include "BKE_report.h"
 | 
					
						
							| 
									
										
										
										
											2009-08-16 19:50:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 11:53:13 +02:00
										 |  |  | #include "DEG_depsgraph.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-25 15:21:40 +02:00
										 |  |  | #include "DEG_depsgraph_query.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-21 11:53:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | #include "RNA_define.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-21 01:39:03 +10:00
										 |  |  | #include "GPU_glew.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-21 17:49:21 -04:00
										 |  |  | #include "GPU_matrix.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-27 19:07:23 -06:00
										 |  |  | #include "GPU_state.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-13 17:20:06 +03:00
										 |  |  | #include "IMB_colormanagement.h"
 | 
					
						
							|  |  |  | #include "IMB_imbuf_types.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-27 23:24:13 +01:00
										 |  |  | #include "IMB_imbuf.h"
 | 
					
						
							| 
									
										
										
										
											2014-04-13 17:20:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-31 00:38:50 +00:00
										 |  |  | #include "RE_render_ext.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "ED_view3d.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | #include "ED_screen.h"
 | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-28 19:35:26 +00:00
										 |  |  | #include "BLI_sys_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | #include "ED_mesh.h" /* for face mask functions */
 | 
					
						
							| 
									
										
										
										
											2019-08-07 12:43:04 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "DRW_select_buffer.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | #include "WM_api.h"
 | 
					
						
							|  |  |  | #include "WM_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | #include "paint_intern.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 20:19:55 +00:00
										 |  |  | /* Convert the object-space axis-aligned bounding box (expressed as
 | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  |  * its minimum and maximum corners) into a screen-space rectangle, | 
					
						
							|  |  |  |  * returns zero if the result is empty */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | bool paint_convert_bb_to_rect(rcti *rect, | 
					
						
							|  |  |  |                               const float bb_min[3], | 
					
						
							|  |  |  |                               const float bb_max[3], | 
					
						
							|  |  |  |                               const ARegion *ar, | 
					
						
							|  |  |  |                               RegionView3D *rv3d, | 
					
						
							|  |  |  |                               Object *ob) | 
					
						
							| 
									
										
										
										
											2011-12-26 20:19:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float projection_mat[4][4]; | 
					
						
							|  |  |  |   int i, j, k; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BLI_rcti_init_minmax(rect); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* return zero if the bounding box has non-positive volume */ | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   if (bb_min[0] > bb_max[0] || bb_min[1] > bb_max[1] || bb_min[2] > bb_max[2]) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ED_view3d_ob_project_mat_get(rv3d, ob, projection_mat); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |   for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  |     for (j = 0; j < 2; j++) { | 
					
						
							|  |  |  |       for (k = 0; k < 2; k++) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         float vec[3], proj[2]; | 
					
						
							|  |  |  |         int proj_i[2]; | 
					
						
							|  |  |  |         vec[0] = i ? bb_min[0] : bb_max[0]; | 
					
						
							|  |  |  |         vec[1] = j ? bb_min[1] : bb_max[1]; | 
					
						
							|  |  |  |         vec[2] = k ? bb_min[2] : bb_max[2]; | 
					
						
							|  |  |  |         /* convert corner to screen space */ | 
					
						
							|  |  |  |         ED_view3d_project_float_v2_m4(ar, vec, proj, projection_mat); | 
					
						
							|  |  |  |         /* expand 2D rectangle */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* we could project directly to int? */ | 
					
						
							|  |  |  |         proj_i[0] = proj[0]; | 
					
						
							|  |  |  |         proj_i[1] = proj[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         BLI_rcti_do_minmax_v(rect, proj_i); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* return false if the rectangle has non-positive area */ | 
					
						
							|  |  |  |   return rect->xmin < rect->xmax && rect->ymin < rect->ymax; | 
					
						
							| 
									
										
										
										
											2011-12-26 20:19:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Get four planes in object-space that describe the projection of
 | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  |  * screen_rect from screen into object-space (essentially converting a | 
					
						
							|  |  |  |  * 2D screens-space bounding box into four 3D planes) */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | void paint_calc_redraw_planes(float planes[4][4], | 
					
						
							|  |  |  |                               const ARegion *ar, | 
					
						
							|  |  |  |                               Object *ob, | 
					
						
							|  |  |  |                               const rcti *screen_rect) | 
					
						
							| 
									
										
										
										
											2011-12-26 20:19:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BoundBox bb; | 
					
						
							|  |  |  |   rcti rect; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* use some extra space just in case */ | 
					
						
							|  |  |  |   rect = *screen_rect; | 
					
						
							|  |  |  |   rect.xmin -= 2; | 
					
						
							|  |  |  |   rect.xmax += 2; | 
					
						
							|  |  |  |   rect.ymin -= 2; | 
					
						
							|  |  |  |   rect.ymax += 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ED_view3d_clipping_calc(&bb, planes, ar, ob, &rect); | 
					
						
							| 
									
										
										
										
											2011-12-26 20:19:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | float paint_calc_object_space_radius(ViewContext *vc, const float center[3], float pixel_radius) | 
					
						
							| 
									
										
										
										
											2011-01-07 22:46:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Object *ob = vc->obact; | 
					
						
							|  |  |  |   float delta[3], scale, loc[3]; | 
					
						
							|  |  |  |   const float mval_f[2] = {pixel_radius, 0.0f}; | 
					
						
							|  |  |  |   float zfac; | 
					
						
							| 
									
										
										
										
											2011-01-07 22:46:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   mul_v3_m4v3(loc, ob->obmat, center); | 
					
						
							| 
									
										
										
										
											2011-01-07 22:46:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   zfac = ED_view3d_calc_zfac(vc->rv3d, loc, NULL); | 
					
						
							|  |  |  |   ED_view3d_win_to_delta(vc->ar, mval_f, delta, zfac); | 
					
						
							| 
									
										
										
										
											2011-01-07 22:46:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   scale = fabsf(mat4_to_scale(ob->obmat)); | 
					
						
							|  |  |  |   scale = (scale == 0.0f) ? 1.0f : scale; | 
					
						
							| 
									
										
										
										
											2011-01-07 22:46:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return len_v3(delta) / scale; | 
					
						
							| 
									
										
										
										
											2011-01-07 22:46:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-03 18:43:18 +11:00
										 |  |  | float paint_get_tex_pixel(const MTex *mtex, float u, float v, struct ImagePool *pool, int thread) | 
					
						
							| 
									
										
										
										
											2011-01-07 22:03:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float intensity, rgba[4]; | 
					
						
							|  |  |  |   float co[3] = {u, v, 0.0f}; | 
					
						
							| 
									
										
										
										
											2011-01-07 22:03:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   externtex(mtex, co, &intensity, rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false); | 
					
						
							| 
									
										
										
										
											2011-01-07 22:03:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return intensity; | 
					
						
							| 
									
										
										
										
											2011-01-07 22:03:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | void paint_get_tex_pixel_col(const MTex *mtex, | 
					
						
							|  |  |  |                              float u, | 
					
						
							|  |  |  |                              float v, | 
					
						
							|  |  |  |                              float rgba[4], | 
					
						
							|  |  |  |                              struct ImagePool *pool, | 
					
						
							|  |  |  |                              int thread, | 
					
						
							|  |  |  |                              bool convert_to_linear, | 
					
						
							|  |  |  |                              struct ColorSpace *colorspace) | 
					
						
							| 
									
										
										
										
											2013-03-31 00:38:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float co[3] = {u, v, 0.0f}; | 
					
						
							|  |  |  |   int hasrgb; | 
					
						
							|  |  |  |   float intensity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   hasrgb = externtex( | 
					
						
							|  |  |  |       mtex, co, &intensity, rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false, false); | 
					
						
							|  |  |  |   if (!hasrgb) { | 
					
						
							|  |  |  |     rgba[0] = intensity; | 
					
						
							|  |  |  |     rgba[1] = intensity; | 
					
						
							|  |  |  |     rgba[2] = intensity; | 
					
						
							|  |  |  |     rgba[3] = 1.0f; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   if (convert_to_linear) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, colorspace); | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   linearrgb_to_srgb_v3_v3(rgba, rgba); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-04 11:31:51 +11:00
										 |  |  |   clamp_v4(rgba, 0.0f, 1.0f); | 
					
						
							| 
									
										
										
										
											2013-03-31 00:38:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-03 14:00:34 +02:00
										 |  |  | void paint_stroke_operator_properties(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   static const EnumPropertyItem stroke_mode_items[] = { | 
					
						
							|  |  |  |       {BRUSH_STROKE_NORMAL, "NORMAL", 0, "Regular", "Apply brush normally"}, | 
					
						
							|  |  |  |       {BRUSH_STROKE_INVERT, | 
					
						
							|  |  |  |        "INVERT", | 
					
						
							|  |  |  |        0, | 
					
						
							|  |  |  |        "Invert", | 
					
						
							|  |  |  |        "Invert action of brush for duration of stroke"}, | 
					
						
							|  |  |  |       {BRUSH_STROKE_SMOOTH, | 
					
						
							|  |  |  |        "SMOOTH", | 
					
						
							|  |  |  |        0, | 
					
						
							|  |  |  |        "Smooth", | 
					
						
							|  |  |  |        "Switch brush to smooth mode for duration of stroke"}, | 
					
						
							|  |  |  |       {0}, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); | 
					
						
							|  |  |  |   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   RNA_def_enum(ot->srna, | 
					
						
							|  |  |  |                "mode", | 
					
						
							|  |  |  |                stroke_mode_items, | 
					
						
							|  |  |  |                BRUSH_STROKE_NORMAL, | 
					
						
							|  |  |  |                "Stroke Mode", | 
					
						
							|  |  |  |                "Action taken when a paint stroke is made"); | 
					
						
							| 
									
										
										
										
											2014-09-03 14:00:34 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | /* 3D Paint */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void imapaint_project(float matrix[4][4], const float co[3], float pco[4]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   copy_v3_v3(pco, co); | 
					
						
							|  |  |  |   pco[3] = 1.0f; | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   mul_m4_v4(matrix, pco); | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static void imapaint_tri_weights(float matrix[4][4], | 
					
						
							| 
									
										
										
										
											2019-09-14 08:10:50 +10:00
										 |  |  |                                  const GLint view[4], | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                                  const float v1[3], | 
					
						
							|  |  |  |                                  const float v2[3], | 
					
						
							|  |  |  |                                  const float v3[3], | 
					
						
							|  |  |  |                                  const float co[2], | 
					
						
							|  |  |  |                                  float w[3]) | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float pv1[4], pv2[4], pv3[4], h[3], divw; | 
					
						
							|  |  |  |   float wmat[3][3], invwmat[3][3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* compute barycentric coordinates */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* project the verts */ | 
					
						
							|  |  |  |   imapaint_project(matrix, v1, pv1); | 
					
						
							|  |  |  |   imapaint_project(matrix, v2, pv2); | 
					
						
							|  |  |  |   imapaint_project(matrix, v3, pv3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* do inverse view mapping, see gluProject man page */ | 
					
						
							|  |  |  |   h[0] = (co[0] - view[0]) * 2.0f / view[2] - 1.0f; | 
					
						
							|  |  |  |   h[1] = (co[1] - view[1]) * 2.0f / view[3] - 1.0f; | 
					
						
							|  |  |  |   h[2] = 1.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* solve for (w1,w2,w3)/perspdiv in:
 | 
					
						
							|  |  |  |    * h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   wmat[0][0] = pv1[0]; | 
					
						
							|  |  |  |   wmat[1][0] = pv2[0]; | 
					
						
							|  |  |  |   wmat[2][0] = pv3[0]; | 
					
						
							|  |  |  |   wmat[0][1] = pv1[1]; | 
					
						
							|  |  |  |   wmat[1][1] = pv2[1]; | 
					
						
							|  |  |  |   wmat[2][1] = pv3[1]; | 
					
						
							|  |  |  |   wmat[0][2] = pv1[3]; | 
					
						
							|  |  |  |   wmat[1][2] = pv2[3]; | 
					
						
							|  |  |  |   wmat[2][2] = pv3[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   invert_m3_m3(invwmat, wmat); | 
					
						
							|  |  |  |   mul_m3_v3(invwmat, h); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   copy_v3_v3(w, h); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* w is still divided by perspdiv, make it sum to one */ | 
					
						
							|  |  |  |   divw = w[0] + w[1] + w[2]; | 
					
						
							|  |  |  |   if (divw != 0.0f) { | 
					
						
							|  |  |  |     mul_v3_fl(w, 1.0f / divw); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* compute uv coordinates of mouse in face */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static void imapaint_pick_uv(Mesh *me_eval, | 
					
						
							|  |  |  |                              Scene *scene, | 
					
						
							|  |  |  |                              Object *ob_eval, | 
					
						
							|  |  |  |                              unsigned int faceindex, | 
					
						
							|  |  |  |                              const int xy[2], | 
					
						
							|  |  |  |                              float uv[2]) | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int i, findex; | 
					
						
							|  |  |  |   float p[2], w[3], absw, minabsw; | 
					
						
							|  |  |  |   float matrix[4][4], proj[4][4]; | 
					
						
							|  |  |  |   GLint view[4]; | 
					
						
							|  |  |  |   const eImagePaintMode mode = scene->toolsettings->imapaint.mode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval); | 
					
						
							|  |  |  |   const int tottri = me_eval->runtime.looptris.len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const MVert *mvert = me_eval->mvert; | 
					
						
							|  |  |  |   const MPoly *mpoly = me_eval->mpoly; | 
					
						
							|  |  |  |   const MLoop *mloop = me_eval->mloop; | 
					
						
							|  |  |  |   const int *index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* get the needed opengl matrices */ | 
					
						
							|  |  |  |   GPU_viewport_size_get_i(view); | 
					
						
							|  |  |  |   GPU_matrix_model_view_get(matrix); | 
					
						
							|  |  |  |   GPU_matrix_projection_get(proj); | 
					
						
							|  |  |  |   view[0] = view[1] = 0; | 
					
						
							|  |  |  |   mul_m4_m4m4(matrix, matrix, ob_eval->obmat); | 
					
						
							|  |  |  |   mul_m4_m4m4(matrix, proj, matrix); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   minabsw = 1e10; | 
					
						
							|  |  |  |   uv[0] = uv[1] = 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* test all faces in the derivedmesh with the original index of the picked face */ | 
					
						
							|  |  |  |   /* face means poly here, not triangle, indeed */ | 
					
						
							|  |  |  |   for (i = 0; i < tottri; i++, lt++) { | 
					
						
							|  |  |  |     findex = index_mp_to_orig ? index_mp_to_orig[lt->poly] : lt->poly; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (findex == faceindex) { | 
					
						
							|  |  |  |       const MLoopUV *mloopuv; | 
					
						
							|  |  |  |       const MPoly *mp = &mpoly[lt->poly]; | 
					
						
							|  |  |  |       const MLoopUV *tri_uv[3]; | 
					
						
							|  |  |  |       float tri_co[3][3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (int j = 3; j--;) { | 
					
						
							|  |  |  |         copy_v3_v3(tri_co[j], mvert[mloop[lt->tri[j]].v].co); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (mode == IMAGEPAINT_MODE_MATERIAL) { | 
					
						
							|  |  |  |         const Material *ma; | 
					
						
							|  |  |  |         const TexPaintSlot *slot; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 11:23:58 +01:00
										 |  |  |         ma = BKE_object_material_get(ob_eval, mp->mat_nr + 1); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         slot = &ma->texpaintslot[ma->paint_active_slot]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!(slot && slot->uvname && | 
					
						
							|  |  |  |               (mloopuv = CustomData_get_layer_named(&me_eval->ldata, CD_MLOOPUV, slot->uvname)))) { | 
					
						
							|  |  |  |           mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       tri_uv[0] = &mloopuv[lt->tri[0]]; | 
					
						
							|  |  |  |       tri_uv[1] = &mloopuv[lt->tri[1]]; | 
					
						
							|  |  |  |       tri_uv[2] = &mloopuv[lt->tri[2]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       p[0] = xy[0]; | 
					
						
							|  |  |  |       p[1] = xy[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       imapaint_tri_weights(matrix, view, UNPACK3(tri_co), p, w); | 
					
						
							|  |  |  |       absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]); | 
					
						
							|  |  |  |       if (absw < minabsw) { | 
					
						
							|  |  |  |         uv[0] = tri_uv[0]->uv[0] * w[0] + tri_uv[1]->uv[0] * w[1] + tri_uv[2]->uv[0] * w[2]; | 
					
						
							|  |  |  |         uv[1] = tri_uv[0]->uv[1] * w[0] + tri_uv[1]->uv[1] * w[1] + tri_uv[2]->uv[1] * w[2]; | 
					
						
							|  |  |  |         minabsw = absw; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* returns 0 if not found, otherwise 1 */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int imapaint_pick_face(ViewContext *vc, | 
					
						
							|  |  |  |                               const int mval[2], | 
					
						
							|  |  |  |                               unsigned int *r_index, | 
					
						
							|  |  |  |                               unsigned int totpoly) | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   if (totpoly == 0) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* sample only on the exact position */ | 
					
						
							| 
									
										
										
										
											2019-05-16 09:26:33 +10:00
										 |  |  |   ED_view3d_select_id_validate(vc); | 
					
						
							| 
									
										
										
										
											2019-08-15 10:31:54 -03:00
										 |  |  |   *r_index = DRW_select_buffer_sample_point(vc->depsgraph, vc->ar, vc->v3d, mval); | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   (*r_index)--; | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return 1; | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-09 18:03:42 +01:00
										 |  |  | static Image *imapaint_face_image(Object *ob, Mesh *me, int face_index) | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Image *ima; | 
					
						
							|  |  |  |   MPoly *mp = me->mpoly + face_index; | 
					
						
							| 
									
										
										
										
											2020-02-05 11:23:58 +01:00
										 |  |  |   Material *ma = BKE_object_material_get(ob, mp->mat_nr + 1); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ima = ma && ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL; | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return ima; | 
					
						
							| 
									
										
										
										
											2014-07-21 12:02:05 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 14:39:54 +02:00
										 |  |  | /* Uses symm to selectively flip any axis of a coordinate. */ | 
					
						
							| 
									
										
										
										
											2020-01-07 16:46:56 +01:00
										 |  |  | void flip_v3_v3(float out[3], const float in[3], const ePaintSymmetryFlags symm) | 
					
						
							| 
									
										
										
										
											2013-12-19 14:39:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   if (symm & PAINT_SYMM_X) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     out[0] = -in[0]; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     out[0] = in[0]; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (symm & PAINT_SYMM_Y) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     out[1] = -in[1]; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     out[1] = in[1]; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (symm & PAINT_SYMM_Z) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     out[2] = -in[2]; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     out[2] = in[2]; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-12-19 14:39:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-07 16:46:56 +01:00
										 |  |  | void flip_qt_qt(float out[4], const float in[4], const ePaintSymmetryFlags symm) | 
					
						
							| 
									
										
										
										
											2016-01-21 21:05:49 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float axis[3], angle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   quat_to_axis_angle(axis, &angle, in); | 
					
						
							|  |  |  |   normalize_v3(axis); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (symm & PAINT_SYMM_X) { | 
					
						
							|  |  |  |     axis[0] *= -1.0f; | 
					
						
							|  |  |  |     angle *= -1.0f; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (symm & PAINT_SYMM_Y) { | 
					
						
							|  |  |  |     axis[1] *= -1.0f; | 
					
						
							|  |  |  |     angle *= -1.0f; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (symm & PAINT_SYMM_Z) { | 
					
						
							|  |  |  |     axis[2] *= -1.0f; | 
					
						
							|  |  |  |     angle *= -1.0f; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   axis_angle_normalized_to_quat(out, axis, angle); | 
					
						
							| 
									
										
										
										
											2016-01-21 21:05:49 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | /* used for both 3d view and image window */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | void paint_sample_color( | 
					
						
							|  |  |  |     bContext *C, ARegion *ar, int x, int y, bool texpaint_proj, bool use_palette) | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Scene *scene = CTX_data_scene(C); | 
					
						
							| 
									
										
										
										
											2019-07-25 16:36:22 +02:00
										 |  |  |   Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Paint *paint = BKE_paint_get_active_from_context(C); | 
					
						
							|  |  |  |   Palette *palette = BKE_paint_palette(paint); | 
					
						
							|  |  |  |   PaletteColor *color = NULL; | 
					
						
							|  |  |  |   Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); | 
					
						
							|  |  |  |   unsigned int col; | 
					
						
							|  |  |  |   const unsigned char *cp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   CLAMP(x, 0, ar->winx); | 
					
						
							|  |  |  |   CLAMP(y, 0, ar->winy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (use_palette) { | 
					
						
							|  |  |  |     if (!palette) { | 
					
						
							|  |  |  |       palette = BKE_palette_add(CTX_data_main(C), "Palette"); | 
					
						
							|  |  |  |       BKE_paint_palette_set(paint, palette); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     color = BKE_palette_color_add(palette); | 
					
						
							|  |  |  |     palette->active_color = BLI_listbase_count(&palette->colors) - 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (CTX_wm_view3d(C) && texpaint_proj) { | 
					
						
							| 
									
										
										
										
											2019-04-29 14:14:14 +10:00
										 |  |  |     /* first try getting a color directly from the mesh faces if possible */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     ViewLayer *view_layer = CTX_data_view_layer(C); | 
					
						
							|  |  |  |     Object *ob = OBACT(view_layer); | 
					
						
							|  |  |  |     Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | 
					
						
							|  |  |  |     bool sample_success = false; | 
					
						
							|  |  |  |     ImagePaintSettings *imapaint = &scene->toolsettings->imapaint; | 
					
						
							|  |  |  |     bool use_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ob) { | 
					
						
							|  |  |  |       CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH; | 
					
						
							|  |  |  |       cddata_masks.pmask |= CD_MASK_ORIGINDEX; | 
					
						
							|  |  |  |       Mesh *me = (Mesh *)ob->data; | 
					
						
							|  |  |  |       Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob_eval, &cddata_masks); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ViewContext vc; | 
					
						
							|  |  |  |       const int mval[2] = {x, y}; | 
					
						
							|  |  |  |       unsigned int faceindex; | 
					
						
							|  |  |  |       unsigned int totpoly = me->totpoly; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (CustomData_has_layer(&me_eval->ldata, CD_MLOOPUV)) { | 
					
						
							| 
									
										
										
										
											2019-09-18 17:19:07 +02:00
										 |  |  |         ED_view3d_viewcontext_init(C, &vc, depsgraph); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         view3d_operator_needs_opengl(C); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (imapaint_pick_face(&vc, mval, &faceindex, totpoly)) { | 
					
						
							|  |  |  |           Image *image; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |           if (use_material) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             image = imapaint_face_image(ob_eval, me_eval, faceindex); | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |             image = imapaint->canvas; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           if (image) { | 
					
						
							| 
									
										
										
										
											2020-01-13 15:09:21 +01:00
										 |  |  |             float uv[2]; | 
					
						
							|  |  |  |             float u, v; | 
					
						
							|  |  |  |             ImageUser iuser; | 
					
						
							|  |  |  |             BKE_imageuser_default(&iuser); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             imapaint_pick_uv(me_eval, scene, ob_eval, faceindex, mval, uv); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (image->source == IMA_SRC_TILED) { | 
					
						
							|  |  |  |               float new_uv[2]; | 
					
						
							|  |  |  |               iuser.tile = BKE_image_get_tile_from_pos(image, uv, new_uv, NULL); | 
					
						
							|  |  |  |               u = new_uv[0]; | 
					
						
							|  |  |  |               v = new_uv[1]; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |               u = fmodf(uv[0], 1.0f); | 
					
						
							|  |  |  |               v = fmodf(uv[1], 1.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |               if (u < 0.0f) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                 u += 1.0f; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |               } | 
					
						
							|  |  |  |               if (v < 0.0f) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                 v += 1.0f; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2020-01-13 15:09:21 +01:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, NULL); | 
					
						
							| 
									
										
										
										
											2020-02-11 17:13:33 +11:00
										 |  |  |             if (ibuf && (ibuf->rect || ibuf->rect_float)) { | 
					
						
							| 
									
										
										
										
											2020-01-13 15:09:21 +01:00
										 |  |  |               sample_success = true; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |               u = u * ibuf->x; | 
					
						
							|  |  |  |               v = v * ibuf->y; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               if (ibuf->rect_float) { | 
					
						
							|  |  |  |                 float rgba_f[4]; | 
					
						
							|  |  |  |                 bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); | 
					
						
							|  |  |  |                 straight_to_premul_v4(rgba_f); | 
					
						
							|  |  |  |                 if (use_palette) { | 
					
						
							|  |  |  |                   linearrgb_to_srgb_v3_v3(color->rgb, rgba_f); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                   linearrgb_to_srgb_v3_v3(rgba_f, rgba_f); | 
					
						
							|  |  |  |                   BKE_brush_color_set(scene, br, rgba_f); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               else { | 
					
						
							|  |  |  |                 unsigned char rgba[4]; | 
					
						
							|  |  |  |                 bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v); | 
					
						
							|  |  |  |                 if (use_palette) { | 
					
						
							|  |  |  |                   rgb_uchar_to_float(color->rgb, rgba); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                   float rgba_f[3]; | 
					
						
							|  |  |  |                   rgb_uchar_to_float(rgba_f, rgba); | 
					
						
							|  |  |  |                   BKE_brush_color_set(scene, br, rgba_f); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             BKE_image_release_ibuf(image, ibuf, NULL); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!sample_success) { | 
					
						
							|  |  |  |       glReadBuffer(GL_FRONT); | 
					
						
							|  |  |  |       glReadPixels( | 
					
						
							|  |  |  |           x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); | 
					
						
							|  |  |  |       glReadBuffer(GL_BACK); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       return; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:19:45 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     glReadBuffer(GL_FRONT); | 
					
						
							|  |  |  |     glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); | 
					
						
							|  |  |  |     glReadBuffer(GL_BACK); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   cp = (unsigned char *)&col; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (use_palette) { | 
					
						
							|  |  |  |     rgb_uchar_to_float(color->rgb, cp); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     float rgba_f[3]; | 
					
						
							|  |  |  |     rgb_uchar_to_float(rgba_f, cp); | 
					
						
							|  |  |  |     BKE_brush_color_set(scene, br, rgba_f); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-02-19 23:53:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | static int brush_curve_preset_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); | 
					
						
							| 
									
										
										
										
											2013-04-02 18:19:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (br) { | 
					
						
							|  |  |  |     Scene *scene = CTX_data_scene(C); | 
					
						
							|  |  |  |     ViewLayer *view_layer = CTX_data_view_layer(C); | 
					
						
							|  |  |  |     BKE_brush_curve_preset(br, RNA_enum_get(op->ptr, "shape")); | 
					
						
							|  |  |  |     BKE_paint_invalidate_cursor_overlay(scene, view_layer, br->curve); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 11:47:00 +02:00
										 |  |  | static bool brush_curve_preset_poll(bContext *C) | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return br && br->curve; | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BRUSH_OT_curve_preset(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PropertyRNA *prop; | 
					
						
							|  |  |  |   static const EnumPropertyItem prop_shape_items[] = { | 
					
						
							|  |  |  |       {CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""}, | 
					
						
							|  |  |  |       {CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""}, | 
					
						
							|  |  |  |       {CURVE_PRESET_MAX, "MAX", 0, "Max", ""}, | 
					
						
							|  |  |  |       {CURVE_PRESET_LINE, "LINE", 0, "Line", ""}, | 
					
						
							|  |  |  |       {CURVE_PRESET_ROUND, "ROUND", 0, "Round", ""}, | 
					
						
							|  |  |  |       {CURVE_PRESET_ROOT, "ROOT", 0, "Root", ""}, | 
					
						
							|  |  |  |       {0, NULL, 0, NULL, NULL}, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ot->name = "Preset"; | 
					
						
							|  |  |  |   ot->description = "Set brush shape"; | 
					
						
							|  |  |  |   ot->idname = "BRUSH_OT_curve_preset"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ot->exec = brush_curve_preset_exec; | 
					
						
							|  |  |  |   ot->poll = brush_curve_preset_poll; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   prop = RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", ""); | 
					
						
							|  |  |  |   RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ | 
					
						
							| 
									
										
										
										
											2009-08-14 04:45:29 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* face-select ops */ | 
					
						
							| 
									
										
										
										
											2010-10-15 01:36:14 +00:00
										 |  |  | static int paint_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   paintface_select_linked(C, CTX_data_active_object(C), NULL, true); | 
					
						
							|  |  |  |   ED_region_tag_redraw(CTX_wm_region(C)); | 
					
						
							|  |  |  |   return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PAINT_OT_face_select_linked(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->name = "Select Linked"; | 
					
						
							|  |  |  |   ot->description = "Select linked faces"; | 
					
						
							|  |  |  |   ot->idname = "PAINT_OT_face_select_linked"; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->exec = paint_select_linked_exec; | 
					
						
							|  |  |  |   ot->poll = facemask_paint_poll; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 09:03:46 +00:00
										 |  |  | static int paint_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const bool select = !RNA_boolean_get(op->ptr, "deselect"); | 
					
						
							|  |  |  |   view3d_operator_needs_opengl(C); | 
					
						
							|  |  |  |   paintface_select_linked(C, CTX_data_active_object(C), event->mval, select); | 
					
						
							|  |  |  |   ED_region_tag_redraw(CTX_wm_region(C)); | 
					
						
							|  |  |  |   return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PAINT_OT_face_select_linked_pick(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->name = "Select Linked Pick"; | 
					
						
							|  |  |  |   ot->description = "Select linked faces under the cursor"; | 
					
						
							|  |  |  |   ot->idname = "PAINT_OT_face_select_linked_pick"; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->invoke = paint_select_linked_pick_invoke; | 
					
						
							|  |  |  |   ot->poll = facemask_paint_poll; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items"); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | static int face_select_all_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Object *ob = CTX_data_active_object(C); | 
					
						
							|  |  |  |   if (paintface_deselect_all_visible(C, ob, RNA_enum_get(op->ptr, "action"), true)) { | 
					
						
							|  |  |  |     ED_region_tag_redraw(CTX_wm_region(C)); | 
					
						
							|  |  |  |     return OPERATOR_FINISHED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | void PAINT_OT_face_select_all(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->name = "(De)select All"; | 
					
						
							|  |  |  |   ot->description = "Change selection for all faces"; | 
					
						
							|  |  |  |   ot->idname = "PAINT_OT_face_select_all"; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->exec = face_select_all_exec; | 
					
						
							|  |  |  |   ot->poll = facemask_paint_poll; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   WM_operator_properties_select_all(ot); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-12 19:06:06 +00:00
										 |  |  | static int vert_select_all_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Object *ob = CTX_data_active_object(C); | 
					
						
							|  |  |  |   paintvert_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), true); | 
					
						
							|  |  |  |   paintvert_tag_select_update(C, ob); | 
					
						
							|  |  |  |   ED_region_tag_redraw(CTX_wm_region(C)); | 
					
						
							|  |  |  |   return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2011-07-12 19:06:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PAINT_OT_vert_select_all(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->name = "(De)select All"; | 
					
						
							|  |  |  |   ot->description = "Change selection for all vertices"; | 
					
						
							|  |  |  |   ot->idname = "PAINT_OT_vert_select_all"; | 
					
						
							| 
									
										
										
										
											2011-07-12 19:06:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->exec = vert_select_all_exec; | 
					
						
							|  |  |  |   ot->poll = vert_paint_poll; | 
					
						
							| 
									
										
										
										
											2011-07-12 19:06:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2011-07-12 19:06:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   WM_operator_properties_select_all(ot); | 
					
						
							| 
									
										
										
										
											2011-07-12 19:06:06 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-09-18 17:10:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-16 16:11:50 +00:00
										 |  |  | static int vert_select_ungrouped_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Object *ob = CTX_data_active_object(C); | 
					
						
							|  |  |  |   Mesh *me = ob->data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (BLI_listbase_is_empty(&ob->defbase) || (me->dvert == NULL)) { | 
					
						
							|  |  |  |     BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object"); | 
					
						
							|  |  |  |     return OPERATOR_CANCELLED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   paintvert_select_ungrouped(ob, RNA_boolean_get(op->ptr, "extend"), true); | 
					
						
							|  |  |  |   paintvert_tag_select_update(C, ob); | 
					
						
							|  |  |  |   ED_region_tag_redraw(CTX_wm_region(C)); | 
					
						
							|  |  |  |   return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2013-03-16 16:11:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PAINT_OT_vert_select_ungrouped(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* identifiers */ | 
					
						
							|  |  |  |   ot->name = "Select Ungrouped"; | 
					
						
							|  |  |  |   ot->idname = "PAINT_OT_vert_select_ungrouped"; | 
					
						
							|  |  |  |   ot->description = "Select vertices without a group"; | 
					
						
							| 
									
										
										
										
											2013-03-16 16:11:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* api callbacks */ | 
					
						
							|  |  |  |   ot->exec = vert_select_ungrouped_exec; | 
					
						
							|  |  |  |   ot->poll = vert_paint_poll; | 
					
						
							| 
									
										
										
										
											2013-03-16 16:11:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* flags */ | 
					
						
							|  |  |  |   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2013-03-16 16:11:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); | 
					
						
							| 
									
										
										
										
											2013-03-16 16:11:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | static int face_select_hide_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const bool unselected = RNA_boolean_get(op->ptr, "unselected"); | 
					
						
							|  |  |  |   Object *ob = CTX_data_active_object(C); | 
					
						
							|  |  |  |   paintface_hide(C, ob, unselected); | 
					
						
							|  |  |  |   ED_region_tag_redraw(CTX_wm_region(C)); | 
					
						
							|  |  |  |   return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PAINT_OT_face_select_hide(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->name = "Face Select Hide"; | 
					
						
							|  |  |  |   ot->description = "Hide selected faces"; | 
					
						
							|  |  |  |   ot->idname = "PAINT_OT_face_select_hide"; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->exec = face_select_hide_exec; | 
					
						
							|  |  |  |   ot->poll = facemask_paint_poll; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_def_boolean( | 
					
						
							|  |  |  |       ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects"); | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-20 02:28:07 +11:00
										 |  |  | static int face_select_reveal_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const bool select = RNA_boolean_get(op->ptr, "select"); | 
					
						
							|  |  |  |   Object *ob = CTX_data_active_object(C); | 
					
						
							|  |  |  |   paintface_reveal(C, ob, select); | 
					
						
							|  |  |  |   ED_region_tag_redraw(CTX_wm_region(C)); | 
					
						
							|  |  |  |   return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PAINT_OT_face_select_reveal(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->name = "Face Select Reveal"; | 
					
						
							|  |  |  |   ot->description = "Reveal hidden faces"; | 
					
						
							|  |  |  |   ot->idname = "PAINT_OT_face_select_reveal"; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->exec = face_select_reveal_exec; | 
					
						
							|  |  |  |   ot->poll = facemask_paint_poll; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_def_boolean(ot->srna, "select", true, "Select", ""); | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | } |