[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25100] branches/sculpt25/source/blender: Sculpt Branch:

Brecht Van Lommel brecht at blender.org
Thu Dec 3 19:35:37 CET 2009


Revision: 25100
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25100
Author:   blendix
Date:     2009-12-03 19:35:37 +0100 (Thu, 03 Dec 2009)

Log Message:
-----------
Sculpt Branch:

* Multithread parts of multires and subsurf. Only loops working on
  face grid data and do no memory allocation have been multithreaded,
  others would be more complicated.
* Force some CCGSubsurf functions to be inlined, gives a small overall
  speedup in subsurf code.

* Fix sculpting not working correct with transformed objects.
* Fix a few cases of "spikes" on lower level multires levels. There's
  still cases where it happens, usually on boundary cornders. The
  problem is that in such cases the limit surfaces can be very different
  from the low res surface, so the tangent space is very different too..
* Fix crash deleting multires higher levels with level set to 0.
* Fix crashes that happened sometimes when adding faces in editmode.

Modified Paths:
--------------
    branches/sculpt25/source/blender/blenkernel/BKE_DerivedMesh.h
    branches/sculpt25/source/blender/blenkernel/BKE_subsurf.h
    branches/sculpt25/source/blender/blenkernel/intern/CCGSubSurf.c
    branches/sculpt25/source/blender/blenkernel/intern/multires.c
    branches/sculpt25/source/blender/blenkernel/intern/subsurf_ccg.c
    branches/sculpt25/source/blender/editors/sculpt_paint/sculpt.c
    branches/sculpt25/source/blender/gpu/intern/gpu_buffers.c

Modified: branches/sculpt25/source/blender/blenkernel/BKE_DerivedMesh.h
===================================================================
--- branches/sculpt25/source/blender/blenkernel/BKE_DerivedMesh.h	2009-12-03 18:28:04 UTC (rev 25099)
+++ branches/sculpt25/source/blender/blenkernel/BKE_DerivedMesh.h	2009-12-03 18:35:37 UTC (rev 25100)
@@ -151,6 +151,7 @@
 	int (*getGridSize)(DerivedMesh *dm);
 	DMGridData **(*getGridData)(DerivedMesh *dm);
 	DMGridAdjacency *(*getGridAdjacency)(DerivedMesh *dm);
+	int *(*getGridOffset)(DerivedMesh *dm);
 
 	/* Iterate over each mapped vertex in the derived mesh, calling the
 	 * given function with the original vert and the mapped vert's new

Modified: branches/sculpt25/source/blender/blenkernel/BKE_subsurf.h
===================================================================
--- branches/sculpt25/source/blender/blenkernel/BKE_subsurf.h	2009-12-03 18:28:04 UTC (rev 25099)
+++ branches/sculpt25/source/blender/blenkernel/BKE_subsurf.h	2009-12-03 18:35:37 UTC (rev 25100)
@@ -73,6 +73,7 @@
 
 	struct DMGridData **gridData;
 	struct DMGridAdjacency *gridAdjacency;
+	int *gridOffset;
 	struct _CCGFace **gridFaces;
 
 	struct {

Modified: branches/sculpt25/source/blender/blenkernel/intern/CCGSubSurf.c
===================================================================
--- branches/sculpt25/source/blender/blenkernel/intern/CCGSubSurf.c	2009-12-03 18:28:04 UTC (rev 25099)
+++ branches/sculpt25/source/blender/blenkernel/intern/CCGSubSurf.c	2009-12-03 18:35:37 UTC (rev 25100)
@@ -8,6 +8,12 @@
 
 #include "BLO_sys_types.h" // for intptr_t support
 
+#ifdef _MSC_VER
+#define CCG_INLINE __inline
+#else
+#define CCG_INLINE inline
+#endif
+
 /* used for normalize_v3 in BLI_math_vector
  * float.h's FLT_EPSILON causes trouble with subsurf normals - campbell */
 #define EPSILON (1.0e-35f)
@@ -523,19 +529,19 @@
 	return f;
 }
 
-static void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize) {
+static CCG_INLINE void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize) {
 	int maxGridSize = 1 + (1<<(levels-1));
 	int spacing = 1<<(levels-lvl);
 	byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize));
 	return &gridBase[dataSize*x*spacing];
 }
-static void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize) {
+static CCG_INLINE void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize) {
 	int maxGridSize = 1 + (1<<(levels-1));
 	int spacing = 1<<(levels-lvl);
 	byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize));
 	return &gridBase[dataSize*(maxGridSize + (y*maxGridSize + x)*spacing)];
 }
-static float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) {
+static CCG_INLINE float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) {
 	int maxGridSize = 1 + (1<<(levels-1));
 	int spacing = 1<<(levels-lvl);
 	byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize));
@@ -548,7 +554,7 @@
 			return i;
 	return -1;
 }
-static void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, int levels, int dataSize) {
+static CCG_INLINE void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, int levels, int dataSize) {
 	int maxGridSize = 1 + (1<<(levels-1));
 	int spacing = 1<<(levels-lvl);
 	int S, x, y, cx, cy;
@@ -1146,9 +1152,11 @@
 	int normalDataOffset = ss->normalDataOffset;
 	int vertDataSize = ss->meshIFC.vertDataSize;
 
+	#pragma omp parallel for private(ptrIdx) schedule(static)
 	for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
 		CCGFace *f = (CCGFace*) effectedF[ptrIdx];
 		int S, x, y;
+		float no[3];
 
 		for (S=0; S<f->numVerts; S++) {
 			for (y=0; y<gridSize-1; y++)
@@ -1164,13 +1172,7 @@
 			if (FACE_getVerts(f)[S]->flags&Vert_eEffected)
 				NormZero(FACE_getIFNo(f, lvl, S, gridSize-1, gridSize-1));
 		}
-	}
 
-	for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
-		CCGFace *f = (CCGFace*) effectedF[ptrIdx];
-		int S, x, y;
-		float no[3];
-
 		for (S=0; S<f->numVerts; S++) {
 			int yLimit = !(FACE_getEdges(f)[(S-1+f->numVerts)%f->numVerts]->flags&Edge_eEffected);
 			int xLimit = !(FACE_getEdges(f)[S]->flags&Edge_eEffected);
@@ -1275,18 +1277,16 @@
 			}
 		}
 	}
+
+	#pragma omp parallel for private(ptrIdx) schedule(static)
 	for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
 		CCGFace *f = (CCGFace*) effectedF[ptrIdx];
-		int S;
+		int S, x, y;
 
 		for (S=0; S<f->numVerts; S++) {
 			NormCopy(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, gridSize-1),
 					 FACE_getIFNo(f, lvl, S, gridSize-1, 0));
 		}
-	}
-	for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
-		CCGFace *f = (CCGFace*) effectedF[ptrIdx];
-		int S, x, y;
 
 		for (S=0; S<f->numVerts; S++) {
 			for (y=0; y<gridSize; y++) {
@@ -1320,12 +1320,14 @@
 	int edgeSize = 1 + (1<<curLvl);
 	int gridSize = 1 + (1<<(curLvl-1));
 	int nextLvl = curLvl+1;
-	int ptrIdx, S, y, x, i, cornerIdx;
+	int ptrIdx, cornerIdx, i;
+	int vertDataSize = ss->meshIFC.vertDataSize;
 	void *q = ss->q, *r = ss->r;
-	int vertDataSize = ss->meshIFC.vertDataSize;
 
+	#pragma omp parallel for private(ptrIdx) schedule(static)
 	for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
 		CCGFace *f = (CCGFace*) effectedF[ptrIdx];
+		int S, x, y;
 
 			/* interior face midpoints
 			 *  o old interior face points
@@ -1406,6 +1408,7 @@
 	for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
 		CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
 		float sharpness = EDGE_getSharpness(e, curLvl);
+		int x, j;
 
 		if (_edge_isBoundary(e) || sharpness>1.0) {
 			for (x=0; x<edgeSize-1; x++) {
@@ -1429,8 +1432,8 @@
 				VertDataCopy(q, co0);
 				VertDataAdd(q, co1);
 
-				for (i=0; i<e->numFaces; i++) {
-					CCGFace *f = e->faces[i];
+				for (j=0; j<e->numFaces; j++) {
+					CCGFace *f = e->faces[j];
 					VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx, 1, subdivLevels, vertDataSize));
 					numFaces++;
 				}
@@ -1460,10 +1463,10 @@
 		void *nCo = VERT_getCo(v, nextLvl);
 		int sharpCount = 0, allSharp = 1;
 		float avgSharpness = 0.0;
-		int seam = VERT_seam(v), seamEdges = 0;
+		int j, seam = VERT_seam(v), seamEdges = 0;
 
-		for (i=0; i<v->numEdges; i++) {
-			CCGEdge *e = v->edges[i];
+		for (j=0; j<v->numEdges; j++) {
+			CCGEdge *e = v->edges[j];
 			float sharpness = EDGE_getSharpness(e, curLvl);
 
 			if (seam && _edge_isBoundary(e))
@@ -1493,8 +1496,8 @@
 			int numBoundary = 0;
 
 			VertDataZero(r);
-			for (i=0; i<v->numEdges; i++) {
-				CCGEdge *e = v->edges[i];
+			for (j=0; j<v->numEdges; j++) {
+				CCGEdge *e = v->edges[j];
 				if (_edge_isBoundary(e)) {
 					VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize));
 					numBoundary++;
@@ -1510,15 +1513,15 @@
 			int numEdges = 0, numFaces = 0;
 
 			VertDataZero(q);
-			for (i=0; i<v->numFaces; i++) {
-				CCGFace *f = v->faces[i];
+			for (j=0; j<v->numFaces; j++) {
+				CCGFace *f = v->faces[j];
 				VertDataAdd(q, FACE_getIFCo(f, nextLvl, _face_getVertIndex(f,v), cornerIdx, cornerIdx));
 				numFaces++;
 			}
 			VertDataMulN(q, 1.0f/numFaces);
 			VertDataZero(r);
-			for (i=0; i<v->numEdges; i++) {
-				CCGEdge *e = v->edges[i];
+			for (j=0; j<v->numEdges; j++) {
+				CCGEdge *e = v->edges[j];
 				VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1,vertDataSize));
 				numEdges++;
 			}
@@ -1540,8 +1543,8 @@
 				allSharp = 1;
 			}
 
-			for (i=0; i<v->numEdges; i++) {
-				CCGEdge *e = v->edges[i];
+			for (j=0; j<v->numEdges; j++) {
+				CCGEdge *e = v->edges[j];
 				float sharpness = EDGE_getSharpness(e, curLvl);
 
 				if (seam) {
@@ -1585,6 +1588,7 @@
 		float sharpness = EDGE_getSharpness(e, curLvl);
 		int sharpCount = 0;
 		float avgSharpness = 0.0;
+		int x, j;
 
 		if (sharpness!=0.0f) {
 			sharpCount = 2;
@@ -1622,8 +1626,8 @@
 				VertDataZero(r);
 				VertDataAdd(r, EDGE_getCo(e, curLvl, x-1));
 				VertDataAdd(r, EDGE_getCo(e, curLvl, x+1));
-				for (i=0; i<e->numFaces; i++) {
-					CCGFace *f = e->faces[i];
+				for (j=0; j<e->numFaces; j++) {
+					CCGFace *f = e->faces[j];
 					VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx-1, 1, subdivLevels, vertDataSize));
 					VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx+1, 1, subdivLevels, vertDataSize));
 
@@ -1654,52 +1658,91 @@
 		}
 	}
 
-	for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
-		CCGFace *f = (CCGFace*) effectedF[ptrIdx];
+	#pragma omp parallel private(ptrIdx)
+	{
+		void *q, *r;
 
-			/* interior center point shift
-			 *  o old face center point (shifting)
-			 *  o old interior edge points
-			 *  o new interior face midpoints
-			 */
-		VertDataZero(q);
-		for (S=0; S<f->numVerts; S++) {
-			VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1));
+		#pragma omp critical
+		{
+			q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
+			r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
 		}
-		VertDataMulN(q, 1.0f/f->numVerts);
-		VertDataZero(r);
-		for (S=0; S<f->numVerts; S++) {
-			VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1));
-		}
-		VertDataMulN(r, 1.0f/f->numVerts);
 
-		VertDataMulN(FACE_getCenterData(f), f->numVerts-2.0f);
-		VertDataAdd(FACE_getCenterData(f), q);
-		VertDataAdd(FACE_getCenterData(f), r);
-		VertDataMulN(FACE_getCenterData(f), 1.0f/f->numVerts);
+		#pragma omp for schedule(static)
+		for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
+			CCGFace *f = (CCGFace*) effectedF[ptrIdx];
+			int S, x, y;
 
-		for (S=0; S<f->numVerts; S++) {
-				/* interior face shift
-				 *  o old interior face point (shifting)
-				 *  o new interior edge midpoints
+				/* interior center point shift
+				 *  o old face center point (shifting)
+				 *  o old interior edge points
 				 *  o new interior face midpoints
 				 */
-			for (x=1; x<gridSize-1; x++) {
-				for (y=1; y<gridSize-1; y++) {
+			VertDataZero(q);
+			for (S=0; S<f->numVerts; S++) {
+				VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1));
+			}
+			VertDataMulN(q, 1.0f/f->numVerts);
+			VertDataZero(r);
+			for (S=0; S<f->numVerts; S++) {
+				VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1));
+			}
+			VertDataMulN(r, 1.0f/f->numVerts);
+
+			VertDataMulN(FACE_getCenterData(f), f->numVerts-2.0f);
+			VertDataAdd(FACE_getCenterData(f), q);
+			VertDataAdd(FACE_getCenterData(f), r);
+			VertDataMulN(FACE_getCenterData(f), 1.0f/f->numVerts);
+
+			for (S=0; S<f->numVerts; S++) {
+					/* interior face shift

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list