[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11059] branches/pyapi_devel/source/ blender/src/sculptmode-stroke.c: Didnt add this file from trunk.

Campbell Barton cbarton at metavr.com
Tue Jun 26 06:29:00 CEST 2007


Revision: 11059
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11059
Author:   campbellbarton
Date:     2007-06-26 06:28:23 +0200 (Tue, 26 Jun 2007)

Log Message:
-----------
Didnt add this file from trunk.

Added Paths:
-----------
    branches/pyapi_devel/source/blender/src/sculptmode-stroke.c

Added: branches/pyapi_devel/source/blender/src/sculptmode-stroke.c
===================================================================
--- branches/pyapi_devel/source/blender/src/sculptmode-stroke.c	                        (rev 0)
+++ branches/pyapi_devel/source/blender/src/sculptmode-stroke.c	2007-06-26 04:28:23 UTC (rev 11059)
@@ -0,0 +1,280 @@
+/*
+ * $Id$
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Storage and manipulation of sculptmode brush strokes.
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+#include "DNA_listBase.h"
+#include "BLI_blenlib.h"
+#include "BIF_gl.h"
+#include "BDR_sculptmode.h"
+#include <math.h>
+
+/* Temporary storage of input stroke control points */
+typedef struct StrokePoint {
+	struct StrokePoint *next, *prev;
+	short x, y;
+} StrokePoint;
+typedef struct SculptStroke {
+	short (*loc)[2];
+	int max;
+	int index;
+	float length;
+	ListBase final;
+	StrokePoint *final_mem;
+} SculptStroke;
+
+void sculpt_stroke_new(const int max)
+{
+	SculptSession *ss = sculpt_session();
+
+	ss->stroke = MEM_callocN(sizeof(SculptStroke), "SculptStroke");
+	ss->stroke->loc = MEM_callocN(sizeof(short) * 2 * max, "SculptStroke.loc");
+	ss->stroke->max = max;
+	ss->stroke->index = -1;
+}
+
+void sculpt_stroke_free()
+{
+	SculptSession *ss = sculpt_session();
+	if(ss && ss->stroke) {
+		if(ss->stroke->loc) MEM_freeN(ss->stroke->loc);
+		if(ss->stroke->final_mem) MEM_freeN(ss->stroke->final_mem);
+
+		MEM_freeN(ss->stroke);
+		ss->stroke = NULL;
+	}
+}
+
+void sculpt_stroke_add_point(const short x, const short y)
+{
+	SculptStroke *stroke = sculpt_session()->stroke;
+	const int next = stroke->index + 1;
+
+	if(stroke->index == -1) {
+		stroke->loc[0][0] = x;
+		stroke->loc[0][1] = y;
+		stroke->index = 0;
+	}
+	else if(next < stroke->max) {
+		const int dx = x - stroke->loc[stroke->index][0];
+		const int dy = y - stroke->loc[stroke->index][1];
+		stroke->loc[next][0] = x;
+		stroke->loc[next][1] = y;
+		stroke->length += sqrt(dx*dx + dy*dy);
+		stroke->index = next;
+	}
+}
+
+void sculpt_stroke_smooth(SculptStroke *stroke)
+{
+	/* Apply smoothing (exclude the first and last points)*/
+	StrokePoint *p = stroke->final.first;
+	if(p && p->next && p->next->next) {
+		for(p = p->next->next; p && p->next && p->next->next; p = p->next) {
+			p->x = p->prev->prev->x*0.1 + p->prev->x*0.2 + p->x*0.4 + p->next->x*0.2 + p->next->next->x*0.1;
+			p->y = p->prev->prev->y*0.1 + p->prev->y*0.2 + p->y*0.4 + p->next->y*0.2 + p->next->next->y*0.1;
+		}
+	}	
+}
+
+void sculpt_stroke_create_final()
+{
+	SculptStroke *stroke = sculpt_session()->stroke;
+
+	if(stroke) {
+		StrokePoint *p, *pnext;
+		int i;
+
+		/* Copy loc into final */
+		if(stroke->final_mem)
+			MEM_freeN(stroke->final_mem);
+		stroke->final_mem = MEM_callocN(sizeof(StrokePoint) * (stroke->index + 1) * 2, "SculptStroke.final");
+		stroke->final.first = stroke->final.last = NULL;
+		for(i = 0; i <= stroke->index; ++i) {
+			p = &stroke->final_mem[i];
+			p->x = stroke->loc[i][0];
+			p->y = stroke->loc[i][1];
+			BLI_addtail(&stroke->final, p);
+		}
+
+		/* Remove shortest edges */
+		for(p = ((StrokePoint*)stroke->final.first)->next; p && p->next; p = pnext) {
+			const int dx = p->x - p->prev->x;
+			const int dy = p->y - p->prev->y;
+			const float len = sqrt(dx*dx + dy*dy);
+			pnext = p->next;
+			if(len < 10) {
+				BLI_remlink(&stroke->final, p);
+			}
+		}
+
+		sculpt_stroke_smooth(stroke);
+
+		/* Subdivide edges */
+		for(p = stroke->final.first; p && p->next; p = pnext) {
+			StrokePoint *np = &stroke->final_mem[i++];
+
+			pnext = p->next;
+			np->x = (p->x + p->next->x) / 2;
+			np->y = (p->y + p->next->y) / 2;
+			BLI_insertlink(&stroke->final, p, np);
+		}
+
+		sculpt_stroke_smooth(stroke);
+	}
+}
+
+float sculpt_stroke_seglen(StrokePoint *p1, StrokePoint *p2)
+{
+	int dx = p2->x - p1->x;
+	int dy = p2->y - p1->y;
+	return sqrt(dx*dx + dy*dy);
+}
+
+void sculpt_stroke_apply(struct EditData *e)
+{
+	SculptStroke *stroke = sculpt_session()->stroke;
+
+	if(stroke) {
+		sculpt_stroke_create_final();
+
+		if(stroke->length > 200) {
+			const short spacing = 2;
+			const int dots = stroke->length / spacing;
+			int i;
+			StrokePoint *p = stroke->final.first;
+			float startloc = 0;
+
+			for(i = 0; i < dots && p && p->next; ++i) {
+				const float dotloc = spacing * i;
+				short co[2];
+				float len = sculpt_stroke_seglen(p, p->next);
+				float u, v;
+				
+				/* Find edge containing dot */
+				while(dotloc > startloc + len && p && p->next && p->next->next) {
+					p = p->next;
+					startloc += len;
+					len = sculpt_stroke_seglen(p, p->next);
+				}
+
+				if(!p || !p->next) break;
+
+
+				u = (dotloc - startloc) / len;
+				v = 1 - u;
+					
+				co[0] = p->x*u + p->next->x*v;
+				co[1] = p->y*u + p->next->y*v;
+
+				if(startloc > 100)
+					break;
+
+				do_symmetrical_brush_actions(e, co, NULL);
+			}
+
+			/* Replace remaining values in stroke->loc with remaining stroke->final values */
+			stroke->index = -1;
+			stroke->length = 0;
+			for(; p; p = p->next) {
+				++stroke->index;
+				stroke->loc[stroke->index][0] = p->x;
+				stroke->loc[stroke->index][1] = p->y;
+				if(p->next) {
+					stroke->length += sculpt_stroke_seglen(p, p->next);
+				}
+			}
+		}
+	}
+}
+
+void sculpt_stroke_apply_all(struct EditData *e)
+{
+	SculptStroke *stroke = sculpt_session()->stroke;
+
+	sculpt_stroke_create_final();
+
+	if(stroke) {
+		const short spacing = 2;
+		const int dots = stroke->length / spacing;
+		int i;
+		StrokePoint *p = stroke->final.first;
+		float startloc = 0;
+
+		for(i = 0; i < dots && p && p->next; ++i) {
+			const float dotloc = spacing * i;
+			short co[2];
+			float len = sculpt_stroke_seglen(p, p->next);
+			float u, v;
+				
+			/* Find edge containing dot */
+			while(dotloc > startloc + len && p && p->next && p->next->next) {
+				p = p->next;
+				startloc += len;
+				len = sculpt_stroke_seglen(p, p->next);
+			}
+
+			if(!p || !p->next) break;
+
+
+			u = (dotloc - startloc) / len;
+			v = 1 - u;
+					
+			co[0] = p->x*u + p->next->x*v;
+			co[1] = p->y*u + p->next->y*v;
+
+			do_symmetrical_brush_actions(e, co, NULL);
+		}
+	}
+}
+
+void sculpt_stroke_draw()
+{
+	SculptStroke *stroke = sculpt_session()->stroke;
+
+	if(stroke) {
+		StrokePoint *p;
+
+		/* Draws the original stroke */
+		/*glColor3f(1, 0, 0);		
+		glBegin(GL_LINE_STRIP);
+		for(i = 0; i <= stroke->index; ++i)
+			glVertex2s(stroke->loc[i][0], stroke->loc[i][1]);
+		glEnd();*/
+
+		/* Draws the smoothed stroke */
+		glColor3f(0, 1, 0);
+		glBegin(GL_LINE_STRIP);
+		for(p = stroke->final.first; p; p = p->next)
+			glVertex2s(p->x, p->y);
+		glEnd();
+	}
+}





More information about the Bf-blender-cvs mailing list