mind = blown Daniel Salazar patazstudio.com
On Mon, Oct 15, 2012 at 7:39 PM, Nicholas Bishop <[email protected]> wrote: > I agree a modifier version would be nice. I've been thinking though > that as new BMesh tools are added, there might be room for a lot of > new modifiers. (For example, the convex hull operator I added in the > last release would also work well as a modifier.) Perhaps it would be > better to create a generic BMesh modifier that applies a BMesh > operator to the input? > > -Nicholas > > On Mon, Oct 15, 2012 at 9:26 PM, Daniel Salazar - 3Developer.com > <[email protected]> wrote: >> Not so fast! This is too cool to exist only as an operator. What about >> a modifier? ^_^ >> >> awesomesauce >> >> Daniel Salazar >> patazstudio.com >> >> >> On Mon, Oct 15, 2012 at 5:50 PM, Nicholas Bishop >> <[email protected]> wrote: >>> Revision: 51356 >>> >>> http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51356 >>> Author: nicholasbishop >>> Date: 2012-10-15 23:50:09 +0000 (Mon, 15 Oct 2012) >>> Log Message: >>> ----------- >>> Add BMesh and WM symmetrize operators >>> >>> * The symmetrize operation makes the input mesh elements symmetrical, >>> but unlike mirroring it only copies in one direction. The edges and >>> faces that cross the plane of symmetry are split as needed to >>> enforce symmetry. >>> >>> * The symmetrize operator can be controlled with the "direction" >>> property, which combines the choices of symmetry plane and >>> positive-negative/negative-positive. The enum for this is >>> BMO_SymmDirection. >>> >>> * Added menu items in the top-level Mesh menu and the WKEY specials >>> menu. >>> >>> * Documentation: >>> http://wiki.blender.org/index.php/User:Nicholasbishop/Symmetrize >>> >>> * Reviewed by Brecht: >>> https://codereview.appspot.com/6618059 >>> >>> Modified Paths: >>> -------------- >>> trunk/blender/release/scripts/startup/bl_ui/space_view3d.py >>> trunk/blender/source/blender/bmesh/CMakeLists.txt >>> trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c >>> trunk/blender/source/blender/bmesh/intern/bmesh_operator_api.h >>> trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h >>> trunk/blender/source/blender/editors/mesh/editmesh_tools.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/bmesh/operators/bmo_symmetrize.c >>> >>> Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d.py >>> =================================================================== >>> --- trunk/blender/release/scripts/startup/bl_ui/space_view3d.py 2012-10-15 >>> 23:17:24 UTC (rev 51355) >>> +++ trunk/blender/release/scripts/startup/bl_ui/space_view3d.py 2012-10-15 >>> 23:50:09 UTC (rev 51356) >>> @@ -1668,7 +1668,7 @@ >>> layout.menu("VIEW3D_MT_uv_map", text="UV Unwrap...") >>> >>> layout.separator() >>> - >>> + layout.operator("mesh.symmetrize") >>> layout.operator("view3d.edit_mesh_extrude_move_normal", >>> text="Extrude Region") >>> layout.operator("view3d.edit_mesh_extrude_individual_move", >>> text="Extrude Individual") >>> layout.operator("mesh.duplicate_move") >>> @@ -1719,6 +1719,7 @@ >>> layout.operator("mesh.shape_propagate_to_all") >>> layout.operator("mesh.select_vertex_path") >>> layout.operator("mesh.sort_elements") >>> + layout.operator("mesh.symmetrize") >>> >>> >>> class VIEW3D_MT_edit_mesh_select_mode(Menu): >>> >>> Modified: trunk/blender/source/blender/bmesh/CMakeLists.txt >>> =================================================================== >>> --- trunk/blender/source/blender/bmesh/CMakeLists.txt 2012-10-15 23:17:24 >>> UTC (rev 51355) >>> +++ trunk/blender/source/blender/bmesh/CMakeLists.txt 2012-10-15 23:50:09 >>> UTC (rev 51356) >>> @@ -52,6 +52,7 @@ >>> operators/bmo_mirror.c >>> operators/bmo_primitive.c >>> operators/bmo_removedoubles.c >>> + operators/bmo_symmetrize.c >>> operators/bmo_subdivide.c >>> operators/bmo_subdivide.h >>> operators/bmo_triangulate.c >>> >>> Modified: trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c >>> =================================================================== >>> --- trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2012-10-15 >>> 23:17:24 UTC (rev 51355) >>> +++ trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2012-10-15 >>> 23:50:09 UTC (rev 51356) >>> @@ -1182,6 +1182,29 @@ >>> 0 >>> }; >>> >>> +/* >>> + * Symmetrize >>> + * >>> + * Mekes the mesh elements in the "input" slot symmetrical. Unlike >>> + * normal mirroring, it only copies in one direction, as specified by >>> + * the "direction" slot. The edges and faces that cross the plane of >>> + * symmetry are split as needed to enforce symmetry. >>> + * >>> + * All new vertices, edges, and faces are added to the "geomout" slot. >>> + */ >>> +static BMOpDefine bmo_symmetrize_def = { >>> + "symmetrize", >>> + {{BMO_OP_SLOT_ELEMENT_BUF, "input"}, >>> + {BMO_OP_SLOT_INT, "direction"}, >>> + >>> + /* Outputs */ >>> + {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, >>> + >>> + {0} /* null-terminating sentinel */}, >>> + bmo_symmetrize_exec, >>> + 0 >>> +}; >>> + >>> BMOpDefine *opdefines[] = { >>> &bmo_automerge_def, >>> &bmo_average_vert_facedata_def, >>> @@ -1246,6 +1269,7 @@ >>> &bmo_split_def, >>> &bmo_split_edges_def, >>> &bmo_subdivide_edges_def, >>> + &bmo_symmetrize_def, >>> &bmo_transform_def, >>> &bmo_translate_def, >>> &bmo_triangle_fill_def, >>> >>> Modified: trunk/blender/source/blender/bmesh/intern/bmesh_operator_api.h >>> =================================================================== >>> --- trunk/blender/source/blender/bmesh/intern/bmesh_operator_api.h >>> 2012-10-15 23:17:24 UTC (rev 51355) >>> +++ trunk/blender/source/blender/bmesh/intern/bmesh_operator_api.h >>> 2012-10-15 23:50:09 UTC (rev 51356) >>> @@ -266,6 +266,16 @@ >>> DEL_ONLYTAGGED >>> }; >>> >>> +typedef enum { >>> + BMO_SYMMETRIZE_NEGATIVE_X, >>> + BMO_SYMMETRIZE_NEGATIVE_Y, >>> + BMO_SYMMETRIZE_NEGATIVE_Z, >>> + >>> + BMO_SYMMETRIZE_POSITIVE_X, >>> + BMO_SYMMETRIZE_POSITIVE_Y, >>> + BMO_SYMMETRIZE_POSITIVE_Z, >>> +} BMO_SymmDirection; >>> + >>> void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag); >>> void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag); >>> >>> >>> Modified: >>> trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h >>> =================================================================== >>> --- trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h >>> 2012-10-15 23:17:24 UTC (rev 51355) >>> +++ trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h >>> 2012-10-15 23:50:09 UTC (rev 51356) >>> @@ -96,6 +96,7 @@ >>> void bmo_split_edges_exec(BMesh *bm, BMOperator *op); >>> void bmo_split_exec(BMesh *bm, BMOperator *op); >>> void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op); >>> +void bmo_symmetrize_exec(BMesh *bm, BMOperator *op); >>> void bmo_transform_exec(BMesh *bm, BMOperator *op); >>> void bmo_translate_exec(BMesh *bm, BMOperator *op); >>> void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op); >>> >>> Added: trunk/blender/source/blender/bmesh/operators/bmo_symmetrize.c >>> =================================================================== >>> --- trunk/blender/source/blender/bmesh/operators/bmo_symmetrize.c >>> (rev 0) >>> +++ trunk/blender/source/blender/bmesh/operators/bmo_symmetrize.c >>> 2012-10-15 23:50:09 UTC (rev 51356) >>> @@ -0,0 +1,663 @@ >>> +/* >>> + * ***** 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. >>> + * >>> + * Contributor(s): Nicholas Bishop >>> + * >>> + * ***** END GPL LICENSE BLOCK ***** >>> + */ >>> + >>> +#include "MEM_guardedalloc.h" >>> + >>> +#include "BLI_array.h" >>> +#include "BLI_math.h" >>> +#include "BLI_utildefines.h" >>> + >>> +#include "bmesh.h" >>> +#include "intern/bmesh_operators_private.h" >>> + >>> +enum { >>> + SYMM_OUTPUT_GEOM = (1 << 0) >>> +}; >>> + >>> +/* Note: don't think there's much need to make these user-adjustable? */ >>> +#define SYMM_AXIS_THRESHOLD 0.00002f >>> +#define SYMM_VERT_THRESHOLD 0.00002f >>> + >>> +typedef enum { >>> + /* Coordinate lies on the side being copied from */ >>> + SYMM_SIDE_KEEP, >>> + /* Coordinate lies on the side being copied from and within the >>> + * axis threshold */ >>> + SYMM_SIDE_AXIS, >>> + /* Coordinate lies on the side being copied to */ >>> + SYMM_SIDE_KILL >>> +} SymmSide; >>> + >>> +typedef struct { >>> + BMesh *bm; >>> + BMOperator *op; >>> + >>> + int axis; >>> + BMO_SymmDirection direction; >>> + >>> + /* Maps from input vertices to their mirrors. If the vertex >>> + * doesn't have a mirror, it's not in this map. If the vertex is >>> + * within the axis threshold, it's mapped to itself. */ >>> + GHash *vert_symm_map; >>> + >>> + /* Edges that cross the symmetry plane and are asymmetric get >>> + * split. This map goes from input edges to output vertices. If an >>> + * edge is not split, it's not in this map. */ >>> + GHash *edge_split_map; >>> +} Symm; >>> + >>> +/* Return which side the coordinate lies on */ >>> +static SymmSide symm_co_side(const Symm *symm, >>> + const float *co) >>> +{ >>> + float comp = co[symm->axis]; >>> + if (ELEM3(symm->direction, >>> + BMO_SYMMETRIZE_NEGATIVE_X, >>> + BMO_SYMMETRIZE_NEGATIVE_Y, >>> + BMO_SYMMETRIZE_NEGATIVE_Z)) >>> + { >>> + comp = -comp; >>> + } >>> + >>> + if (comp >= 0) { >>> + if (comp < SYMM_AXIS_THRESHOLD) >>> + return SYMM_SIDE_AXIS; >>> + else >>> + return SYMM_SIDE_KEEP; >>> + } >>> + else >>> + return SYMM_SIDE_KILL; >>> +} >>> + >>> +/* Output vertices and the vert_map array */ >>> +static void symm_verts_mirror(Symm *symm) >>> +{ >>> + BMOIter oiter; >>> + BMVert *src_v, *dst_v; >>> + >>> + symm->vert_symm_map = BLI_ghash_ptr_new(AT); >>> + >>> + BMO_ITER (src_v, &oiter, symm->bm, symm->op, "input", BM_VERT) { >>> + SymmSide side = symm_co_side(symm, src_v->co); >>> + float co[3]; >>> + >>> + switch (side) { >>> + case SYMM_SIDE_KEEP: >>> + /* The vertex is outside the axis area; >>> output its mirror */ >>> + copy_v3_v3(co, src_v->co); >>> + co[symm->axis] = -co[symm->axis]; >>> + >>> + dst_v = BM_vert_create(symm->bm, co, src_v); >>> + BMO_elem_flag_enable(symm->bm, dst_v, >>> SYMM_OUTPUT_GEOM); >>> + BLI_ghash_insert(symm->vert_symm_map, >>> src_v, dst_v); >>> + break; >>> + >>> + case SYMM_SIDE_AXIS: >>> + /* The vertex is within the axis area, snap >>> to center */ >>> + src_v->co[symm->axis] = 0; >>> + /* Vertex isn't copied, map to itself */ >>> + BLI_ghash_insert(symm->vert_symm_map, >>> src_v, src_v); >>> + break; >>> + >>> + case SYMM_SIDE_KILL: >>> + /* The vertex does not lie in the >>> half-space being >>> + * copied from, nothing to do */ >>> + break; >>> + } >>> + } >>> +} >>> + >>> +static int symm_edge_crosses_axis(const Symm *symm, const BMEdge *e) >>> +{ >>> + const int sides[2] = {symm_co_side(symm, e->v1->co), >>> + symm_co_side(symm, >>> e->v2->co)}; >>> + >>> + return ((sides[0] != SYMM_SIDE_AXIS) && >>> + (sides[1] != SYMM_SIDE_AXIS) && >>> + (sides[0] != sides[1])); >>> +} >>> + >>> +/* Output edge split vertices for asymmetric edges and the edge_splits >>> + * mapping array */ >>> +static void symm_split_asymmetric_edges(Symm *symm) >>> +{ >>> + BMOIter oiter; >>> + BMEdge *e; >>> + >>> + symm->edge_split_map = BLI_ghash_ptr_new(AT); >>> + >>> + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { >>> + float flipped[3]; >>> + >>> + copy_v3_v3(flipped, e->v1->co); >>> + flipped[symm->axis] = -flipped[symm->axis]; >>> + >>> + if (symm_edge_crosses_axis(symm, e) && >>> + (!compare_v3v3(e->v2->co, flipped, >>> SYMM_VERT_THRESHOLD))) >>> + { >>> + /* Endpoints lie on opposite sides and are >>> asymmetric */ >>> + >>> + BMVert *v; >>> + float lambda = 0, edge_dir[3], co[3]; >>> + float plane_co[3][3][3] = { >>> + /* axis == 0 */ >>> + {{0, 0, 0}, {0, 1, 0}, {0, 0, 1}}, >>> + /* axis == 1 */ >>> + {{0, 0, 0}, {1, 0, 0}, {0, 0, 1}}, >>> + /* axis == 2 */ >>> + {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}}, >>> + }; >>> + int r; >>> + >>> + /* Find intersection of edge with symmetry plane */ >>> + sub_v3_v3v3(edge_dir, e->v2->co, e->v1->co); >>> + normalize_v3(edge_dir); >>> + r = isect_ray_plane_v3(e->v1->co, >>> + edge_dir, >>> + >>> plane_co[symm->axis][0], >>> + >>> plane_co[symm->axis][1], >>> + >>> plane_co[symm->axis][2], >>> + &lambda, >>> TRUE); >>> + BLI_assert(r); >>> + >>> + madd_v3_v3v3fl(co, e->v1->co, edge_dir, lambda); >>> + co[symm->axis] = 0; >>> + >>> + /* Edge is asymmetric, split it with a new vertex */ >>> + v = BM_vert_create(symm->bm, co, e->v1); >>> + BMO_elem_flag_enable(symm->bm, v, SYMM_OUTPUT_GEOM); >>> + BLI_ghash_insert(symm->edge_split_map, e, v); >>> + } >>> + } >>> +} >>> + >>> +static void symm_mirror_edges(Symm *symm) >>> +{ >>> + BMOIter oiter; >>> + BMEdge *e; >>> + >>> + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { >>> + BMVert *v1 = NULL, *v2 = NULL; >>> + BMEdge *e_new; >>> + >>> + v1 = BLI_ghash_lookup(symm->vert_symm_map, e->v1); >>> + v2 = BLI_ghash_lookup(symm->vert_symm_map, e->v2); >>> + >>> + if (v1 && v2) { >>> + e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE); >>> + BMO_elem_flag_enable(symm->bm, e_new, >>> SYMM_OUTPUT_GEOM); >>> + } >>> + else if (v1 || v2) { >>> >>> @@ Diff output truncated at 10240 characters. @@ >>> _______________________________________________ >>> Bf-blender-cvs mailing list >>> [email protected] >>> http://lists.blender.org/mailman/listinfo/bf-blender-cvs >> _______________________________________________ >> Bf-committers mailing list >> [email protected] >> http://lists.blender.org/mailman/listinfo/bf-committers > _______________________________________________ > Bf-committers mailing list > [email protected] > http://lists.blender.org/mailman/listinfo/bf-committers _______________________________________________ Bf-committers mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-committers
