#!BPY """ Name: 'ROTOBox' Blender: 240 Group: 'Misc' Tooltip: 'ROTOBox is a utility to set up image references for mesh design.' """ __author__ = "Paul Jesson" __url__ = ("blender", "elysiun","ROTOBox homepage, http://www.dogobe.com/rotobox.html",) __version__ = "1.3" __bpydoc__ = """Description: utility to set up image references for use in mesh design Usage: * To prepare reference images the side/bottom/top views should be aligned in the same direction as should the side/front/back views. * Select your reference images. Select as many as you require - blank images are ignored. * Select Create. This will create a UV'd plane for each image you selected. * To see the images select alt+z. * Create a new mesh and set to drawtype to wire - in Object Buttons F7. Start modelling against the references. * Select the Exit button or press q (in the script window) to exit the script Notes: * No image validity is checked before trying to open them. """ __email__ = "paul@dogobe.com" # -------------------------------------------------------------------------- # roto.py # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- # -- ----------------------------------------------------------------------- # -- Change History # -- ----------------------------------------------------------------------- # v1.3 20060115 # * Replaced ImageSelector with FileSelector # v1.2 20051220 # * positioned plans correctly # v1.1 20051217 # * Correct GPL header # * Code tidy up # * Flipped UV coordinates # * Object naming # * Added scale value # * Allowed for repeatable runs of script # v1.0 20051216 # * Inital release import sys import Blender from Blender import * pyDEBUG = 0 # Globals topImageText = Blender.Draw.Create('') sideImageText = Blender.Draw.Create('') bottomImageText = Blender.Draw.Create('') frontImageText = Blender.Draw.Create('') backImageText = Blender.Draw.Create('') scaleNumber = Blender.Draw.Create(3.0) bscale = 3 postfix = 1 # -- ----------------------------------------------------------------------- # -- ----------------------------------------------------------------------- # -- FUNCTIONS # -- ----------------------------------------------------------------------- # -- ----------------------------------------------------------------------- def validImageFile(filename): return 1 def createROTOBox(): global topImageText, sideImageText, bottomImageText, frontImageText, backImageText global bscale, postfix # determine valid files maxHeight = 0 maxWidth = 0 maxLength = 0 if topImageText.val != '' : try: imageTop = Blender.Image.Load(topImageText.val) topX, topY = imageTop.getMaxXY() maxWidth = topX maxLength = topY except: print 'ERROR: Failed to open image file ', topImageText.val imageTop = 0 else : imageTop = 0 if sideImageText.val != '' : try: imageSide = Blender.Image.Load(sideImageText.val) sideX, sideY = imageSide.getMaxXY() maxHeight = sideY maxLength = max(maxLength,sideX) except: print 'ERROR: Failed to open image file ', sideImageText.val imageSide = 0 else : imageSide = 0 if bottomImageText.val != '' : try: imageBottom = Blender.Image.Load(bottomImageText.val) bottomX, bottomY = imageBottom.getMaxXY() maxWidth = max(maxWidth, bottomX) maxLength = max(maxLength,bottomY) except: print 'ERROR: Failed to open image file ', bottomImageText.val imageBottom = 0 else : imageBottom = 0 if frontImageText.val != '' : try: imageFront = Blender.Image.Load(frontImageText.val) frontX, frontY = imageFront.getMaxXY() maxWidth = max(maxWidth, frontX) maxHeight = max(maxHeight,frontY) except: print 'ERROR: Failed to open image file ', frontImageText.val imageFront = 0 else : imageFront = 0 if backImageText.val != '' : try: imageBack = Blender.Image.Load(backImageText.val) backX, backY = imageBack.getMaxXY() maxWidth = max(maxWidth, backX) maxHeight = max(maxHeight,backY) except: print 'ERROR: Failed to open image file ', backImageText.val imageBack = 0 else : imageBack = 0 if imageTop : # crete plane #if maxHeight == 0 : #else : #z = maxHeight/100.0 * bscale z = 0.0 x = (topY/100.0) * bscale y = ((topX/100.0) * bscale) mTop = NMesh.GetRaw() # verts v=NMesh.Vert(0.0,0.0,z) mTop.verts.append(v) v=NMesh.Vert(x,0.0,z) mTop.verts.append(v) v=NMesh.Vert(x,y,z) mTop.verts.append(v) v=NMesh.Vert(0.0, y,z) mTop.verts.append(v) # face f=NMesh.Face() f.v.append(mTop.verts[0]) f.v.append(mTop.verts[1]) f.v.append(mTop.verts[2]) f.v.append(mTop.verts[3]) f.image = imageTop f.uv = list([ tuple([0.0,1.0]), tuple([0.0,0.0]), tuple([1.0,0.0]), tuple([1.0,1.0]) ]) mTop.faces.append(f) mTop.hasFaceUV(1) oTop = NMesh.PutRaw(mTop, "ROTOBoxTop" + repr(postfix), 1) if oTop: oTop.setName("ROTOBoxTop" + repr(postfix)) if imageSide : # crete plane z = (sideY/100.0) * bscale x = 0.0 y = (sideX/100.0) * bscale mSide = NMesh.GetRaw() # verts v=NMesh.Vert(x,0.0,0.0) mSide.verts.append(v) v=NMesh.Vert(x,0.0,z) mSide.verts.append(v) v=NMesh.Vert(x,y,z) mSide.verts.append(v) v=NMesh.Vert(x,y,0.0) mSide.verts.append(v) # face f=NMesh.Face() f.v.append(mSide.verts[0]) f.v.append(mSide.verts[3]) f.v.append(mSide.verts[2]) f.v.append(mSide.verts[1]) f.image = imageSide f.uv = list([ tuple([0.0,0.0]), tuple([1.0,0.0]), tuple([1.0,1.0]), tuple([0.0,1.0]) ]) mSide.faces.append(f) mSide.hasFaceUV(1) oSide = NMesh.PutRaw(mSide, "ROTOBoxSide" + repr(postfix), 1) if oSide: oSide.setName("ROTOBoxSide" + repr(postfix)) if imageFront : # crete plane if maxLength != 0 : y = (maxLength/100.0) * bscale else : y = 0.0 z = (frontY/100.0) * bscale x = (frontX/100.0) * bscale mFront = NMesh.GetRaw() # verts v=NMesh.Vert(0.0,y,0.0) mFront.verts.append(v) v=NMesh.Vert(0.0,y,z) mFront.verts.append(v) v=NMesh.Vert(x,y,z) mFront.verts.append(v) v=NMesh.Vert(x,y,0.0) mFront.verts.append(v) # face f=NMesh.Face() f.v.append(mFront.verts[3]) f.v.append(mFront.verts[2]) f.v.append(mFront.verts[1]) f.v.append(mFront.verts[0]) f.image = imageFront f.uv = list([ tuple([1.0,0.0]), tuple([1.0,1.0]), tuple([0.0,1.0]), tuple([0.0,0.0]) ]) mFront.faces.append(f) mFront.hasFaceUV(1) oFront = NMesh.PutRaw(mFront, "ROTOBoxFront" + repr(postfix), 1) if oFront: oFront.setName("ROTOBoxFront" + repr(postfix)) if imageBack : # crete plane y = 0.0 z = backY/100.0 * bscale x = backX/100.0 * bscale mBack = NMesh.GetRaw() # verts v=NMesh.Vert(0.0,y,0.0) mBack.verts.append(v) v=NMesh.Vert(0.0,y,z) mBack.verts.append(v) v=NMesh.Vert(x,y,z) mBack.verts.append(v) v=NMesh.Vert(x,y,0.0) mBack.verts.append(v) # face f=NMesh.Face() f.v.append(mBack.verts[0]) f.v.append(mBack.verts[1]) f.v.append(mBack.verts[2]) f.v.append(mBack.verts[3]) f.image = imageBack f.uv = list([ tuple([1.0,0.0]), tuple([1.0,1.0]), tuple([0.0,1.0]), tuple([0.0,0.0]) ]) mBack.faces.append(f) mBack.hasFaceUV(1) oBack = NMesh.PutRaw(mBack, "ROTOBoxBack" + repr(postfix), 1) if oBack: oBack.setName("ROTOBoxBack" + repr(postfix)) if imageBottom : # crete plane if maxHeight: z = maxHeight/100.0 * bscale else : z = 0.0 y = (bottomX/100.0) * bscale x = (bottomY/100.0) * bscale mBottom = NMesh.GetRaw() # verts v=NMesh.Vert(0.0,0.0,z) mBottom.verts.append(v) v=NMesh.Vert(0.0,y,z) mBottom.verts.append(v) v=NMesh.Vert(x,y,z) mBottom.verts.append(v) v=NMesh.Vert(x,0.0,z) mBottom.verts.append(v) f=NMesh.Face() f.v.append(mBottom.verts[0]) f.v.append(mBottom.verts[1]) f.v.append(mBottom.verts[2]) f.v.append(mBottom.verts[3]) f.image = imageBottom f.uv = list([ tuple([0.0,0.0]), tuple([1.0,0.0]), tuple([1.0,1.0]), tuple([0.0,1.0]) ]) mBottom.faces.append(f) mBottom.hasFaceUV(1) oBottom = NMesh.PutRaw(mBottom, "ROTOBoxBottom" + repr(postfix), 1) if oBottom: oBottom.setName("ROTOBoxBottom" + repr(postfix)) postfix = postfix + 1 Blender.Redraw() return 1 def myGUI(): ymax = 350 ypos = 0 global topImageText, sideImageText, bottomImageText, frontImageText, backImageText, scaleNumber global topImageButton, sideImageButton, bottomImageButton, frontImageButton, backImageButton global __version__, pyDEBUG BGL.glClearColor(0,0,0, 1) BGL.glColor3f(0.75,0.75,0.75) BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) Blender.Draw.Button("Exit", 1, 10,ymax - (ypos),50,20, "Exit ROTOBox") ypos += 25 BGL.glRasterPos2d(10, ymax-ypos) Blender.Draw.Text("ROTOBox v" + __version__) ypos += 25 # File top topImageText = Blender.Draw.String("", 10, 10, ymax - (ypos+20), 300, 20, topImageText.val, 250, "") topImageButton = Blender.Draw.Button("Top", 20, 350,ymax - (ypos+20),50,20, "select top view image") ypos += 25 # File side sideImageText = Blender.Draw.String("", 11, 10, ymax - (ypos+20), 300, 20, sideImageText.val, 250, "") sideImageButton = Blender.Draw.Button("Side", 21, 350,ymax - (ypos+20),50,20, "select side view image") ypos += 25 # File bottom bottomImageText = Blender.Draw.String("", 12, 10, ymax - (ypos+20), 300, 20, bottomImageText.val, 250, "") bottomImageButton = Blender.Draw.Button("Bottom", 22, 350,ymax - (ypos+20),50,20, "select bottom view image") ypos += 25 # File front frontImageText = Blender.Draw.String("", 13, 10, ymax - (ypos+20), 300, 20, frontImageText.val, 250, "") frontImageButton = Blender.Draw.Button("Front", 23, 350,ymax - (ypos+20),50,20, "select front view image") ypos += 25 # File back backImageText = Blender.Draw.String("", 14, 10, ymax - (ypos+20), 300, 20, backImageText.val, 250, "") backImageButton = Blender.Draw.Button("Back", 24, 350,ymax - (ypos+20),50,20, "select back view image") ypos += 25 # Scale Indicator scaleNumber = Blender.Draw.Number("Grid units per 100 pixels : ", 15, 10, ymax - (ypos+20), 300, 20, scaleNumber.val, 1.0, 15.0, "Scale indicator") ypos += 25 # Create Rotobox Blender.Draw.Button("Create",2,10,ymax - (ypos+20),250,20, "Create rotoscope reference") ypos += 25 def selectTop(filename): global topImageText if validImageFile(filename) : topImageText.val = filename Draw.Redraw() def selectSide(filename): global sideImageText if validImageFile(filename) : sideImageText.val = filename Draw.Redraw() def selectBottom(filename): global bottomImageText if validImageFile(filename) : bottomImageText.val = filename Draw.Redraw() def selectFront(filename): global frontImageText if validImageFile(filename) : frontImageText.val = filename Draw.Redraw() def selectBack(filename): global backImageText if validImageFile(filename) : backImageText.val = filename Draw.Redraw() def myExit(): print '==============================================================' print '== Exiting script ROTObox' print '==============================================================' print '' Draw.Exit() def event(evt, val): if (evt== Blender.Draw.QKEY and not val): myExit() def bevent(evt): global bscale, scaleNumber if (evt == 20): Blender.Window.FileSelector(selectTop, 'Select top view') elif (evt == 21): Blender.Window.FileSelector(selectSide, 'Select side view') elif (evt == 22): Blender.Window.FileSelector(selectBottom, 'Select bottom view') elif (evt == 23): Blender.Window.FileSelector(selectFront, 'Select front view') elif (evt == 24): Blender.Window.FileSelector(selectBack, 'Select back view') elif (evt == 15): bscale = scaleNumber.val elif (evt == 2): createROTOBox() elif evt == 1: myExit() else : return # -- ----------------------------------------------------------------------- # -- ----------------------------------------------------------------------- # -- MAIN # -- ----------------------------------------------------------------------- # -- ----------------------------------------------------------------------- print '' print '==============================================================' print '== Starting script ROTObox version ', __version__, ' ...' print '==============================================================' Blender.Draw.Register(myGUI, event, bevent)