QQ登录

只需一步,快速开始

扫一扫,访问微社区

犀牛建筑网

查看: 211011|回复: 2

面向设计师的Rhino Python基础教程: 第二课

[复制链接]
发表于 2014-8-20 15:03:39 | 显示全部楼层 |阅读模式
犀牛网校
一 Python与PyCharm的安装

1 关于版本
学习Python目前有两个版本可选,Python 2.x和Python 3.x(http://wiki.python.org/moin/Python2orPython3上有较详细的介绍),Python 2.x已经停止开发,最后一个版本为Python 2.7.5,虽然已经停止开发,但这个版本目前应用得最为广泛,rhino5上的Python版本便是Python 2.7.x(因为IronPython还没有更新到Python 3.x)。Python 3.x的开发代号为Python 3000,相对于Python 2.x有较大的升级,而且并不向下兼容(有一个2to3的脚本,但大部分情况下都不太好用) ,是Python社区目前主要维护的版本和未来的开发方向。虽然Python 3.x目前的第三方库并不丰富,但Python 3.x的改变是朝向更为简洁、更易理解和更为准确的方向,而且相对于最新的Python 2.7.x如Rhino5上的Python 2.7.x,语法和基本库上矛盾的地方不多(从Python 2.6.x开始,开发组就考虑了用户向Python 3.x的过渡),本教程以Python基于目前最新版Python 3.3.2(2013.07.**),因为很多同学学习Python的目的是使用Rhino.Python,因此遇到语法特别之处我会指出。
2 下载和安装Python
如果你使用的是今年发布的Mac OS X操作系统的苹果电脑或者Ubuntu、Red Hat、openSUSE等主流的Linux操作系统,系统里已经预装好了Python 3.x,如果你使用的是Windows 操作系统,你需要下载一个Python副本安装到系统当中,如果你想在Android平板或者Ipad上学习Python那也是可以的,你可以下载Python for IOS和Python for Android。同样还有Sun Solaris、AS/400、BeOS等非主流平台上的版本。因此Python是一个跨平台的计算机语言,一次编写,随处可用,但本教程将基于Windows 7系统。Windows、Mac OS X和Linux用户可在http://www.python.org/getit/下载最新的Python版本(初学者不建议到其他地方下载山寨版,除非有特殊需要),同时也提供了源代码下载,用户可自己编译。
Windows用户下载以下页面当中的前两项,其中64位系统最好下载第二项,32位系统用户最好下载第一项。然后一路下一步即可,其中在安装组件选择页面可勾选最后一项,设置系统变量,Python将默认安装在C:\Python33目录下,建议不要更改(方便IDE识别到Python安装的位置),还可以在同一个系统下安装多个版本的Python,这些版本互不冲突。


                     
Python3.3.2安装包选择与安装界面




添加系统路径




安装完成之后,在Python开始程序目录下(用Windows8的同学估计只有到安装目录下去找)如右图的一些文件,其中IDLE是一个交互式的代码编辑器,是Python初学者最主要使用的编辑器,基于自带图形库TK GUI,另外一个编辑器(Python command line)是一个命令行下的编辑器,不建议使用,并且,这里还有一些用户文档和Pydoc的模块引擎。
IDLE(以下简称Shell)是一个可见即可得的Python文本编辑器,具有简单的语法高亮功能(程序内置函数,特殊字符等用不同颜色予以显示),虽然它并不太好用,对于管理项目来说不免麻烦了点,但Shell提供了不错的交互式编程环境,而且具有完整的Debug功能,是一个不错的探索Python的互动环境。
请尝试一下在Shell中输入一些东西,然后按下回车(一次只能输入一行代码),例如输入一个数值,它将返回一个数值,输入一个有效的计算式,可以返回一个值,输入一个字符串。返回一个字符串(字符串必须加上引号),或者随便输入一些字母符号,如果不是运气够好的话,一般会返回一个错误,如下:


Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:06:53) [MSC v.160064 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> 123
123
>>> 1*5+6-(2/3)
10.333333333333334
>>> 'love'
'love'
>>> asdfa
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    asdfa
NameError: name 'asdfa' is not defined
>>> 'sdfdf'*'sdfdf'
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    'sdfdf'*'sdfdf'
TypeError: can't multiply sequence by non-int of type 'str'
>>>





从上面的例子可以看出Python并不是智能的语言,所有的输入都必须遵循一定的语法它才能理解并按之正确的执行。以上的两个错误都属于静态错误,前者是语法错误,即"asdfa"是一个并不存在的语法定义,后一个是静态语义错误,即语言意义上的错误,两个字符串是无法相乘的(但在Python中字符串和数值是可以相乘的),除此之外,另一种错误是动态错误,在程序执行过程中出现的错误,一个优秀的IDE很容易识别出程序员所犯的静态错误,但动态错误难以识别,甚至有些时候可以通过编译,便形成了一个程序的Bug,程序语言的语法有些时候相当苛刻,而有的时候却大而化之,例如Python允许字符串和数值相乘,但一个优秀的程序员一定会有一个良好的编程风格,不会在自己代码中带有太多有歧义的东西,我们在后面的过程中再来慢慢的学习这些东西。
Shell中的优秀交互功能还包含了即时的帮助功能,输入help()或help(object)来获得编程过程中遇到的问题。例如我们输入help(print)可获得print()函数的相关说明,包含了函数的参数,缺省值,输入和返回值的数据类型等,如果你还不懂这些,没关系,往下学就行了。如果你输入的是一个Python标准库中不存在函数、模块或关键字,将返回一句语法错误。
输入help()之后,注意提示符从>>> 改变为 help>,进入交互帮助模式,在该模式下是无法进行程序本身的编写的,例如定义一个变量,创建一个函数等,在help>什么也不输入直接回车即可退出帮助交互模式。

>>> help
Type help() for interactive help, or help(object) for help about object.
>>> help()
Welcome to Python 3.3!  This is the interactive help utility.
If this is your first time using Python, you should definitely check out
the tutorial on the Internet at http://docs.python.org/3.3/tutorial/.
Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules.  To quit this help utilityand
return to the interpreter, just type "quit".
To get a list of available modules, keywords, or topics, type"modules",
"keywords", or "topics".  Each module also comes with a one-line summary
of what it does; to list the modules whose summaries contain a given word
such as "spam", type "modules spam".
help> print
Help on built-in function print in module builtins:
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
   
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.
help> asdfggf
no Python documentation found for 'asdfggf'

在Shell新建窗口中进行,这里我们可以一次输入多行代码,然后按F5返回Shell并运行。现在我们来学习刚才的print()函数,这个函数在Python3.x中做了巨大的改变,在Python2.x中print是一个语句,例如写一个hello world程序直接是使用print  'hello world'即可,而在Python3.x中print变为一个函数,必须加上()并在内传递一个合法的参数才可以将其显示出来。现在我们尝试一下在Shell中写hello world程序和做一些其他的尝试,以下代码本次教程附件文件中的1_print exercise.py。





## 打印'Hello world!'
print('Hello world!')
## 打印出数值与字符串组合
print('I am',25,'years old.')
## 打印出两个数值
print(2,3)
## 打印出一个数组
print((2,3))
## 不换行即打印下一个数据
print('Hello world!',end='')
print('Hello world!')
>>> ================================ RESTART================================
>>>
Hello world!
I am 25 years old.
2 3
(2, 3)
Hello world!Hello world!
>>>

在这段代码中我们可以看到"## 打印出两个数值"这样的描述,这是一行注释,注释是对程序中某些部分的注解,不会影响程序进行,主要帮助程序员对代码的理解和控制,Python中的单行注释一般使用"#"(个人习惯采用两个##,这没有任何影响),多行注释可用'''     '''(各三个单引号)把注释内容包起来。另一个就是采用中文的问题,Python默认采用UTF-8编码,可用任意使用中文,甚至是中文变量,但为了养成良好习惯我们一般在第一行处可加上,这样我们在Rhino.Python中就不会遇到问题。

#-*- coding:utf-8 -*-
>>> 世界您好 = 'Hello world!'
>>> print(世界您好)
Hello world!

3 PyCharm的安装和使用
要使用Python来编写程序,自带的Shell并不算好,目前优秀的语言编辑器(以下简称IDE,即语言集成开发环境)能够智能输入补充,高亮语法、变量和各种关键字、静态错误自动判断等,http://wiki.python.org/moin/IntegratedDevelopmentEnvironments这个页面有一个Python目前可用的IDE清单,其中JetBrains PyCharm、NetBeansWing IDE、Eclipse比较推荐,我使用的是JetBrains PyCharm 2.6.3。使用搜索引擎搜索这个IDE很容易找到。
在安装完成PyCharm后第一次通过一个Welcome页面设置,设置代码高亮样式和显示风格,我个人偏向使用的是Eclipse代码样式,twlight显示风格。




设置完成后,PyCharm的整个外观如下,整个IDE可分为五个部分,1菜单区,包含如项目建立,管理,程序设置,debug,版本管理等等;2 主要工具栏,包含文件打开储存,程序运行等;3 项目文件管理;4 代码部分;5程序辅助区,错误提示,项目结构管理,debug辅助等等。当然这些窗体如图Rhino一样并不是一成不变的,可以自己按偏好调整。






PyCharm强大但功能复杂,作为我们初学者而言并不需要用到大部分的功能,我们最需要的是在写代码时的一系列代码补全,错误提示,自动错误修正建议等功能。如下:




变量补全



导入库名字补全



自动错误提示




在File-setting下面有一系列需要我们注意的地方,首先如果第一次通过欢迎页面设置的显示效果令你不满,可以再Code Style下重新设置整个显示风格。另外在Project Interpreter下我们可以管理多个版本的Python。






现在我们用PyCharm来运行我们第一个真正意义上的程序,代码如下,见课程附件文件中的2_smile.py,相比起前面的Hello World,这算是一个完整的程序,它导入了Python标准库中的tkinter GUI模块,这是一个比较简单的程序界面开发和二维绘图库,用它来绘制一个经典笑脸并显示Hello World,并且可以在画布上用蓝色笔自由绘制,你可以修改里面的一些参数结果将会发生变化。程序结构详见注释。作为初学者而言,这里面的内容可能你大部分不懂,没有关系,这或许是你第一个直接从代码运行的程序,我的第一个程序也相当弱智,大概用了两个星期四次上机课的时间用LOGO语言绘制了一只虫子在爬,让我们从一个笑脸开始来正式学习Python编程。

#-*- coding:utf-8 -*-
__author__ = 'Wang Dachuan @ChongQing Univercity'
__copyright__ = '<共享,非商业,署名>'
## 导入tkinter GUI模块
from tkinter import *
## 定义变量
lastx, lasty = 0, 0
## 绘制笑脸
def addFace():
    canvas.create_arc(154.04, 70.23, 245.96, 162.16,start=0,extent=-180,width=6,style=ARC)
    canvas.create_oval(122.22, 38.41, 277.78, 193.98, width=6,)
    canvas.create_oval(163.73, 77.10, 176.01, 89.37,width=3,fill='black')
    canvas.create_oval(223.99, 77.10, 236.27, 89.37,width=3,fill='black')
## Hello world文字部分
def addWord():
    word = 'Hello world!'
    canvas.create_text(199.67, 240.92,text=word ,font='Helvetica -36 bold')
## 画笔绘图部分
def addLine(event):
    global lastx, lasty
    x, y = canvas.canvasx(event.x), canvas.canvasy(event.y)
    canvas.create_line((lastx, lasty, x, y), fill='blue', width=2,tags='currentline')
    lastx, lasty = x, y
def xy(event):
    global lastx, lasty
    lastx, lasty = canvas.canvasx(event.x), canvas.canvasy(event.y)
## 创建窗口,在窗口中调用之前的绘图和文字部分
root = Tk()
root.title('Hello world!')
canvas = Canvas(root,width=400,height=350)
canvas.grid(column=0, row=0, sticky=(N, W, E, S))
canvas.bind(addFace())
canvas.bind(addWord())
canvas.bind("<Button-1>", xy)
canvas.bind("<B1-Motion>", addLine)
root.mainloop()







二 变量的故事
1变量的定义
    程序语言中的变量与我们之前政治生物所学的用于对研究对象进行定量稍有不同,也没有自变量、因变量之分。程序语言中的变量很好理解,就是程序语言运行时储存在计算机内存中的,且值可修改的一个储存空间。如下图,在程序运行时,将为一个变量分配一个内存单元,在用到这个变量时,将调用这个内存单元中的值。内存地址是通过变量名联系起来的。





一般来说变量具有以下的属性:
&#8226;     数据类型:变量所储存的数据具有类型特征,例如数值、字符串
&#8226;     名字/别名:变量允许是空值,但必须有一个名字(或称作标识符),如果用名字去传递一个变量,那个这个变量就具有一个别名,例如下面代码片段中,变量b即是a的别名,它们都指向内存中的同一个地址。

a = 10
b = a
print(b)

&#8226;     存储属性:存储该变量的存储器类型,例如自动型、静态型、寄存器型、外部型,一般同的语言具有不同的变量存储类型。
&#8226;     生命周期:该变量的存在时间,当该变量不再使用时,其先前所占用的内存空间将回收
&#8226;     作用域:变量的有效区域,分为全局变量或局部变量。例如在Python中以下一段代码将报错,因为a这个变量是Variable()子函数中的局部变量。

def Variable():
    a = 10
    print(a)
Variable()
print(a)


--------------------------------------
NameError: name 'a' is not defined
Process finished with exit code 1

变量的命名规则:
&#8226;     变量的名字只能由字母、数值和下划线三类字符构成,且首个字符必须是字母或下划线,例如a1是合法的变量名,而1a则是不合法的变量名
&#8226;     变量名具有大小写之分,A和a是两个不同的变量名字
&#8226;     变量名具有255位字符长度的限制
&#8226;     在变量所处的作用域内
&#8226;     对于Python而言,其有一系列内置的关键字,这些关键字不能作为变量名
False      class      finally    is         return
None      continue   for       lambda    try
True       def       from      nonlocal   while
and        del       global    not        with
as         elif       if        or         yield
assert      else      import     pass
break      except    in        raise

以上内容就不多介绍,这些底层的知识需要你在后续学习中慢慢理解,现在看得越多反而越晕,初学者需要了解的便是,变量是a=10这个整体,而不是a,它是计算机中内存单元在语言中的抽象,是编程语言中最基本的概念,它具有以上一些基本的属性,这些属性在Python大部分时候都是自动实现的,并不需要我们进行特别的定义,需要注意的是变量命名的规则和其适用的代码范围,下面我们来看Python中的基本数据类型。
2 Python中的基本数据类型
在当代计算机语言的概念当中,一切皆为对象,从基本数值、字符串到函数、类、模块都可以理解为数据类型,对于一些处理特定问题的编程语言来说,数据内型的概念更是丰富多样,例如RhinoPython中的点、线、面都属于数据类型。数据类型的存在是因为不同类型的数据可以做不同的事,例如数值可以做加减乘除,而字符串则不能。作为编程的初学者,我们需要理解程序语言最基本的一些数据类型,对于Python而言,以下数据类型是必须理解的:
① Number数值型  123(整数), 2.0(浮点数), 0.2345(浮点数), math.pi(三角函数), Fraction(2, 3)(分数)
② String字符串型  'love', 'Chongqing University'
③ Booleans布尔型  True, False
③ Bytes字节型
④ 数据集合  包括:元组、列表、集合、字典等
2.1 数值型数据
讲第一种数据类型之前先比较一下VB语言,VB这类需要声明变量类型的语言用数值简直是可畏的,数值分为整数和实数,整数又分为整型和长整型、实数分为单精度型和双精度型,在创建一个数值变量时,必须声明它的类型,例如 Dim a as Int,就声明了一个整数变量,如果需要有小数,则要用到 Dim a as Double,而在Python中,变量是无需声明的,Python帮你搞定一切,在程序运行时,它会自动识别数据类型,自动进行数据间的转换,像VB这类语言需要强制定义变量类型,称作静态类型语言。Python这类无需定义变量类型的语言称作动态类型语言,虽然这一定程度上有损运行速度,但这就是Python异常简洁,适合初学者学习的特点之一。
Python中的基本数值类型包含整数、浮点数和其他数值,通过小数点进行区分,也可利用特殊的函数相互转换。请看以下例子(位于3_number.py):
## 创建一个整数变量
a = 1
## 创建一个浮点数变量
b = 3.5
## 整数与浮点数相加,用type()函数取得该变量类型
c = a + b + b
print()
print('c=',c,'c的类型',type(c))
## 整数转换成浮点数
d = float(a)
print('d=',d,'d的类型',type(d))
## 浮点数转换成整数
e = int(b)
print('e=',e,'e的类型',type(e))
>>> ================================ RESTART================================
c= 8.0 c的类型 <class 'float'>
d= 1.0 d的类型 <class 'float'>
e= 3 e的类型 <class 'int'>

可以看到,当Python遇到一个整数型数值和浮点数型数值进行运算时,会将整数自动转换为浮点数进行预算,然后结果返回一个浮点数类型c=8.0,可以通过int()函数和float()函数强制将数值转换为整数和浮点数,当浮点数转换为整数时,并不是四舍五入的法则,而是砍掉小数部分,例如int(3.2) = 3,int(-2.8) = -2。
就我经验,取整在参数化建模的一些过程中也常常用到,下面来看看这些函数(4_quzheng.py):

from math import *
a = 1.5
b = -1.5
c = 1.3
d = -1.7
e = -1.3
## int取整直接砍掉小数部分
print('int函数结果:a=',int(a),' b=',int(b),' c=',int(c),' d=',int(d),' e=',int(e))
## round函数四舍五入,可用一个参数选择保留小数点位数,如round(a,1)将返回1.5
print('round函数结果:a=',round(a),' b=',round(b),' c=',round(c),' d=',round(d),' e=',round(e))
##floor取小于或等于该数的最大整数
print('floor函数结果:a=',floor(a),' b=',floor(b),' c=',floor(c),' d=',floor(d),' e=',floor(e))


>>> ================================ RESTART================================
int函数结果:a= 1  b= -1  c= 1  d= -1  e= -1
round函数结果:a= 2  b= -2  c= 1  d= -2  e= -1
floor函数结果:a= 1  b= -2  c= 1  d= -2  e= -2

其他数值类型包括分数、pi、随机数和复数等,抱歉复数的知识我差不多搞忘了,这些也不太常用,简单看一下(5_other number.py):

## 导入分数、数学和随机模块
from fractions import *
import math
import random
##定义分数与分数运算
x = Fraction(1, 3)
y = Fraction(2, 3)
z = x * y
print('z=',z)
##三角函数,随机数等
a = math.pi/2
b = random.random()
c = random.choice([5,3,6,1])
print('a=',a,' b=',b,' c=',c)
##复数为实数部分和虚数部分构成,real + imag(J/j后缀),是j不是i
aComplex = 3 + 2j
bComplex = 3 + 2j
cComplex = aComplex*bComplex
print('cComplex=',cComplex)


>>> ====================== RESTART========================
z= 2
a= 1.5707963267948966  b= 0.9468646011445573  c= 1
cComplex= (5+12j)

2.2 字符串型数据
字符串是用来记录文本信息的一系列字符的集合,需要注意的是,定义一个字符串时,必须用''单引号将其引起来,这是Python用来区分字符串与数值和变量名的。字符串严格意义上来说与数值无法相互操作或转换,但在Python中也允许将字符串与整数相乘,将纯数字的字符串转换为数值,这也是许多老派程序员不喜欢Python 的地方。在Shell中来看下面的例子。

>>> a = 'love'
>>> b = 4
>>> a + b
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    a + b
TypeError: Can't convert 'int' object to str implicitly
>>> a * b
'lovelovelovelove'
>>> c = '1.45'
>>> c + b
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    c + b
TypeError: Can't convert 'int' object to str implicitly
>>> float(c)+b
5.45
字符串的基本操作如下:
&#8226;     len()函数取得字符串的长度
&#8226;     str[x]:x为正时,用来取得该字符串中的第x+1个字符,x从0开始计数,x为负时,用来取得该字符串中的倒数第/x/个字符,x从-1开始计数
&#8226;     str[x:y]:通过一个切片取值(都为负值时较大值在右边)
&#8226;     max()和min()找到ASCII编码中字符串中的最大字符和最小字符
&#8226;     str.index()找到某字符的索引位置,为str[x]的反向操作
&#8226;     str.count()统计某个字符出现的次数
例如(6_string.py):
city = 'Chongqing'
##len()函数取得字符串的长度
print(len(city))
##str[x]:x为正时,用来取得该字符串中的第x+1个字符,x从0开始计数
##x为负时,用来取得该字符串中的倒数第/x/个字符,x从-1开始计数
print(city[0],city[5])
print(city[-1],city[-3])
##str[x:y]:通过一个切片取值,负值时较大值在右边
print(city[0:5])
print(city[-3:-1])
##max()和min()找到ASCII编码中字符串中的最大字符和最小字符
print(min(city))
print(max(city))
##str.index()找到某字符的索引位置,为str[x]的反向操作
print(city.index('n'))
##str.count()统计某个字符出现的次数
print(city.count('g'))
>>> ================ RESTART===================
9
C q
g i
Chong
in
C
q
3
2

2.3 布尔类型
布尔是一种逻辑数据,它只有真(True )和假(False )两种原始类型,布尔数据来源于逻辑代数这一同属于逻辑学和数学分支的学科,我们目前使用的计算机的一切运算便是基于布尔值之间的五种基本运算(与、或、非、与非、或非),(未来可能出现的量子计算机则是基于量子理论,到时候必然有全新的编程语言和算法逻辑出现,朋友们以后也一定要跟上时代步伐)。
绝大部分程序语言用True和非零来代表真,用False和0来代表假, 在Python中也是如此,注意首字母大写,例如可以用While 1或While True来表达一个恒为真的条件,用While 0或While False来表达一个恒为假的条件。
while 1:
  print('True')
  break
while 0:
  print('False')
  break
>>> ==================== RESTART===================
>>>
True
>>>

在Python中对于布尔值的相互运算有and、or、not三种基本运算符号,分别代表与,或,非,高中数学应该学过,当两个条件同为True时,使用and运算返回True,其他情况返回False,不多介绍,请在Shell中尝试一下:
>>> True and True
True
>>> True and False
False
>>> True or False
True
>>> False or False
False
>>> not True
False
>>> not (True and False)
True
数值类型和字符串类型的对比也将返回布尔值;布尔在编程语言中通常用来判断某一条件是否成立,如果成立则执行相应的代码,如果不成立则执行另外的代码。请看下面例子(7_bool.py):
x = 12.4
y = 12.3
##符号'=='用于判断两个数是否相等,这条语句的result=False,注意和赋值符号=的区别,这里用的两个"="
print(x==y)
##这条语句的result = True
x= 12.3
print(x == y)
##符号'!='用于判断两个数是否不相等,这条语句的result=False
print(x != y)
a = 12
b = 14
##符号'>='用于判断a是否大于等于b,这条语句的result=False
print(a >= b)
##符号'<='用于判断a是否小于等于b,这条语句的result=True
print(a <= b)
##符号'>'用于判断a是否大于b,这条语句的result=False
print(a > b)
##符号'<'用于判断a是否小于b,这条语句的result=True
print(a < b)
##也可以对两个字符串进行大小的判断,判断的依据是该字符串首字母在ASCII码的位置靠前靠后
a= 'aaa'
b= 'bbb'
print(a > b)
print(a < b)
>>> ================================ RESTART================================
>>>
False
True
False
False
True
False
True
False
True
>>>
Python中的布尔值True和False也可以直接当作1和0进行数值运算,当然这是所有程序员都不推荐使用的,这会导致代码混乱和理解混乱。
>>> True*True
1
>>> (True+True)**10
1024
>>> True/True
1.0
>>> True+3
4
>>> False *1000
0
>>> False / 5
0.0
>>> True/False
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    True/False
ZeroDivisionError: division by zero

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

发表于 2014-8-20 16:17:43 | 显示全部楼层
果然大师级
回复 支持 反对

使用道具 举报

发表于 2014-8-21 05:49:22 | 显示全部楼层
多谢,已收藏
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们|网站地图|BIM|rhino3d ( 沪ICP备19001822号-2 )

GMT+8, 2024-4-17 04:28 , Processed in 0.064844 second(s), 25 queries .