196
199
BMIter viter, eiter, fiter;
197
200
GHash *vhash, *ehash;
202
BMOpSlot *slot_boundary_map_out = BMO_slot_get(op->slots_out, "boundary_map.out");
203
BMOpSlot *slot_face_map_out = BMO_slot_get(op->slots_out, "face_map.out");
204
BMOpSlot *slot_isovert_map_out = BMO_slot_get(op->slots_out, "isovert_map.out");
199
206
/* initialize pointer hashes */
200
vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh dupeops v");
201
ehash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh dupeops e");
207
vhash = BLI_ghash_ptr_new("bmesh dupeops v");
208
ehash = BLI_ghash_ptr_new("bmesh dupeops e");
203
210
/* duplicate flagged vertices */
204
BM_ITER_MESH (v, &viter, source, BM_VERTS_OF_MESH) {
205
if (BMO_elem_flag_test(source, v, DUPE_INPUT) &&
206
!BMO_elem_flag_test(source, v, DUPE_DONE))
211
BM_ITER_MESH (v, &viter, bm_src, BM_VERTS_OF_MESH) {
212
if (BMO_elem_flag_test(bm_src, v, DUPE_INPUT) &&
213
!BMO_elem_flag_test(bm_src, v, DUPE_DONE))
216
bool isolated = true;
211
v2 = copy_vertex(source, v, target, vhash);
218
v2 = copy_vertex(bm_src, v, bm_dst, vhash);
213
220
BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
214
if (BMO_elem_flag_test(source, f, DUPE_INPUT)) {
221
if (BMO_elem_flag_test(bm_src, f, DUPE_INPUT)) {
221
228
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
222
if (BMO_elem_flag_test(source, e, DUPE_INPUT)) {
229
if (BMO_elem_flag_test(bm_src, e, DUPE_INPUT)) {
230
BMO_slot_map_ptr_insert(source, op, "isovertmap", v, v2);
237
BMO_slot_map_elem_insert(op, slot_isovert_map_out, v, v2);
233
BMO_elem_flag_enable(source, v, DUPE_DONE);
240
BMO_elem_flag_enable(bm_src, v, DUPE_DONE);
237
244
/* now we dupe all the edges */
238
BM_ITER_MESH (e, &eiter, source, BM_EDGES_OF_MESH) {
239
if (BMO_elem_flag_test(source, e, DUPE_INPUT) &&
240
!BMO_elem_flag_test(source, e, DUPE_DONE))
245
BM_ITER_MESH (e, &eiter, bm_src, BM_EDGES_OF_MESH) {
246
if (BMO_elem_flag_test(bm_src, e, DUPE_INPUT) &&
247
!BMO_elem_flag_test(bm_src, e, DUPE_DONE))
242
249
/* make sure that verts are copied */
243
if (!BMO_elem_flag_test(source, e->v1, DUPE_DONE)) {
244
copy_vertex(source, e->v1, target, vhash);
245
BMO_elem_flag_enable(source, e->v1, DUPE_DONE);
250
if (!BMO_elem_flag_test(bm_src, e->v1, DUPE_DONE)) {
251
copy_vertex(bm_src, e->v1, bm_dst, vhash);
252
BMO_elem_flag_enable(bm_src, e->v1, DUPE_DONE);
247
if (!BMO_elem_flag_test(source, e->v2, DUPE_DONE)) {
248
copy_vertex(source, e->v2, target, vhash);
249
BMO_elem_flag_enable(source, e->v2, DUPE_DONE);
254
if (!BMO_elem_flag_test(bm_src, e->v2, DUPE_DONE)) {
255
copy_vertex(bm_src, e->v2, bm_dst, vhash);
256
BMO_elem_flag_enable(bm_src, e->v2, DUPE_DONE);
251
258
/* now copy the actual edge */
252
copy_edge(op, source, e, target, vhash, ehash);
253
BMO_elem_flag_enable(source, e, DUPE_DONE);
259
copy_edge(op, slot_boundary_map_out, bm_src, e, bm_dst, vhash, ehash);
260
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
257
264
/* first we dupe all flagged faces and their elements from source */
258
BM_ITER_MESH (f, &fiter, source, BM_FACES_OF_MESH) {
259
if (BMO_elem_flag_test(source, f, DUPE_INPUT)) {
265
BM_ITER_MESH (f, &fiter, bm_src, BM_FACES_OF_MESH) {
266
if (BMO_elem_flag_test(bm_src, f, DUPE_INPUT)) {
260
267
/* vertex pass */
261
268
BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
262
if (!BMO_elem_flag_test(source, v, DUPE_DONE)) {
263
copy_vertex(source, v, target, vhash);
264
BMO_elem_flag_enable(source, v, DUPE_DONE);
269
if (!BMO_elem_flag_test(bm_src, v, DUPE_DONE)) {
270
copy_vertex(bm_src, v, bm_dst, vhash);
271
BMO_elem_flag_enable(bm_src, v, DUPE_DONE);
269
276
BM_ITER_ELEM (e, &eiter, f, BM_EDGES_OF_FACE) {
270
if (!BMO_elem_flag_test(source, e, DUPE_DONE)) {
271
copy_edge(op, source, e, target, vhash, ehash);
272
BMO_elem_flag_enable(source, e, DUPE_DONE);
277
if (!BMO_elem_flag_test(bm_src, e, DUPE_DONE)) {
278
copy_edge(op, slot_boundary_map_out, bm_src, e, bm_dst, vhash, ehash);
279
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
314
321
* BMOP_DUPE_FNEW: Buffer containing pointers to the new mesh faces
317
void bmo_dupe_exec(BMesh *bm, BMOperator *op)
324
void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
319
326
BMOperator *dupeop = op;
320
BMesh *bm2 = BMO_slot_ptr_get(op, "dest");
327
BMesh *bm2 = BMO_slot_ptr_get(op->slots_in, "dest");
326
BMO_slot_buffer_flag_enable(bm, dupeop, "geom", BM_ALL, DUPE_INPUT);
333
BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL_NOLOOP, DUPE_INPUT);
328
335
/* use the internal copy function */
329
copy_mesh(dupeop, bm, bm2);
336
bmo_mesh_copy(dupeop, bm, bm2);
332
339
/* First copy the input buffers to output buffers - original data */
333
BMO_slot_copy(dupeop, dupeop, "geom", "origout");
340
BMO_slot_copy(dupeop, slots_in, "geom",
341
dupeop, slots_out, "geom_orig.out");
335
343
/* Now alloc the new output buffers */
336
BMO_slot_buffer_from_enabled_flag(bm, dupeop, "newout", BM_ALL, DUPE_NEW);
344
BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL_NOLOOP, DUPE_NEW);
339
347
#if 0 /* UNUSED */
378
386
BMOperator *splitop = op;
379
387
BMOperator dupeop;
380
388
BMOperator delop;
381
const short use_only_faces = BMO_slot_bool_get(op, "use_only_faces");
389
const bool use_only_faces = BMO_slot_bool_get(op->slots_in, "use_only_faces");
383
391
/* initialize our sub-operator */
384
BMO_op_init(bm, &dupeop, "dupe");
385
BMO_op_init(bm, &delop, "del");
392
BMO_op_init(bm, &dupeop, op->flag, "duplicate");
393
BMO_op_init(bm, &delop, op->flag, "delete");
387
BMO_slot_copy(splitop, &dupeop, "geom", "geom");
395
BMO_slot_copy(splitop, slots_in, "geom",
396
&dupeop, slots_in, "geom");
388
397
BMO_op_exec(bm, &dupeop);
390
BMO_slot_buffer_flag_enable(bm, splitop, "geom", BM_ALL, SPLIT_INPUT);
399
BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT);
392
401
if (use_only_faces) {
429
438
/* connect outputs of dupe to delete, exluding keep geometry */
430
BMO_slot_int_set(&delop, "context", DEL_FACES);
431
BMO_slot_buffer_from_enabled_flag(bm, &delop, "geom", BM_ALL, SPLIT_INPUT);
439
BMO_slot_int_set(delop.slots_in, "context", DEL_FACES);
440
BMO_slot_buffer_from_enabled_flag(bm, &delop, delop.slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT);
433
442
BMO_op_exec(bm, &delop);
435
444
/* now we make our outputs by copying the dupe output */
436
BMO_slot_copy(&dupeop, splitop, "newout", "geomout");
437
BMO_slot_copy(&dupeop, splitop, "boundarymap", "boundarymap");
438
BMO_slot_copy(&dupeop, splitop, "isovertmap", "isovertmap");
445
BMO_slot_copy(&dupeop, slots_out, "geom.out",
446
splitop, slots_out, "geom.out");
448
BMO_slot_copy(&dupeop, slots_out, "boundary_map.out",
449
splitop, slots_out, "boundary_map.out");
451
BMO_slot_copy(&dupeop, slots_out, "isovert_map.out",
452
splitop, slots_out, "isovert_map.out");
441
456
BMO_op_finish(bm, &delop);
442
457
BMO_op_finish(bm, &dupeop);
446
void bmo_del_exec(BMesh *bm, BMOperator *op)
461
void bmo_delete_exec(BMesh *bm, BMOperator *op)
448
463
#define DEL_INPUT 1
450
465
BMOperator *delop = op;
452
467
/* Mark Buffer */
453
BMO_slot_buffer_flag_enable(bm, delop, "geom", BM_ALL, DEL_INPUT);
468
BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL_NOLOOP, DEL_INPUT);
455
BMO_remove_tagged_context(bm, DEL_INPUT, BMO_slot_int_get(op, "context"));
470
BMO_remove_tagged_context(bm, DEL_INPUT, BMO_slot_int_get(op->slots_in, "context"));
469
484
BMOperator dupop, extop;
470
485
float cent[3], dvec[3];
471
float axis[3] = {0.0f, 0.0f, 1.0f};
472
487
float rmat[3][3];
474
489
int steps, do_dupli, a, usedvec;
476
BMO_slot_vec_get(op, "cent", cent);
477
BMO_slot_vec_get(op, "axis", axis);
491
BMO_slot_vec_get(op->slots_in, "cent", cent);
492
BMO_slot_vec_get(op->slots_in, "axis", axis);
478
493
normalize_v3(axis);
479
BMO_slot_vec_get(op, "dvec", dvec);
494
BMO_slot_vec_get(op->slots_in, "dvec", dvec);
480
495
usedvec = !is_zero_v3(dvec);
481
steps = BMO_slot_int_get(op, "steps");
482
phi = BMO_slot_float_get(op, "ang") * DEG2RADF(1.0f) / steps;
483
do_dupli = BMO_slot_bool_get(op, "do_dupli");
496
steps = BMO_slot_int_get(op->slots_in, "steps");
497
phi = BMO_slot_float_get(op->slots_in, "angle") / steps;
498
do_dupli = BMO_slot_bool_get(op->slots_in, "use_duplicate");
485
500
axis_angle_to_mat3(rmat, axis, phi);
487
BMO_slot_copy(op, op, "geom", "lastout");
502
BMO_slot_copy(op, slots_in, "geom",
503
op, slots_out, "geom_last.out");
488
504
for (a = 0; a < steps; a++) {
490
BMO_op_initf(bm, &dupop, "dupe geom=%s", op, "lastout");
506
BMO_op_initf(bm, &dupop, op->flag, "duplicate geom=%S", op, "geom_last.out");
491
507
BMO_op_exec(bm, &dupop);
492
BMO_op_callf(bm, "rotate cent=%v mat=%m3 verts=%s",
493
cent, rmat, &dupop, "newout");
494
BMO_slot_copy(&dupop, op, "newout", "lastout");
508
BMO_op_callf(bm, op->flag,
509
"rotate cent=%v matrix=%m3 verts=%S",
510
cent, rmat, &dupop, "geom.out");
511
BMO_slot_copy(&dupop, slots_out, "geom.out",
512
op, slots_out, "geom_last.out");
495
513
BMO_op_finish(bm, &dupop);
498
BMO_op_initf(bm, &extop, "extrude_face_region edgefacein=%s",
516
BMO_op_initf(bm, &extop, op->flag, "extrude_face_region geom=%S",
517
op, "geom_last.out");
500
518
BMO_op_exec(bm, &extop);
501
BMO_op_callf(bm, "rotate cent=%v mat=%m3 verts=%s",
502
cent, rmat, &extop, "geomout");
503
BMO_slot_copy(&extop, op, "geomout", "lastout");
519
BMO_op_callf(bm, op->flag,
520
"rotate cent=%v matrix=%m3 verts=%S",
521
cent, rmat, &extop, "geom.out");
522
BMO_slot_copy(&extop, slots_out, "geom.out",
523
op, slots_out, "geom_last.out");
504
524
BMO_op_finish(bm, &extop);
508
BMO_op_callf(bm, "translate vec=%v verts=%s", dvec, op, "lastout");
528
mul_m3_v3(rmat, dvec);
529
BMO_op_callf(bm, op->flag,
530
"translate vec=%v verts=%S",
531
dvec, op, "geom_last.out");