[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55303] trunk/blender/source/blender/ editors/mesh: knife projection feature,
Campbell Barton
ideasman42 at gmail.com
Fri Mar 15 14:06:32 CET 2013
Revision: 55303
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55303
Author: campbellbarton
Date: 2013-03-15 13:06:31 +0000 (Fri, 15 Mar 2013)
Log Message:
-----------
knife projection feature,
apart of 3d printing tools - use to cookie-cut text into a mesh.
Modified Paths:
--------------
trunk/blender/source/blender/editors/mesh/CMakeLists.txt
trunk/blender/source/blender/editors/mesh/editmesh_knife.c
trunk/blender/source/blender/editors/mesh/mesh_intern.h
trunk/blender/source/blender/editors/mesh/mesh_ops.c
Added Paths:
-----------
trunk/blender/source/blender/editors/mesh/editmesh_knife_project.c
Modified: trunk/blender/source/blender/editors/mesh/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/editors/mesh/CMakeLists.txt 2013-03-15 11:59:46 UTC (rev 55302)
+++ trunk/blender/source/blender/editors/mesh/CMakeLists.txt 2013-03-15 13:06:31 UTC (rev 55303)
@@ -43,6 +43,7 @@
editmesh_add.c
editmesh_bvh.c
editmesh_knife.c
+ editmesh_knife_project.c
editmesh_loopcut.c
editmesh_rip.c
editmesh_select.c
Modified: trunk/blender/source/blender/editors/mesh/editmesh_knife.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_knife.c 2013-03-15 11:59:46 UTC (rev 55302)
+++ trunk/blender/source/blender/editors/mesh/editmesh_knife.c 2013-03-15 13:06:31 UTC (rev 55303)
@@ -37,6 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_array.h"
+#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_smallhash.h"
#include "BLI_memarena.h"
@@ -3270,3 +3271,167 @@
RNA_def_boolean(ot->srna, "use_occlude_geometry", TRUE, "Occlude Geometry", "Only cut the front most geometry");
RNA_def_boolean(ot->srna, "only_selected", FALSE, "Only Selected", "Only cut selected geometry");
}
+
+
+/* -------------------------------------------------------------------- */
+/* Knife tool as a utility function
+ * that can be used for internal slicing operations */
+
+static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, float projmat[4][4])
+{
+ float co[3];
+ float co_ss[2];
+
+ {
+ BMLoop *l;
+ float tangent[3];
+
+ l = BM_FACE_FIRST_LOOP(f);
+ BM_loop_calc_face_tangent(l, tangent);
+ /* get a point inside the face (tiny offset) - we could be more clever here */
+ mul_v3_fl(tangent, 0.02f);
+ add_v3_v3v3(co, l->v->co, tangent);
+ }
+
+ ED_view3d_project_float_v3_m4(ar, co, co_ss, projmat);
+
+ /* check */
+ {
+ LinkNode *p = polys;
+ int isect = 0;
+
+ while (p) {
+ const float (*mval_fl)[2] = p->link;
+ const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
+ isect += (int)isect_point_poly_v2(co_ss, mval_fl, mval_tot - 1);
+ p = p->next;
+ }
+
+ if (isect % 2) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * \param use_tag When set, tag all faces inside the polylines.
+ */
+void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag)
+{
+ KnifeTool_OpData *kcd;
+
+ view3d_operator_needs_opengl(C);
+
+ /* init */
+ {
+ const bool only_select = false;
+ const bool cut_through = false;
+
+ kcd = MEM_callocN(sizeof(KnifeTool_OpData), __func__);
+
+ knifetool_init(C, kcd, only_select, cut_through);
+
+ kcd->ignore_edge_snapping = true;
+ kcd->ignore_vert_snapping = true;
+
+ if (use_tag) {
+ BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false);
+ }
+ }
+
+ /* execute */
+ {
+ LinkNode *p = polys;
+
+ knife_recalc_projmat(kcd);
+
+ while (p) {
+ const float (*mval_fl)[2] = p->link;
+ const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
+ int i;
+
+ for (i = 0; i < mval_tot; i++) {
+ knifetool_update_mval(kcd, mval_fl[i]);
+ if (i == 0) {
+ knife_start_cut(kcd);
+ kcd->mode = MODE_DRAGGING;
+ }
+ else {
+ knife_add_cut(kcd);
+ }
+ }
+ knife_finish_cut(kcd);
+ kcd->mode = MODE_IDLE;
+ p = p->next;
+ }
+ }
+
+ /* finish */
+ {
+ knifetool_finish_ex(kcd);
+
+ /* tag faces inside! */
+ if (use_tag) {
+ BMesh *bm = kcd->em->bm;
+ float projmat[4][4];
+
+ BMEdge *e;
+ BMIter iter;
+
+ bool keep_search;
+
+ ED_view3d_ob_project_mat_get(kcd->ar->regiondata, kcd->ob, projmat);
+
+ BM_mesh_elem_hflag_disable_all(kcd->em->bm, BM_FACE, BM_ELEM_TAG, false);
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+
+ /* check are we tagged?, then we are an original face */
+ if (BM_elem_flag_test(e, BM_ELEM_TAG) == false) {
+ BMFace *f;
+ BMIter fiter;
+ BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
+
+ /* if we trusy b*/
+ if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ }
+ }
+ }
+ }
+
+ do {
+ BMFace *f;
+ keep_search = false;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_TAG) == false) {
+ /* am I connected to a tagged face via a tagged edge (ie, not across a cut) */
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter = l_first;
+ int found = false;
+
+ do {
+ if (BM_elem_flag_test(l_iter, BM_ELEM_TAG) != false) {
+ found = true;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (found) {
+ // if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat))
+ {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ keep_search = true;
+ }
+ }
+ }
+ }
+ } while (keep_search);
+ }
+
+ knifetool_exit_ex(C, kcd);
+ kcd = NULL;
+ }
+}
Added: trunk/blender/source/blender/editors/mesh/editmesh_knife_project.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_knife_project.c (rev 0)
+++ trunk/blender/source/blender/editors/mesh/editmesh_knife_project.c 2013-03-15 13:06:31 UTC (rev 55303)
@@ -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;
+}
+
Property changes on: trunk/blender/source/blender/editors/mesh/editmesh_knife_project.c
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: trunk/blender/source/blender/editors/mesh/mesh_intern.h
===================================================================
--- trunk/blender/source/blender/editors/mesh/mesh_intern.h 2013-03-15 11:59:46 UTC (rev 55302)
+++ trunk/blender/source/blender/editors/mesh/mesh_intern.h 2013-03-15 13:06:31 UTC (rev 55303)
@@ -48,6 +48,7 @@
struct wmKeyMap;
struct wmOperator;
struct wmOperatorType;
+struct LinkNode;
/* ******************** editmesh_utils.c */
@@ -204,6 +205,8 @@
void MESH_OT_loopcut(struct wmOperatorType *ot);
void MESH_OT_knife_tool(struct wmOperatorType *ot);
+void MESH_OT_knife_project(wmOperatorType *ot);
+
void MESH_OT_bevel(struct wmOperatorType *ot);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list