基于osg的python三维程序开发(三)------几何形体及纹理


下面这个函数从osg 3.4.0 example  目录中的osggeometry.cpp  改写而来, 它演示了几种常见几何体的创建及使用方法,其中的各个类的用法与C++版本别无二致。

值得指出的是,代码移植到PYTHON下面后,个别API接口发生了变化:

1.  各种以numpy array 为输入参数的API, 不需要指明输入数据的长度,因为numpy.ndarray的纬度,我们在python环境下都是可以得到的。

2. 用numpy array作为顶点或法向量或颜色数组时候,记得调用reshape函数重新将数据组织成合适的维度样式

3. c++中的宏改成python环境下的各种常量, 如   osg.BIND_OVERALL, 省掉了中间的类名或空间名。

 

  1 def createScene():
  2     geode = osg.Geode()
  3     pointsGeom = osg.Geometry()
  4     vertices = osg.Vec3Array()
  5     vertices.push_back((-1.02168, -2.15188e-09, 0.885735))
  6     vertices.push_back((-0.976368, -2.15188e-09, 0.832179))
  7     vertices.push_back((-0.873376, 9.18133e-09, 0.832179))
  8     vertices.push_back((-0.836299, -2.15188e-09, 0.885735))
  9     vertices.push_back((-0.790982, 9.18133e-09, 0.959889))
 10     pointsGeom.setVertexArray(vertices)
 11     colors = osg.Vec4Array()
 12     colors.push_back((1.0,1.0,0.0,1.0))
 13     geode = osg.Geode()
 14     pointsGeom.setColorArray(colors, osg.BIND_OVERALL)
 15     normals = osg.Vec3Array()
 16     normals.push_back((0.0,-1.0,0.0))
 17     pointsGeom.setNormalArray(normals, osg.BIND_OVERALL)
 18     pointsGeom.addPrimitiveSet(osg.DrawArrays(osg.POINTS,0,vertices.size()))
 19     geode.addDrawable(pointsGeom)
 20     #create LINES
 21     linesGeom = osg.Geometry()
 22     arr = np.array([-1.13704, -2.15188e-09, 0.40373,
 23                     -0.856897, -2.15188e-09, 0.531441,
 24                     -0.889855, -2.15188e-09, 0.444927,
 25                     -0.568518, -2.15188e-09, 0.40373,
 26                     -1.00933, -2.15188e-09, 0.370773,
 27                     -0.716827, -2.15188e-09, 0.292498,
 28                     -1.07936, 9.18133e-09, 0.317217,
 29                     -0.700348, 9.18133e-09, 0.362533],np.float32)
 30     arr = np.reshape(arr,(-1,3))
 31     vertices = osg.Vec3Array(arr)
 32     linesGeom.setVertexArray(vertices)
 33     colors = osg.Vec4Array()
 34     colors.push_back((1.0,1.0,0.0,1.0))
 35     linesGeom.setColorArray(colors, osg.BIND_OVERALL)
 36     normals = osg.Vec3Array()
 37     normals.push_back((0.0,-1.0,0.0))
 38     linesGeom.setNormalArray(normals, osg.BIND_OVERALL)
 39     linesGeom.addPrimitiveSet(osg.DrawArrays(osg.LINES,0,8))
 40     geode.addDrawable(linesGeom)
 41     linesGeom = osg.Geometry();  
 42     arr = np.array([-0.0741545, -2.15188e-09, 0.416089,
 43                     0.234823, -2.15188e-09, 0.259541,
 44                     0.164788, -2.15188e-09, 0.366653,
 45                     -0.0288379, -2.15188e-09, 0.333695,
 46                     -0.0453167, -2.15188e-09, 0.280139], np.float32)
 47     arr = np.reshape(arr, [-1, 3])
 48     vertices = osg.Vec3Array(arr)
 49     linesGeom.setVertexArray(vertices)
 50     colors = osg.Vec4Array()
 51     colors.push_back((1.0,1.0,0.0,1.0))
 52     linesGeom.setColorArray(colors, osg.BIND_OVERALL)
 53     normals = osg.Vec3Array()
 54     normals.push_back((0.0,-1.0,0.0))
 55     linesGeom.setNormalArray(normals, osg.BIND_OVERALL)
 56     linesGeom.addPrimitiveSet(osg.DrawArrays(osg.LINE_STRIP,0,5))
 57     geode.addDrawable(linesGeom)
 58     #create LINE_LOOP
 59     linesGeom = osg.Geometry()
 60     myCoords = np.array([0.741546, -2.15188e-09, 0.453167,
 61                         0.840418, -2.15188e-09, 0.304858,
 62                         1.12468, -2.15188e-09, 0.300738,
 63                         1.03816, 9.18133e-09, 0.453167,
 64                         0.968129, -2.15188e-09, 0.337815,
 65                         0.869256, -2.15188e-09, 0.531441],np.float32)
 66     myCoords = np.reshape(myCoords, [-1, 3])
 67     vertices = osg.Vec3Array(myCoords)
 68     linesGeom.setVertexArray(vertices)
 69     colors = osg.Vec4Array()
 70     colors.push_back((1.0,1.0,0.0,1.0))
 71     linesGeom.setColorArray(colors, osg.BIND_OVERALL)
 72     normals = osg.Vec3Array()
 73     normals.push_back((0.0,-1.0,0.0))
 74     linesGeom.setNormalArray(normals, osg.BIND_OVERALL)
 75     numCoords = myCoords.shape[0]
 76     linesGeom.addPrimitiveSet(osg.DrawArrays(osg.LINE_LOOP,0,numCoords))
 77     geode.addDrawable(linesGeom)
 78     shared_colors = osg.Vec4Array()
 79     shared_colors.push_back((1.0,1.0,0.0,1.0))
 80     shared_normals =  osg.Vec3Array()
 81     shared_normals.push_back((0.0,-1.0,0.0))
 82     # create POLYGON
 83     polyGeom = osg.Geometry()
 84     myCoords = np.array([-1.0464, 0.0, -0.193626,
 85                         -1.0258, 0.0, -0.26778,
 86                         -0.807461, 0.0, -0.181267,
 87                         -0.766264, 0.0, -0.0576758,
 88                         -0.980488, 0.0, -0.094753],np.float32)
 89     myCoords = np.reshape(myCoords, [-1, 3])
 90     numCoords = myCoords.shape[0]
 91     vertices = osg.Vec3Array(myCoords)
 92     polyGeom.setVertexArray(vertices)
 93     polyGeom.setColorArray(shared_colors, osg.BIND_OVERALL)
 94     polyGeom.setNormalArray(shared_normals, osg.BIND_OVERALL)
 95     polyGeom.addPrimitiveSet(osg.DrawArrays(osg.POLYGON,0,numCoords))
 96     geode.addDrawable(polyGeom)
 97     #create QUADS
 98     polyGeom = osg.Geometry()
 99     myCoords = np.array([0.0247182, 0.0, -0.156548,
100                         0.0247182, 0.0, -0.00823939,
101                         -0.160668, 0.0, -0.0453167,
102                         -0.222464, 0.0, -0.13183,
103                         0.238942, 0.0, -0.251302,
104                         0.333696, 0.0, 0.0329576,
105                         0.164788, 0.0, -0.0453167,
106                         0.13595,  0.0, -0.255421],np.float32)
107     myCoords = np.reshape(myCoords, [-1, 3])
108     numCoords = myCoords.shape[0] 
109     vertices = osg.Vec3Array(myCoords)
110     polyGeom.setVertexArray(vertices)
111     polyGeom.setColorArray(shared_colors, osg.BIND_OVERALL)
112     polyGeom.setNormalArray(shared_normals, osg.BIND_OVERALL)
113     polyGeom.addPrimitiveSet(osg.DrawArrays(osg.QUADS,0,numCoords))
114     geode.addDrawable(polyGeom)
115     ##create QUAD_STRIP
116     polyGeom = osg.Geometry()
117     myCoords = np.array([0.733306, -2.15188e-09, -0.0741545,
118                         0.758024, -2.15188e-09, -0.205985,
119                         0.885735, -2.15188e-09, -0.0576757,
120                         0.885735, -2.15188e-09, -0.214224,
121                         0.964009, 9.18133e-09, -0.0370773,
122                         1.0464, 9.18133e-09, -0.173027,
123                         1.11232, -2.15188e-09, 0.0123591,
124                         1.12468, 9.18133e-09, -0.164788],np.float32)
125     myCoords = np.reshape(myCoords, [-1, 3])
126     numCoords = myCoords.shape[0]
127     vertices = osg.Vec3Array(myCoords) #numpy array as input
128     polyGeom.setVertexArray(vertices)
129     polyGeom.setColorArray(shared_colors, osg.BIND_OVERALL)
130     polyGeom.setNormalArray(shared_normals, osg.BIND_OVERALL)
131     polyGeom.addPrimitiveSet(osg.DrawArrays(osg.QUAD_STRIP,0,numCoords))
132     geode.addDrawable(polyGeom)
133     ## create TRIANGLES, TRIANGLE_STRIP and TRIANGLE_FAN all in one Geometry/
134     #create Geometry object to store all the vertices and lines primitive.
135     polyGeom =  osg.Geometry()
136     myCoords = np.array([-1.12056, -2.15188e-09, -0.840418,
137                         -0.95165, -2.15188e-09, -0.840418,
138                         -1.11644, 9.18133e-09, -0.716827,
139                         -0.840418, 9.18133e-09, -0.778623,
140                         -0.622074, 9.18133e-09, -0.613835,
141                         -1.067, 9.18133e-09, -0.609715,
142                         -0.160668, -2.15188e-09, -0.531441,
143                         -0.160668, -2.15188e-09, -0.749785,
144                         0.0617955, 9.18133e-09, -0.531441,
145                         0.168908, -2.15188e-09, -0.753905,
146                         0.238942, -2.15188e-09, -0.531441,
147                         0.280139, -2.15188e-09, -0.823939,
148                         0.844538, 9.18133e-09, -0.712708,
149                         1.0258, 9.18133e-09, -0.799221,
150                         1.03816, -2.15188e-09, -0.692109,
151                         0.988727, 9.18133e-09, -0.568518,
152                         0.840418, -2.15188e-09, -0.506723], np.float32)
153       
154     myCoords = np.reshape(myCoords, [-1, 3])
155     numCoords = myCoords.shape[0]
156     vertices = osg.Vec3Array(myCoords)
157     polyGeom.setVertexArray(vertices)
158     polyGeom.setColorArray(shared_colors, osg.BIND_OVERALL)
159     polyGeom.setNormalArray(shared_normals, osg.BIND_OVERALL)
160     polyGeom.addPrimitiveSet(osg.DrawArrays(osg.TRIANGLES,0,6))
161     polyGeom.addPrimitiveSet(osg.DrawArrays(osg.TRIANGLE_STRIP,6,6))
162     polyGeom.addPrimitiveSet(osg.DrawArrays(osg.TRIANGLE_FAN,12,5))
163     # polygon stipple
164     stateSet = osg.StateSet()
165     polyGeom.setStateSet(stateSet)
166     geode.addDrawable(polyGeom)
167     return geode

 

下面还是以osggeometry中的例子,演示纹理的用法

 1 def createBackground():
 2     image = osgDB.readImageFile("./Images/primitives.gif")
 3     if (not image):
 4         return None 
 5     # create Geometry object to store all the vertices and lines primitive.
 6     polyGeom = osg.Geometry()
 7     #note, anticlockwise ordering.
 8     myCoords = np.array([1.22908,0.0,1.0,
 9                            -1.22908,0.0,-1.0,
10                            1.22908,0.0,-1.0,
11                            1.22908,0.0,1.0], np.float32)
12     myCoords = np.reshape(myCoords, [-1,3])
13     numCoords = myCoords.shape[0]
14     # pass the created vertex array to the points geometry object.
15     va = osg.Vec3Array(myCoords)
16     polyGeom.setVertexArray(va)
17     colors = osg.Vec4Array()
18     colors.push_back((1.0,1.0,1.0,1.0))
19     polyGeom.setColorArray(colors, osg.BIND_OVERALL)
20     ##set the normal in the same way color.
21     normals = osg.Vec3Array()
22     normals.push_back((0.0,-1.0,0.0))
23     polyGeom.setNormalArray(normals, osg.BIND_OVERALL)
24     myTexCoords = np.array([0,1,0,0,1,0,1,1], np.float32) 
25     myTexCoords = np.reshape(myTexCoords,[-1,2])
26     numTexCoords = myTexCoords.shape[0]
27     # pass the created tex coord array to the points geometry object,
28     # and use it to set texture unit 0.
29     # crash!!!
30     # polyGeom.setTexCoordArray(0,osg.Vec2Array(myTexCoords))
31     texArr = osg.Vec2Array(myTexCoords)
32     polyGeom.setTexCoordArray(0, texArr)
33     # well use indices and DrawElements to define the primitive this time.
34     myIndices = np.array([0, 1, 3, 2], np.int)
35     numIndices = myIndices.shape[0]
36     #There are three variants of the DrawElements osg::Primitive, UByteDrawElements which
37     #contains unsigned char indices, UShortDrawElements which contains unsigned short indices,
38     #and UIntDrawElements which contains ... unsigned int indices.
39     #The first parameter to DrawElements is
40     deus = osg.DrawElementsUShort(osg.TRIANGLE_STRIP,myIndices)
41     polyGeom.addPrimitiveSet(deus)
42     # new we need to add the texture to the Drawable, we do so by creating a
43     # StateSet to contain the Texture2D StateAttribute.
44     stateset = osg.StateSet()
45     # set up the texture.
46     texture = osg.Texture2D()
47     texture.setImage(image)
48     stateset.setTextureAttributeAndModes(0, texture,osg.ON)
49     polyGeom.setStateSet(stateset)
50     geode = osg.Geode()
51     # add the points geometry to the geode.
52     geode.addDrawable(polyGeom)
53     transform = osg.MatrixTransform()
54     nodeCb = MyTransformCallback(1.0)
55     transform.setUpdateCallback(nodeCb)
56     transform.addChild(geode)
57     return transform

主要通过image 对象及节点的StateSet属性来实现贴图。其中用到了transform 及 nodecallback 来实现简单动画,这部分内容放在下一随笔。

https://github.com/enigma19971/pyosg

posted @ 2020-03-15 10:53  小阳明  阅读(1211)  评论(0)    收藏  举报