Exemple #1
0
static bool edbm_bevel_calc(wmOperator *op)
{
	BevelData *opdata = op->customdata;
	BMEditMesh *em = opdata->em;
	BMOperator bmop;
	const float offset = RNA_float_get(op->ptr, "offset");
	const int offset_type = RNA_enum_get(op->ptr, "offset_type");
	const int segments = RNA_int_get(op->ptr, "segments");
	const float profile = RNA_float_get(op->ptr, "profile");
	const bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
	const bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
	int material = RNA_int_get(op->ptr, "material");
	const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide");

	/* revert to original mesh */
	if (opdata->is_modal) {
		EDBM_redo_state_restore(opdata->mesh_backup, em, false);
	}

	if (em->ob) {
		material = CLAMPIS(material, -1, em->ob->totcol - 1);
	}

	EDBM_op_init(em, &bmop, op,
	             "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b "
	             "material=%i loop_slide=%b",
	             BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile,
	             clamp_overlap, material, loop_slide);

	BMO_op_exec(em->bm, &bmop);

	if (offset != 0.0f) {
		/* not essential, but we may have some loose geometry that
		 * won't get bevel'd and better not leave it selected */
		EDBM_flag_disable_all(em, BM_ELEM_SELECT);
		BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
	}

	/* no need to de-select existing geometry */
	if (!EDBM_op_finish(em, &bmop, op, true)) {
		return false;
	}

	EDBM_mesh_normals_update(opdata->em);

	EDBM_update_generic(opdata->em, true, true);

	return true;
}
Exemple #2
0
bool EDBM_op_call_and_selectf(
        BMEditMesh *em, wmOperator *op,
        const char *select_slot_out, const bool select_extend,
        const char *fmt, ...)
{
	BMOpSlot *slot_select_out;
	BMesh *bm = em->bm;
	BMOperator bmop;
	va_list list;
	char hflag;

	va_start(list, fmt);

	if (!BMO_op_vinitf(bm, &bmop, BMO_FLAG_DEFAULTS, fmt, list)) {
		BKE_reportf(op->reports, RPT_ERROR, "Parse error in %s", __func__);
		va_end(list);
		return false;
	}

	if (!em->emcopy) {
		em->emcopy = BKE_editmesh_copy(em);
	}
	em->emcopyusers++;

	BMO_op_exec(bm, &bmop);

	slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out);
	hflag = slot_select_out->slot_subtype.elem & BM_ALL_NOLOOP;
	BLI_assert(hflag != 0);

	if (select_extend == false) {
		BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
	}

	BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, hflag, BM_ELEM_SELECT, true);

	va_end(list);
	return EDBM_op_finish(em, &bmop, op, true);
}
Exemple #3
0
bool EDBM_op_call_silentf(BMEditMesh *em, const char *fmt, ...)
{
	BMesh *bm = em->bm;
	BMOperator bmop;
	va_list list;

	va_start(list, fmt);

	if (!BMO_op_vinitf(bm, &bmop, BMO_FLAG_DEFAULTS, fmt, list)) {
		va_end(list);
		return false;
	}

	if (!em->emcopy) {
		em->emcopy = BKE_editmesh_copy(em);
	}
	em->emcopyusers++;

	BMO_op_exec(bm, &bmop);

	va_end(list);
	return EDBM_op_finish(em, &bmop, NULL, false);
}
Exemple #4
0
bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...)
{
	BMesh *bm = em->bm;
	BMOperator bmop;
	va_list list;

	va_start(list, fmt);

	if (!BMO_op_vinitf(bm, &bmop, BMO_FLAG_DEFAULTS, fmt, list)) {
		BKE_reportf(op->reports, RPT_ERROR, "Parse error in %s", __func__);
		va_end(list);
		return false;
	}

	if (!em->emcopy) {
		em->emcopy = BKE_editmesh_copy(em);
	}
	em->emcopyusers++;

	BMO_op_exec(bm, &bmop);

	va_end(list);
	return EDBM_op_finish(em, &bmop, op, true);
}
Exemple #5
0
static bool edbm_bevel_calc(wmOperator *op)
{
  BevelData *opdata = op->customdata;
  BMEditMesh *em;
  BMOperator bmop;
  bool changed = false;

  const float offset = get_bevel_offset(op);
  const int offset_type = RNA_enum_get(op->ptr, "offset_type");
  const int segments = RNA_int_get(op->ptr, "segments");
  const float profile = RNA_float_get(op->ptr, "profile");
  const bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
  const bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
  int material = RNA_int_get(op->ptr, "material");
  const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide");
  const bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam");
  const bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
  const bool harden_normals = RNA_boolean_get(op->ptr, "harden_normals");
  const int face_strength_mode = RNA_enum_get(op->ptr, "face_strength_mode");
  const int miter_outer = RNA_enum_get(op->ptr, "miter_outer");
  const int miter_inner = RNA_enum_get(op->ptr, "miter_inner");
  const float spread = RNA_float_get(op->ptr, "spread");

  for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
    em = opdata->ob_store[ob_index].em;

    /* revert to original mesh */
    if (opdata->is_modal) {
      EDBM_redo_state_restore(opdata->ob_store[ob_index].mesh_backup, em, false);
    }

    if (em->ob) {
      material = CLAMPIS(material, -1, em->ob->totcol - 1);
    }

    Mesh *me = em->ob->data;

    if (harden_normals && !(me->flag & ME_AUTOSMOOTH)) {
      /* harden_normals only has a visible effect if autosmooth is on, so turn it on */
      me->flag |= ME_AUTOSMOOTH;
    }

    EDBM_op_init(em,
                 &bmop,
                 op,
                 "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f "
                 "clamp_overlap=%b material=%i loop_slide=%b mark_seam=%b mark_sharp=%b "
                 "harden_normals=%b face_strength_mode=%i "
                 "miter_outer=%i miter_inner=%i spread=%f smoothresh=%f",
                 BM_ELEM_SELECT,
                 offset,
                 segments,
                 vertex_only,
                 offset_type,
                 profile,
                 clamp_overlap,
                 material,
                 loop_slide,
                 mark_seam,
                 mark_sharp,
                 harden_normals,
                 face_strength_mode,
                 miter_outer,
                 miter_inner,
                 spread,
                 me->smoothresh);

    BMO_op_exec(em->bm, &bmop);

    if (offset != 0.0f) {
      /* not essential, but we may have some loose geometry that
       * won't get bevel'd and better not leave it selected */
      EDBM_flag_disable_all(em, BM_ELEM_SELECT);
      BMO_slot_buffer_hflag_enable(
          em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
    }

    /* no need to de-select existing geometry */
    if (!EDBM_op_finish(em, &bmop, op, true)) {
      continue;
    }

    EDBM_mesh_normals_update(em);

    EDBM_update_generic(em, true, true);
    changed = true;
  }
  return changed;
}
Exemple #6
0
static bool edbm_inset_calc(wmOperator *op)
{
	InsetData *opdata;
	BMEditMesh *em;
	BMOperator bmop;

	const bool use_boundary        = RNA_boolean_get(op->ptr, "use_boundary");
	const bool use_even_offset     = RNA_boolean_get(op->ptr, "use_even_offset");
	const bool use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset");
	const bool use_edge_rail       = RNA_boolean_get(op->ptr, "use_edge_rail");
	const float thickness          = RNA_float_get(op->ptr,   "thickness");
	const float depth              = RNA_float_get(op->ptr,   "depth");
	const bool use_outset          = RNA_boolean_get(op->ptr, "use_outset");
	const bool use_select_inset    = RNA_boolean_get(op->ptr, "use_select_inset"); /* not passed onto the BMO */
	const bool use_individual      = RNA_boolean_get(op->ptr, "use_individual");
	const bool use_interpolate     = RNA_boolean_get(op->ptr, "use_interpolate");

	opdata = op->customdata;
	em = opdata->em;

	if (opdata->is_modal) {
		EDBM_redo_state_restore(opdata->mesh_backup, em, false);
	}

	if (use_individual) {
		EDBM_op_init(em, &bmop, op,
		             "inset_individual faces=%hf use_even_offset=%b  use_relative_offset=%b "
		             "use_interpolate=%b thickness=%f depth=%f",
		             BM_ELEM_SELECT, use_even_offset, use_relative_offset, use_interpolate,
		             thickness, depth);
	}
	else {
		EDBM_op_init(em, &bmop, op,
		             "inset_region faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b "
		             "use_interpolate=%b thickness=%f depth=%f use_outset=%b use_edge_rail=%b",
		             BM_ELEM_SELECT, use_boundary, use_even_offset, use_relative_offset, use_interpolate,
		             thickness, depth, use_outset, use_edge_rail);

		if (use_outset) {
			BMO_slot_buffer_from_enabled_hflag(em->bm, &bmop, bmop.slots_in, "faces_exclude", BM_FACE, BM_ELEM_HIDDEN);
		}
	}
	BMO_op_exec(em->bm, &bmop);

	if (use_select_inset) {
		/* deselect original faces/verts */
		EDBM_flag_disable_all(em, BM_ELEM_SELECT);
		BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
	}
	else {
		EDBM_flag_disable_all(em, BM_ELEM_SELECT);
		BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_in, "faces", BM_FACE, BM_ELEM_SELECT, true);
	}

	if (!EDBM_op_finish(em, &bmop, op, true)) {
		return false;
	}
	else {
		EDBM_update_generic(em, true, true);
		return true;
	}
}
static int mesh_bisect_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);

	/* both can be NULL, fallbacks values are used */
	View3D *v3d = CTX_wm_view3d(C);
	RegionView3D *rv3d = ED_view3d_context_rv3d(C);

	Object *obedit = CTX_data_edit_object(C);
	BMEditMesh *em = BKE_editmesh_from_object(obedit);
	BMesh *bm;
	BMOperator bmop;
	float plane_co[3];
	float plane_no[3];
	float imat[4][4];

	const float thresh = RNA_float_get(op->ptr, "threshold");
	const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
	const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner");
	const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer");

	PropertyRNA *prop_plane_co;
	PropertyRNA *prop_plane_no;

	prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
	if (RNA_property_is_set(op->ptr, prop_plane_co)) {
		RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co);
	}
	else {
		copy_v3_v3(plane_co, ED_view3d_cursor3d_get(scene, v3d));
		RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
	}

	prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
	if (RNA_property_is_set(op->ptr, prop_plane_no)) {
		RNA_property_float_get_array(op->ptr, prop_plane_no, plane_no);
	}
	else {
		if (rv3d) {
			copy_v3_v3(plane_no, rv3d->viewinv[1]);
		}
		else {
			/* fallback... */
			plane_no[0] = plane_no[1] = 0.0f; plane_no[2] = 1.0f;
		}
		RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
	}



	/* -------------------------------------------------------------------- */
	/* Modal support */
	/* Note: keep this isolated, exec can work wihout this */
	if ((op->customdata != NULL) &&
	    mesh_bisect_interactive_calc(C, op, em, plane_co, plane_no))
	{
		/* write back to the props */
		RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
		RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
	}
	/* End Modal */
	/* -------------------------------------------------------------------- */



	bm = em->bm;

	invert_m4_m4(imat, obedit->obmat);
	mul_m4_v3(imat, plane_co);
	mul_mat3_m4_v3(imat, plane_no);

	EDBM_op_init(em, &bmop, op,
	             "bisect_plane geom=%hvef plane_co=%v plane_no=%v dist=%f clear_inner=%b clear_outer=%b",
	             BM_ELEM_SELECT, plane_co, plane_no, thresh, clear_inner, clear_outer);
	BMO_op_exec(bm, &bmop);

	EDBM_flag_disable_all(em, BM_ELEM_SELECT);

	if (use_fill) {
		float normal_fill[3];
		BMOperator bmop_fill;
		BMOperator bmop_attr;

		normalize_v3_v3(normal_fill, plane_no);
		if (clear_outer == true && clear_inner == false) {
			negate_v3(normal_fill);
		}

		/* Fill */
		BMO_op_initf(
		        bm, &bmop_fill, op->flag,
		        "triangle_fill edges=%S normal=%v use_dissolve=%b",
		        &bmop, "geom_cut.out", normal_fill, true);
		BMO_op_exec(bm, &bmop_fill);

		/* Copy Attributes */
		BMO_op_initf(bm, &bmop_attr, op->flag,
		             "face_attribute_fill faces=%S use_normals=%b use_data=%b",
		             &bmop_fill, "geom.out", false, true);
		BMO_op_exec(bm, &bmop_attr);

		BMO_slot_buffer_hflag_enable(bm, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);

		BMO_op_finish(bm, &bmop_attr);
		BMO_op_finish(bm, &bmop_fill);
	}

	BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);

	if (!EDBM_op_finish(em, &bmop, op, true)) {
		return OPERATOR_CANCELLED;
	}
	else {
		EDBM_update_generic(em, true, true);
		EDBM_selectmode_flush(em);
		return OPERATOR_FINISHED;
	}
}