Revision: 60035 http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60035 Author: campbellbarton Date: 2013-09-11 07:10:15 +0000 (Wed, 11 Sep 2013) Log Message: ----------- fix [#36020] SmartUV Project is messy on a cube was using very simple/stupid check to rotate us islands, replace with box_fit_2d() function.
missed docstring last commit. Modified Paths: -------------- trunk/blender/release/scripts/startup/bl_operators/uvcalc_smart_project.py trunk/blender/source/blender/python/mathutils/mathutils_geometry.c Modified: trunk/blender/release/scripts/startup/bl_operators/uvcalc_smart_project.py =================================================================== --- trunk/blender/release/scripts/startup/bl_operators/uvcalc_smart_project.py 2013-09-11 07:07:16 UTC (rev 60034) +++ trunk/blender/release/scripts/startup/bl_operators/uvcalc_smart_project.py 2013-09-11 07:10:15 UTC (rev 60035) @@ -24,7 +24,6 @@ DEG_TO_RAD = 0.017453292519943295 # pi/180.0 SMALL_NUM = 0.0000001 # see bug [#31598] why we dont have smaller values -BIG_NUM = 1e15 global USER_FILL_HOLES global USER_FILL_HOLES_QUALITY @@ -233,113 +232,19 @@ return 0 # NO INTERSECTION - - -# Returns the X/y Bounds of a list of vectors. -def testNewVecLs2DRotIsBetter(vecs, mat=-1, bestAreaSoFar = -1): - - # UV's will never extend this far. - minx = miny = BIG_NUM - maxx = maxy = -BIG_NUM - - for i, v in enumerate(vecs): - - # Do this along the way - if mat != -1: - v = vecs[i] = mat * v - x= v.x - y= v.y - if x<minx: minx= x - if y<miny: miny= y - if x>maxx: maxx= x - if y>maxy: maxy= y - - # Specific to this algo, bail out if we get bigger then the current area - if bestAreaSoFar != -1 and (maxx-minx) * (maxy-miny) > bestAreaSoFar: - return (BIG_NUM, None), None - w = maxx-minx - h = maxy-miny - return (w*h, w,h), vecs # Area, vecs - def optiRotateUvIsland(faces): - global currentArea + uv_points = [uv for f in faces for uv in f.uv] + angle = geometry.box_fit_2d(uv_points) - # Best-fit Rotation - def best2dRotation(uvVecs, MAT1, MAT2): - global currentArea + if angle != 0.0: + mat = Matrix.Rotation(angle, 2) + i = 0 # count the serialized uv/vectors + for f in faces: + for j, k in enumerate(range(i, len(f.v) + i)): + f.uv[j][:] = mat * uv_points[k] + i += len(f.v) - newAreaPos, newfaceProjectionGroupListPos =\ - testNewVecLs2DRotIsBetter(uvVecs[:], MAT1, currentArea[0]) - - # Why do I use newpos here? May as well give the best area to date for an early bailout - # some slight speed increase in this. - # If the new rotation is smaller then the existing, we can - # avoid copying a list and overwrite the old, crappy one. - - if newAreaPos[0] < currentArea[0]: - newAreaNeg, newfaceProjectionGroupListNeg =\ - testNewVecLs2DRotIsBetter(uvVecs, MAT2, newAreaPos[0]) # Reuse the old bigger list. - else: - newAreaNeg, newfaceProjectionGroupListNeg =\ - testNewVecLs2DRotIsBetter(uvVecs[:], MAT2, currentArea[0]) # Cant reuse, make a copy. - - - # Now from the 3 options we need to discover which to use - # we have cerrentArea/newAreaPos/newAreaNeg - bestArea = min(currentArea[0], newAreaPos[0], newAreaNeg[0]) - - if currentArea[0] == bestArea: - return uvVecs - elif newAreaPos[0] == bestArea: - uvVecs = newfaceProjectionGroupListPos - currentArea = newAreaPos - elif newAreaNeg[0] == bestArea: - uvVecs = newfaceProjectionGroupListNeg - currentArea = newAreaNeg - - return uvVecs - - - # Serialized UV coords to Vectors - uvVecs = [uv for f in faces for uv in f.uv] - - # Theres a small enough number of these to hard code it - # rather then a loop. - - # Will not modify anything - currentArea, dummy =\ - testNewVecLs2DRotIsBetter(uvVecs) - - - # Try a 45d rotation - newAreaPos, newfaceProjectionGroupListPos = testNewVecLs2DRotIsBetter(uvVecs[:], ROTMAT_2D_POS_45D, currentArea[0]) - - if newAreaPos[0] < currentArea[0]: - uvVecs = newfaceProjectionGroupListPos - currentArea = newAreaPos - # 45d done - - # Testcase different rotations and find the one that best fits in a square - for ROTMAT in RotMatStepRotation: - uvVecs = best2dRotation(uvVecs, ROTMAT[0], ROTMAT[1]) - - # Only if you want it, make faces verticle! - if currentArea[1] > currentArea[2]: - # Rotate 90d - # Work directly on the list, no need to return a value. - testNewVecLs2DRotIsBetter(uvVecs, ROTMAT_2D_POS_90D) - - - # Now write the vectors back to the face UV's - i = 0 # count the serialized uv/vectors - for f in faces: - #f.uv = [uv for uv in uvVecs[i:len(f)+i] ] - for j, k in enumerate(range(i, len(f.v)+i)): - f.uv[j][:] = uvVecs[k] - i += len(f.v) - - # Takes an island list and tries to find concave, hollow areas to pack smaller islands into. def mergeUvIslands(islandList): global USER_FILL_HOLES Modified: trunk/blender/source/blender/python/mathutils/mathutils_geometry.c =================================================================== --- trunk/blender/source/blender/python/mathutils/mathutils_geometry.c 2013-09-11 07:07:16 UTC (rev 60034) +++ trunk/blender/source/blender/python/mathutils/mathutils_geometry.c 2013-09-11 07:10:15 UTC (rev 60035) @@ -1507,12 +1507,12 @@ PyDoc_STRVAR(M_Geometry_box_fit_2d_doc, ".. function:: box_fit_2d(points)\n" "\n" -" Returns a list of indices into the list given\n" +" Returns an angle that best fits the points to an axis aligned rectangle\n" "\n" " :arg points: list of 2d points.\n" " :type points: list\n" -" :return: a list of indices\n" -" :rtype: list of ints\n" +" :return: angle\n" +" :rtype: float\n" ); static PyObject *M_Geometry_box_fit_2d(PyObject *UNUSED(self), PyObject *pointlist) { _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs