From 03f02019f221cb4c0f122d0bb1fe982cac60f70e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Mar 2013 13:06:31 +0000 Subject: knife projection feature, apart of 3d printing tools - use to cookie-cut text into a mesh. --- .../blender/editors/mesh/editmesh_knife_project.c | 163 +++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 source/blender/editors/mesh/editmesh_knife_project.c (limited to 'source/blender/editors/mesh/editmesh_knife_project.c') diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c new file mode 100644 index 00000000000..7bb7e362c98 --- /dev/null +++ b/source/blender/editors/mesh/editmesh_knife_project.c @@ -0,0 +1,163 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mesh/editmesh_knife_project.c + * \ingroup edmesh + */ + +#include "DNA_curve_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_windowmanager_types.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_linklist.h" +#include "BLI_listbase.h" + +#include "BKE_library.h" +#include "BKE_mesh.h" +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_tessmesh.h" +#include "BKE_report.h" + +#include "MEM_guardedalloc.h" + +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_view3d.h" + +#include "mesh_intern.h" + + +static LinkNode *knifeproject_poly_from_object(ARegion *ar, Scene *scene, Object *ob, LinkNode *polys) +{ + DerivedMesh *dm; + bool dm_needsFree; + + if (ob->type == OB_MESH || ob->derivedFinal) { + dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + dm_needsFree = false; + } + else if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { + dm = CDDM_from_curve(ob); + dm_needsFree = true; + } + + if (dm) { + ListBase nurbslist = {NULL, NULL}; + float projmat[4][4]; + + BKE_mesh_to_curve_nurblist(dm, &nurbslist, 0); /* wire */ + BKE_mesh_to_curve_nurblist(dm, &nurbslist, 1); /* boundary */ + + ED_view3d_ob_project_mat_get(ar->regiondata, ob, projmat); + + if (nurbslist.first) { + Nurb *nu; + for (nu = nurbslist.first; nu; nu = nu->next) { + if (nu->bp) { + int a; + BPoint *bp; + bool is_cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0; + float (*mval)[2] = MEM_mallocN(sizeof(*mval) * (nu->pntsu + is_cyclic), __func__); + + for (bp = nu->bp, a = 0; a < nu->pntsu; a++, bp++) { + ED_view3d_project_float_v3_m4(ar, bp->vec, mval[a], projmat); + } + if (is_cyclic) { + copy_v2_v2(mval[a], mval[0]); + } + + BLI_linklist_prepend(&polys, mval); + } + } + } + + BKE_nurbList_free(&nurbslist); + + if (dm_needsFree) { + dm->release(dm); + } + } + + + return polys; +} + +static int knifeproject_exec(bContext *C, wmOperator *op) +{ + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + + LinkNode *polys = NULL; + + CTX_DATA_BEGIN (C, Object *, ob, selected_objects) + { + if (ob != obedit) { + polys = knifeproject_poly_from_object(ar, scene, ob, polys); + } + } + CTX_DATA_END; + + if (polys) { + EDBM_mesh_knife(C, polys, true); + + /* select only tagged faces */ + BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false); + BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_TAG); + + BLI_linklist_freeN(polys); + + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_ERROR, "No other selected objects found to use for projection"); + return OPERATOR_CANCELLED; + } +} + +void MESH_OT_knife_project(wmOperatorType *ot) +{ + /* description */ + ot->name = "Knife Project"; + ot->idname = "MESH_OT_knife_project"; + ot->description = "Use other objects outlines & boundaries to project knife cuts"; + + /* callbacks */ + ot->exec = knifeproject_exec; + ot->poll = ED_operator_editmesh_view3d; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; +} + -- cgit v1.2.3