def read_vector4(io_stream): vec = Vector((0, 0, 0, 0)) vec.x = read_float(io_stream) vec.y = read_float(io_stream) vec.z = read_float(io_stream) vec.w = read_float(io_stream) return vec
def calculate_tangent_space(vertex, uv_layer): vertex_tangent = Vector((0.0, 0.0, 0.0, 0.0)) vertex_bitangent = Vector((0.0, 0.0, 0.0, 0.0)) # Accumulate faceted tangents for i in range(len(vertex.link_faces)): face = vertex.link_faces[i] position0 = face.loops[0].vert.co position1 = face.loops[1].vert.co position2 = face.loops[2].vert.co uv0 = face.loops[0][uv_layer].uv uv1 = face.loops[1][uv_layer].uv uv2 = face.loops[2][uv_layer].uv position_edge1 = position1 - position0 position_edge2 = position2 - position0 uv_edge1 = uv1 - uv0 uv_edge2 = uv2 - uv0 inverseDet = uv_edge1.x * uv_edge2.y - uv_edge1.y * uv_edge2.x if inverseDet != 0.0: inverseDet = 1.0 / inverseDet vertex_tangent.xyz += (position_edge1 * uv_edge2.y - position_edge2 * uv_edge1.y) * inverseDet vertex_bitangent.xyz += (position_edge2 * uv_edge1.x - position_edge1 * uv_edge2.x) * inverseDet # Gram-Schmidt orthogonalize n = vertex.normal t = vertex_tangent.xyz.copy() b = vertex_bitangent.xyz.copy() n_dot_t = n.dot(t) vertex_tangent.xyz = (t - n * n_dot_t).normalized() vertex_bitangent.xyz = (b - n * n_dot_t).normalized() handedness = -1.0 if (n.cross(t).dot(b) < 0.0) else 1.0 vertex_tangent.w = handedness vertex_bitangent.w = handedness return (vertex_tangent, vertex_bitangent)
def resize_primary_brush(self, radius): context = bpy.context primary_brush = self.primary_brush region_height = context.region.height region_width = context.region.width # Determine the world space radius of the primary brush necessary to # project a circle onto the view plane with the specified region space # radius. # Determine the z-depth of the primary brush's center in normalized # device coordinates. projection_matrix = context.region_data.perspective_matrix co = primary_brush.center.copy() co.resize(4) co.w = 1 co.xyzw = projection_matrix * co w = co.w co.xyz /= w NDC_z_depth = co.z # Determine the region space coordinates of the primary brush's center. region_x = (co.x + 1) * region_width / 2 region_y = (co.y + 1) * region_height / 2 # Determine the NDC coordinates of a point on the edge of the # circle that should result from projecting the brush onto the view # plane. co = Vector((region_x, region_y)) + Vector((radius, 0)) co.x = co.x * 2 / region_width - 1 co.y = co.y * 2 / region_height - 1 co.resize(3) co.z = NDC_z_depth # Calculate the world space radius of the primary brush. co.resize(4) co.w = 1 co.xyzw = projection_matrix.inverted() * co w = co.w co.resize(3) co.xyz /= w primary_brush.radius = (co - primary_brush.center).length
def discard_outside_of_view(self, view): # Assume that the mesh object's bounding box is fully contained in the # view projection, and test this assumption. bounding_box = mesh_object.bound_box bounding_box_contained_in_projection = True # Transform the coordinates of each vertex of the bounding box from # object space to clip space. As soon as any single vertex is # found to be outside of the view projection, duly indicate, and exit # the loop. projection_matrix = view.projection_matrix for vertex in bounding_box: co = Vector(vertex) co.resize(4) co.w = 1 co.xyzw = projection_matrix * co w = co.w # Determine if the coordinates are within the view projection. if abs(co.x) > w or\ abs(co.y) > w or\ abs(co.z) > w: bounding_box_contained_in_projection = False break # If the bounding box is not entirely contained within the view # projection then some vertices may exist outside of the view # projection. if not bounding_box_contained_in_projection: clip_space_map = self.coordinate_map # Retain each clip space vertex that is inside of the view # projection. indices = self.indices self.indices = [ index for index in indices if abs(clip_space_map[index].x) < clip_space_map[index].w and\ abs(clip_space_map[index].y) < clip_space_map[index].w and\ abs(clip_space_map[index].z) < clip_space_map[index].w ]
def stroke(self, region_x, region_y): props = self.props brushes = props.brushes derived_brushes = brushes.derived_brushes primary_brush = brushes.primary_brush active_object = bpy.context.active_object indices_affected_by_stroke = self.indices_affected_by_stroke vertices = active_object.data.vertices # The primary brush must be on the mesh in order to execute a stroke. if not primary_brush.is_on_mesh: return # Only proceed if at least one vertex is affected by the stroke. if not indices_affected_by_stroke: return # Determine the terminal position of the stroke in world space # coordinates. inverted_perspective_matrix =\ bpy.context.region_data.perspective_matrix.inverted() co = Vector((region_x, region_y)) co.x = co.x * 2 / bpy.context.region.width - 1 co.y = co.y * 2 / bpy.context.region.height - 1 co.resize(4) co.z = self.stroke_z_depth co.w = 1 co = inverted_perspective_matrix @ co w = co.w co.resize(3) co /= w stroke_terminal_co = co # Apply the stroke to each brush. inverted_model_matrix = active_object.matrix_world.inverted() for brush in [primary_brush] + brushes.derived_brushes: # Determine the displaced position of the brush caused by the # stroke. displaced_brush_center =\ brush.transformation_matrix @ stroke_terminal_co # Calculate an object space displacement vector between the brush's # original position and its displaced position. object_space_displacement = ( inverted_model_matrix @ displaced_brush_center - inverted_model_matrix @ brush.center ) # Move the brush to its displaced position. brush.center = displaced_brush_center # Add the displacement vector to the coordinates of the brush's # affected vertices, taking into account brush falloff. falloff_map = brush.falloff_map for index in brush.indices: vertices[index].co +=\ falloff_map[index] * object_space_displacement # Constrain the vertices to the specified target, if necessary. if self.target: surface_constraint_props = self.surface_constraint_props apply_shrinkwrap( offset = self.offset, target = self.target, wrap_method = surface_constraint_props.wrap_method_map[ surface_constraint_props.direction ], affected_indices = list(indices_affected_by_stroke) ) # Update the octree's coordinate map. model_matrix = active_object.matrix_world world_space_submap = { index : model_matrix @ vertices[index].co for index in indices_affected_by_stroke } self.props.octree.coordinate_map.update(world_space_submap)
def main(filename): sce = bpy.context.scene obs = sce.objects dfaces = {} f = open(filename, 'w') f.write('<?xml version="1.0" encoding="utf-8"?>\n<scene>\n\t<directionalLight>\n\t\t<color r="255" g="255" b="255"/>\n\t\t<direction x="-1" y="-1" z="-1"/>\n\t</directionalLight>\n\t<ambientLight>\n\t\t<color r="255" g="255" b="255"/>\n\t</ambientLight>\n') for ob in obs: if ob.type == 'CAMERA': camz = Vector().to_4d() camy = Vector().to_4d() camy.y = 1 camy.w = 0 camz.z = -10 #camz.w = 0 target = ob.matrix_world * camz normal = ob.matrix_world*camy f.write('\t<camera>\n') f.write('\t\t<position x="%f" y="%f" z="%f"/>\n' %(ob.location.x, ob.location.y, ob.location.z)) f.write('\t\t<target x="%f" y="%f" z="%f"/>\n' %(target.x, target.y, target.z)) f.write('\t\t<normal x="%f" y="%f" z="%f"/>' % (normal.x, normal.y, normal.z)) f.write('\n\t\t<viewplane w="16/2" h="9/2" d="%f"/>\n\t</camera>\n' %(ob.data.lens/4)) if ob.type == 'MESH': dfaces = {} mesh = ob.data verts = mesh.vertices ob_mat = ob.matrix_world scale = Matrix() scale[0][0] = ob.scale.x scale[1][1] = ob.scale.y scale[2][2] = ob.scale.z verts = [ob_mat * scale * vert.co.to_4d() for vert in verts] faces = mesh.polygons for face in faces: material = Material() if len(ob.material_slots) > 0: #print("index", face.material_index) mat = ob.material_slots[face.material_index].material if mat.use_vertex_color_paint: material.color = mesh.vertex_colors[0].data[face.index].color1 else: material.color = mat.diffuse_color if mat.use_transparency: material.transparency= mat.raytrace_transparency.fresnel_factor if mat.use_raytrace: material.reflexivity = mat.raytrace_mirror.reflect_factor material.ambiant = mat.ambient material.diffuse = mat.diffuse_intensity material.specular = mat.specular_intensity material.shininess = mat.specular_hardness if not material in dfaces: dfaces[material] = [] dfaces[material].append(face) for material in dfaces: f.write("\t<object>\n") f.write('\t\t<shape>\n') f.write('\t\t\t<list>\n') for face in dfaces[material]: vs = face.vertices if len(vs)==3: writeTriangle(f, mesh.vertices, verts, vs, material) elif len(vs)==4: vs1 = vs[:3] vs2 = [vs[0],vs[2], vs[3]] writeTriangle(f, mesh.vertices, verts, vs1, material) writeTriangle(f, mesh.vertices, verts, vs2, material) else: print("Pas de face") f.write('\t\t\t</list>\n') f.write('\t\t</shape>\n') f.write('\t\t<material>\n\t\t\t<phong>\n') f.write('\t\t\t\t<color r="%d" g="%d" b="%d"/>\n' % (int(255*material.color.r), int(255*material.color.g), int(255*material.color.b))) f.write('\t\t\t\t<specular v="%f"/>\n' % (material.specular)) f.write('\t\t\t\t<diffuse v="%f"/>\n' % (material.diffuse)) f.write('\t\t\t\t<ambiant v="%f"/>\n' % (material.ambiant)) f.write('\t\t\t\t<shininess v="%f"/>\n' % (material.shininess)) f.write('\t\t\t\t<reflexivity v="%f"/>\n' % (material.reflexivity)) f.write('\t\t\t\t<transparency v="%f"/>\n' % (material.transparency)) f.write('\t\t\t</phong>\n\t\t</material>\n') f.write("\t</object>\n") f.write("</scene>") f.close() print ("\nExport to PRay xml completed.") return {'FINISHED'}
def stroke(self, region_x, region_y): props = self.props brushes = props.brushes derived_brushes = brushes.derived_brushes primary_brush = brushes.primary_brush active_object = bpy.context.active_object indices_affected_by_stroke = self.indices_affected_by_stroke vertices = active_object.data.vertices # The primary brush must be on the mesh in order to execute a stroke. if not primary_brush.is_on_mesh: return # Only proceed if at least one vertex is affected by the stroke. if not indices_affected_by_stroke: return # Determine the terminal position of the stroke in world space # coordinates. inverted_perspective_matrix =\ bpy.context.region_data.perspective_matrix.inverted() co = Vector((region_x, region_y)) co.x = co.x * 2 / bpy.context.region.width - 1 co.y = co.y * 2 / bpy.context.region.height - 1 co.resize(4) co.z = self.stroke_z_depth co.w = 1 co = inverted_perspective_matrix * co w = co.w co.resize(3) co /= w stroke_terminal_co = co # Apply the stroke to each brush. inverted_model_matrix = active_object.matrix_world.inverted() for brush in [primary_brush] + brushes.derived_brushes: # Determine the displaced position of the brush caused by the # stroke. displaced_brush_center =\ brush.transformation_matrix * stroke_terminal_co # Calculate an object space displacement vector between the brush's # original position and its displaced position. object_space_displacement = ( inverted_model_matrix * displaced_brush_center - inverted_model_matrix * brush.center ) # Move the brush to its displaced position. brush.center = displaced_brush_center # Add the displacement vector to the coordinates of the brush's # affected vertices, taking into account brush falloff. falloff_map = brush.falloff_map for index in brush.indices: vertices[index].co +=\ falloff_map[index] * object_space_displacement # Constrain the vertices to the specified target, if necessary. if self.target: surface_constraint_props = self.surface_constraint_props apply_shrinkwrap( offset = self.offset, target = self.target, wrap_method = surface_constraint_props.wrap_method_map[ surface_constraint_props.direction ], affected_indices = list(indices_affected_by_stroke) ) # Update the octree's coordinate map. model_matrix = active_object.matrix_world world_space_submap = { index : model_matrix * vertices[index].co for index in indices_affected_by_stroke } self.props.octree.coordinate_map.update(world_space_submap)