[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39356] branches/soc-2011-onion/source/ blender/editors/sculpt_paint/paint_uv.c: smooth brush
Antony Riakiotakis
kalast at gmail.com
Sat Aug 13 04:33:27 CEST 2011
Revision: 39356
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39356
Author: psy-fi
Date: 2011-08-13 02:33:23 +0000 (Sat, 13 Aug 2011)
Log Message:
-----------
smooth brush
============
-Ported HC relaxation algorithm to uvs(Now stroke applies this to uvs)
there are quite a few optimizations to be made, this is a proof of concept stuff.
It looks like it works though :)
Modified Paths:
--------------
branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c
Modified: branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c 2011-08-13 00:39:53 UTC (rev 39355)
+++ branches/soc-2011-onion/source/blender/editors/sculpt_paint/paint_uv.c 2011-08-13 02:33:23 UTC (rev 39356)
@@ -65,6 +65,10 @@
#include "UI_view2d.h"
+
+#define MARK_BOUNDARY 1
+#define SELECTED 2
+
typedef struct UvAdjacencyElement {
/* pointer to original uvelement */
UvElement *element;
@@ -81,6 +85,35 @@
char flag;
}UvAdjacencyEdge;
+
+/* custom data for uv smoothing brush */
+typedef struct UvBrushData{
+ /* Contains the first of each set of coincident uvs.
+ * These will be used to perform smoothing on and propagate the changes
+ * to their coincident uvs */
+ UvAdjacencyElement *uv;
+
+ /* ...Is what it says */
+ int totalUniqueUvs;
+
+ /* Holds, for each UvElement in elementMap, a pointer to its unique uv.*/
+ int *uniqueUv;
+
+ /* Edges used for adjacency info, used with laplacian smoothing */
+ UvAdjacencyEdge *uvedges;
+
+ /* Need I say more? */
+ int totalUvEdges;
+
+ /* Timer to be used for airbrush-type brush */
+ wmTimer *timer;
+
+ /* To determine quickly adjacent uvs */
+ UvElementMap *elementMap;
+ /* uvsmooth Paint for fast reference */
+ Paint *uvpaint;
+}UvBrushData;
+
/*********** Improved Laplacian Relaxation Operator ************************/
/* Original code by Raul "farsthary"
* adapted to uv smoothing by Antony Riakiatakis
@@ -89,7 +122,7 @@
typedef struct Temp_UvData{
float sum_co[2], p[2], b[2], sum_b[2];
int ncounter;
-}Temp_VertexData;
+}Temp_UVData;
void set_border_flag(struct EditMesh *em){
EditFace *efa;
@@ -125,81 +158,66 @@
}
-void HC_relaxation(bContext *C, int edges){
- Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
- EditVert *eve;
- EditEdge *eed;
- Temp_VertexData *adr, *adror, *data;
+void HC_relaxation_iteration_uv(EditMesh *em, UvBrushData *brushdata, float mouse_coord[2], float alpha, float radius, float aspectRatio){
+ Temp_UVData *tmp_uvdata;
float diff[2];
+ int i;
+ Brush *brush = paint_brush(brushdata->uvpaint);
- if (edges) set_border_flag(em);
+ /* This will happen on initialization instead of here */
+ //if (edges) set_border_flag(em);
- adr=adror=(Temp_VertexData *)MEM_callocN((em->totvert)* sizeof(Temp_VertexData), "Temporal data");
+ tmp_uvdata = (Temp_UVData *)MEM_callocN(brushdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
- /* asigning memory */
- eve= em->verts.first;
- while(eve) {
- eve->tmp.p = adr;
- adr++;
- eve= eve->next;
- }
-
/* counting neighbors */
- for (eed = em->edges.first; eed; eed = eed->next){
- ((Temp_VertexData *)eed->v1->tmp.p)->ncounter++;
- ((Temp_VertexData *)eed->v2->tmp.p)->ncounter++;
+ for (i = 0; i < brushdata->totalUvEdges; i++){
+ UvAdjacencyEdge *tmpedge = brushdata->uvedges+i;
+ tmp_uvdata[tmpedge->uv1].ncounter++;
+ tmp_uvdata[tmpedge->uv2].ncounter++;
- add_v2_v2(((Temp_VertexData *)eed->v2->tmp.p)->sum_co, eed->v1->co);
- add_v2_v2(((Temp_VertexData *)eed->v1->tmp.p)->sum_co, eed->v2->co);
+ add_v2_v2(tmp_uvdata[tmpedge->uv2].sum_co, brushdata->uv[tmpedge->uv1].uv);
+ add_v2_v2(tmp_uvdata[tmpedge->uv1].sum_co, brushdata->uv[tmpedge->uv2].uv);
}
- for (eve = em->verts.first; eve; eve = eve->next){
- data = ((Temp_VertexData *)eve->tmp.p);
+ for (i = 0; i < brushdata->totalUniqueUvs; i++){
+ copy_v2_v2(diff,tmp_uvdata[i].sum_co);
+ mul_v2_fl(diff,1.f/tmp_uvdata[i].ncounter);
+ copy_v2_v2(tmp_uvdata[i].p,diff);
- copy_v2_v2(diff,data->sum_co);
- mul_v2_fl(diff,1.f/data->ncounter);
- copy_v2_v2(data->p,diff);
-
- data->b[0] = diff[0] - eve->co[0];
- data->b[1] = diff[1] - eve->co[1];
+ tmp_uvdata[i].b[0] = diff[0] - brushdata->uv[i].uv[0];
+ tmp_uvdata[i].b[1] = diff[1] - brushdata->uv[i].uv[1];
}
- for (eed = em->edges.first; eed; eed = eed->next){
- add_v2_v2(((Temp_VertexData *)eed->v1->tmp.p)->sum_b, ((Temp_VertexData *)eed->v2->tmp.p)->b);
- add_v2_v2(((Temp_VertexData *)eed->v2->tmp.p)->sum_b, ((Temp_VertexData *)eed->v1->tmp.p)->b);
+ for (i = 0; i < brushdata->totalUvEdges; i++){
+ UvAdjacencyEdge *tmpedge = brushdata->uvedges+i;
+ add_v2_v2(tmp_uvdata[tmpedge->uv1].sum_b, tmp_uvdata[tmpedge->uv2].b);
+ add_v2_v2(tmp_uvdata[tmpedge->uv2].sum_b, tmp_uvdata[tmpedge->uv1].b);
}
- for (eve = em->verts.first; eve; eve = eve->next){
- data = ((Temp_VertexData *)eve->tmp.p);
+ for (i = 0; i < brushdata->totalUniqueUvs; i++){
+ float dist;
+ sub_v2_v2v2(diff, brushdata->uv[i].uv, mouse_coord);
+ diff[1] /= aspectRatio;
+ if((dist = dot_v2v2(diff, diff)) <= radius){
+ UvElement *element;
+ float strength;
+ strength = alpha*brush_curve_strength(brush, dist, radius);
- if (!eve->f2 && (eve->f & SELECT)){
- eve->co[0] = data->p[0] - 0.5f*(data->b[0] + data->sum_b[0]/data->ncounter);
- eve->co[1] = data->p[1] - 0.5f*(data->b[1] + data->sum_b[1]/data->ncounter);
- }
+ brushdata->uv[i].uv[0] = (1.0-strength)*brushdata->uv[i].uv[0] + strength*(tmp_uvdata[i].p[0] - 0.5f*(tmp_uvdata[i].b[0] + tmp_uvdata[i].sum_b[0]/tmp_uvdata[i].ncounter));
+ brushdata->uv[i].uv[1] = (1.0-strength)*brushdata->uv[i].uv[1] + strength*(tmp_uvdata[i].p[1] - 0.5f*(tmp_uvdata[i].b[1] + tmp_uvdata[i].sum_b[1]/tmp_uvdata[i].ncounter));
- /* clip if needed by mirror modifier */
- if (eve->f2) {
- if (eve->f2 & 4) {
- eve->co[0]= 0.0f;
+ for(element = brushdata->uv[i].element; element; element = element->next){
+ MTFace *mt;
+ if(element->separate && element != brushdata->uv[i].element)
+ break;
+ mt = CustomData_em_get(&em->fdata, element->face->data, CD_MTFACE);
+ copy_v2_v2(mt->uv[element->tfindex], brushdata->uv[i].uv);
}
- if (eve->f2 & 8) {
- eve->co[1]= 0.0f;
- }
- if (eve->f2 & 16) {
- eve->co[2]= 0.0f;
- }
}
-
- eve->tmp.p= NULL;
}
- BKE_mesh_end_editmesh(obedit->data, em);
- MEM_freeN(adror);
+ MEM_freeN(tmp_uvdata);
- DAG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
-
return;
}
@@ -209,11 +227,11 @@
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
EditVert *eve;
EditEdge *eed;
- Temp_VertexData *adr, *adror, *data;
+ Temp_UVData *adr, *adror, *data;
float delta[2], prev_co[2];
int index =0;
- adr=adror=(Temp_VertexData *)MEM_callocN((em->totvert)* sizeof(Temp_VertexData), "Temporal data");
+ adr=adror=(Temp_UVData *)MEM_callocN((em->totvert)* sizeof(Temp_UVData), "Temporal data");
/* asigning memory */
eve= em->verts.first;
@@ -226,11 +244,11 @@
eed= em->edges.first;
while(eed){
- ((Temp_VertexData *)eed->v1->tmp.p)->ncounter++;
- ((Temp_VertexData *)eed->v2->tmp.p)->ncounter++;
+ ((Temp_UVData *)eed->v1->tmp.p)->ncounter++;
+ ((Temp_UVData *)eed->v2->tmp.p)->ncounter++;
- add_v2_v2(((Temp_VertexData *)eed->v2->tmp.p)->sum_co, eed->v1->co);
- add_v2_v2(((Temp_VertexData *)eed->v1->tmp.p)->sum_co, eed->v2->co);
+ add_v2_v2(((Temp_UVData *)eed->v2->tmp.p)->sum_co, eed->v1->co);
+ add_v2_v2(((Temp_UVData *)eed->v1->tmp.p)->sum_co, eed->v2->co);
eed = eed->next;
}
@@ -239,7 +257,7 @@
eve= em->verts.first;
while(eve){
if (!eve->f2 && (eve->f & SELECT)){
- data = ((Temp_VertexData *)eve->tmp.p);
+ data = ((Temp_UVData *)eve->tmp.p);
copy_v2_v2(prev_co,eve->co);
mul_v2_fl(data->sum_co, 1.f/data->ncounter);
copy_v2_v2(eve->co, data->sum_co);
@@ -273,10 +291,10 @@
if (!repeat) repeat = 1;
- for (i=0; i<repeat; i++) {
- if (relax == 1) HC_relaxation(C, edges);
+/* for (i=0; i<repeat; i++) {
+ if (relax == 1) HC_relaxation_iteration_uv(C, edges);
else smooth_laplacian_uv(C, edges); //default
- }
+ }*/
return OPERATOR_FINISHED;
}
@@ -310,51 +328,22 @@
}
-/* custom data for uv smoothing brush */
-typedef struct SmoothBrushData{
- /* Contains the first of each set of coincident uvs.
- * These will be used to perform smoothing on and propagate the changes
- * to their coincident uvs */
- UvAdjacencyElement *uv;
-
- /* ...Is what it says */
- int totalUniqueUvs;
-
- /* Holds, for each UvElement in elementMap, a pointer to its unique uv.*/
- int *uniqueUv;
-
- /* Edges used for adjacency info, used with laplacian smoothing */
- UvAdjacencyEdge *uvedges;
-
- /* Need I say more? */
- int totalUvEdges;
-
- /* Timer to be used for airbrush-type brush */
- wmTimer *timer;
-
- /* To determine quickly adjacent uvs */
- UvElementMap *elementMap;
- /* uvsmooth Paint for fast reference */
- Paint *uvpaint;
-}SmoothBrushData;
-
-
static void uv_smooth_stroke_apply(bContext *C, wmOperator *op, wmEvent *event, Object *obedit)
{
float co[2], radius;
ARegion *ar= CTX_wm_region(C);
EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
EditFace *efa;
- SmoothBrushData *smoothbrushdata = (SmoothBrushData *)op->customdata;
+ UvBrushData *brushdata = (UvBrushData *)op->customdata;
SpaceImage *sima;
int invert;
int width, height;
float aspectRatio;
float alpha;
- Brush *brush = paint_brush(smoothbrushdata->uvpaint);
+ Brush *brush = paint_brush(brushdata->uvpaint);
invert = RNA_boolean_get(op->ptr, "invert")? -1 : 1;
- alpha = brush_alpha(brush)*invert;
+ alpha = brush_alpha(brush);//*invert;
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
radius = brush_size(brush);
@@ -364,6 +353,8 @@
radius /= width;
radius = radius*radius;
+ //Implementation for uv pinching, temporarily disabled
+ /*
for(efa = em->faces.first; efa; efa= efa->next){
int nverts, i;
MTFace *mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
@@ -382,13 +373,19 @@
}
}
}
+ */
+ HC_relaxation_iteration_uv(em, brushdata, co, alpha, radius, aspectRatio);
+// for(){
+
+// }
+
BKE_mesh_end_editmesh(obedit->data, em);
}
static void uv_smooth_stroke_exit(bContext *C, wmOperator *op)
{
- SmoothBrushData *data = op->customdata;
+ UvBrushData *data = op->customdata;
if(data->timer){
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), data->timer);
}
@@ -438,12 +435,12 @@
}
-static SmoothBrushData *uv_smooth_stroke_init(bContext *C, wmOperator *op)
+static UvBrushData *uv_smooth_stroke_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = scene->toolsettings;
- SmoothBrushData *data = MEM_callocN(sizeof(*data), "UV Smooth Brush Data");
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list