def transform4(matrix, shape): """ Return a shape transformed by a Matrix4. """ if matrix == None: matrix = pgl.Matrix4() scale, (a, e, r), translation = matrix.getTransformation2() if type(shape) is pgl.Cylinder and matrix != pgl.Matrix4(): #print "scale for cylinder is :", scale #print "scale.xyz = ", scale.x, scale.y, scale.z if round(scale.x, 1) == 1.0 and round(scale.y, 1) == 1.0 and round( scale.z, 1) == 1.0: shape = pgl.Translated(translation, pgl.EulerRotated(a, e, r, shape)) else: raise Exception, "Invalid transformation for cylinder!" elif type(shape) is pgl.Sphere: shape = pgl.Translated( translation, pgl.EulerRotated(a, e, r, pgl.Scaled(scale, shape))) elif type(shape) is pgl.BezierPatch: scale1 = pgl.Vector3(1, 1, 1) shape = pgl.Translated( translation, pgl.EulerRotated(a, e, r, pgl.Scaled(scale, pgl.Scaled(scale1, shape)))) else: shape = pgl.Translated( translation, pgl.EulerRotated(a, e, r, pgl.Scaled(scale, shape))) return shape
def setFromAxisAngle(x, y, z, angle): n = sqrt(x * x + y * y + z * z) n = 1 / n x *= n y *= n z *= n c = cos(angle) s = sin(angle) omc = 1.0 - c m00 = c + x * x * omc m11 = c + y * y * omc m22 = c + z * z * omc tmp1 = x * y * omc tmp2 = z * s m01 = tmp1 - tmp2 m10 = tmp1 + tmp2 tmp1 = x * z * omc tmp2 = y * s m02 = tmp1 + tmp2 m20 = tmp1 - tmp2 tmp1 = y * z * omc tmp2 = x * s m12 = tmp1 - tmp2 m21 = tmp1 + tmp2 m03 = m13 = m23 = m30 = m31 = m32 = 0 m33 = 1 vec1 = Vector4(m00, m10, m20, m30) vec2 = Vector4(m01, m11, m21, m31) vec3 = Vector4(m02, m12, m22, m32) vec4 = Vector4(m03, m13, m23, m33) return pgl.Matrix4(vec1, vec2, vec3, vec4)
def Scale(self, scaleX=0., scaleY=0., scaleZ=0., **kwds): # TODO: put the code in geometry sx = float(scaleX) sy = float(scaleY) sz = float(scaleZ) matrix = pgl.Matrix3.scaling(Vector3(sx, sy, sz)) return (None, pgl.Matrix4(matrix))
def transform(self, elements, **kwds): # TODO: put the code in geometry matrix = elements[0] assert matrix.tag == 'matrix' m4 = map(float, matrix.text.strip().split()) m4 = pgl.Matrix4(m4[:4], m4[4:8], m4[8:12], m4[12:]) m4 = m4.transpose() return m4
def old_transform4(matrix, shape): """ Return a shape transformed by a Matrix4. """ if matrix == None: matrix = pgl.Matrix4() scale, (a, e, r), translation = matrix.getTransformation2() shape = pgl.Translated(translation, pgl.Scaled(scale, pgl.EulerRotated(a, e, r, shape))) return shape
def Rotate(self, rotateX=0., rotateY=0., rotateZ=0., **kwds): # TODO: put the code in geometry rx = radians(float(rotateX)) ry = radians(float(rotateY)) rz = radians(float(rotateZ)) mx = pgl.Matrix3.axisRotation(Vector3(1, 0, 0), rx) my = pgl.Matrix3.axisRotation(Vector3(0, 1, 0), ry) mz = pgl.Matrix3.axisRotation(Vector3(0, 0, 1), rz) matrix = mx * my * mz return (None, pgl.Matrix4(matrix))
def grotation(self, strength): """ Doc """ m = self.m t = m.getColumn(2) v0 = t.x v1 = t.y v2 = t.z q = 1 / sqrt(t.x * t.x + t.y * t.y + t.z * t.z) v0 *= q v1 *= q v2 *= q v02 = v0 * v0 v12 = v1 * v1 q = v02 + v12 m00 = m11 = m22 = m10 = m20 = m01 = m21 = m02 = m12 = 0 local_m = 0 if (q < 1e-10) or (v2 * v2 > 0.99999): if v2 * (v2 - strength) < 0: m00 = m.getRow(0).x m10 = -m.getRow(1).x m20 = -m.getRow(2).x m01 = m.getRow(0).y m11 = -m.getRow(1).y m21 = -m.getRow(2).y m02 = m.getRow(0).z m12 = -m.getRow(1).z m22 = -m.getRow(2).z else: m00 = m11 = m22 = 1 m10 = m20 = m01 = m21 = m02 = m12 = 0 else: n = 1 / sqrt(1 - 2 * strength * v2 + strength * strength) m22 = (1 - strength * v2) * n m02 = strength * v0 * n m20 = -m02 m12 = strength * v1 * n m21 = -m12 q = 1 / q m00 = (v12 + v02 * m22) * q m11 = (v02 + v12 * m22) * q m01 = m10 = v0 * v1 * (m22 - 1) * q vec1 = Vector4(m00, m10, m20, 0) vec2 = Vector4(m01, m11, m21, 0) vec3 = Vector4(m02, m12, m22, 0) vec4 = Vector4(0, 0, 0, 1) local_m = pgl.Matrix4(vec1, vec2, vec3, vec4) return local_m
def directionalTropism(m, direction, strength): t = m.getColumn(2) x = direction[2] * t.y - direction[1] * t.z y = direction[0] * t.z - direction[2] * t.x z = direction[1] * t.x - direction[0] * t.y vec3 = Vector3(x, y, z) angle = strength * sqrt((x * x + y * y + z * z) / (t.x * t.x + t.y * t.y + t.z * t.z)) if (angle * angle) >= 1e-20: vec3 = invTransformVector(m, vec3) return setFromAxisAngle(vec3.x, vec3.y, vec3.z, angle) else: vec1 = Vector4(1, 0, 0, 0) vec2 = Vector4(0, 1, 0, 0) vec3 = Vector4(0, 0, 1, 0) vec4 = Vector4(0, 0, 0, 1) return pgl.Matrix4(vec1, vec2, vec3, vec4)
def setFinalGeometry(self): # traverse the graph g = self._graph #if self._scene: #return self._scene #else: #self._scene = pgl.Scene() self.visited = set() self._graph.add_vertex_property('final_geometry') #final_geometry = g.vertex_property("final_geometry") transfos = [pgl.Matrix4()] self.traverse2(g.root)
def BezierSurface(self, uCount, data, dimension, **kwds): points = str(data) dimension = int(dimension) points = [float(num) for num in points.split(",")] items, chunk = points, dimension pdlist = zip(*[iter(items)] * chunk) p4m = pgl.Point4Matrix(dimension, dimension) its, pice = pdlist, 4 pdmrlst = zip(*[iter(its)] * pice) for i in range(len(pdmrlst)): for j in range(len(pdmrlst[i])): p4m.__setitem__((i, j), pdmrlst[i][j]) return (pgl.BezierPatch(p4m), pgl.Matrix4())
def scenegraph(self): # traverse the graph g = self._graph if self._scene: return self._scene else: self._scene = pgl.Scene() self.visited = set() self._graph.add_vertex_property('final_geometry') final_geometry = g.vertex_property("final_geometry") transfos = [pgl.Matrix4()] self.traverse2(g.root) self._scene.merge(pgl.Scene(final_geometry.values())) return self._scene
def ShadedNull(self, transform, **kwds): print "pass null in" transform = str(transform) transform = [float(num) for num in transform.split(",")] items, chunk = transform, 4 m4rlist = zip(*[iter(items)] * chunk) m4 = pgl.Matrix4() for i in range(len(m4rlist)): for j in range(len(m4rlist[i])): m4.__setitem__((i,j),m4rlist[i][j]) #self._current_turtle.color = self.color(color) print "pass null out" return (None, m4)
def Transfo(self, objmap): import openalea.plantgl.all as pgl import math m = pgl.Matrix4() print(self.attributes) def fixtransfoname(t): if t == 'Scale' : return 'Scaling' else : return t for t,p in list(self.attributes.items()): print('*',t,p) if t == 'EulerRotation': p = parse_attributes(p, {}) p = (p.get('Elevation',0.),p.get('Azimuth',0.),p.get('Roll',0.)) p = [math.radians(float(v)) for v in p] transf = pgl.EulerRotation(*p) else: transf = pgl.__dict__[fixtransfoname(t)]( p) m *= transf.getMatrix() return pgl.Transform4(m)
def positionalTropism(m, target, strength): x = target[0] - m.getRow(0).w y = target[1] - m.getRow(1).w z = target[2] - m.getRow(2).w l = x * x + y * y + z * z t = m.getColumn(2) if l > 0: xv = z * t.y - y * t.z yv = x * t.z - z * t.x zv = y * t.x - x * t.y vec3 = Vector3(xv, yv, zv) angle = strength * sqrt((xv * xv + yv * yv + zv * zv) / (l * (t.x * t.x + t.y * t.y + t.z * t.z))) if (angle * angle) >= 1e-20: invTransformVector(m, vec3) return setFromAxisAngle(vec3.x, vec3.y, vec3.z, angle) else: vec1 = Vector4(1, 0, 0, 0) vec2 = Vector4(0, 1, 0, 0) vec3 = Vector4(0, 0, 1, 0) vec4 = Vector4(0, 0, 0, 1) return pgl.Matrix4(vec1, vec2, vec3, vec4)
def RH(self, angle, **kwds): # Rotation around the z axis angle = radians(float(angle)) matrix = pgl.Matrix3.axisRotation(Vector3(0, 0, 1), angle) return (None, pgl.Matrix4(matrix))
def RU(self, angle, **kwds): # Rotation around negative y axis <-- NO, Wrong idea angle = radians(float(angle)) matrix = pgl.Matrix3.axisRotation(Vector3(0, 1, 0), angle) return (None, pgl.Matrix4(matrix))
def traverse2(self, vid): from openalea.container.traversal.graph import breadth_first_search g = self._graph edge_type = g.edge_property("edge_type") transform = g.vertex_property("transform") local_turtles = g.vertex_property("turtle_state") transfos = {g.root: pgl.Matrix4()} # CPL turtles = {g.root: TurtleState()} def parent(vid): for eid in g.in_edges(vid): if edge_type[eid] in ['<', '+', '/']: return g.source(eid) return vid def update_turtle(v, ts): local_turtle = local_turtles.get(v, TurtleState()) global_turtle = ts.combine(local_turtle) return global_turtle for v in breadth_first_search(g, vid): pid = parent(v) if pid == v and v != g.root: print "ERRRORRRR" print v continue # print "v",v # print "parent(v)", parent(v) # print "transfos", transfos #m = transfos[parent(v)] m = transfos.get(pid) # CPL ts = turtles.get(pid, TurtleState()) gt = global_turtle = update_turtle(v, ts) local_t = transform.get(v) if local_t == self.FUNCTIONAL: # Get the functional shape to compute the transformation and geometry # with the turtle state local_t = self.f_shape(v, global_turtle) # print "every m : ", m # Transform the current shape with the stack of transfos m from the root. # Store the result in the graph. self._local2global(v, m, global_turtle.color) # print "local_t : ", local_t if local_t == -1: m = adjust_lu(m) elif local_t == -2: #RV and RG local_m = grotation(m, gt.tropism) m = m * local_m elif local_t == -3: # RD local_m = directionalTropism(m, gt.tropism_direction, gt.tropism) m = m * local_m elif local_t == -4: # RO local_m = orthogonalTropism(m, gt.tropism_direction, gt.tropism) m = m * local_m elif local_t == -5: #RP and RN local_m = positionalTropism(m, gt.tropism_target, gt.tropism) m = m * local_m elif local_t: if local_t.getColumn(3) != Vector4(0, 0, 0, 1): m = m * local_t else: m = m * local_t else: # print m pass transfos[v] = m turtles[v] = global_turtle
def test_matrix(): t = pgl.Matrix4() jsonconversion(t)