你好,這里是BIMBOX。
我們的老朋友,建筑學和計算機雙修的小神仙@VCTCN93又來BOX分享了。
當我問到他這次打算聊點啥,VCTCN93說,100%原創(chuàng)首發(fā),聊一個很多人還不知道的事,可能有點超前,但他相信代表了未來的工作方式:給Dynamo搭一個服務(wù)器,讓它成為真正的變形金剛。
下面的文章,代碼部分你可以照著實操一下,絕對可以驗證;如果你從來沒寫過Python、甚至沒用過Dynamo,也完全可以跳過代碼部分,看這套方法背后的思想,還能給給漲點談資。
Let’s rock it.
很多人不知道,Python 有很多不同的版本,比如 CPython、 Jython、 RPython 與 IronPython 等等。一般大家口中所說的 Python,默認代指的是標準版CPython,基于C語言實現(xiàn),能夠兼容諸多 CAPI。CAPI是什么你不需要知道,只需要知道這些 CAPI 幾乎無所不能,運行速度極快,于是大神們便通過它們,為 CPython 創(chuàng)造了一個又一個牛逼哄哄的武器:第三方庫,這些武器能夠把 Python 武裝起來,最終讓 Python 成了編程世界中一個無比強大的存在。
如果你去看大神們寫的Python代碼,會經(jīng)??吹剿鼈兘?jīng)常以這樣的語句開頭:from pyecharts.charts
import
Bar
import plotly.express as px
這里的 import 某某,就是在召喚某個強大的第三方庫進入python,你可以把它理解為一個別人寫好的插件,不需要知道它的工作原理,只要載進來,就能幫你做到很多厲害的事。比如,使用第三方庫 pandas_profiling ,你只需要一行代碼,就能做出一份完整的數(shù)據(jù)報表。import pandas as pd
import pandas_profiling
#前兩行是導入,命令就下面一行
df = pd.read_csv(‘churn.csv’)
可以說,沒有第三方庫的 Python,就像失去了武器的武者,要他干活,就像要他肉身搏坦克。
前面我們說的是標準版 CPython,遺憾的是,Windows平臺下的很多設(shè)計軟件,比如我們熟知的 Grasshopper 與 Dynamo,它們內(nèi)置的 Python 都是 IronPython。IronPython 雖然也有 Python 之名,但其底層是基于 .NET 平臺實現(xiàn)的,與基于 C語言 的 原生Python 有天壤之別。它從一出生就注定了無法使用大神們創(chuàng)造的強大第三方武器。從某種意義上來說,與 CPython 相比,IronPython 就是個只能用肉身搏坦克的先天殘疾。想要讓手上的 Python 發(fā)出最大的威力,使用那些屬于 Python 的利器,你就需要繞過 IronPython 的封鎖,奔向 CPython 的自由世界。
想在 Dynamo 中直接裝 CPython?這是不現(xiàn)實的,不然就不會有 IronPython 這樣折衷的存在了。我曾在教程「Dynamo 場地有限元分析」課程中提到過 MVP(Model-View-Present) 模式,簡單來說就是,讓計算與顯示互不干涉、完全分離,把參數(shù)發(fā)給計算者,計算者返回你結(jié)果。用大白話來解釋就是:你不需要管我是怎么計算的,你給我數(shù)據(jù),我給你結(jié)果就行了。舉個最簡單的例子,你日常瀏覽網(wǎng)頁就是一個這樣的過程。你在瀏覽器中輸入了一串網(wǎng)頁地址,按下回車,瀏覽器就把包含了參數(shù)的 URL 地址發(fā)給了網(wǎng)站的服務(wù)器,服務(wù)器再經(jīng)過海量的計算,把計算的結(jié)果返回給你,這就形成了你日??吹降木W(wǎng)頁。有些 URL 不僅是一個網(wǎng)站的地址,還包括一定的運算規(guī)則。比如你在搜索引擎中搜索 「ArchiPython」,瀏覽器中的那一條 URL 中,就蘊含了大量需要完成本次搜索的參數(shù),服務(wù)器計算了你提供的這些參數(shù)之后,才把所有本次運算的結(jié)果 ,也就是「含有ArchiPython的條目」返回給你。想要擺脫 IronPython 的束縛,使用 CPython?我們大可以模仿這種方式。沒錯,我就是要你在 Dynamo 中,像訪問網(wǎng)頁一樣使用 Cpython。我們的思路是,搭建一個使用 CPython 的本地服務(wù)器,接收 Dynamo 發(fā)來的含有參數(shù)的 URL,服務(wù)器計算出結(jié)果,再把計算的結(jié)果發(fā)回 Dynamo。整個過程,其實是完全不用 Dynamo 中的電池做任何計算,而是讓 Dynamo 成為一個純顯示端的存在。云負責計算有所數(shù)據(jù),本地負責顯示所有結(jié)果,這也就是云計算的基本思想。高能預警:下面開始出現(xiàn)代碼,沒有基礎(chǔ)的小白同學可以跳著看看熱鬧。日后用到的時候,再回來看源代碼做參考。
前面我們說到了CPython 強大的第三方庫,接下來要干的活兒自然也少不了它的幫忙。你只需要幾行代碼,就能使用 flask 庫,在 CPython 中搭建本地服務(wù)器:fromflaskimportFlask
__publisher__ = ‘ArchiPython’
app=Flast(__name__)
if__name__=='__main__':
app.run()
諾,服務(wù)器就這么簡單的搭好了,運行這個文件,你就開啟了服務(wù)器。圖中Running on http://后邊是一串服務(wù)器的地址你可以在這個服務(wù)器中實現(xiàn)一些功能,比如測試是否成功鏈接:fromflaskimportFlask
__author__ = ‘Vctcn93’
__publisher__ = ‘ArchiPython’
app=Flask(__name__)
@app.route('/connect')
defconnect():
return'連接成功!'
if__name__=='__main__':
app.run()
通過設(shè)置的 connect
函數(shù),如果連接成功,網(wǎng)頁上就會顯示出 連接成功 四個字。值得注意的是,服務(wù)器只能返回字符串 (string),如果你想將計算結(jié)果用于 Dynamo 中,還需要對服務(wù)器返回的數(shù)據(jù)進行加工,以確保其類型的正確。你也可以讓服務(wù)器根據(jù)輸入的參數(shù),來計算出結(jié)果。在腳本中添加一個 add
函數(shù),讓他求參數(shù) a
和 參數(shù) b
的和:總結(jié)說來,一條滿足服務(wù)器計算的 URL,需要滿足如下公式:與服務(wù)器只能返回字符串的特性一樣,你通過請求(request)得到的參數(shù)也全是字符。恭喜你,你現(xiàn)在已經(jīng)成功突破了 Dynamo 的封鎖!基于以上代碼,你就可以在這個 CPython 環(huán)境的服務(wù)器下,使用各種 Python 強大武器了,比如大名鼎鼎的 Numpy,pandas 等等。在 Dynamo 中像在瀏覽器里一般發(fā)送接請求,就可以獲得使用 CPython 計算的結(jié)果了。
由于 Dynamo 中的 Python 是 IronPython,所以它發(fā)送請求的方式是使用 .NET
的庫,與 CPython 有非常大的不同,我們需要把發(fā)送和接受轉(zhuǎn)化成 CPython 的方式,下面直接送上 DynamoPythonScript 中實現(xiàn)的代碼:(代碼中帶有#的灰色行是代碼說明)# 啟用 Python 支持和加載 DesignScript 庫
importclr
clr.AddReference('ProtoGeometry')
fromAutodesk.DesignScript.Geometryimport*
# 該節(jié)點的輸入內(nèi)容將存儲為 IN 變量中的一個列表。
dataEnteringNode=IN
# 將代碼放在該行下面
# IronPython 庫的環(huán)境變量,一般在這個位置
importsys
sys.path.append('C:/Program Files (x86)/IronPython 2.7/Lib')
fromSystem.NetimportWebRequest
fromSystem.IOimportStreamReader
fromSystem.TextimportEncoding
__author__ = ‘Vctcn93’
__publisher__ = ‘ArchiPython’
# 服務(wù)器地址
url=r'http://127.0.0.1:5000/'
# 可在在此處對 URL 進行編輯,使其支持參數(shù)
# 發(fā)送請求
request=WebRequest.Create(url)
# 獲取計算的結(jié)果
response=request.GetResponse()
result=StreamReader(response.GetResponseStream()).ReadToEnd()
# 將輸出內(nèi)容指定給 OUT 變量。
OUT=result
開啟服務(wù)器后,你只需要對那個 URL 做一定的修改,Dynamo 就能發(fā)送請求,收到結(jié)果了。
下面我們來試試具體能做些什么,拋磚引玉,歡迎大家迸發(fā)新的靈感。
在 CPython 中有一個幾何庫,稱為 shapely
,它功能強大,運算速度極快,是目前 Python 世界中非常流行的幾何庫之一。
繞開了 IronPython 的封鎖后,你就可以通過服務(wù)器,使用 shapely 做相關(guān)的幾何運算。運算速度一般比 Dynamo 自帶電池快 1000 倍以上。
我們來設(shè)計一個函數(shù),通過一條多段線(polyline)與精度(density),返回一個均分的點矩陣(matrix),寫成代碼如下:defcreate_grid(polyline:List[list],deisty:float):->List(list)
pass
根據(jù)這個要求,你就可以開始搭建自己的服務(wù)器了,功能代碼如下:importnumpyasnp
fromflaskimportFlask,request
fromshapely.geometryimportPolygon,Point
__author__ = ‘Vctcn93’
__publisher__ = ‘ArchiPython’
app=Flask(__name__)
@app.route('/connect')
defconnect():
return'連接成功!'
@app.route('/add')
defadd():
# 拿到 URL 中的參數(shù)
a=request.args.get('a')
b=request.args.get('b')
# 將他們還原成數(shù)字
a,b=eval(a),eval(b)
# 計算
result=a+b
# 只能返回字符串
returnstr(result)
@app.route('/create_grid')
defcreate_grid():
# 獲得polyline參數(shù)
polyline=request.args.get('polyline')
print(polyline)
# 獲得density
density=request.args.get('density')
# 還原他們的類型
polyline,density=eval(polyline),eval(density)
# 獲得圖形信息
polygon=Polygon(polyline)
bbox=polygon.bounds
start_coords=bbox[:-2]
width=bbox[2]-bbox[0]
height=bbox[3]-bbox[1]
round_x=round(width/density)
round_y=round(height/density)
# 定義基本矢量
vector_right=np.array([density,0])
vector_up=np.array([0,density])
vector_point_start=np.array(start_coords)
# 獲得原始點矩陣
matrix=list()
forxinrange(round_x):
foryinrange(round_y):
vector_point=vector_point_start+vector_right*x+vector_up*y
point=Point(vector_point)
# 同時做判斷,如果點在范圍內(nèi)
ifpolygon.contains(point):
matrix.append(point)
# 將結(jié)果輸出為字符
result=[
list(p.coords)[0]forpinmatrix
]
returnstr(result)
if__name__=='__main__':
app.run()
在 Console 中運行這個腳本,你就可以在瀏覽器中輸入?yún)?shù)來測試結(jié)果:輸入一個 polyline,其幾何為 [[0,0],[100,0],[100,100],[0,100]], density 為 10,求出其結(jié)果。
接下來,使用 Dynamo 發(fā)送這次請求,并獲得服務(wù)器返回的結(jié)果:# 啟用 Python 支持和加載 DesignScript 庫
—
importclr
clr.AddReference('ProtoGeometry')
fromAutodesk.DesignScript.Geometryimport*
# 該節(jié)點的輸入內(nèi)容將存儲為 IN 變量中的一個列表。
dataEnteringNode=IN
# 將代碼放在該行下面
# IronPython 庫的環(huán)境變量,一般在這個位置
importsys
sys.path.append('C:/Program Files (x86)/IronPython 2.7/Lib')
fromSystem.NetimportWebRequest
fromSystem.IOimportStreamReader
fromSystem.TextimportEncoding
__author__ = ‘Vctcn93’
__publisher__ = ‘ArchiPython’
# 服務(wù)器地址
url=http://127.0.0.1:5000/
url+='creaet_grid?'
url+='polyline=[[0,0],[100,0],[100,100],[0,100]]&'
url+='density=10'
# 發(fā)送請求
request=WebRequest.Create(url)
# 獲取計算的結(jié)果
response=request.GetResponse()
result=StreamReader(response.GetResponseStream()).ReadToEnd()
# 將結(jié)果處理為一個個的點:
points=[Point.ByCoordinates(*coords)forcoordsineval(result)]
# 將輸出內(nèi)容指定給 OUT 變量。
OUT=points
到這一步,我們就真正實現(xiàn)了 0 節(jié)點運算,僅靠服務(wù)器本身完成復雜的功能,Dynamo 在整個鏈條中,僅僅起到了顯示的作用。
你也可以使用 Dynamo 中的 Polyline
與 NumberSlider
來完成這項計算:? 將紅線導入 Dynamo 中,設(shè)置 number slider,讓 Density 參數(shù)可調(diào)。? 修改部分代碼,讓鏈接地址隨參數(shù)變化而變化。? 此時,你便會得到一個響應(yīng)速度極快的、使用 CPython 實時計算的點矩陣。
從表面上來看,這只是一個通過搭建服務(wù)器,跳出 Dynamo 自帶的 IronPython,實現(xiàn)使用原生 Python 牛哄哄功能的方法。這對于純建筑人員來說或許有些許難度,而對于程序員而言,或許并不是很厲害的功能。但是,這篇分享的意義,遠不止搭建個服務(wù)器這么簡單。VCTCN93 認為,「本地客戶端只負責顯示,運算交給云端」,這極有可能是未來幾年越來越普及的工作方式。在這個案例之中,在傳統(tǒng)工作流中起到計算作用的 Dynamo,完全成為了顯示結(jié)果的存在,所有的計算,都在服務(wù)器上完成了。這次的分享僅僅只是引入了少量矢量庫,未來有可能會引入計算機神經(jīng)引擎,而正如我們前面所說的,Dynamo 也好,Revit 也好,目前都是不支持這些尖兒貨的。如果我們能在任意軟件使用自己開發(fā)的功能,又何須要被軟件本身的功能和API鎖死自己的生產(chǎn)力呢?軟件如果能做,那就用軟件做;軟件如果不能做,那么我就只把它當做顯示工具,整個系統(tǒng)都可能會被時代拋棄掉。往大點的方向說,5G時代將要來臨了,人類數(shù)據(jù)傳輸?shù)男视謱⑦M入一個新的臺階,云計算一定會成為未來的主流。建筑師只需要把設(shè)計參數(shù)發(fā)送給云端,云端就能返回給你算好的結(jié)果,企業(yè)對于軟件功能和硬件性能的升級,也只對應(yīng)著云端服務(wù)器,能大量節(jié)省本地的資源。今天只是 Dynamo 成了我們的顯示端,但其實我可以用任何東西作為我的顯示端。如果一個工程師說「這件事我做不了,因為軟件沒有這個功能」,他就是被軟件功能鎖死了。軟件本身應(yīng)該為工程師的自身業(yè)務(wù)服務(wù),而不是由工程師去遷就軟件功能劃出的地牢。和很多建筑圈的計算機大牛一樣,VCTCN93 曾經(jīng)不止一次的在多個場合呼吁,不要局限在軟件層面,更不要被任何軟件鎖死的原因。因為把別人造好的輪子玩得滾瓜爛熟,遠不如自己掌握核心科技。很多人會說,工程師是做設(shè)計、做施工的,憑啥去學 Dynamo、學Python?每個人當然有權(quán)不學,我們希望的是,至少人們知道自己腳下的邊界在哪里,邊界之外,還有多廣闊的天地。今天你至少收獲了一個談資:下次別人再告訴你學 Dynamo 要把 Python 玩兒溜,你可以反問一句:你說的是 CPython 還是 IronPython ? IronPython 可不夠用??!關(guān)于云計算是怎么回事,它的發(fā)展和未來,我們在《精讀10本好書中的20項新科技》這門音頻課程里專門有一節(jié)講到了它,特地拿出來給你設(shè)置成免費收聽,感興趣的話可以聽聽看。作為BIMBOX小伙伴里的建筑+計算機雙修撐場專員,再次向你誠意推薦 VCTCN93 的《Dynamo可視化腳本思維課》,能幫你打開一片為所欲為的新天地。另外,VCTCN93 和BOX合作的 Dynamo+Python 工程師自我提升課程,也在積極籌備中,各位小伙伴有哪方面的實際需求,也歡迎給我們留言,幫助我們打造一套有價值的好教程。有態(tài)度,有深度,BIMBOX,咱們下次見!