| 
									
										
										
										
											2012-02-19 18:31:04 +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, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bmesh | 
					
						
							| 
									
										
										
										
											2013-03-30 08:54:50 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Basic mirror, optionally with UVs's. | 
					
						
							| 
									
										
										
										
											2012-04-06 09:21:19 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_math.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_customdata.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bmesh.h"
 | 
					
						
							| 
									
										
										
										
											2012-03-08 03:25:53 +00:00
										 |  |  | #include "intern/bmesh_operators_private.h" /* own include */
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define ELE_NEW 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-28 09:48:00 +00:00
										 |  |  | void bmo_mirror_exec(BMesh *bm, BMOperator *op) | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   BMOperator dupeop, weldop; | 
					
						
							|  |  |  |   BMOIter siter; | 
					
						
							| 
									
										
										
										
											2021-01-05 15:07:38 +11:00
										 |  |  |   BMVert *v; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |   float scale[3] = {1.0f, 1.0f, 1.0f}; | 
					
						
							| 
									
										
										
										
											2012-11-20 05:50:19 +00:00
										 |  |  |   float dist = BMO_slot_float_get(op->slots_in, "merge_dist"); | 
					
						
							| 
									
										
										
										
											2021-01-05 15:07:38 +11:00
										 |  |  |   int i; | 
					
						
							| 
									
										
										
										
											2012-11-19 14:58:31 +00:00
										 |  |  |   int axis = BMO_slot_int_get(op->slots_in, "axis"); | 
					
						
							| 
									
										
										
										
											2013-01-14 16:42:43 +00:00
										 |  |  |   bool mirror_u = BMO_slot_bool_get(op->slots_in, "mirror_u"); | 
					
						
							|  |  |  |   bool mirror_v = BMO_slot_bool_get(op->slots_in, "mirror_v"); | 
					
						
							| 
									
										
										
										
											2020-05-07 12:34:13 +02:00
										 |  |  |   bool mirror_udim = BMO_slot_bool_get(op->slots_in, "mirror_udim"); | 
					
						
							| 
									
										
										
										
											2012-11-20 13:29:27 +00:00
										 |  |  |   BMOpSlot *slot_targetmap; | 
					
						
							| 
									
										
										
										
											2021-01-05 15:07:38 +11:00
										 |  |  |   BMOpSlot *slot_vertmap; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-21 00:58:02 +00:00
										 |  |  |   BMO_op_initf(bm, &dupeop, op->flag, "duplicate geom=%s", op, "geom"); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |   BMO_op_exec(bm, &dupeop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-27 00:50:59 +00:00
										 |  |  |   BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |   /* feed old data to transform bmo */ | 
					
						
							|  |  |  |   scale[axis] = -1.0f; | 
					
						
							| 
									
										
										
										
											2021-01-05 15:42:04 +11:00
										 |  |  |   BMO_op_callf(bm, | 
					
						
							|  |  |  |                op->flag, | 
					
						
							|  |  |  |                "scale verts=%fv vec=%v space=%s use_shapekey=%s", | 
					
						
							|  |  |  |                ELE_NEW, | 
					
						
							|  |  |  |                scale, | 
					
						
							|  |  |  |                op, | 
					
						
							|  |  |  |                "matrix", | 
					
						
							|  |  |  |                op, | 
					
						
							|  |  |  |                "use_shapekey"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-21 00:58:02 +00:00
										 |  |  |   BMO_op_init(bm, &weldop, op->flag, "weld_verts"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-20 13:29:27 +00:00
										 |  |  |   slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap"); | 
					
						
							| 
									
										
										
										
											2021-01-05 15:07:38 +11:00
										 |  |  |   slot_vertmap = BMO_slot_get(dupeop.slots_out, "vert_map.out"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-05 15:07:38 +11:00
										 |  |  |   BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) { | 
					
						
							| 
									
										
										
										
											2012-11-06 00:18:01 +00:00
										 |  |  |     if (fabsf(v->co[axis]) <= dist) { | 
					
						
							| 
									
										
										
										
											2021-01-05 15:07:38 +11:00
										 |  |  |       BMVert *v_new = BMO_slot_map_elem_get(slot_vertmap, v); | 
					
						
							|  |  |  |       BLI_assert(v_new != NULL); | 
					
						
							|  |  |  |       BMO_slot_map_elem_insert(&weldop, slot_targetmap, v_new, v); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-14 16:42:43 +00:00
										 |  |  |   if (mirror_u || mirror_v) { | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |     BMFace *f; | 
					
						
							|  |  |  |     BMLoop *l; | 
					
						
							|  |  |  |     MLoopUV *luv; | 
					
						
							| 
									
										
										
										
											2013-06-26 04:17:02 +00:00
										 |  |  |     const int totlayer = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |     BMIter liter; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-20 05:50:19 +00:00
										 |  |  |     BMO_ITER (f, &siter, dupeop.slots_out, "geom.out", BM_FACE) { | 
					
						
							| 
									
										
										
										
											2012-04-19 13:47:58 +00:00
										 |  |  |       BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |         for (i = 0; i < totlayer; i++) { | 
					
						
							|  |  |  |           luv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i); | 
					
						
							| 
									
										
										
										
											2019-03-27 17:14:36 +11:00
										 |  |  |           if (mirror_u) { | 
					
						
							| 
									
										
										
										
											2020-05-07 12:34:13 +02:00
										 |  |  |             float uv_u = luv->uv[0]; | 
					
						
							|  |  |  |             if (mirror_udim) { | 
					
						
							|  |  |  |               luv->uv[0] = ceilf(uv_u) - fmodf(uv_u, 1.0f); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               luv->uv[0] = 1.0f - uv_u; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-03-27 17:14:36 +11:00
										 |  |  |           } | 
					
						
							|  |  |  |           if (mirror_v) { | 
					
						
							| 
									
										
										
										
											2020-05-07 12:34:13 +02:00
										 |  |  |             float uv_v = luv->uv[1]; | 
					
						
							|  |  |  |             if (mirror_udim) { | 
					
						
							|  |  |  |               luv->uv[1] = ceilf(uv_v) - fmodf(uv_v, 1.0f); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |               luv->uv[1] = 1.0f - uv_v; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-03-27 17:14:36 +11:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |   BMO_op_exec(bm, &weldop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  |   BMO_op_finish(bm, &weldop); | 
					
						
							|  |  |  |   BMO_op_finish(bm, &dupeop); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-27 00:50:59 +00:00
										 |  |  |   BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | } |