[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