[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43127] branches/bmesh/blender/source/ blender: update UV project modifier to use MLoopUV' s rather then tessface UV's

Campbell Barton ideasman42 at gmail.com
Wed Jan 4 15:42:23 CET 2012


Revision: 43127
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43127
Author:   campbellbarton
Date:     2012-01-04 14:42:11 +0000 (Wed, 04 Jan 2012)
Log Message:
-----------
update UV project modifier to use MLoopUV's rather then tessface UV's

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/blenkernel/BKE_mesh.h
    branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c
    branches/bmesh/blender/source/blender/modifiers/intern/MOD_uvproject.c

Modified: branches/bmesh/blender/source/blender/blenkernel/BKE_mesh.h
===================================================================
--- branches/bmesh/blender/source/blender/blenkernel/BKE_mesh.h	2012-01-04 13:43:40 UTC (rev 43126)
+++ branches/bmesh/blender/source/blender/blenkernel/BKE_mesh.h	2012-01-04 14:42:11 UTC (rev 43127)
@@ -86,6 +86,9 @@
 void mesh_calc_poly_normal(struct MPoly *mpoly, struct MLoop *loopstart, 
                            struct MVert *mvarray, float no[3]);
 
+void mesh_calc_poly_normal_coords(struct MPoly *mpoly, struct MLoop *loopstart,
+                                  const float (*vertex_coords)[3], float no[3]);
+
 void mesh_calc_poly_center(struct MPoly *mpoly, struct MLoop *loopstart,
                            struct MVert *mvarray, float cent[3]);
 

Modified: branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c
===================================================================
--- branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c	2012-01-04 13:43:40 UTC (rev 43126)
+++ branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c	2012-01-04 14:42:11 UTC (rev 43127)
@@ -2600,7 +2600,85 @@
 		no[2] = 1.0;
 	}
 }
+/* duplicate of function above _but_ takes coords rather then mverts */
+static void mesh_calc_ngon_normal_coords(MPoly *mpoly, MLoop *loopstart,
+                                         const float (*vertex_coords)[3], float normal[3])
+{
 
+	float *v1, *v2, *v3;
+	double u[3], v[3], w[3];
+	double n[3] = {0.0, 0.0, 0.0}, l;
+	int i;
+
+	for(i = 0; i < mpoly->totloop; i++){
+		v1 = vertex_coords + loopstart[i].v;
+		v2 = vertex_coords + loopstart[(i+1)%mpoly->totloop].v;
+		v3 = vertex_coords + loopstart[(i+2)%mpoly->totloop].v;
+
+		VECCOPY(u, v1);
+		VECCOPY(v, v2);
+		VECCOPY(w, v3);
+
+		/*this fixes some weird numerical error*/
+		if (i==0) {
+			u[0] += 0.0001f;
+			u[1] += 0.0001f;
+			u[2] += 0.0001f;
+		}
+
+		n[0] += (u[1] - v[1]) * (u[2] + v[2]);
+		n[1] += (u[2] - v[2]) * (u[0] + v[0]);
+		n[2] += (u[0] - v[0]) * (u[1] + v[1]);
+	}
+
+	l = n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
+	l = sqrt(l);
+
+	if (l == 0.0) {
+		normal[0] = 0.0f;
+		normal[1] = 0.0f;
+		normal[2] = 1.0f;
+
+		return;
+	} else l = 1.0f / l;
+
+	n[0] *= l;
+	n[1] *= l;
+	n[2] *= l;
+
+	normal[0] = (float) n[0];
+	normal[1] = (float) n[1];
+	normal[2] = (float) n[2];
+}
+
+void mesh_calc_poly_normal_coords(MPoly *mpoly, MLoop *loopstart,
+                           const float (*vertex_coords)[3], float no[3])
+{
+	if (mpoly->totloop > 4) {
+		mesh_calc_ngon_normal_coords(mpoly, loopstart, vertex_coords, no);
+	}
+	else if (mpoly->totloop == 3){
+		normal_tri_v3(no,
+		              vertex_coords[loopstart[0].v],
+		              vertex_coords[loopstart[1].v],
+		              vertex_coords[loopstart[2].v]
+		              );
+	}
+	else if (mpoly->totloop == 4) {
+		normal_quad_v3(no,
+		               vertex_coords[loopstart[0].v],
+		               vertex_coords[loopstart[1].v],
+		               vertex_coords[loopstart[2].v],
+		               vertex_coords[loopstart[3].v]
+		               );
+	}
+	else { /* horrible, two sided face! */
+		no[0] = 0.0;
+		no[1] = 0.0;
+		no[2] = 1.0;
+	}
+}
+
 static void mesh_calc_ngon_center(MPoly *mpoly, MLoop *loopstart,
                                   MVert *mvert, float cent[3])
 {

Modified: branches/bmesh/blender/source/blender/modifiers/intern/MOD_uvproject.c
===================================================================
--- branches/bmesh/blender/source/blender/modifiers/intern/MOD_uvproject.c	2012-01-04 13:43:40 UTC (rev 43126)
+++ branches/bmesh/blender/source/blender/modifiers/intern/MOD_uvproject.c	2012-01-04 14:42:11 UTC (rev 43127)
@@ -47,6 +47,7 @@
 
 
 #include "BKE_camera.h"
+#include "BKE_mesh.h"
 #include "BKE_DerivedMesh.h"
 
 #include "MOD_modifiertypes.h"
@@ -147,10 +148,12 @@
 					 Object *ob, DerivedMesh *dm)
 {
 	float (*coords)[3], (*co)[3];
-	MTFace *tface;
-	int i, numVerts, numFaces;
+	MLoopUV *mloop_uv;
+	MTexPoly *mtexpoly, *mt;
+	int i, numVerts, numPolys, numLoops;
 	Image *image = umd->image;
-	MFace *mface, *mf;
+	MPoly *mpoly, *mp;
+	MLoop *mloop;
 	int override_image = ((umd->flags & MOD_UVPROJECT_OVERRIDEIMAGE) != 0);
 	Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
 	int num_projectors = 0;
@@ -172,10 +175,10 @@
 
 	/* make sure there are UV Maps available */
 
-	if(!CustomData_has_layer(&dm->faceData, CD_MTFACE)) return dm;
+	if(!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) return dm;
 
 	/* make sure we're using an existing layer */
-	CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name, uvname);
+	CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, umd->uvlayer_name, uvname);
 
 	/* calculate a projection matrix and normal for each projector */
 	for(i = 0; i < num_projectors; ++i) {
@@ -259,12 +262,17 @@
 		mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
 	}
 
-	numFaces = dm->getNumTessFaces(dm);
+	numPolys = dm->getNumPolys(dm);
+	numLoops = dm->getNumLoops(dm);
 
 	/* make sure we are not modifying the original UV map */
-	tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
-			CD_MTFACE, uvname, numFaces);
+	mloop_uv = CustomData_duplicate_referenced_layer_named(&dm->loopData,
+			CD_MLOOPUV, uvname, numLoops);
 
+	/* can be NULL */
+	mtexpoly = CustomData_duplicate_referenced_layer_named(&dm->polyData,
+			CD_MTEXPOLY, uvname, numPolys);
+
 	numVerts = dm->getNumVerts(dm);
 
 	coords = MEM_callocN(sizeof(*coords) * numVerts,
@@ -280,26 +288,28 @@
 		for(i = 0, co = coords; i < numVerts; ++i, ++co)
 			mul_project_m4_v3(projectors[0].projmat, *co);
 
-	mface = dm->getTessFaceArray(dm);
-	numFaces = dm->getNumTessFaces(dm);
+	mpoly = dm->getPolyArray(dm);
+	mloop = dm->getLoopArray(dm);
 
 	/* apply coords as UVs, and apply image if tfaces are new */
-	for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tface) {
-		if(override_image || !image || tface->tpage == image) {
+	for(i = 0, mp = mpoly; i < numPolys; ++i, ++mp, ++mt) {
+		if(override_image || !image || (mtexpoly == NULL || mt->tpage == image)) {
 			if(num_projectors == 1) {
 				if(projectors[0].uci) {
-					unsigned int fidx= mf->v4 ? 3:2;
+					unsigned int fidx= mp->totloop - 1;
 					do {
-						unsigned int vidx= *(&mf->v1 + fidx);
-						project_from_camera(tface->uv[fidx], coords[vidx], projectors[0].uci);
+						unsigned int lidx= mp->loopstart + fidx;
+						unsigned int vidx= mloop[lidx].v;
+						project_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci);
 					} while (fidx--);
 				}
 				else {
 					/* apply transformed coords as UVs */
-					unsigned int fidx= mf->v4 ? 3:2;
+					unsigned int fidx= mp->totloop - 1;
 					do {
-						unsigned int vidx= *(&mf->v1 + fidx);
-						copy_v2_v2(tface->uv[fidx], coords[vidx]);
+						unsigned int lidx= mp->loopstart + fidx;
+						unsigned int vidx= mloop[lidx].v;
+						copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]);
 					} while (fidx--);
 				}
 			} else {
@@ -312,11 +322,7 @@
 				float best_dot;
 
 				/* get the untransformed face normal */
-				if(mf->v4) {
-					normal_quad_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3], coords[mf->v4]);
-				} else { 
-					normal_tri_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3]);
-				}
+				mesh_calc_poly_normal_coords(mp, mloop + mp->loopstart, (const float (*)[3])coords, face_no);
 
 				/* find the projector which the face points at most directly
 				* (projector normal with largest dot product is best)
@@ -334,29 +340,31 @@
 				}
 
 				if(best_projector->uci) {
-					unsigned int fidx= mf->v4 ? 3:2;
+					unsigned int fidx= mp->totloop - 1;
 					do {
-						unsigned int vidx= *(&mf->v1 + fidx);
-						project_from_camera(tface->uv[fidx], coords[vidx], best_projector->uci);
+						unsigned int lidx= mp->loopstart + fidx;
+						unsigned int vidx= mloop[lidx].v;
+						project_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci);
 					} while (fidx--);
 				}
 				else {
-					unsigned int fidx= mf->v4 ? 3:2;
+					unsigned int fidx= mp->totloop - 1;
 					do {
-						unsigned int vidx= *(&mf->v1 + fidx);
+						unsigned int lidx= mp->loopstart + fidx;
+						unsigned int vidx= mloop[lidx].v;
 						float tco[3];
 
 						copy_v3_v3(tco, coords[vidx]);
 						mul_project_m4_v3(best_projector->projmat, tco);
-						copy_v2_v2(tface->uv[fidx], tco);
+						copy_v2_v2(mloop_uv[lidx].uv, tco);
 
 					} while (fidx--);
 				}
 			}
 		}
 
-		if(override_image) {
-			tface->tpage = image;
+		if(override_image && mtexpoly) {
+			mt->tpage = image;
 		}
 	}
 



More information about the Bf-blender-cvs mailing list