home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2005 November / WNnov2005.iso / Windows / Equipement / Blender / blender-2.37a-windows.exe / $_5_ / .blender / scripts / knife.py < prev    next >
Text File  |  2005-05-18  |  21KB  |  715 lines

  1. #!BPY
  2.  
  3. """
  4. Name: 'Knife Tool'
  5. Blender: 232
  6. Group: 'Object'
  7. Tooltip: 'Cut selected mesh(es) along an active plane w/o creating doubles'
  8. """
  9.  
  10. __author__ = ["Stefano <S68> Selleri", "Wim Van Hoydonck"]
  11. __url__ = ("blender", "elysiun")
  12. __version__ = "0.0.8a 03/31/04"
  13.  
  14. __bpydoc__ = """\
  15. "Blender Knife Tool" uses the active mesh plane to cut all selected meshes.
  16.  
  17. Usage:
  18.  
  19. Create, resize and position a "cutting plane", which will be used to cut
  20. the mesh(es), then:
  21.  
  22. - select mesh(es) to be cut;<br>
  23. - select cutting plane (it will be the active object);<br>
  24. - run this script from 3d View's "Object->Scripts" menu.
  25.  
  26. Options:
  27.  
  28. - edit object: knife creates new vertices in the selected mesh(es);<br>
  29. - create new object: knife duplicates objects and creates new vertices in the
  30. new objects;<br>
  31. - create two new objects: knife creates two new separate objects.
  32. """
  33.  
  34. # $Id: knife.py,v 1.6 2005/05/17 07:17:52 ianwill Exp $
  35. #
  36. ###################################################################
  37. #                                                                 #
  38. # Blender Knife Tool                                              #
  39. #                                                                 #
  40. # v. 0.0.0 - 0.0.6 (C) December 2002 Stefano <S68> Selleri        #
  41. # v. 0.0.7 (C) March 2004 Wim Van Hoydonck                        #
  42. # v. 0.0.8 (C) March 2004 Wim Van Hoydonck & Stefano <S68> Selleri#
  43. #                                                                 #
  44. # Released under the Blender Artistic Licence (BAL)               #
  45. # See www.blender.org                                             #
  46. #                                                                 #
  47. # Works in Blender 2.32 and higher                                #
  48. #                                                                 #
  49. # this script can be found online at:                             #
  50. # http://users.pandora.be/tuinbels/scripts/knife-0.0.8.py         #
  51. # http://www.selleri.org/Blender                                  #
  52. #                                                                 #
  53. # email: tuinbels@hotmail.com                                     #
  54. #        selleri@det.unifi.it                                     #
  55. ###################################################################
  56. # History                                                         #
  57. # V: 0.0.0 - 08-12-02 - The script starts to take shape, a        #
  58. #                       history is now deserved :)                #
  59. #    0.0.1 - 09-12-02 - The faces are correctly selected and      #
  60. #                       assigned to the relevant objects now the  #
  61. #                       hard (splitting) part...                  #
  62. #    0.0.2 - 14-12-02 - Still hacking on the splitting...         #
  63. #                       It works, but I have to de-globalize      #
  64. #                       the intersection coordinates              #
  65. #    0.0.3 - 15-12-02 - First Alpha version                       #
  66. #    0.0.4 - 17-12-02 - Upgraded accordingly to eeshlo tips       #
  67. #                       Use Matrices for coordinate transf.       #
  68. #                       Add a GUI                                 #
  69. #                       Make it Run on 2.23                       #
  70. #    0.0.5 - 17-12-02 - Eeshlo solved some problems....           #
  71. #                       Theeth too adviced me                     #
  72. #    0.0.6 - 18-12-02 - Better error messages                     #
  73. #    0.0.7 - 26-03-04 - Developer team doubles!                   #
  74. #                       This version is by Wim!                   #
  75. #                       Doesn't create doubles (AFAIK)            #
  76. #                     - Faster (for small meshes), global         #
  77. #                       coordinates of verts are calculated only  #
  78. #                       once                                      #
  79. #                     - Editing the CutPlane in editmode (move)   #
  80. #                       shouldn't cause problems anymore          #
  81. #                     - Menu button added to choose between the   #
  82. #                       different Edit Methods                    #
  83. #                     - If a mesh is cut twice at the same place, #
  84. #                       this gives errors :( (also happened in    #
  85. #                       previous versions)                        #
  86. #                     - Willian Padovani Germano solved           #
  87. #                       a problem, many thanks :)                 #
  88. #                     - Stefano Selleri made some good            #
  89. #                       suggestions, thanks :)                    #
  90. #    0.0.8 - 26-03-04 - General Interface rewrite (Stefano)       #
  91. #    0.0.8a- 31-03-04 - Added some error messages                 #
  92. #                     - Cut multiple meshes at once               #
  93. #                                                                 #
  94. ###################################################################
  95.  
  96. import Blender
  97. from Blender import *
  98. from Blender.sys import time
  99. from math import *
  100.  
  101. Epsilon = 0.00001
  102. msg = ''
  103. RBmesh0 = Draw.Create(0)
  104. RBmesh1 = Draw.Create(0)
  105. RBmesh2 = Draw.Create(1)
  106.  
  107. VERSION = '0.0.8'
  108.  
  109. # see if time module is available
  110. #try:
  111. #    import time
  112. #    timport = 1
  113. #except:
  114. #    timport = 0
  115.  
  116.  
  117. BL_VERSION = Blender.Get('version')
  118. if (BL_VERSION<=223):
  119.     import Blender210
  120.  
  121. #=================================#
  122. # Vector and matrix manipulations #
  123. #=================================#
  124.  
  125. # vector addition
  126. def vecadd(a, b):
  127.     return [a[0] - b[0], a[1] - b[1], a[2] + b[2]]
  128.  
  129. # vector substration
  130. def vecsub(a, b):
  131.     return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
  132.  
  133. # vector crossproduct
  134. def veccross(x, y):
  135.     v = [0, 0, 0]
  136.     v[0] = x[1]*y[2] - x[2]*y[1]
  137.     v[1] = x[2]*y[0] - x[0]*y[2]
  138.     v[2] = x[0]*y[1] - x[1]*y[0]
  139.     return v
  140.  
  141. # vector dotproduct
  142. def vecdot(x, y):
  143.     return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]
  144.  
  145. # vector length
  146. def length(v):
  147.     return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
  148.  
  149. # vector multiplied by constant s
  150. def vecmul(a, s):
  151.     return[a[0]*s, a[1]*s, a[2]*s]
  152.  
  153. # vector divided by constant s
  154. def vecdiv(a, s):
  155.     if s!=0.0: s = 1.0/s
  156.     return vecmul(a, s)
  157.  
  158. # matrix(4x3) vector multiplication
  159. def mulmatvec4x3(a, b):
  160.     # a is vector, b is matrix
  161.     r = [0, 0, 0]
  162.     r[0] = a[0]*b[0][0] + a[1]*b[1][0] + a[2]*b[2][0] + b[3][0]
  163.     r[1] = a[0]*b[0][1] + a[1]*b[1][1] + a[2]*b[2][1] + b[3][1]
  164.     r[2] = a[0]*b[0][2] + a[1]*b[1][2] + a[2]*b[2][2] + b[3][2]
  165.     return r
  166.  
  167. # Normalization of a vector
  168. def Normalize(a):
  169.     lengte = length(a)
  170.     return vecdiv(a, lengte)
  171.  
  172. # calculate normal from 3 verts
  173. def Normal(v0, v1, v2):
  174.     return veccross(vecsub(v0, v1),vecsub(v0, v2))
  175.  
  176. #===========================#
  177. # Coordinatetransformations #
  178. #===========================#
  179.  
  180. def GlobalPosition(P, Obj):
  181.  
  182.     if (BL_VERSION<=223):
  183.         m = Obj.matrix
  184.     else:
  185.         m = Obj.getMatrix()
  186.  
  187.     return mulmatvec4x3(P, m)
  188.  
  189. def LocalPosition(P, Obj):
  190.  
  191.     if (BL_VERSION<=223):
  192.         m = Blender210.getObject(Obj.name).inverseMatrix
  193.     else:
  194.         m = Obj.getInverseMatrix()
  195.  
  196.     return mulmatvec4x3(P, m)
  197.  
  198. #================#
  199. # Get Plane Data #
  200. #================#
  201.  
  202. def PlaneData(Plane):
  203.     global msg
  204.     #
  205.     # Calculate: 
  206.     # - the normal of the plane, 
  207.     # - the offset of the plane wrt the global coordinate system
  208.     #   in the direction of the normal of the plane
  209.     # 
  210.     PlaneMesh   = NMesh.GetRawFromObject(Plane.name)
  211.  
  212.     if (len(PlaneMesh.faces)>1):
  213.         msg =  "ERROR: Active object must be a single face plane"
  214.         return ((0,0,0),(0,0,0),1)
  215.     else:
  216.         if (len(PlaneMesh.verts)<3):
  217.             msg = "ERROR: 3 vertices needed to define a plane"
  218.             return ((0,0,0),(0,0,0),1)
  219.         else:
  220.             v0 = GlobalPosition(PlaneMesh.faces[0].v[0].co, Plane)
  221.             v1 = GlobalPosition(PlaneMesh.faces[0].v[1].co, Plane)
  222.             v2 = GlobalPosition(PlaneMesh.faces[0].v[2].co, Plane)
  223.             
  224.             # the normal of the plane, calculated from the first 3 verts
  225.             PNormal = Normalize(Normal(v0,v1,v2))
  226.  
  227.             # offset of the plane, using 1st vertex instead of Plane.getLocaction()
  228.             POffset = vecdot(v0,PNormal)
  229.  
  230.             return PNormal, POffset, 0
  231.  
  232. #====================================#
  233. # Position with respect to Cut Plane #
  234. #====================================#
  235.  
  236. def Distance(P, N, d0):
  237.     #
  238.     # distance from a point to a plane
  239.     #
  240.     return vecdot(P, N) - d0
  241.  
  242. def FacePosition(dist):
  243.     #
  244.     # position of a face wrt to the plane
  245.     #
  246.     np, nn, nz = 0, 0, 0
  247.  
  248.     for d in dist:
  249.  
  250.         # the distances are calculated in advance
  251.         if d > 0:
  252.             np += 1
  253.         elif d < 0:
  254.             nn += 1
  255.         else:
  256.             nz += 1 
  257.  
  258.     if np == 0:
  259.         return -1
  260.     if nn == 0:
  261.         return 1
  262.     return 0
  263.  
  264. #==========================================#
  265. # Append existing faces / create new faces #
  266. #==========================================#
  267.  
  268. def FaceAppend(me, fidx):
  269.     #
  270.     # append a face to a mesh based on a list of vertex-indices
  271.     #
  272.     nf = NMesh.Face()
  273.  
  274.     for i in fidx:
  275.         nf.v.append(me.verts[i])
  276.     me.faces.append(nf)
  277.  
  278. def FaceMake(me, vl):
  279.     #
  280.     # make one or two new faces based on a list of vertex-indices
  281.     #
  282.     idx = len(me.verts)
  283.  
  284.      if len(vl) <= 4:
  285.         nf = NMesh.Face()
  286.         for i in range(len(vl)):
  287.             nf.v.append(me.verts[vl[i]])
  288.         me.faces.append(nf)
  289.     else:
  290.         nf = NMesh.Face()
  291.         nf.v.append(me.verts[vl[0]])
  292.         nf.v.append(me.verts[vl[1]])
  293.         nf.v.append(me.verts[vl[2]])
  294.         nf.v.append(me.verts[vl[3]])
  295.         me.faces.append(nf)
  296.  
  297.         nf = NMesh.Face()
  298.         nf.v.append(me.verts[vl[3]])
  299.         nf.v.append(me.verts[vl[4]])
  300.         nf.v.append(me.verts[vl[0]])
  301.         me.faces.append(nf)
  302.    
  303. #=====================================#
  304. # Generate vertex lists for new faces #
  305. #=====================================#
  306.  
  307. def Split(Obj, MeshPos, MeshNeg, Vglob, Vidx, N, d0, newvidx, newvcoo, totverts, d):
  308.     #
  309.     # - calculate intersectionpoints of the plane with faces
  310.     # - see if this intersectionpoint already exists (look for vertices close to the new vertex)
  311.     # - if it does not yet exist, append a vertex to the mesh,
  312.     #   remember its index and location and append the index to the appropriate vertex-lists
  313.     # - if it does, use that vertex (and its index) to create the face
  314.     #
  315.  
  316.     vp = []
  317.     vn = []
  318.  
  319.     # distances of the verts wrt the plane are calculated in main part of script
  320.     
  321.     for i in range(len(d)):
  322.         # the previous vertex
  323.         dim1 = d[int(fmod(i-1,len(d)))]
  324.         Vim1 = Vglob[int(fmod(i-1,len(d)))]
  325.  
  326.         if abs(d[i]) < Epsilon:
  327.             # if the vertex lies in the cutplane            
  328.             vp.append(Vidx[i])
  329.             vn.append(Vidx[i])
  330.         else:
  331.             if abs(dim1) < Epsilon:
  332.                 # if the previous vertex lies in cutplane
  333.                 if d[i] > 0:
  334.                     vp.append(Vidx[i])
  335.                 else:
  336.                     vn.append(Vidx[i])
  337.             else:
  338.                 if d[i]*dim1 > 0:
  339.                     # if they are on the same side of the plane
  340.                     if d[i] > 0:
  341.                         vp.append(Vidx[i])
  342.                     else:
  343.                         vn.append(Vidx[i])
  344.                 else:
  345.                     # the vertices are not on the same side of the plane, so we have an intersection
  346.  
  347.                     Den = vecdot(vecsub(Vglob[i],Vim1),N)
  348.  
  349.                     Vi = []    
  350.                     Vi.append ( ((Vim1[0]*Vglob[i][1]-Vim1[1]*Vglob[i][0])*N[1]+(Vim1[0]*Vglob[i][2]-Vim1[2]*Vglob[i][0])*N[2]+(Vglob[i][0]-Vim1[0])*d0)/Den)
  351.                     Vi.append ( ((Vim1[1]*Vglob[i][0]-Vim1[0]*Vglob[i][1])*N[0]+(Vim1[1]*Vglob[i][2]-Vim1[2]*Vglob[i][1])*N[2]+(Vglob[i][1]-Vim1[1])*d0)/Den)
  352.                     Vi.append ( ((Vim1[2]*Vglob[i][0]-Vim1[0]*Vglob[i][2])*N[0]+(Vim1[2]*Vglob[i][1]-Vim1[1]*Vglob[i][2])*N[1]+(Vglob[i][2]-Vim1[2])*d0)/Den)
  353.  
  354.                     ViL = LocalPosition(Vi, Obj)
  355.  
  356.                     if newvidx == []: 
  357.                         # if newvidx is empty (the first time Split is called), append a new vertex
  358.                         # to the mesh and remember its vertex-index and location
  359.                         ViLl = NMesh.Vert(ViL[0],ViL[1],ViL[2])
  360.  
  361.                         if MeshPos == MeshNeg:
  362.                             MeshPos.verts.append(ViLl)
  363.  
  364.                         else:
  365.                             MeshPos.verts.append(ViLl)
  366.                             MeshNeg.verts.append(ViLl)
  367.  
  368.                         nvidx = totverts
  369.                         newvidx.append(nvidx)
  370.                         newvcoo.append(ViL)
  371.  
  372.                         vp.append(nvidx)
  373.                         vn.append(nvidx)
  374.                     else:
  375.                         # newvidx is not empty
  376.                         dist1 = []
  377.                         tlr = 0
  378.                         for j in range(len(newvidx)): 
  379.                             # calculate the distance from the new vertex to the vertices
  380.                             # in the list with new vertices
  381.                             dist1.append(length(vecsub(ViL, newvcoo[j])))
  382.                         for k in range(len(dist1)):
  383.                             if dist1[k] < Epsilon:
  384.                                 # if distance is smaller than epsilon, use the other vertex
  385.                                 # use newvidx[k] as vert
  386.                                 vp.append(newvidx[k])
  387.                                 vn.append(newvidx[k])
  388.                                 break # get out of closest loop
  389.                             else:
  390.                                 tlr += 1
  391.  
  392.                         if tlr == len(newvidx):
  393.                             nvidx = totverts + len(newvidx)
  394.                             ViLl = NMesh.Vert(ViL[0],ViL[1],ViL[2])
  395.  
  396.                             if MeshPos == MeshNeg:
  397.                                 MeshPos.verts.append(ViLl)
  398.  
  399.                             else:
  400.                                 MeshPos.verts.append(ViLl)
  401.                                 MeshNeg.verts.append(ViLl)
  402.  
  403.                             newvidx.append(nvidx)
  404.                             newvcoo.append(ViL)
  405.                             vp.append(nvidx)
  406.                             vn.append(nvidx)
  407.  
  408.                     if d[i] > 0:
  409.                         vp.append(Vidx[i])
  410.                     else:
  411.                         vn.append(Vidx[i])
  412.   
  413.     return vp, vn, newvidx, newvcoo
  414.  
  415. #===========#
  416. # Main part #
  417. #===========#
  418.  
  419. def CutMesh():
  420.     global msg
  421.     global RBmesh0,RBmesh1,RBmesh2
  422.     #if timport == 1:
  423.     #    start = time.clock()
  424.     start = time()
  425.     
  426.     selected_obs = Object.GetSelected()
  427.  
  428.     total = len(selected_obs)
  429.  
  430.     NoErrors=0
  431.  
  432.     meshes = 0
  433.  
  434.     # check to see if every selected object is a mesh
  435.     for ob in selected_obs:
  436.         type = ob.getType()
  437.         if type == 'Mesh':
  438.             meshes += 1
  439.  
  440.     # at least select two objects
  441.     if meshes <= 1:
  442.         msg = "ERROR: At least two objects should be selected"
  443.         NoErrors = 1
  444.  
  445.     # if not every object is a mesh
  446.     if meshes != total:
  447.         msg = "ERROR: You should only select meshobjects"
  448.         NoErrors=1
  449.  
  450.     # everything is ok
  451.     if NoErrors == 0:
  452.         Pln = selected_obs[0]
  453.         PNormal, POffset, NoErrors = PlaneData(Pln)
  454.  
  455.     # loop to cut multiple meshes at once
  456.     for o in range(1, total):
  457.         
  458.         Obj = selected_obs[o]
  459.  
  460.         if (NoErrors == 0) :
  461.         
  462.             m = Obj.getData()
  463.  
  464.             if RBmesh1.val == 1:
  465.  
  466.                 MeshNew = NMesh.GetRaw()
  467.  
  468.             if RBmesh2.val == 1:
  469.  
  470.                 MeshPos = NMesh.GetRaw()
  471.                 MeshNeg = NMesh.GetRaw()
  472.  
  473.             # get the indices of the faces of the mesh
  474.             idx = []
  475.             for i in range(len(m.faces)):
  476.                 idx.append(i)
  477.  
  478.             # if idx is not reversed, this results in a list index out of range if
  479.             # the original mesh is used (RBmesh1 == 0)
  480.             idx.reverse()
  481.  
  482.             lenface, vertglob, vertidx, vertdist = [], [], [], []
  483.  
  484.             # total number of vertices
  485.             totverts = len(m.verts)
  486.  
  487.             # for every face: calculate global coordinates of the vertices
  488.             #                 append the vertex-index to a list
  489.             #                 calculate distance of vertices to cutplane in advance
  490.  
  491.             for i in idx:
  492.                 fvertidx, Ve, dist = [], [], []
  493.                 fa = m.faces[i]
  494.                 lenface.append(len(fa))
  495.                 for v in fa.v:
  496.                     globpos = GlobalPosition(v.co, Obj)
  497.                     Ve.append(globpos)
  498.                     fvertidx.append(v.index)
  499.                     dist.append(Distance(globpos, PNormal, POffset))
  500.                 vertidx.append(fvertidx)
  501.                 vertglob.append(Ve)
  502.                 vertdist.append(dist)
  503.  
  504.  
  505.             # append the verts of the original mesh to the new mesh
  506.             if RBmesh1.val == 1:
  507.                 for v in m.verts:
  508.                     MeshNew.verts.append(v)
  509.     
  510.             if RBmesh2.val == 1:
  511.                 idx2 = []
  512.                 dist2 = []
  513.                 for v in m.verts:
  514.                     MeshPos.verts.append(v)
  515.                     MeshNeg.verts.append(v)
  516.                     idx2.append(v.index)
  517.                     dist2.append(Distance(GlobalPosition(v.co, Obj), PNormal, POffset))
  518.  
  519.             # remove all faces of m if the original object has to be used
  520.  
  521.             if RBmesh0.val == 1:
  522.                 m.faces = []
  523.  
  524.             newvidx, newvcoo = [], []
  525.             testidxpos, testidxneg = [], []
  526.  
  527.             # what its all about...
  528.             for i in idx:
  529.                 fp = FacePosition(vertdist[i])
  530.  
  531.                 # no intersection
  532.                 if fp > 0:
  533.                     if RBmesh0.val == 1:
  534.                         FaceAppend(m, vertidx[i])
  535.             
  536.                     elif RBmesh1.val == 1:
  537.                         FaceAppend(MeshNew, vertidx[i])
  538.                 
  539.                     elif RBmesh2.val == 1:
  540.                         FaceAppend(MeshPos, vertidx[i])
  541.  
  542.                         if testidxpos == []:
  543.                             testidxpos = vertidx[i]
  544.                 elif fp < 0:
  545.                     if RBmesh0.val == 1:
  546.                         FaceAppend(m, vertidx[i])
  547.                     elif RBmesh1.val == 1:
  548.                         FaceAppend(MeshNew, vertidx[i])
  549.                     
  550.                     elif RBmesh2.val == 1:
  551.                         FaceAppend(MeshNeg, vertidx[i])
  552.  
  553.                         if testidxneg == []:
  554.                             testidxneg = vertidx[i]
  555.  
  556.                 # intersected faces
  557.                 else:
  558.                     # make new mesh
  559.                     if RBmesh1.val == 1:
  560.                         vlp, vln, newvidx, newvcoo = Split(Obj, MeshNew, MeshNew, vertglob[i], vertidx[i], PNormal, POffset, newvidx, newvcoo, totverts, vertdist[i])
  561.  
  562.                         if vlp != 0 and vln != 0:
  563.                             FaceMake(MeshNew, vlp)
  564.                             FaceMake(MeshNew, vln)
  565.                         # two new meshes
  566.                     elif RBmesh2.val == 1:
  567.                         vlp, vln, newvidx, newvcoo = Split(Obj, MeshPos, MeshNeg, vertglob[i], vertidx[i], PNormal, POffset, newvidx, newvcoo, totverts, vertdist[i])
  568.     
  569.                         if vlp != 0 and vln != 0:
  570.                             FaceMake(MeshPos, vlp)
  571.                             FaceMake(MeshNeg, vln)
  572.  
  573.                     # use old mesh
  574.                     elif RBmesh0.val == 1:
  575.     
  576.                         vlp, vln, newvidx, newvcoo = Split(Obj, m, m, vertglob[i], vertidx[i], PNormal, POffset, newvidx, newvcoo, totverts, vertdist[i])
  577.     
  578.                         if vlp != 0 and vln != 0:
  579.                             FaceMake(m, vlp)
  580.                             FaceMake(m, vln)
  581.  
  582.             if RBmesh1.val == 1:
  583.  
  584.                 ObOne = NMesh.PutRaw(MeshNew)
  585.  
  586.                 ObOne.LocX, ObOne.LocY, ObOne.LocZ = Obj.LocX, Obj.LocY, Obj.LocZ
  587.                 ObOne.RotX, ObOne.RotY, ObOne.RotZ = Obj.RotX, Obj.RotY, Obj.RotZ
  588.                 ObOne.SizeX, ObOne.SizeY, ObOne.SizeZ = Obj.SizeX, Obj.SizeY, Obj.SizeZ
  589.  
  590.             elif RBmesh2.val == 1:
  591.  
  592.                 # remove verts that do not belong to a face
  593.                 idx2.reverse()
  594.                 dist2.reverse()
  595.  
  596.                 for i in range(len(idx2)):
  597.                     if dist2[i] < 0:
  598.                         v = MeshPos.verts[idx2[i]]
  599.                         MeshPos.verts.remove(v)
  600.                     if dist2[i] > 0:
  601.                         v = MeshNeg.verts[idx2[i]]
  602.                         MeshNeg.verts.remove(v)
  603.  
  604.                 ObPos = NMesh.PutRaw(MeshPos)
  605.  
  606.                 ObPos.LocX, ObPos.LocY, ObPos.LocZ = Obj.LocX, Obj.LocY, Obj.LocZ
  607.                 ObPos.RotX, ObPos.RotY, ObPos.RotZ = Obj.RotX, Obj.RotY, Obj.RotZ
  608.                 ObPos.SizeX, ObPos.SizeY, ObPos.SizeZ = Obj.SizeX, Obj.SizeY, Obj.SizeZ
  609.  
  610.                 ObNeg = NMesh.PutRaw(MeshNeg)
  611.  
  612.                 ObNeg.LocX, ObNeg.LocY, ObNeg.LocZ = Obj.LocX, Obj.LocY, Obj.LocZ
  613.                 ObNeg.RotX, ObNeg.RotY, ObNeg.RotZ = Obj.RotX, Obj.RotY, Obj.RotZ
  614.                 ObNeg.SizeX, ObNeg.SizeY, ObNeg.SizeZ = Obj.SizeX, Obj.SizeY, Obj.SizeZ
  615.  
  616.             elif RBmesh0.val == 1:
  617.                 m.update()
  618.  
  619.  
  620.     #if timport == 1:
  621.         #end = time.clock()
  622.         #total = end - start
  623.         #print "mesh(es) cut in", total, "seconds" 
  624.  
  625.     end = time()
  626.     total = end - start
  627.     print "mesh(es) cut in", total, "seconds"
  628.  
  629. #############################################################
  630. # Graphics                                                  #
  631. #############################################################
  632. def Warn():
  633.     BGL.glRasterPos2d(115, 23)
  634.         Blender.Window.Redraw(Blender.Window.Const.TEXT)
  635.  
  636. def draw():
  637.     global msg
  638.     global RBmesh0,RBmesh1,RBmesh2
  639.     global VERSION
  640.     
  641.     BGL.glClearColor(0.5, 0.5, 0.5, 0.0)
  642.     BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
  643.     BGL.glColor3f(0, 0, 0)             # Black
  644.     BGL.glRectf(2, 2, 482, 220)
  645.     BGL.glColor3f(0.48, 0.4, 0.57)         # Light Purple
  646.     BGL.glRectf(4, 179, 480, 210)
  647.     BGL.glRectf(4, 34, 480, 150)
  648.     BGL.glColor3f(0.3, 0.27, 0.35)         # Dark purple
  649.     BGL.glRectf(4, 151,480, 178)
  650.     BGL.glRectf(4, 4, 480, 33)
  651.     
  652.  
  653.     BGL.glColor3f(1, 1, 1)
  654.     BGL.glRasterPos2d(8, 200)
  655.     Draw.Text("Blender Knife Tool -  V. 0.0.8a - 26 March 2004")
  656.     BGL.glRasterPos2d(8, 185)
  657.     Draw.Text("by Wim <tuinbels> Van Hoydonck & Stefano <S68> Selleri")
  658.     Draw.Button("Exit", 1, 430, 185, 40, 20)
  659.  
  660.     RBmesh0 = Draw.Toggle("Edit Object",    10,10,157,153,18,RBmesh0.val, "The knife creates new vertices in the selected object.");
  661.     RBmesh1 = Draw.Toggle("New Object",     11,165,157,153,18,RBmesh1.val, "The knife duplicates the object and creates new vertices in the new object.");
  662.     RBmesh2 = Draw.Toggle("Two New Objects",12,320,157,153,18,RBmesh2.val, "The knife creates two new separate objects.");
  663.  
  664.     BGL.glRasterPos2d(8, 128)
  665.     Draw.Text("1 - Draw a Mesh Plane defining the Cut Plane")
  666.     BGL.glRasterPos2d(8, 108)
  667.     Draw.Text("2 - Select the Meshes to be Cut and the Cut Plane")
  668.     BGL.glRasterPos2d(8, 88)
  669.     Draw.Text("      (Meshes Dark Purple, Plane Light Purple)")
  670.     BGL.glRasterPos2d(8, 68)
  671.     Draw.Text("3 - Choose the Edit Method (Radio Buttons above)")
  672.     BGL.glRasterPos2d(8, 48)
  673.     Draw.Text("4 - Push the 'CUT' button (below)")
  674.     #Create Buttons
  675.     Draw.Button("CUT", 4, 10, 10, 465, 18, "Cut the selected mesh along the plane")
  676.  
  677.     
  678.     BGL.glRasterPos2d(10, 223)
  679.     BGL.glColor3f(1,0,0)
  680.     Draw.Text(msg)
  681.     msg = ''
  682.     
  683. def event(evt, val):
  684.     if (evt == Draw.QKEY or evt == Draw.ESCKEY) and not val:
  685.         Draw.Exit()
  686.     if evt == Draw.CKEY and not val:
  687.         CutMesh()
  688.         Draw.Redraw()
  689.  
  690. def bevent(evt):
  691.     global RBmesh0,RBmesh1,RBmesh2
  692.  
  693.     if evt == 1:
  694.         Draw.Exit()
  695.     elif evt == 4:
  696.         CutMesh()
  697.         Draw.Redraw()
  698.     elif evt == 10:
  699.         RBmesh0.val = 1
  700.         RBmesh1.val = 0
  701.         RBmesh2.val = 0
  702.         Draw.Redraw()
  703.     elif evt == 11:
  704.         RBmesh0.val = 0
  705.         RBmesh1.val = 1
  706.         RBmesh2.val = 0
  707.         Draw.Redraw()
  708.     elif evt == 12:
  709.         RBmesh0.val = 0
  710.         RBmesh1.val = 0
  711.         RBmesh2.val = 1
  712.         Draw.Redraw()
  713.  
  714. Draw.Register(draw, event, bevent)
  715.