[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48699] branches/soc-2012-sushi/source/ blender/bmesh/operators/bmo_bevel.c: first version of bevel algorithm
Alexander Mokhov
alexander.mokhov at gmail.com
Sat Jul 7 02:26:53 CEST 2012
Revision: 48699
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48699
Author: redtriangle
Date: 2012-07-07 00:26:50 +0000 (Sat, 07 Jul 2012)
Log Message:
-----------
first version of bevel algorithm
Modified Paths:
--------------
branches/soc-2012-sushi/source/blender/bmesh/operators/bmo_bevel.c
Modified: branches/soc-2012-sushi/source/blender/bmesh/operators/bmo_bevel.c
===================================================================
--- branches/soc-2012-sushi/source/blender/bmesh/operators/bmo_bevel.c 2012-07-07 00:17:46 UTC (rev 48698)
+++ branches/soc-2012-sushi/source/blender/bmesh/operators/bmo_bevel.c 2012-07-07 00:26:50 UTC (rev 48699)
@@ -26,6 +26,8 @@
#include "MEM_guardedalloc.h"
+//#include "BLI_heap.h"
+#include "BLI_listbase.h"
#include "BLI_array.h"
#include "BLI_math.h"
#include "BLI_smallhash.h"
@@ -35,7 +37,9 @@
#include "bmesh.h"
#include "intern/bmesh_operators_private.h" /* own include */
+#include "intern/bmesh_private.h"
+#include <stdbool.h>
#define BEVEL_FLAG 1
#define BEVEL_DEL 2
#define FACE_NEW 4
@@ -45,6 +49,8 @@
#define FACE_SPAN 64
#define FACE_HOLE 128
+#define EDGE_SELECTED 6
+
typedef struct LoopTag {
BMVert *newv;
} LoopTag;
@@ -53,6 +59,29 @@
BMVert *newv1, *newv2;
} EdgeTag;
+// Item in the list of vertices
+typedef struct VertexItem{
+ struct VertexItem *next, *prev;
+ BMVert *v;
+ bool onEdge; // true if new vertex located on edge; edge1 = edge, edge2 = NULL
+ // false, new vert located betwen edge1 and edge2
+ BMEdge *edge1;
+ BMEdge *edge2;
+}VertexItem;
+
+// list of new vertices formed around v
+typedef struct AdditionalVert{
+ struct AdditionalVert *next, *prev;
+ BMVert *v;
+ ListBase vertices;
+} AdditionalVert;
+
+
+typedef struct BevelParams{
+ ListBase vertList;
+ float offset;
+} BevelParams;
+
static void calc_corner_co(BMLoop *l, const float fac, float r_co[3],
const short do_dist, const short do_even)
{
@@ -178,8 +207,241 @@
(etags[BM_elem_index_get((e))].newv2) \
)
+// build point on edge
+// todo rename function
+BMVert* bevel_calc_aditional_vert(BMesh *bm, BevelParams *bp, BMEdge* edge, BMVert* vert)
+{
+ // TODO добавить проверку на то что эдж содержит вершину
+ float vect[3], normV[3];
+
+ BMVert *new_Vert = NULL;
+
+ sub_v3_v3v3(vect, BM_edge_other_vert(edge, vert)->co, vert->co);
+ normalize_v3_v3(normV, vect);
+ mul_v3_fl(normV, bp->offset);
+
+ add_v3_v3(normV, vert->co);
+
+ new_Vert = BM_vert_create(bm, normV, NULL);
+ return new_Vert;
+}
+
+// build point between edges
+BMVert* bevel_middle_vert(BMesh *bm, BevelParams *bp, BMEdge *edge_a, BMEdge *edge_b, BMVert *vert)
+{
+ float offset, v_a[3], v_b[3], v_c[3], norm_a[3], norm_b[3],norm_c[3], angel;
+ BMVert* new_vert = NULL;
+ offset = bp->offset;
+ // calc vectors
+ // TODO: ДОБАВИТЬ ПРОВЕРКУ НА ПАРАЛЕЛЬНОСТЬ
+ sub_v3_v3v3(v_a, BM_edge_other_vert(edge_a, vert)->co, vert->co);
+ sub_v3_v3v3(v_b, BM_edge_other_vert(edge_b, vert)->co, vert->co);
+ normalize_v3_v3(norm_a, v_a);
+ normalize_v3_v3(norm_b, v_b);
+ add_v3_v3v3(v_c, norm_a, norm_b);
+ mul_v3_fl(v_c, 0.5);
+ normalize_v3_v3(norm_c, v_c);
+
+ // v_c ^ edge_a
+ //cos = (v_c[0]*v_a[0] + v_c[1]*v_a[1] + v_c[2]*v_a[0]) / (len_v3(v_c)*len_v3(v_a));
+ angel = angle_normalized_v3v3(norm_c, norm_a);
+ //offset = offset / (sqrt(1-cos*cos));
+ offset = offset / sin(angel);
+
+ mul_v3_fl(norm_c, offset);
+ add_v3_v3(norm_c, vert->co);
+ new_vert = BM_vert_create(bm, norm_c, NULL);
+ return new_vert;
+}
+
+// additional construction arround the vertex
+void bevel_aditional_construction_by_vert(BMesh *bm, BevelParams *bp, BMOperator *op, BMVert *v)
+{
+ BMOIter siter;
+ BMIter iter;
+ BMEdge *e, **edges = NULL;
+ BLI_array_declare(edges);
+
+ // calc count input edges
+ BMO_ITER (e, &siter, bm, op, "geom", BM_EDGE) {
+ if ((e->v1 == v)|| (BM_edge_other_vert(e, e->v1) == v))
+ {
+ BMO_elem_flag_enable (bm, e, EDGE_SELECTED);
+ BLI_array_append(edges, e);
+ }
+ }
+
+ if (BLI_array_count(edges) == 1)
+ {
+ // TODO разработать плоский варинат
+ AdditionalVert *av;
+ av = (AdditionalVert*)MEM_callocN(sizeof(AdditionalVert), "AdditionalVert");
+ av->v = v;
+ av->vertices.first = av->vertices.last = NULL;
+ BLI_addtail(&bp->vertList, av);
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH)
+ {
+ if (e!= edges[0])
+ {
+ if ((e->v1 == v)||(BM_edge_other_vert(e, e->v1) == v)){
+ VertexItem *item;
+ item = (VertexItem*)MEM_callocN(sizeof(VertexItem), "VertexItem");
+ item->onEdge = true;
+ item->edge1 = e;
+ item->edge2 = NULL;
+ item->v = bevel_calc_aditional_vert(bm, bp, e, v);
+ BLI_addtail(&av->vertices, item);
+ }
+ }
+ }
+ }
+
+ if (BLI_array_count(edges) > 1)
+ {
+ BMEdge *cur_e, *prev_e;
+ AdditionalVert *av;
+ av = (AdditionalVert*)MEM_callocN(sizeof(AdditionalVert), "AdditionalVert");
+ av->v = v;
+ av->vertices.first = av->vertices.last = NULL;
+ BLI_addtail(&bp->vertList, av);
+ e = edges[0];
+ cur_e = e;
+ do {
+ prev_e = cur_e;
+ cur_e = bmesh_disk_edge_next(cur_e, v);
+ if (!BMO_elem_flag_test(bm, cur_e, EDGE_SELECTED)){
+ VertexItem *item;
+ item = (VertexItem*)MEM_callocN(sizeof(VertexItem), "VertexItem");
+ item->onEdge = true;
+ item->edge1 = cur_e;
+ item->edge2 = NULL;
+ item->v = bevel_calc_aditional_vert(bm, bp, cur_e, v);
+ BLI_addtail(&av->vertices, item);
+ }else {
+ if ( BMO_elem_flag_test(bm, cur_e, EDGE_SELECTED) &&
+ BMO_elem_flag_test(bm, prev_e, EDGE_SELECTED)){
+ VertexItem *item;
+ item = (VertexItem*)MEM_callocN(sizeof(VertexItem), "VertexItem");
+ item->onEdge = false;
+ item->edge1 = cur_e;
+ item->edge2 = prev_e;
+ item->v = bevel_middle_vert(bm, bp, prev_e,cur_e, v);
+ BLI_addtail(&av->vertices, item);
+ }
+ }
+ } while (e!= cur_e);
+ }
+}
+
+// Build the polygons along the selected Edge
+void bevel_build_polygon(BMesh *bm, BevelParams *bp, BMEdge *e){
+ BMVert *vi[4]; // only for linear case with seg = 1
+ BMFace *f1, *f2;
+ AdditionalVert *item, *av1, *av2;
+ VertexItem *vItem;
+ int i = 0;
+ // find pair
+ for (item = bp->vertList.first; item ; item = item->next){
+ if (item->v == e->v1)
+ av1 = item;
+ if (item->v == BM_edge_other_vert(e, e->v1))
+ av2 = item;
+ }
+
+
+ for (vItem = av1->vertices.first; vItem; vItem = vItem->next){
+ if (vItem->onEdge)
+ {
+ if (vItem->edge1 == bmesh_disk_edge_next(e, av1->v))
+ {
+ vi[i] = vItem->v;
+ i++;
+ }
+ if (vItem->edge1 == bmesh_disk_edge_prev(e, av1->v))
+ {
+ vi[i] = vItem->v;
+ i++;
+ }
+ }
+ else
+ {
+ if ((vItem->edge1 == bmesh_disk_edge_next(e, av1->v)) ||
+ (vItem->edge2 == bmesh_disk_edge_next(e, av1->v)))
+ {
+ vi[i] = vItem->v;
+ i++;
+ }
+ if ((vItem->edge1 == bmesh_disk_edge_prev(e, av1->v)) ||
+ (vItem->edge2 == bmesh_disk_edge_prev(e, av1->v)))
+ {
+ vi[i] = vItem->v;
+ i++;
+ }
+ }
+ }
+ for (vItem = av2->vertices.first; vItem; vItem = vItem->next){
+ if (vItem->onEdge)
+ {
+ if (vItem->edge1 == bmesh_disk_edge_next(e, av2->v))
+ {
+ vi[i] = vItem->v;
+ i++;
+ }
+ if (vItem->edge1 == bmesh_disk_edge_prev(e, av2->v))
+ {
+ vi[i] = vItem->v;
+ i++;
+ }
+ }
+ else
+ {
+ if ((vItem->edge1 == bmesh_disk_edge_next(e, av2->v)) ||
+ (vItem->edge2 == bmesh_disk_edge_next(e, av2->v)))
+ {
+ vi[i] = vItem->v;
+ i++;
+ }
+ if ((vItem->edge1 == bmesh_disk_edge_prev(e, av2->v)) ||
+ (vItem->edge2 == bmesh_disk_edge_prev(e, av2->v)))
+ {
+ vi[i] = vItem->v;
+ i++;
+ }
+ }
+ }
+ BM_face_create_quad_tri(bm, vi[0], vi[1], vi[3], vi[2], NULL, TRUE);
+
+
+}
+
void bmo_bevel_exec(BMesh *bm, BMOperator *op)
{
+ BMOIter siter;
+ BMVert *v;
+ BMEdge *e;
+ BevelParams bp;
+ AdditionalVert *item;
+
+ bp.offset = 0.1;
+ bp.vertList.first = bp.vertList.last = NULL;
+ // The analysis of the input vertices and vyrolnenine additional constructions
+ BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
+ bevel_aditional_construction_by_vert(bm, &bp, op, v);
+ }
+
+ // Build polgiony found at verteces
+ // First construct the polygons along the edge
+ BMO_ITER(e, &siter, bm, op, "geom", BM_EDGE){
+ bevel_build_polygon(bm, &bp, e);
+ }
+
+
+}
+
+
+void bmo_bevel_exec_old(BMesh *bm, BMOperator *op)
+{
BMOIter siter;
BMIter iter;
BMEdge *e;
@@ -211,7 +473,7 @@
BMO_elem_flag_enable(bm, e, BEVEL_FLAG | BEVEL_DEL);
BMO_elem_flag_enable(bm, e->v1, BEVEL_FLAG | BEVEL_DEL);
BMO_elem_flag_enable(bm, e->v2, BEVEL_FLAG | BEVEL_DEL);
-
+ // разбраться с этим случаем
if (BM_edge_face_count(e) < 2) {
BMO_elem_flag_disable(bm, e, BEVEL_DEL);
BMO_elem_flag_disable(bm, e->v1, BEVEL_DEL);
More information about the Bf-blender-cvs
mailing list