基于osg的python三维程序开发------几何形体及纹理
Posted 小阳明
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于osg的python三维程序开发------几何形体及纹理相关的知识,希望对你有一定的参考价值。
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))#记住, 一定要改成最低维数为3的array 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]) #记住, 一定要改成最低维度为3的array
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])#记住, 一定要改成最低维度为3的array
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]) #记住, 一定要改成最低维度为3的array
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]) #记住, 一定要改成最低维度为3的array
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]) #记住, 一定要改成最低维度为3的array
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]) #记住, 一定要改成最低维度为3的array
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
上面这个函数从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, 省掉了中间的类名或空间名。
下面还是以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
以上是关于基于osg的python三维程序开发------几何形体及纹理的主要内容,如果未能解决你的问题,请参考以下文章