Blenderで日経平均チャートを作成するPythonScript

 Blenderを使用して立体的なローソク足による日経平均チャートを作成する

使い方は、スクリプトを画面上のスクリプトエディタに貼り付ける。Webスクレイピングを使用してるので、ライブラリとかアドオンとか入っていないとエラーがでるし、場合によってはPythonのバージョンで動作しないかもしれない。基本的な構造を理解して修正すればよい。このスクリプトはMacで作成したのでディレクトリのパスは使用するPC環境に合わせる必要がある。特にフォントはかなり違いがあるので変更が必要だろう


日経平均の数日前の株価を取得して日足チャートを作成する。猫は手動でオブジェクトを挿入してる。場合によっては、ローソクが変な場所に移動したりする。これは急落急騰したときに座標が大きく変動するからなので、そういったときは手動でオブジェクトを移動させたりする。


以下Pythonスクリプト

 
import os
import bpy
import math
import copy
import time
import pandas_datareader.data as data
from datetime import datetime,timedelta

#blender 2.91 ,2.93
#Mac Big Sur
#ターミナル起動site ,Text menu >> Run Script このスクリプトを実行させる
#/Applications/Blender.app/Contents/MacOS/Blender

#GLOBAL
# count
# xmove
# bairitsu

#2021/09/20 move animation
'''
keyframe Num 24
candle1 0,4
candle2 4,8
candle3 8,12
candle4 12,16
candle5 16,20
candle6 20,24
one by one move 
'''
def fmoveObjAnime(fobjname,fhighHaba,fstep):
    changeFrame=0
    counter=0    
    #obj is only one 
    for item in bpy.data.objects:
        if fobjname in item.name:
            counter+=1
    
    #obj are many        
    for item in bpy.data.objects:
        if fobjname in item.name:
            if counter==1:
                changeFrame=24#last frame number
            else:
                changeFrame+=fstep
            frame_num=changeFrame
            ob=bpy.data.objects[item.name]
            bpy.context.scene.frame_set(frame_num)
            ob.keyframe_insert(data_path = "location",index = -1)

    #frame move keyframe
    tmpNum=0
    changeFrame=0
    for item in bpy.data.objects:
        if fobjname in item.name:
            if counter==1:
                changeFrame=20#before 4 frame at last frame24
            else:
                changeFrame=fstep*tmpNum
            tmpNum+=1
            frame_num=changeFrame
            ob=bpy.data.objects[item.name]
            
            #first move frame 
            bpy.context.scene.frame_set(frame_num)
            #second move obj
            #z up 
            ob.location[2]+=fhighHaba
            ob.keyframe_insert(data_path = "location",index = -1)     
    #set 0
    bpy.context.scene.frame_set(0)


#https://bluebirdofoz.hatenablog.com/entry/2018/04/25/231414
# オブジェクトの原点変更
# オブジェクトの原点を指定位置に移動する
# 引数   arg_objectname:指定オブジェクト名
# 戻り値
def set_origin_cursor(arg_objectname='Default',arg_location=(0,0,0)):
  # 他のオブジェクトの寸法を適用しないよう全てのオブジェクトを走査する
  for ob in bpy.context.scene.objects:
    # 非選択状態に設定する
    #ob.select=False#2.7
    ob.select_set(False) #2.9
  # 指定オブジェクトを取得する
  selectob = bpy.data.objects[arg_objectname]
  # 変更オブジェクトをアクティブに変更する
  #bpy.context.scene.objects.active = selectob#2.7
  bpy.context.view_layer.objects.active=selectob#2.9
  # 変更オブジェクトを選択状態にする  
  #selectob.select=True #2.7
  selectob.select_set(True) #2.9
  # 3Dカーソルの元の位置を記録しておく(参照型のコピー)
  #cursorpos = copy.copy(bpy.context.scene.cursor_location)
  # 3Dカーソルの位置を指定位置に移動する
  #bpy.context.scene.cursor_location = arg_location#2.7
  bpy.context.scene.cursor.location=arg_location#2.9
  # オブジェクトの原点を3Dカーソル位置に移動する
  bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
  # 3Dカーソルの位置を元に戻す
  #bpy.context.scene.cursor_location = cursorpos #2.7
  #bpy.context.scene.cursor.location=cursorpos#2.9 not use
  bpy.context.scene.cursor.location=(0.0,0.0,0.0)
  return

def fcandle(candleType,kopen,kclose,bairitsu,xmove,mat1,mat2):
    #count is Global
    global count
    #global xmove
    #global bairitsu
    
    if bairitsu=='' or bairitsu==0:
        print('def fcandle(),bairitsu not defined,use 0.001')
        bairitsu=0.001
    if count=='':
        print('def fcandle(),count is Global, not defined, Please check, so use 1')
        count=1
                  
    candle=candleType
    #1.円柱location:図形の中心座標 radius:円の半径 depth:高さ rotation:立体の回転角(rad)
    bpy.ops.mesh.primitive_cylinder_add(location=(0, 0, 0), radius=0.022, depth=3, rotation=(0, 0, 0))
    if candle=='yousen':
        bpy.context.object.data.materials.append(mat1) # 材質(赤)指定
    else:#insen 
        bpy.context.object.data.materials.append(mat2) # 材質(青)指定
    bpy.ops.transform.translate(value=(xmove,0,0))
    #location=bpy.context.object.location
    
    for obj in bpy.context.selected_objects:
        if obj.name=='Cylinder':
            tmpcount=count+1
            obj.name = "candle"+str(tmpcount)
    
    #bpy.ops.object.shade_smooth()
    
    new_bar = bpy.context.object
    for vert in new_bar.data.vertices:
        if candle=='yousen':
            if vert.co[2] > 0:#Zjiku ni up
                vert.co[2] = kclose*bairitsu#close
            else:
                vert.co[2] = kopen*bairitsu
        elif candle=='insen':
            if vert.co[2] > 0:
                vert.co[2] = kopen*bairitsu
            else:
                vert.co[2] = kclose*bairitsu
    clocation=(xmove,0,(kopen+kclose)*bairitsu/2) 
    set_origin_cursor(obj.name,clocation)
    location=bpy.context.object.location
    
    return  location#candle             
#end def

def fcandle_hige(candleType,khigh,klow,bairitsu,candleLocation,mat1,mat2):
    global count
    #global xmove
    #global bairitsu    
    #count,bairitsu is Global
    #if bairistu=='' or bairitsu==0:
    #    print('def fcandle_hige(),bairitsu not defined, so use 0.001')
    #    bairitsu=0.001
    if count=='':
        print('def fcandle_hige(),count is Global, not defined, Please check, so use 1')
        count=1
        
    candle=candleType
    bpy.ops.mesh.primitive_cylinder_add(location=(0, 0, 0), radius=0.022/7, depth=3, rotation=(0, 0, 0))
    if candle=='yousen':
        bpy.context.object.data.materials.append(mat1) # 材質(赤)指定
    else:#insen 
        bpy.context.object.data.materials.append(mat2) # 材質(青)指定
    bpy.ops.transform.translate(value=(candleLocation[0],candleLocation[1],0))#hige location is same candle location
    
    for obj in bpy.context.selected_objects:
        if obj.name=='Cylinder':
            tmpcount=count+1
            obj.name = "hige"+str(tmpcount)
    
    #xmove+=0.048
    #bpy.ops.object.shade_smooth()
    
    new_bar = bpy.context.object
    for vert in new_bar.data.vertices:
            if vert.co[2] > 0:#Zjiku ni up
                vert.co[2] = khigh*bairitsu#close
            else:
                vert.co[2] = klow*bairitsu
    set_origin_cursor(obj.name,candleLocation)
    
#end def
# テキストオブジェクトの追加
def add_text(text, t_color,location):
# 角度設定時に利用
  ROT_QUATER = math.pi / 2
  bpy.ops.object.text_add()
  ob = bpy.context.object
  ob.data.body = text
  ob.data.extrude = 0.05
  ob.data.bevel_depth = 0.002
  
  bpy.ops.font.open(filepath="/System/Library/Fonts/ヒラギノ角ゴシック W6.ttc")
  #bpy.data.fonts["HiraginoSans-W6"].name = "HiraginoSans-W6"
  fnt = bpy.data.fonts.load('/System/Library/Fonts/ヒラギノ角ゴシック W6.ttc')
  ob.data.font = fnt 
  
  ob.rotation_euler[0] = ROT_QUATER
  # 3Dカーソルの位置を0,0,0
  bpy.context.scene.cursor.location=(0.0,0.0,0.0)
  #3Dカーソルを原点を変更してから、translateする必要がある。
  bpy.ops.transform.translate(value=location)#26500*0.001,(1.8,0.1/3,26.5)
  bpy.ops.transform.resize(value=(0.2,0.1,0.2)) # 図形を変形
  
  #ob.rotation_euler[2] = ROT_QUATER
  ob.data.align_x = 'CENTER'
  ob.data.align_y = 'CENTER'
  mat = bpy.data.materials.new('color_txt')
  mat.diffuse_color = t_color#(0.8, 0.8, 0.8, 1.0)
  # マテリアルスロットを追加する
  bpy.ops.object.material_slot_add()
  # 作成したマテリアルスロットに新規マテリアルを設定する
  bpy.context.object.active_material = mat
  #ob.active_material.diffuse_color = (1,0,0)
  #bpy.context.object.active_material.diffuse_color = (1,0,0)
  #mat.diffuse_color = (1.0,0.0,0.0)
  
  #mat.diffuse_color = (1,0,0)#t_color #error , I do not yet 2020/05/15 
  #ob.data.materials.append(mat)
  #ob.active_material.diffuse_color = t_color # error

#convert to mesh

  #s = bpy.context.scene.objects.active
  #s.name = "text_name"
  bpy.ops.object.convert(target='MESH')# work
  for obj in bpy.context.selected_objects:
     if obj.name=='Text':
         obj.name=text

  return ob
#end def

def add_textKai(text, t_color,location,size):
# 角度設定時に利用
  ROT_QUATER = math.pi / 2
  bpy.ops.object.text_add()
  ob = bpy.context.object
  ob.data.body = text
  ob.data.extrude = 0.05
  ob.data.bevel_depth = 0.002
  
  bpy.ops.font.open(filepath="/System/Library/Fonts/ヒラギノ角ゴシック W6.ttc")
  #2022/0404 here error 
  #bpy.data.fonts["HiraginoSans-W6"].name = "HiraginoSans-W6"
  fnt = bpy.data.fonts.load('/System/Library/Fonts/ヒラギノ角ゴシック W6.ttc')
  ob.data.font = fnt 
  
  ob.rotation_euler[0] = ROT_QUATER
  # 3Dカーソルの位置を0,0,0
  bpy.context.scene.cursor.location=(0.0,0.0,0.0)
  #3Dカーソルを原点を変更してから、translateする必要がある。
  bpy.ops.transform.translate(value=location)#26500*0.001,(1.8,0.1/3,26.5)
  bpy.ops.transform.resize(value=size) # 図形を変形(0.2,0.1,0.2)
  
  #ob.rotation_euler[2] = ROT_QUATER
  ob.data.align_x = 'CENTER'
  ob.data.align_y = 'CENTER'
  mat = bpy.data.materials.new('color_txt')
  mat.diffuse_color = t_color#(0.8, 0.8, 0.8, 1.0)
  # マテリアルスロットを追加する
  bpy.ops.object.material_slot_add()
  # 作成したマテリアルスロットに新規マテリアルを設定する
  bpy.context.object.active_material = mat
  #ob.active_material.diffuse_color = (1,0,0)
  #bpy.context.object.active_material.diffuse_color = (1,0,0)
  #mat.diffuse_color = (1.0,0.0,0.0)
  #mat.diffuse_color = (1,0,0)#t_color #error , I do not yet 2020/05/15 
  #ob.data.materials.append(mat)
  #ob.active_material.diffuse_color = t_color # error
#convert to mesh
  #s = bpy.context.scene.objects.active
  #s.name = "text_name"
  bpy.ops.object.convert(target='MESH')# work
  for obj in bpy.context.selected_objects:
     if obj.name=='Text':
         obj.name=text  
  return ob
#end def

#2020/12/29
#print('Max:',max(df['High']))#最大値が取れる
#高値の最大値maxと安値の最小値minを取得して
#500円ごとのバー基準株価線(26500,27000,27500)を自動で作成したい。
def makeBarMaxtoMin(highobj,lowobj):
    #print('Max:',max(highobj))#df['High']
    #print('Min:',min(lowobj))#df['Low']
    #bairitsu is Global
    global count
    global xmove
    global bairitsu    
    #if bairistu=='' or bairitsu==0:
    #    print('def makeBarMaxtoMin(),bairitsu not defined,use 0.001')
     #   bairitsu=0.001    
    #every 500yen
    priceRange=500
    #highPriceNumはバーの本数を取得する
    highPriceNum,highmod=divmod(max(highobj),priceRange)#26200/priceRange
    lowPriceNum,lowmod=divmod(min(lowobj),priceRange)
    #高値については、余りが出たら、1を追加する
    #print('highmod:',highmod)
    if highmod!=0:
        highPriceNum=highPriceNum+1
        #Rangeで範囲を指定してしようする場合1加算では足りないので、rangeで更に1を加算する
        #print('after highPriceNum:',highPriceNum)

    for i in range(math.floor(lowPriceNum),math.floor(highPriceNum+1)):
        #range()が出力するのは、(highPriceNum-1)なので1を加算してhighPriceNum分までを計算させる
        print('barPrice:',i*priceRange)
        #i*priceRangeの位置でBarオブジェクトを作成する。
        # 3Dカーソルの位置を0,0,0
        bpy.context.scene.cursor.location=(0.0,0.0,0.0) 
        color=(0.8,0.5,0.8,0.8)
        add_text(str(i*priceRange), color,(1.8,0.1/3, (i*priceRange)*bairitsu+0.045))#0.045 is ajustment
        
        bpy.context.scene.cursor.location=(0.0,0.0,0.0)
        # 平板作成 26500bar1
        bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0), size=2.0)
        bpy.ops.transform.translate(value=(0.0,0.1/2,(i*priceRange)*bairitsu))#26500*0.001
        bpy.ops.transform.resize(value=(2.0,0.06/6,0.01/6)) # 図形を変形
        bpy.context.object.data.materials.append(mat3) # 材質
        for obj in bpy.context.selected_objects:
            if obj.name=='Cube':
                obj.name='bar_'+str(i*priceRange) 
#end def
######################################################################
#main
######################################################################
print('start')
count=0#count is Global
xmove=0.8#1# move distancs
bairitsu=0.001# size Global

#anime
animeOn=0 # 1:anime,0:non
highHaba=1.2#m
stepFrame=4

#delet keyframe
context = bpy.context
for ob in bpy.data.objects:
    ob.animation_data_clear()

#Stock date
n=maenohi=5
end = datetime.now()
#start = end - timedelta(days=maenohi)#end.day-7 changes
#start = datetime(end.year, end.month, end.day-7)
##土日があると表示させるローソク足の数が少ないので、数が満たされるまでループするためSleepを入れた
#大量のデータはCSVで取得してからローソク足にしたほうが良さそう
x=0
while x<=(maenohi):
    start = end - timedelta(days=n)
    df=data.DataReader('^N225','yahoo',start,end)#3990.T,#^N225
    date=df.index# 日付
    time.sleep(3)
    print('len(date):',len(date))
    print('3秒待ち')
    x=len(date)
    n=n+1
print(df.head(8))
if len(date)==0:
    print('ERROR Can not get any Price data, Check internet or yahoo finance com.')
    sys.exit()

#animation delete 
#here

# 既存要素削除
for item in bpy.data.meshes:
    bpy.data.meshes.remove(item)

for item in bpy.data.materials:
    bpy.data.materials.remove(item)
        
#bpy.ops.outliner.item_rename()
#2.立方体 location:図形の中心座標 size:立方体の一辺の長さ rotation:立体の回転角(rad)
#bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0), size=1.0, rotation=(0, 0, 0))

# 2.材質の定義(赤色)
mat1 = bpy.data.materials.new('Red')
mat1.diffuse_color = (1.0, 0.0, 0.0, 1.0)

# 3.材質の定義(青色)
mat2 = bpy.data.materials.new('blue')
mat2.diffuse_color = (0.0, 0.0, 1.0, 1.0)

mat3 = bpy.data.materials.new('gray')
mat3.diffuse_color = (0.8, 0.8, 0.8, 0.5)

mat5 = bpy.data.materials.new('yellow')
mat5.diffuse_color = (1.0, 0.9, 0.1, 1.0)

# 平板作成 27000bar
#bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0), size=2.0)
#Resizeして、ポイント移動をするとポイントの縮尺が変わり、想定した位置に移動しない(推測)。
#これはオブジェクトの原点とScaleの考え方の違いかもしれない。
#よって、リサイズして、ポイントを移動させたいときは、
#リサイズをする前にオブジェクト自体を移動させてから、ポイントを移動させたほうが良いと思う。
#bpy.ops.transform.translate(value=(0.0,0.1/2,27))#27000*0.001
#bpy.ops.transform.resize(value=(2.0,0.06/6,0.01/6)) # 図形を変形
#bpy.context.object.data.materials.append(mat3) # 材質

# 平板作成 26500bar1
#bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0), size=2.0)
#bpy.ops.transform.translate(value=(0.0,0.1/2,bar1*bairitsu))#26500*0.001
#bpy.ops.transform.resize(value=(2.0,0.06/6,0.01/6)) # 図形を変形
#bpy.context.object.data.materials.append(mat3) # 材質

# 3Dカーソルの位置を0,0,0
#bpy.context.scene.cursor_location =(0.0,0.0,0.0)
bpy.context.scene.cursor.location=(0.0,0.0,0.0)

#26500txt
#color=(0.8,0.5,0.8,0.8)
#add_text('26500', color,(1.8,0.1/3,bar1*bairitsu+0.045))#0.045 is ajustment
#27000txt
#add_text('27000', color,(1.8,0.1/3,bar2*bairitsu+0.045))


#date=df.indexをカウントして、それぞれを取得する。ちょっとスマートではないが、、
for fdate in date:
    khigh=df['High'][count]
    klow=df['Low'][count]
    kopen=df['Open'][count]
    kclose=df['Adj Close'][count]
    #ここに日付ごとの処理を入れる。
    #
    if kopen-kclose<0: 0.04="" 00:00:00="" 0="" align="WORLD" andle_hige="" andle_main="" bairitsu="" blue="" bpy.data.objects:="" bpy.ops.mesh.primitive_cone_add="" candle="" candlecount="" candlelocation="" candlename="candle" color="" count="" d="" depth="2," else:="" enter_editmode="False," fcandle_hige="" fdate.strftime="" for="" global="" if="" in="" is="" khigh="" klow="" location="(0," m="" mat1="" mat2="" obj.name:="" obj.name="" obj="" print="" radius1="1," radius2="0," red="" rrow="" scale="(0.04," str="" xmove="">0.04
#図形を回転(Y軸周りに90°)
bpy.ops.transform.rotate(value=-3.1415/2 ,orient_axis='Y')
bpy.context.object.data.materials.append(mat5) 
bpy.ops.transform.translate(value=(bpy.data.objects[candleName].location[0]+0.08,bpy.data.objects[candleName].location[1],bpy.data.objects[candleName].location[2]))#


bpy.context.scene.cursor.location=(0.0,0.0,0.0)
#open,close
color=(1.0,1.0,1.0,1.0)
#str,color,location,size
lastOpen=df['Open'][len(date)-1]#始値
lastClose=df['Close'][len(date)-1]#終値
roundOpen='O:'+str(round(lastOpen,2))#画面に表示させる直近の始値文字
roundClose='C:'+str(round(lastClose,2))#画面に表示させる直近の終値文字

add_textKai(roundOpen, color,(xmove+0.1,0,lastOpen*bairitsu),(0.06,0.05,0.06))
add_textKai(roundClose, color,(xmove+0.1,0,lastClose*bairitsu),(0.06,0.05,0.06))

#end.strftime("%Y/%m/%d") or date[len(date)-1].strftime("%Y/%m/%d")today
color=(0.0,1.0,0.0,1.0)
coneLocation=bpy.data.objects['Cone'].location
tyokkinDay=date[len(date)-1].strftime("%Y/%m/%d")
if len(date)>0:
    add_textKai(tyokkinDay,color, (coneLocation[0]+0.16,coneLocation[1],coneLocation[2]),(0.06,0.05,0.06))
#print('last day:',date[len(date)-1])

#始値、終値、直近の日付の調整。オブジェクトが重なってしまう金額が近いときに離す処理
if candle=='yousen':#Openが下側でCloseが上側にあるはず
    #bpy.data.objects[roundOpen].dimensions[1]#Z方向の幅サイズではなくてY軸、理由はローカルで回転させたから
    #bpy.data.objects[roundClose].dimensions[1]
    #bpy.data.objects[tyokkinDay].dimensions[1]
    #始値、終値、直近の日付のlocationを取得する。Z方向ではなくてY軸の幅の半分を上下に加減算して重なりを調べる
    #bpy.data.objects[roundOpen].location[2]
    #bpy.data.objects[roundClose].location[2]
    #bpy.data.objects[tyokkinDay].location[2]
    #roundCloseを調整する.roundCloseの下側位置が、直近日付の上側位置以下になっているときに、直近日付の上の方にroundCloseを上へ移動させる
    
    #location is [2]:Z, dimensions is [1]:Y
    if bpy.data.objects[roundClose].location[2]-bpy.data.objects[roundClose].dimensions[1]/2 <= bpy.data.objects[tyokkinDay].location[2]+bpy.data.objects[tyokkinDay].dimensions[1]/2:
        #直近日付の位置に、プラスへ移動
        bpy.data.objects[roundClose].location[2]=bpy.data.objects[tyokkinDay].location[2]+bpy.data.objects[tyokkinDay].dimensions[1]*1.5
    #roundOpenを調整する。roundOpenの「上側」位置が、直近日付の「下側」以上になっているときに、直近日付の「下の方」にroundOpenを下へ移動させる
    if bpy.data.objects[roundOpen].location[2]+bpy.data.objects[roundOpen].dimensions[1]/2 >=bpy.data.objects[tyokkinDay].location[2]-bpy.data.objects[tyokkinDay].dimensions[1]/2:
            #「マイナス」へ移動
        bpy.data.objects[roundOpen].location[2]=bpy.data.objects[tyokkinDay].location[1]-bpy.data.objects[tyokkinDay].dimensions[1]*1.5
else:#insen Openが上側でCloseが下側にあるはず.Yousenとは逆
    #roundOpen
    print('insen')
    if bpy.data.objects[roundOpen].location[2]-bpy.data.objects[roundOpen].dimensions[1]/2<=bpy.data.objects[tyokkinDay].location[2]+bpy.data.objects[tyokkinDay].dimensions[1]/2:
        bpy.data.objects[roundOpen].location[2]=bpy.data.objects[tyokkinDay].location[2]+bpy.data.objects[tyokkinDay].dimensions[1]*1.5
        print('Open')
    #roundClose
    if bpy.data.objects[roundClose].location[2]+bpy.data.objects[roundClose].dimensions[1]/2>=bpy.data.objects[tyokkinDay].location[2]-bpy.data.objects[tyokkinDay].dimensions[1]/2:
        bpy.data.objects[roundClose].location[2]=bpy.data.objects[tyokkinDay].location[2]-bpy.data.objects[tyokkinDay].dimensions[1]*1.5
        print('Close')

    

#2020/12/29
#print('Max:',max(df['High']))#最大値が取れる
#高値の最大値maxと安値の最小値minを取得して
#500円ごとのバー基準株価線(26500,27000,27500)を自動で作成したい。
makeBarMaxtoMin(df['High'],df['Low'])

#camera move, near Cone obj
camera_obj = bpy.data.objects['Camera']
print(camera_obj.location)
camera_obj.location=(coneLocation[0]+0.16,coneLocation[1]-3.0,coneLocation[2])

#Neko呼び出し
file_path = '/Users/toshiromaseda/Documents/blender/model/テスト、研究モデル/Neko/Neko_simple_001.blend'
inner_path = 'Object'
object_name = 'Neko'
 
bpy.ops.wm.append(
    filepath=os.path.join(file_path, inner_path, object_name),
    directory=os.path.join(file_path, inner_path),
    filename=object_name
    )

bpy.context.scene.cursor.location=(0.0,0.0,0.0)
# 指定オブジェクトを取得する
#arg_objectname='Neko'
selectob = bpy.data.objects[object_name]
selectob.select_set(True) #2.9
selectob.location=(coneLocation[0],coneLocation[1]-0.1,coneLocation[2])
bpy.ops.transform.resize(value=(0.07,0.07,0.07)) # 図形を変形
#bpy.ops.transform.resize(value=(0.37,0.37,0.37)) # 図形を変形

#anime
if animeOn==1 :# if you make animation animeOn:1
    #fmoveObjAnime(fobjname,fhighHaba,fstep)
    fmoveObjAnime('candle',highHaba,stepFrame)
    fmoveObjAnime('hige',highHaba,stepFrame)
    fmoveObjAnime('C:',highHaba,stepFrame)
    fmoveObjAnime('O:',highHaba,stepFrame)
    #fmoveObjAnime('Cone',hightHaba,stepFrame)

print('done.')

''' Result



'''
株式ランキング
株式ランキング にほんブログ村 株ブログ 株 デイトレードへ
にほんブログ村 にほんブログ村 デザインブログ 3DCGへ
にほんブログ村

このブログの人気の投稿

メモ、BlenderPythonスクリプトで参考になるオブジェクトや頂点の選択ツリー選択スクリプトリンクメモ

楽天証券、信用取引口座から楽天FX口座へ振替手順

10/15デイトレは、ジュース代を確保した、日経平均が4万200円超