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
Example #2
0
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)
Example #3
0
    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
            ] 
Example #5
0
    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)
Example #7
0
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'}        
Example #8
0
    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)