diff --git a/release/scripts/bpymodules/BPyMathutils.py b/release/scripts/bpymodules/BPyMathutils.py index 72755d73153..da211c8da52 100644 --- a/release/scripts/bpymodules/BPyMathutils.py +++ b/release/scripts/bpymodules/BPyMathutils.py @@ -182,86 +182,3 @@ def convexHull(point_list_2d): # Concatenate both halfs and return. return [p[1] for ls in (upper, lower) for p in ls] -SMALL_NUM = 0.000001 -def lineIntersect2D(v1a, v1b, v2a, v2b): - ''' - Do 2 lines intersect, if so where. - If there is an error, the retured X value will be None - the y will be an error code- usefull when debugging. - - the first line is (v1a, v1b) - the second is (v2a, v2b) - by Campbell Barton - This function accounts for all known cases of 2 lines ;) - ''' - - x1,y1= v1a.x, v1a.y - x2,y2= v1b.x, v1b.y - _x1,_y1= v2a.x, v2a.y - _x2,_y2= v2b.x, v2b.y - - # Bounding box intersection first. - if min(x1, x2) > max(_x1, _x2) or \ - max(x1, x2) < min(_x1, _x2) or \ - min(y1, y2) > max(_y1, _y2) or \ - max(y1, y2) < min(_y1, _y2): - return None, 100 # Basic Bounds intersection TEST returns false. - - # are either of the segments points? Check Seg1 - if abs(x1 - x2) + abs(y1 - y2) <= SMALL_NUM: - return None, 101 - - # are either of the segments points? Check Seg2 - if abs(_x1 - _x2) + abs(_y1 - _y2) <= SMALL_NUM: - return None, 102 - - # Make sure the HOZ/Vert Line Comes first. - if abs(_x1 - _x2) < SMALL_NUM or abs(_y1 - _y2) < SMALL_NUM: - x1, x2, y1, y2, _x1, _x2, _y1, _y2 = _x1, _x2, _y1, _y2, x1, x2, y1, y2 - - if abs(x2-x1) < SMALL_NUM: # VERTICLE LINE - if abs(_x2-_x1) < SMALL_NUM: # VERTICLE LINE SEG2 - return None, 111 # 2 verticle lines dont intersect. - - elif abs(_y2-_y1) < SMALL_NUM: - return x1, _y1 # X of vert, Y of hoz. no calculation. - - yi = ((_y1 / abs(_x1 - _x2)) * abs(_x2 - x1)) + ((_y2 / abs(_x1 - _x2)) * abs(_x1 - x1)) - - if yi > max(y1, y2): # New point above seg1's vert line - return None, 112 - elif yi < min(y1, y2): # New point below seg1's vert line - return None, 113 - - return x1, yi # Intersecting. - - - if abs(y2-y1) < SMALL_NUM: # HOZ LINE - if abs(_y2-_y1) < SMALL_NUM: # HOZ LINE SEG2 - return None, 121 # 2 hoz lines dont intersect. - - # Can skip vert line check for seg 2 since its covered above. - xi = ((_x1 / abs(_y1 - _y2)) * abs(_y2 - y1)) + ((_x2 / abs(_y1 - _y2)) * abs(_y1 - y1)) - if xi > max(x1, x2): # New point right of seg1's hoz line - return None, 112 - elif xi < min(x1, x2): # New point left of seg1's hoz line - return None, 113 - - return xi, y1 # Intersecting. - - # Accounted for hoz/vert lines. Go on with both anglular. - b1 = (y2-y1)/(x2-x1) - b2 = (_y2-_y1)/(_x2-_x1) - a1 = y1-b1*x1 - a2 = _y1-b2*_x1 - - if b1 - b2 == 0.0: - return None, 200 - - xi = - (a1-a2)/(b1-b2) - yi = a1+b1*xi - if (x1-xi)*(xi-x2) >= 0 and (_x1-xi)*(xi-_x2) >= 0 and (y1-yi)*(yi-y2) >= 0 and (_y1-yi)*(yi-_y2)>=0: - return xi, yi - else: - return None, 300 - diff --git a/release/scripts/bpymodules/BPyMesh_redux.py b/release/scripts/bpymodules/BPyMesh_redux.py index b2d990f51b4..bb6976cd8f8 100644 --- a/release/scripts/bpymodules/BPyMesh_redux.py +++ b/release/scripts/bpymodules/BPyMesh_redux.py @@ -24,7 +24,6 @@ import Blender Vector= Blender.Mathutils.Vector Ang= Blender.Mathutils.AngleBetweenVecs -LineIntersect= Blender.Mathutils.LineIntersect CrossVecs= Blender.Mathutils.CrossVecs import BPyMesh diff --git a/release/scripts/bpymodules/BPyWindow.py b/release/scripts/bpymodules/BPyWindow.py index 9309a9a6084..7d804e4ab72 100755 --- a/release/scripts/bpymodules/BPyWindow.py +++ b/release/scripts/bpymodules/BPyWindow.py @@ -1,6 +1,6 @@ import Blender from Blender import Mathutils, Window, Scene, Draw, Mesh -from Blender.Mathutils import CrossVecs, Matrix, Vector, Intersect, LineIntersect +from Blender.Mathutils import CrossVecs, Matrix, Vector, Intersect # DESCRIPTION: # screen_x, screen_y the origin point of the pick ray diff --git a/release/scripts/image_edit.py b/release/scripts/image_edit.py index e9c264b4bef..4e78b201ad8 100644 --- a/release/scripts/image_edit.py +++ b/release/scripts/image_edit.py @@ -119,6 +119,7 @@ def main(): # ------------------------------- appstring = appstring.replace('%f', imageFileName) + print '\tediting image with command "%s"' % appstring os.system(appstring) if __name__ == '__main__' and os != None: diff --git a/release/scripts/object_cookie_cutter.py b/release/scripts/object_cookie_cutter.py index e67a95a742f..a158a6cdfb4 100755 --- a/release/scripts/object_cookie_cutter.py +++ b/release/scripts/object_cookie_cutter.py @@ -32,8 +32,8 @@ import Blender import BPyMathutils from math import sqrt reload(BPyMathutils) -lineIntersect2D= BPyMathutils.lineIntersect2D Vector= Blender.Mathutils.Vector +LineIntersect2D= Blender.Geometry.LineIntersect2D # Auto class def auto_class(slots): @@ -97,7 +97,7 @@ def point_in_poly2d(pt, fvco): #fvco= [v.co for v in face] isect=0 for i in xrange(len(fvco)): - isect+= (lineIntersect2D(pt, crazy_point, fvco[i], fvco[i-1])[0] != None) + isect+= (LineIntersect2D(pt, crazy_point, fvco[i], fvco[i-1]) != None) return isect%2 # odd number is an intersect which wouold be true (inside the face) @@ -289,11 +289,10 @@ def terrain_cut_2d(t, c, PREF_Z_LOC): if bounds_intersect(eb_t, eb_c): # face/edge bounds intersect? # Now we know the 2 edges might intersect, we'll do a propper test - xi, yi= lineIntersect2D(ed_t.v1.co, ed_t.v2.co, ed_c.v1.co, ed_c.v2.co) - if xi != None: - + x= LineIntersect2D(ed_t.v1.co, ed_t.v2.co, ed_c.v1.co, ed_c.v2.co) + if x: ed_isect= edge_isect_type() - ed_isect.point= Vector(xi,yi,0) # fake 3d + ed_isect.point= x.resize3D() # fake 3d # Find the interpolation Z point @@ -637,9 +636,7 @@ def main(): if point_in_bounds(c, t.bounds): isect_count= 0 for edv1, edv2 in edge_verts_c: - xi, yi= lineIntersect2D(c, crazy_point, edv1, edv2) - if xi!=None: - isect_count+=1 + isect_count += (LineIntersect2D(c, crazy_point, edv1, edv2) != None) if isect_count%2: f.sel= 1 diff --git a/release/scripts/uv_archimap.py b/release/scripts/uv_archimap.py index 08e399b63f1..170f541571c 100644 --- a/release/scripts/uv_archimap.py +++ b/release/scripts/uv_archimap.py @@ -42,7 +42,7 @@ selected faces, or all faces. # -------------------------------------------------------------------------- -from Blender import Object, Scene, Draw, Window, sys, Mesh +from Blender import Object, Scene, Draw, Window, sys, Mesh, Geometry from Blender.Mathutils import CrossVecs, Matrix, Vector, RotationMatrix, DotVecs, TriangleArea from math import cos @@ -262,7 +262,9 @@ def island2Edge(island): # If 2 are the same then they will be together, but full [a,b] order is not correct. # Sort by length - length_sorted_edges = [(key[0], key[1], value) for key, value in edges.iteritems() if value != 0] + + + length_sorted_edges = [(Vector(key[0]), Vector(key[1]), value) for key, value in edges.iteritems() if value != 0] length_sorted_edges.sort(lambda A, B: cmp(B[2], A[2])) # Its okay to leave the length in there. @@ -316,7 +318,7 @@ def pointInIsland(pt, island): # box is (left,bottom, right, top) -def islandIntersectUvIsland(source, target, xSourceOffset, ySourceOffset): +def islandIntersectUvIsland(source, target, SourceOffset): # Is 1 point in the box, inside the vertLoops edgeLoopsSource = source[6] # Pretend this is offset edgeLoopsTarget = target[6] @@ -324,28 +326,20 @@ def islandIntersectUvIsland(source, target, xSourceOffset, ySourceOffset): # Edge intersect test for ed in edgeLoopsSource: for seg in edgeLoopsTarget: - xi, yi = lineIntersection2D(\ - seg[0][0], seg[0][1], seg[1][0], seg[1][1],\ - xSourceOffset+ed[0][0], ySourceOffset+ed[0][1], xSourceOffset+ed[1][0], ySourceOffset+ed[1][1]) - if xi != None: + i = Geometry.LineIntersect2D(\ + seg[0], seg[1], SourceOffset+ed[0], SourceOffset+ed[1]) + if i: return 1 # LINE INTERSECTION # 1 test for source being totally inside target + SourceOffset.resize3D() for pv in source[7]: - p = pv.__copy__() - - p.x += xSourceOffset - p.y += ySourceOffset - if pointInIsland(p, target[0]): + if pointInIsland(pv+SourceOffset, target[0]): return 2 # SOURCE INSIDE TARGET # 2 test for a part of the target being totaly inside the source. for pv in target[7]: - p = pv.__copy__() - - p.x -= xSourceOffset - p.y -= ySourceOffset - if pointInIsland(p, source[0]): + if pointInIsland(pv+SourceOffset, source[0]): return 3 # PART OF TARGET INSIDE SOURCE. return 0 # NO INTERSECTION @@ -457,7 +451,6 @@ def optiRotateUvIsland(faces): 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 @@ -616,7 +609,7 @@ def mergeUvIslands(islandList, islandListArea): ##testcount+=1 #print 'Testing intersect' - Intersect = islandIntersectUvIsland(sourceIsland, targetIsland, boxLeft, boxBottom) + Intersect = islandIntersectUvIsland(sourceIsland, targetIsland, Vector(boxLeft, boxBottom)) #print 'Done', Intersect if Intersect == 1: # Line intersect, dont bother with this any more pass @@ -655,8 +648,7 @@ def mergeUvIslands(islandList, islandListArea): # targetIsland[6].extend(sourceIsland[6]) #while sourceIsland[6]: targetIsland[6].extend( [ (\ - ((e[0][0]+boxLeft, e[0][1]+boxBottom),\ - (e[1][0]+boxLeft, e[1][1]+boxBottom), e[2])\ + (e[0]+offset, e[1]+offset, e[2])\ ) for e in sourceIsland[6] ] ) sourceIsland[6][:] = [] # Empty diff --git a/source/blender/python/api2_2x/Geometry.c b/source/blender/python/api2_2x/Geometry.c index df33d90a3c1..0c3eb056bf0 100644 --- a/source/blender/python/api2_2x/Geometry.c +++ b/source/blender/python/api2_2x/Geometry.c @@ -45,13 +45,19 @@ /* needed for EXPP_ReturnPyObjError and EXPP_check_sequence_consistency */ #include "gen_utils.h" +//#include "util.h" /* MIN2 and MAX2 */ +#include "BKE_utildefines.h" +#define SWAP_FLOAT(a,b,tmp) tmp=a; a=b; b=tmp +#define eul 0.000001 /*-------------------------DOC STRINGS ---------------------------*/ static char M_Geometry_doc[] = "The Blender Geometry module\n\n"; static char M_Geometry_PolyFill_doc[] = "(veclist_list) - takes a list of polylines (each point a vector) and returns the point indicies for a polyline filled with triangles"; +static char M_Geometry_LineIntersect2D_doc[] = "(lineA_p1, lineA_p2, lineB_p1, lineB_p2) - takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None"; /*-----------------------METHOD DEFINITIONS ----------------------*/ struct PyMethodDef M_Geometry_methods[] = { {"PolyFill", ( PyCFunction ) M_Geometry_PolyFill, METH_VARARGS, M_Geometry_PolyFill_doc}, + {"LineIntersect2D", ( PyCFunction ) M_Geometry_LineIntersect2D, METH_VARARGS, M_Geometry_LineIntersect2D_doc}, {NULL, NULL, 0, NULL} }; /*----------------------------MODULE INIT-------------------------*/ @@ -66,7 +72,7 @@ PyObject *Geometry_Init(void) /*----------------------------------Geometry.PolyFill() -------------------*/ /* PolyFill function, uses Blenders scanfill to fill multiple poly lines */ -PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * args ) +static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * args ) { PyObject *tri_list; /*return this list of tri's */ PyObject *polyLineSeq, *polyLine, *polyVec; @@ -164,3 +170,98 @@ PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * args ) return tri_list; } + + +static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) +{ + VectorObject *line_a1, *line_a2, *line_b1, *line_b2; + float a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y, xi, yi, a1,a2,b1,b2, c1,c2, det_inv, m1, m2, newvec[2]; + if( !PyArg_ParseTuple ( args, "O!O!O!O!", + &vector_Type, &line_a1, + &vector_Type, &line_a2, + &vector_Type, &line_b1, + &vector_Type, &line_b2) + ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected 4 vector types\n" ) ); + + a1x= line_a1->vec[0]; + a1y= line_a1->vec[1]; + a2x= line_a2->vec[0]; + a2y= line_a2->vec[1]; + + b1x= line_b1->vec[0]; + b1y= line_b1->vec[1]; + b2x= line_b2->vec[0]; + b2y= line_b2->vec[1]; + + if((MIN2(a1x, a2x) > MAX2(b1x, b2x)) || + (MAX2(a1x, a2x) < MIN2(b1x, b2x)) || + (MIN2(a1y, a2y) > MAX2(b1y, b2y)) || + (MAX2(a1y, a2y) < MIN2(b1y, b2y)) ) { + Py_RETURN_NONE; + } + /* Make sure the hoz/vert line comes first. */ + if (fabs(b1x - b2x) < eul || fabs(b1y - b2y) < eul) { + SWAP_FLOAT(a1x, b1x, xi); /*abuse xi*/ + SWAP_FLOAT(a1y, b1y, xi); + SWAP_FLOAT(a2x, b2x, xi); + SWAP_FLOAT(a2y, b2y, xi); + } + + if (fabs(a1x-a2x) < eul) { /* verticle line */ + if (fabs(b1x-b2x) < eul){ /*verticle second line */ + Py_RETURN_NONE; /* 2 verticle lines dont intersect. */ + } + else if (fabs(b1y-b2y) < eul) { + /*X of vert, Y of hoz. no calculation needed */ + newvec[0]= a1x; + newvec[1]= b1y; + return newVectorObject(newvec, 2, Py_NEW); + } + + yi = ((b1y / fabs(b1x - b2x)) * fabs(b2x - a1x)) + ((b2y / fabs(b1x - b2x)) * fabs(b1x - a1x)); + + if (yi > MAX2(a1y, a2y)) {/* New point above seg1's vert line */ + Py_RETURN_NONE; + } else if (yi < MIN2(a1y, a2y)) { /* New point below seg1's vert line */ + Py_RETURN_NONE; + } + newvec[0]= a1x; + newvec[1]= yi; + return newVectorObject(newvec, 2, Py_NEW); + } else if (fabs(a2y-a1y) < eul) { /* hoz line1 */ + if (fabs(b2y-b1y) < eul) { /*hoz line2*/ + Py_RETURN_NONE; /*2 hoz lines dont intersect*/ + } + + /* Can skip vert line check for seg 2 since its covered above. */ + xi = ((b1x / fabs(b1y - b2y)) * fabs(b2y - a1y)) + ((b2x / fabs(b1y - b2y)) * fabs(b1y - a1y)); + if (xi > MAX2(a1x, a2x)) { /* New point right of hoz line1's */ + Py_RETURN_NONE; + } else if (xi < MIN2(a1x, a2x)) { /*New point left of seg1's hoz line */ + Py_RETURN_NONE; + } + newvec[0]= xi; + newvec[1]= a1y; + return newVectorObject(newvec, 2, Py_NEW); + } + + b1 = (a2y-a1y)/(a2x-a1x); + b2 = (b2y-b1y)/(b2x-b1x); + a1 = a1y-b1*a1x; + a2 = b1y-b2*b1x; + + if (b1 - b2 == 0.0) { + Py_RETURN_NONE; + } + + xi = - (a1-a2)/(b1-b2); + yi = a1+b1*xi; + if ((a1x-xi)*(xi-a2x) >= 0 && (b1x-xi)*(xi-b2x) >= 0 && (a1y-yi)*(yi-a2y) >= 0 && (b1y-yi)*(yi-b2y)>=0) { + newvec[0]= xi; + newvec[1]= yi; + return newVectorObject(newvec, 2, Py_NEW); + } + Py_RETURN_NONE; +} \ No newline at end of file diff --git a/source/blender/python/api2_2x/Geometry.h b/source/blender/python/api2_2x/Geometry.h index ed5288f3835..32eb0265e5f 100644 --- a/source/blender/python/api2_2x/Geometry.h +++ b/source/blender/python/api2_2x/Geometry.h @@ -38,6 +38,7 @@ #include "vector.h" PyObject *Geometry_Init( void ); -PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * args ); +static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * args ); +static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ); #endif /* EXPP_Geometry_H */ diff --git a/source/blender/python/api2_2x/doc/Geometry.py b/source/blender/python/api2_2x/doc/Geometry.py index 5ffc5928cc6..733569cfe76 100644 --- a/source/blender/python/api2_2x/doc/Geometry.py +++ b/source/blender/python/api2_2x/doc/Geometry.py @@ -43,3 +43,10 @@ def PolyFill(polylines): Blender.Redraw() """ + +def LineIntersect2D(vec1, vec2, vec3, vec4): + """ + Takes 2 lines vec1, vec2 for the 2 points of the first line and vec2, vec3 for the 2 points of the second line. + @rtype: Vector + @return: a 2D Vector for the intersection or None where there is no intersection. + """ \ No newline at end of file