def correct_bone_positions(bones):

    for dest_name, end, root_name, root_end, axis in bones_to_correct_spine_position:
        root_bone = bones.get(root_name)
        root = Vector(getattr(root_bone, root_end))
        dest = bones.get(dest_name)
        dest_head = Vector(dest.head)
        dest_tail = Vector(dest.tail)
        if end == "head":
            setattr(dest_head, axis, getattr(root, axis))
            dest.head = dest_head
        elif end == "tail":
            print("set tail")
            setattr(dest_tail, axis, getattr(root, axis))
            dest.tail = dest_tail

    # now do toes
    leftToe = bones.get("LeftToeBase")
    leftToeHead = Vector(leftToe.head)
    leftToeTail = Vector(leftToe.tail)
    leftToeTail.x = leftToeHead.x
    leftToeTail.z = leftToeHead.z
    leftToe.tail = leftToeTail

    rightToe = bones.get("RightToeBase")
    rightToeHead = Vector(rightToe.head)
    rightToeTail = Vector(rightToe.tail)
    rightToeTail.x = rightToeHead.x
    rightToeTail.z = rightToeHead.z
    rightToe.tail = rightToeTail
Beispiel #2
0
def getBoundingBox(scene):
  minimum = Vector() 
  maximum = Vector()

  for obj in scene.objects:
    if obj.type == 'MESH':
      bbox_corners = [obj.matrix_world * Vector(corner) for corner in obj.bound_box]

      for v in bbox_corners:
        if v.x < minimum.x:
          minimum.x = v.x
        if v.y < minimum.y:
          minimum.y = v.y
        if v.z < minimum.z:
          minimum.z = v.z
        if v.x > maximum.x:
          maximum.x = v.x
        if v.y > maximum.y:
          maximum.y = v.y
        if v.z > maximum.z:
          maximum.z = v.z

  return  {
    "minimum" : { "x" : minimum.x, "y" : minimum.y, "z" : minimum.z },
    "maximum" : { "x" : maximum.x, "y" : maximum.y, "z" : maximum.z }
  }
Beispiel #3
0
def combine_bounds(bounds: Iterable[BoundsDataStruct_YK1]) -> BoundsDataStruct_YK1:
    # min_pos = None
    # max_pos = None
    min_pos = Vector((-1000, -1000, -1000))
    max_pos = Vector((+1000, +1000, +1000))

    for bound in bounds:
        min_for_bound = bound.center - bound.box_extents
        max_for_bound = bound.center - bound.box_extents

        if min_pos is None:
            min_pos = min_for_bound
            max_pos = max_for_bound
        else:
            min_pos.x = min(min_for_bound.x, min_pos.x)
            min_pos.y = min(min_for_bound.y, min_pos.y)
            min_pos.z = min(min_for_bound.z, min_pos.z)

            max_pos.x = max(max_for_bound.x, max_pos.x)
            max_pos.y = max(max_for_bound.y, max_pos.y)
            max_pos.z = max(max_for_bound.z, max_pos.z)

    # TODO - This is for the sake of hierarchy objects which have no meshes themselves, but presumably have children with meshes.
    # Will these BBOXes need to be calculated with those other ones in mind?
    # Will these BBOXes need to be calculated with object position in mind?
    # if min_pos is None:
    #     min_pos = Vector((0, 0, 0, 0))
    #     max_pos = Vector((0, 0, 0, 0))

    return bounds_from_minmax(min_pos, max_pos)
    def calcAlign(self, localArea):
        alnVec = Vector([0, 0, 0])
        if len(localArea) == 0:
            return alnVec
        agents = self.sim.agents
        for neighbour in localArea:
            alnVec.x += agents[neighbour].arx
            alnVec.y += agents[neighbour].ary
            alnVec.z += agents[neighbour].arz
        alnVec /= len(localArea)

        alnVec.x -= agents[self.userid].arx
        alnVec.y -= agents[self.userid].ary
        alnVec.z -= agents[self.userid].arz

        alnVec.x %= 2 * math.pi
        alnVec.y %= 2 * math.pi
        alnVec.z %= 2 * math.pi

        if alnVec.x < math.pi:
            alnVec.x = alnVec.x / math.pi
        else:
            alnVec.x = -2 + alnVec.x / math.pi
        if alnVec.y < math.pi:
            alnVec.y = alnVec.y / math.pi
        else:
            alnVec.y = -2 + alnVec.y / math.pi
        if alnVec.z < math.pi:
            alnVec.z = alnVec.z / math.pi
        else:
            alnVec.z = -2 + alnVec.z / math.pi
        return alnVec
Beispiel #5
0
    def calcAlign(self, localArea):
        alnVec = Vector([0, 0, 0])
        if len(localArea) == 0:
            return alnVec
        agents = self.sim.agents
        for neighbour in localArea:
            alnVec.x += agents[neighbour].arx
            alnVec.y += agents[neighbour].ary
            alnVec.z += agents[neighbour].arz
        alnVec /= len(localArea)

        alnVec.x -= agents[self.userid].arx
        alnVec.y -= agents[self.userid].ary
        alnVec.z -= agents[self.userid].arz

        alnVec.x %= 2*math.pi
        alnVec.y %= 2*math.pi
        alnVec.z %= 2*math.pi

        if alnVec.x < math.pi:
            alnVec.x = alnVec.x/math.pi
        else:
            alnVec.x = -2 + alnVec.x/math.pi
        if alnVec.y < math.pi:
            alnVec.y = alnVec.y/math.pi
        else:
            alnVec.y = -2 + alnVec.y/math.pi
        if alnVec.z < math.pi:
            alnVec.z = alnVec.z/math.pi
        else:
            alnVec.z = -2 + alnVec.z/math.pi
        return alnVec
Beispiel #6
0
def getBoundsBF(obj):
    """ brute force method for obtaining object bounding box """
    # initialize min and max
    min = Vector((math.inf, math.inf, math.inf))
    max = Vector((-math.inf, -math.inf, -math.inf))
    # calculate min and max verts
    for v in obj.data.vertices:
        if v.co.x > max.x:
            max.x = v.co.x
        elif v.co.x < min.x:
            min.x = v.co.x
        if v.co.y > max.y:
            max.y = v.co.y
        elif v.co.y < min.y:
            min.y = v.co.y
        if v.co.z > max.z:
            max.z = v.co.z
        elif v.co.z < min.z:
            min.z = v.co.z
    # set up bounding box list of coord lists
    bound_box = [list(min),
                 [min.x, min.y, min.z],
                 [min.x, min.y, max.z],
                 [min.x, max.y, max.z],
                 [min.x, max.y, min.z],
                 [max.x, min.y, min.z],
                 [max.y, min.y, max.z],
                 list(max),
                 [max.x, max.y, min.z]]
    return bound_box
Beispiel #7
0
def readPackedVector(f, format):
    packed = f

    output = Vector()
    if format == 'XZY':
        output.x = packed
        output.y = packed / 65536.0
        output.z = packed / 256.0
    elif format == 'ZXY':
        output.x = packed / 256.0
        output.y = packed / 65536.0
        output.z = packed
    elif format == 'XYZ':
        output.x = packed
        output.y = packed / 256.0
        output.z = packed / 65536.0

    output.x -= math.floor(output.x)
    output.y -= math.floor(output.y)
    output.z -= math.floor(output.z)

    output.x = output.x*2 - 1
    output.y = output.y*2 - 1
    output.z = output.z*2 - 1

    return output
Beispiel #8
0
def getBoundsBF(obj:Object):
    """ brute force method for obtaining object bounding box """
    # initialize min and max
    min = Vector((math.inf, math.inf, math.inf))
    max = Vector((-math.inf, -math.inf, -math.inf))
    # calculate min and max verts
    for v in obj.data.vertices:
        if v.co.x > max.x:
            max.x = v.co.x
        elif v.co.x < min.x:
            min.x = v.co.x
        if v.co.y > max.y:
            max.y = v.co.y
        elif v.co.y < min.y:
            min.y = v.co.y
        if v.co.z > max.z:
            max.z = v.co.z
        elif v.co.z < min.z:
            min.z = v.co.z
    # set up bounding box list of coord lists
    bound_box = [list(min),
                 [min.x, min.y, min.z],
                 [min.x, min.y, max.z],
                 [min.x, max.y, max.z],
                 [min.x, max.y, min.z],
                 [max.x, min.y, min.z],
                 [max.y, min.y, max.z],
                 list(max),
                 [max.x, max.y, min.z]]
    return bound_box
Beispiel #9
0
def analyzeMeshObject(obj, meshFaces):
    global DEFAULT_PART_NAME

    mesh = obj.data
    parts = []
    halfSize = obj.dimensions * 0.5
    candidParts = []
    centerOfMass = Vector((0.0, 0.0, 0.0))
    trianglesCount = 0
    meshVerticesCount = len(mesh.vertices)
    meshMaterialCount = len(mesh.materials)

    if meshMaterialCount > 0:
        # Create parts. It is important to iterate it manually 
        # so material names order is preserved.
        for i in range(meshMaterialCount):
            candidParts.append({'name': mesh.materials[i].name, 'start': 0, 'count': 0})
    else:
        # If there are no materials defined, create default part placeholder.
        candidParts.append({'name': DEFAULT_PART_NAME, 'start': 0, 'count': 0})

    for f in meshFaces:
        # Some faces can be quads - values have to doubled then.
        modifier = 2 if len(f.vertices) == 4 else 1
        candidParts[f.material_index]['count'] += 3 * modifier
        trianglesCount += 1 * modifier

    # Update part`s start attribute so they take other parts into account.
    for i in range(0, len(candidParts)):
        if i > 0:
            candidParts[i]['start'] = candidParts[i - 1]['start'] + candidParts[i - 1]['count']

    # Only export parts that have any triangles assigned.
    for p in candidParts:
        if p['count'] > 0:
            parts.append(p)

    centerMax = Vector((-9999.999, -9999.999, -9999.999))
    centerMin = Vector(( 9999.999,  9999.999,  9999.999))

    for v in mesh.vertices:
        centerMax.x = max(centerMax.x, v.co.x)
        centerMin.x = min(centerMin.x, v.co.x)
        centerMax.y = max(centerMax.y, v.co.y)
        centerMin.y = min(centerMin.y, v.co.y)
        centerMax.z = max(centerMax.z, v.co.z)
        centerMin.z = min(centerMin.z, v.co.z)

    centerOfMass.x = abs(centerMax.x) - abs(centerMin.x)
    centerOfMass.y = abs(centerMax.y) - abs(centerMin.y)
    centerOfMass.z = abs(centerMax.z) - abs(centerMin.z)

    centerOfMass *= 0.5

    return centerOfMass, halfSize, trianglesCount, parts
Beispiel #10
0
def calcBBPos(x, y, z, a1, a2, a3, type='DNA'):
    bb = Vector()
    if type is 'DNA':
        bb.x = x - (0.34 * a1.x + 0.3408 * a2.x)
        bb.y = y - (0.34 * a1.y + 0.3408 * a2.y)
        bb.z = z - (0.34 * a1.z + 0.3408 * a2.z)
    elif type is 'RNA':
        bb.x = x - (0.4 * a1.x + 0.2 * a3.x)
        bb.y = y - (0.4 * a1.y + 0.2 * a3.y)
        bb.z = z - (0.4 * a1.z + 0.2 * a3.z)
    return bb
Beispiel #11
0
def bounding_box(mesh):
    v0 = mesh.vertices[0].co
    vmin = Vector((v0.x, v0.y, v0.z))
    vmax = Vector((v0.x, v0.y, v0.z))
    for i in range(1, len(mesh.vertices)):
        v = mesh.vertices[i].co
        vmin.x = min(vmin.x, v.x)
        vmin.y = min(vmin.y, v.y)
        vmin.z = min(vmin.z, v.z)
        vmax.x = max(vmax.x, v.x)
        vmax.y = max(vmax.y, v.y)
        vmax.z = max(vmax.z, v.z)
    return vmin, vmax
Beispiel #12
0
def bounding_box(mesh):
    v0 = mesh.vertices[0].co
    vmin = Vector((v0.x, v0.y, v0.z))
    vmax = Vector((v0.x, v0.y, v0.z))
    for i in range(1, len(mesh.vertices)):
        v = mesh.vertices[i].co
        vmin.x = min(vmin.x, v.x)
        vmin.y = min(vmin.y, v.y)
        vmin.z = min(vmin.z, v.z)
        vmax.x = max(vmax.x, v.x)
        vmax.y = max(vmax.y, v.y)
        vmax.z = max(vmax.z, v.z)
    return vmin, vmax
Beispiel #13
0
    def execute(self, context):
        switchMode = False
        if context.mode != 'OBJECT':
            switchMode = True
            bpy.ops.object.mode_set(mode='OBJECT', toggle=True)

        for o in context.selected_objects:
            if o.type == "MESH":
                d = o.data
                m = o.matrix_world
                if self.center:
                    bounds_center = (sum(
                        (m @ Vector(b) for b in o.bound_box), Vector())) / 8
                    difference = m.translation - bounds_center
                    local_difference = difference @ m
                    for v in d.vertices:
                        v.co += local_difference
                    m.translation -= difference

                difference = Vector((0, 0, 0))
                if self.side == 'X':
                    bound = max((m @ v.co).x for v in d.vertices)
                    difference.x = m.translation.x - bound
                elif self.side == '-X':
                    bound = min((m @ v.co).x for v in d.vertices)
                    difference.x = m.translation.x - bound
                elif self.side == 'Y':
                    bound = max((m @ v.co).y for v in d.vertices)
                    difference.y = m.translation.y - bound
                elif self.side == '-Y':
                    bound = min((m @ v.co).y for v in d.vertices)
                    difference.y = m.translation.y - bound
                elif self.side == 'Z':
                    bound = max((m @ v.co).z for v in d.vertices)
                    difference.z = m.translation.z - bound
                elif self.side == '-Z':
                    bound = min((m @ v.co).z for v in d.vertices)
                    difference.z = m.translation.z - bound

                local_difference = difference @ m
                for v in d.vertices:
                    v.co += local_difference
                m.translation -= difference

                if self.move:
                    o.location = context.scene.cursor.location
        if switchMode:
            bpy.ops.object.mode_set(mode='OBJECT', toggle=True)

        return {'FINISHED'}
Beispiel #14
0
 def calc_box(self):
     if not self.verts:
         return Vector((0, 0, 0)), Vector((0, 0, 0))
     mins = Vector(self.verts[0])
     maxs = Vector(self.verts[0])
     for v in self.verts:
         mins.x = min(mins.x, v.x)
         mins.y = min(mins.y, v.y)
         mins.z = min(mins.z, v.z)
         maxs.x = max(maxs.x, v.x)
         maxs.y = max(maxs.y, v.y)
         maxs.z = max(maxs.z, v.z)
     size = (maxs - mins)
     center = (maxs + mins) / 2
     return size, center
def find_HalfExtent_scale(loc):
    scale = Vector()
    values = loc.find("*[@Name='HalfExtents']").attrib
    scale.x = float(values['X'])
    scale.y = float(values['Z'])
    scale.z = float(values['Y'])
    return scale
    def modal(self, context, event):
        props = context.scene.tom_props
        prefs = context.user_preferences.addons[__name__].preferences

        # 3Dビューの画面を更新
        if context.area:
            context.area.tag_redraw()

        # キーボードのQキーが押された場合は、オブジェクト並進移動モードを終了
        if event.type == 'Q' and event.value == 'PRESS':
            props.running = False
            print("サンプル3-10: 通常モードへ移行しました。")
            return {'FINISHED'}

        if event.value == 'PRESS':
            value = Vector((0.0, 0.0, 0.0))
            if event.type == prefs.x_axis:
                value.x = 1.0 if not event.shift else -1.0
            if event.type == prefs.y_axis:
                value.y = 1.0 if not event.shift else -1.0
            if event.type == prefs.z_axis:
                value.z = 1.0 if not event.shift else -1.0
            # 選択中のオブジェクトを並進移動する
            bpy.ops.transform.translate(value=value)

        return {'RUNNING_MODAL'}
Beispiel #17
0
def sRGB2linear(rgb):
    a = 0.055
    lrgb = Vector()
    lrgb.x = s2lin(rgb.x)
    lrgb.y = s2lin(rgb.y)
    lrgb.z = s2lin(rgb.z)
    return lrgb
    def modal(self, context, event):
        props = context.scene.tom_props
# @include-source start [get_prefs]
        prefs = context.user_preferences.addons[__name__].preferences
# @include-source end [get_prefs]

        # 3Dビューの画面を更新
        if context.area:
            context.area.tag_redraw()

        # キーボードのQキーが押された場合は、オブジェクト並進移動モードを終了
        if event.type == 'Q' and event.value == 'PRESS':
            props.running = False
            print("サンプル3-10: 通常モードへ移行しました。")
            return {'FINISHED'}

# @include-source start [refer_prefs]
        if event.value == 'PRESS':
            value = Vector((0.0, 0.0, 0.0))
            if event.type == prefs.x_axis:
                value.x = 1.0 if not event.shift else -1.0
            if event.type == prefs.y_axis:
                value.y = 1.0 if not event.shift else -1.0
            if event.type == prefs.z_axis:
                value.z = 1.0 if not event.shift else -1.0
            # 選択中のオブジェクトを並進移動する
            bpy.ops.transform.translate(value=value)
# @include-source end [refer_prefs]

        return {'RUNNING_MODAL'}
Beispiel #19
0
	def update(self, ctx, clickcount, dimantion):
		dim = dimantion
		if self.shift:
			index = -1 if len(self.subclass.knots) < 2 else -2
			lastpoint = self.subclass.knots[index].pos
			dim.view = get_axis_constraint(lastpoint, dim.view)

		if self.drag:
			pos = self.subclass.knots[-1].pos
			outvec = dim.view
			invec = Vector((0,0,0))
			invec.x = pos.x - (outvec.x - pos.x)
			invec.y = pos.y - (outvec.y - pos.y)
			invec.z = pos.z - (outvec.z - pos.z)
			newknot = knot(pos, invec, outvec, 'ALIGNED')
		else:
			newknot = knot(dim.view, dim.view, dim.view, "VECTOR")

		if clickcount != self.lastclick:
			self.subclass.knots.append(newknot)
			self.lastclick = clickcount
			check_for_close(self, ctx)

		if LineData.close:
			self.subclass.knots.pop()
			self.subclass.close = True
			self.forcefinish = True

		self.subclass.knots[-1] = newknot
		self.subclass.lastknot = [knot(dim.view, dim.view, dim.view, "VECTOR")]

		self.subclass.update(ctx)
Beispiel #20
0
 def render(self):
     diameter = 4.0
     sz = 2.125 / diameter
     base_object = helpers.infer_primitive(random.choice(self.PRIMITIVES),
                                           location=(100, 100, 100),
                                           radius=sz)
     latitude = 16
     longitude = latitude * 2
     invlatitude = 1.0 / (latitude - 1)
     invlongitude = 1.0 / (longitude - 1)
     iprc = 0.0
     jprc = 0.0
     phi = 0.0
     theta = 0.0
     invfcount = 1.0 / (self.NUMBER_OF_FRAMES - 1)
     # Animate center of the sphere.
     center = Vector((0.0, 0.0, 0.0))
     startcenter = Vector((0.0, -4.0, 0.0))
     stopcenter = Vector((0.0, 4.0, 0.0))
     # Rotate cubes around the surface of the sphere.
     pt = Vector((0.0, 0.0, 0.0))
     rotpt = Vector((0.0, 0.0, 0.0))
     # Change the axis of rotation for the point.
     baseaxis = Vector((0.0, 1.0, 0.0))
     axis = Vector((0.0, 0.0, 0.0))
     # Slerp between two rotations for each cube.
     startrot = Quaternion((0.0, 1.0, 0.0), pi)
     stoprot = Quaternion((1.0, 0.0, 0.0), pi * 1.5)
     currot = Quaternion()
     for i in range(0, latitude, 1):
         iprc = i * invlatitude
         phi = pi * (i + 1) * invlatitude
         rad = 0.01 + sz * abs(sin(phi)) * 0.99
         pt.z = cos(phi) * diameter
         for j in range(0, longitude, 1):
             jprc = j * invlongitude
             theta = TWOPI * j / longitude
             pt.y = center.y + sin(phi) * sin(theta) * diameter
             pt.x = center.x + sin(phi) * cos(theta) * diameter
             current = helpers.duplicate_object(base_object)
             current.location = pt
             current.name = 'Object ({0:0>2d}, {1:0>2d})'.format(i, j)
             current.data.name = 'Mesh ({0:0>2d}, {1:0>2d})'.format(i, j)
             current.rotation_euler = (0.0, phi, theta)
             helpers.assign_material(
                 current, helpers.random_material(self.MATERIALS_NAMES))
             axis = self.vecrotatex(theta, baseaxis)
             currot = startrot
             center = startcenter
             for f in range(0, self.NUMBER_OF_FRAMES, 1):
                 fprc = f / (self.NUMBER_OF_FRAMES - 1)
                 osc = abs(sin(TWOPI * fprc))
                 bpy.context.scene.frame_set(f)
                 center = startcenter.lerp(stopcenter, osc)
                 current.location = helpers.rotate_vector(
                     TWOPI * fprc, axis, pt)
                 current.keyframe_insert(data_path='location')
                 currot = startrot.slerp(stoprot, jprc * fprc)
                 current.rotation_euler = currot.to_euler()
                 current.keyframe_insert(data_path='rotation_euler')
Beispiel #21
0
def calculate_bbox(verts, matrix=None):
    mapped_verts = verts
    if matrix is not None:
        mapped_verts = map(lambda v, M=matrix: M @ v, verts)

    bbox_min = Vector(next(mapped_verts))
    bbox_max = bbox_min.copy()

    for v in mapped_verts:
        if v.x < bbox_min.x:
            bbox_min.x = v.x
        if v.y < bbox_min.y:
            bbox_min.y = v.y
        if v.z < bbox_min.z:
            bbox_min.z = v.z

        if v.x > bbox_max.x:
            bbox_max.x = v.x
        if v.y > bbox_max.y:
            bbox_max.y = v.y
        if v.z > bbox_max.z:
            bbox_max.z = v.z

    # Return bounding box verts
    return bbox_min, bbox_max
def item_to_vector(item):
    """Converts XML item object to vector. SWAPS Y and Z"""
    v = Vector()
    v.x = float(item.attrib['X'])
    v.y = float(item.attrib['Z'])
    v.z = float(item.attrib['Y'])
    return v
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
Beispiel #24
0
def getRandomLoc(randomLoc, rand, width, height):
    """ get random location between (0,0,0) and (width/2, width/2, height/2) """
    loc = Vector((0, 0, 0))
    loc.xy = [rand.uniform(-(width / 2) * randomLoc,
                           (width / 2) * randomLoc)] * 2
    loc.z = rand.uniform(-(height / 2) * randomLoc, (height / 2) * randomLoc)
    return loc
    def modal(self, context, event):
        props = context.scene.tom_props

        # 3Dビューの画面を更新
        if context.area:
            context.area.tag_redraw()

        # キーボードのQキーが押された場合は、オブジェクト並進移動モードを終了
        if event.type == 'Q' and event.value == 'PRESS':
            props.running = False
            print("サンプル3-2: 通常モードへ移行しました。")
            return {'FINISHED'}

        if event.value == 'PRESS':
            value = Vector((0.0, 0.0, 0.0))
            if event.type == 'X':
                value.x = 1.0 if not event.shift else -1.0
            if event.type == 'Y':
                value.y = 1.0 if not event.shift else -1.0
            if event.type == 'Z':
                value.z = 1.0 if not event.shift else -1.0
            # 選択中のオブジェクトを並進移動する
            bpy.ops.transform.translate(value=value)

        return {'RUNNING_MODAL'}
def find_xyz(loc, valname):
    """returns vector named valname in loc"""
    v = Vector()
    values = loc.find(f"*[@Name='{valname}']").attrib
    v.x = float(values['X'])
    v.y = float(values['Z'])
    v.z = float(values['Y'])
    return v
def find_xyz_from_mat(loc, mat_name):
    """returns xyz from matrix named mat_name in loc"""
    a = Vector()
    values = loc.find(f"*[@Name='{mat_name}']").attrib
    a.x = float(values['M41'])
    a.y = float(values['M43'])
    a.z = float(values['M42'])
    return a
def fencehop():
	cont = bge.logic.getCurrentController()
	own = cont.owner
	
	auto_action = cont.sensors['auto_action']
	
	if not auto_action:
		return False
	elif own['isSpaceon']:
		#Gather info on the fence
		fence_obj = auto_action.hitObject
		fence_pos = fence_obj.worldPosition
		
		#get the normal of the fence
		hit_norm = Vector(auto_action.hitNormal)
		hit_norm.z = 0.0
		
		#Vector axis of Sintel
		own_negative_y = Vector(own.getAxisVect((0.0, -1.0, 0.0)))
		own_negative_y.z = 0.0
		
		#Cross it, then get the absolute vaule
		cross = hit_norm.cross(own_negative_y)
		cross = math.fabs(cross[2])
		
		#print (cross)
		
		#Check the angle of approach
		if cross <=.5:
			new_pos = (fence_pos[2] + 2)
			own.worldPosition[2] = new_pos
			
			own['Leaping']=True
			CURRENT_SPEED = own.getLinearVelocity(True)
			
			
			if CURRENT_SPEED[1] < 11:
				CURRENT_SPEED[1] = 11
				
			CURRENT_SPEED[2] = 10
			#print (CURRENT_SPEED)
			own.setLinearVelocity(CURRENT_SPEED ,True)
			own['Tracking']=False
			return True
		else:
			return False
def get_min_max(vertList):
    min = Vector(vertList[0])
    max = Vector(vertList[0])
    for v in vertList:
        if v.x < min.x:
            min.x = v.x
        elif v.x > max.x:
            max.x = v.x
        if v.y < min.y:
            min.y = v.y
        elif v.y > max.y:
            max.y = v.y
        if v.z < min.z:
            min.z = v.z
        elif v.z > max.z:
            max.z = v.z
    return min, max
Beispiel #30
0
def fencehop():
    cont = bge.logic.getCurrentController()
    own = cont.owner

    auto_action = cont.sensors['auto_action']

    if not auto_action:
        return False
    elif own['isSpaceon']:
        #Gather info on the fence
        fence_obj = auto_action.hitObject
        fence_pos = fence_obj.worldPosition

        #get the normal of the fence
        hit_norm = Vector(auto_action.hitNormal)
        hit_norm.z = 0.0

        #Vector axis of Sintel
        own_negative_y = Vector(own.getAxisVect((0.0, -1.0, 0.0)))
        own_negative_y.z = 0.0

        #Cross it, then get the absolute vaule
        cross = hit_norm.cross(own_negative_y)
        cross = math.fabs(cross[2])

        #print (cross)

        #Check the angle of approach
        if cross <= .5:
            new_pos = (fence_pos[2] + 2)
            own.worldPosition[2] = new_pos

            own['Leaping'] = True
            CURRENT_SPEED = own.getLinearVelocity(True)

            if CURRENT_SPEED[1] < 11:
                CURRENT_SPEED[1] = 11

            CURRENT_SPEED[2] = 10
            #print (CURRENT_SPEED)
            own.setLinearVelocity(CURRENT_SPEED, True)
            own['Tracking'] = False
            return True
        else:
            return False
Beispiel #31
0
    def onKeyPressed(self, keys):
        rot = self.obj.worldOrientation.to_euler()
        pos = Vector([0, 0, 0])
        if key.W in keys: rot.x += 0.01
        if key.S in keys: rot.x -= 0.01
        if key.A in keys: rot.z += 0.01
        if key.D in keys: rot.z -= 0.01
        if key.WHEELUPMOUSE in keys: pos.z = -self.obj.worldPosition.z * 0.3
        if key.WHEELDOWNMOUSE in keys: pos.z = self.obj.worldPosition.z * 0.3

        #Max speed is dependent of the Tile sizes, ex (200m/s = size) / 50fps = 4m/tick
        #Since we are using an extra radius we can guarante a speed of 8m/tick without glitches: 8*60fps = 480m/s = 1728 km/h
        #if pos.length > 8: pos.length = 8
        #But we don't care for now
        if pos.length > 50: pos.length = 50
        pos.rotate(self.obj.worldOrientation)
        self.obj.worldPosition += pos
        self.obj.worldOrientation = rot
Beispiel #32
0
	def onKeyPressed(self, keys):
		rot = self.obj.worldOrientation.to_euler()
		pos = Vector([0,0,0])
		if key.W in keys: rot.x += 0.01
		if key.S in keys: rot.x -= 0.01
		if key.A in keys: rot.z += 0.01
		if key.D in keys: rot.z -= 0.01
		if key.WHEELUPMOUSE in keys: pos.z = -self.obj.worldPosition.z * 0.3
		if key.WHEELDOWNMOUSE in keys: pos.z = self.obj.worldPosition.z * 0.3

		#Max speed is dependent of the Tile sizes, ex (200m/s = size) / 50fps = 4m/tick
		#Since we are using an extra radius we can guarante a speed of 8m/tick without glitches: 8*60fps = 480m/s = 1728 km/h
		#if pos.length > 8: pos.length = 8
		#But we don't care for now
		if pos.length > 50: pos.length = 50
		pos.rotate(self.obj.worldOrientation)
		self.obj.worldPosition += pos
		self.obj.worldOrientation = rot
def get_max(ob):
    mx = Vector((-1000., -1000., -1000.))
    for vx in ob.data.vertices:
        p = ob.matrix_world * vx.co
        mx.x = max(mx.x, p.x)
        mx.y = max(mx.y, p.y)
        mx.z = max(mx.z, p.z)

    return mx
Beispiel #34
0
def processCamera(cont):
    own = cont.owner
    axis = own.childrenRecursive["CameraAxis"]
    own.scene.active_camera.timeOffset = CAMERA_SMOOTH
    posVector = Vector((0, 0, 0))

    if own["Landing"]:
        posVector.y = VIEW_HEIGHT_DISTANCE * 3
        posVector.z = VIEW_HEIGHT_DISTANCE
    else:
        posVector.z = -VIEW_HEIGHT_DISTANCE

        if own["DirectionH"] == "Left":
            posVector.x = -VIEW_AHEAD_DISTANCE
        elif own["DirectionH"] == "Right":
            posVector.x = VIEW_AHEAD_DISTANCE

    axis.worldPosition = own.worldPosition + posVector
def get_all_max_min():
    min_p = Vector([float('inf'), float('inf'), float('inf')])
    max_p = Vector([-float('inf'), -float('inf'), -float('inf')])
    for obj in bpy.data.objects:
        if obj.type != 'MESH':
            continue
        max_min = get_object_max_min(obj)
        # Max
        max_p.x = max(max_p.x, max_min['max'].x)
        max_p.y = max(max_p.y, max_min['max'].y)
        max_p.z = max(max_p.z, max_min['max'].z)
        # Min
        min_p.x = min(min_p.x, max_min['min'].x)
        min_p.y = min(min_p.y, max_min['min'].y)
        min_p.z = min(min_p.z, max_min['min'].z)
    return {
        'min': min_p,
        'max': max_p
    }
Beispiel #36
0
def get_random_loc(random_loc, rand, half_width, half_height):
    """ get random location between (0,0,0) and (width/2, width/2, height/2) """
    loc = Vector((0, 0, 0))
    if random_loc > 0:
        loc.xy = [
            rand.uniform(-half_width * random_loc, half_width * random_loc)
        ] * 2
        loc.z = rand.uniform(-half_height * random_loc,
                             half_height * random_loc)
    return loc
Beispiel #37
0
 def __neg__(self):
     """ return antipodal point """
     coo=Vector()
     if self.co.x > 0:
         coo.x = self.co.x -  math.pi
     else:
         coo.x = self.co.x + math.pi
     coo.y = abs(math.pi - self.co.y)
     coo.z = -self.co.z
     return Reflection(co=coo,
             normalize=False)
Beispiel #38
0
 def roi2point(self, msg):
   """
   Returns a normalized point at the center of the given RegionOfInterest
   message.
   """
   p = Vector([0,0,0])
   if self.camerainfo.width > 0:
     p.x =  0.5 - (msg.x_offset+(msg.width/2.0))/self.camerainfo.width
   if self.camerainfo.height > 0:
     p.z =  0.5 - (msg.y_offset+(msg.height/2.0))/self.camerainfo.height
   return p
Beispiel #39
0
def read_vector_axis_vecteur(node):
    v = Vector((0.0, 0.0, 0.0))
    childs = node.getElementsByTagName('x')
    if childs:
        v.x = ret_float_value(childs[0])
    childs = node.getElementsByTagName('y')
    if childs:
        v.y = ret_float_value(childs[0])
    childs = node.getElementsByTagName('z')
    if childs:
        v.z = ret_float_value(childs[0])
    return v
    def execute(self, context):
        scene = context.scene
        obj = context.active_object
        # check if active object is a mesh object
        if not obj or obj.type != 'MESH':
            self.report({'ERROR'}, "No selected mesh object!")
            return {'CANCELLED'}

        # check if it has one single face
        if len(obj.data.polygons) != 1:
            self.report(
                {'ERROR'},
                "The selected mesh object has to have exactly one quad!")
            return {'CANCELLED'}

        rl = scene.lightfield.row_length
        # use a degree angle here
        angle = degrees(scene.lightfield.angle)
        spacing = scene.lightfield.spacing
        # resolution of final renderings
        res = round(scene.render.resolution_x *
                    (scene.render.resolution_percentage / 100.))
        width = self.getWidth(obj)

        # the offset between n pixels on the focal plane
        fplane_offset = (width / res) * spacing

        # vertices for the basemesh
        verts = []
        # the offset vector
        vec = self.getCamVec(obj, angle)
        # lower left coordinates of the grid
        sx = obj.location[0] - fplane_offset * int(rl / 2)
        sy = obj.location[1] - fplane_offset * int(rl / 2)
        z = obj.location[2]
        # position on the focal plane
        fplane_pos = Vector()
        for x in [sx + fplane_offset * i for i in range(rl)]:
            for y in [sy + fplane_offset * i for i in range(rl)]:
                fplane_pos.x = x
                fplane_pos.y = y
                fplane_pos.z = z
                # position of a vertex in a basemesh
                pos = fplane_pos + vec
                # pack coordinates flat into the vert list
                verts.append((pos.x, pos.y, pos.z))

        # setup the basemesh and add verts
        mesh = bpy.data.meshes.new(self.objName)
        mesh.from_pydata(verts, [], [])
        self.addMeshObj(mesh)

        return {'FINISHED'}
def main():
	cont = bge.logic.getCurrentController()
	own = cont.owner

	wall_ray = cont.sensors["wall_ray"]

	wall_normal = Vector(wall_ray.hitNormal)
	wall_normal.z = 0.0

	own_negative_y = Vector(own.getAxisVect((0.0, -1.0, 0.0)))
	own_negative_y.z = 0.0
				
	cross = wall_normal.cross(own_negative_y)

	if cross.z > 0.0:
		new_dir = Matrix.Rotation(-90.0, 3, 'X') * wall_normal
	else:
		new_dir = Matrix.Rotation(90.0, 3, 'X') * wall_normal
	
	#print (new_dir)
	#own.alignAxisToVect(new_dir, 0, .1)
Beispiel #42
0
    def _move(self, direction, value):
        """ Moves view into direction by value. """

        for view in self.get3DView():
            offset = Vector((0.0, 0.0, 0.0))
            if direction == "horizontal":
                offset.x = value
            elif direction == "vertical":
                offset.y = value
            elif direction == "straightforward":
                offset.z = value

            view.view_location = view.view_rotation*offset + view.view_location
Beispiel #43
0
    def getDimensions(self):
        highest = Vector((-10000, -10000, -10000))
        lowest  = Vector(( 10000,  10000,  10000))

        for bone in self.bones:
            if highest.x < bone.restHead.x: highest.x = bone.restHead.x
            if highest.y < bone.restHead.y: highest.y = bone.restHead.y
            if highest.z < bone.restHead.z: highest.z = bone.restHead.z

            if highest.x < bone.restTail.x: highest.x = bone.restTail.x
            if highest.y < bone.restTail.y: highest.y = bone.restTail.y
            if highest.z < bone.restTail.z: highest.z = bone.restTail.z

            if lowest .x > bone.restHead.x: lowest .x = bone.restHead.x
            if lowest .y > bone.restHead.y: lowest .y = bone.restHead.y
            if lowest .z > bone.restHead.z: lowest .z = bone.restHead.z

            if lowest .x > bone.restTail.x: lowest .x = bone.restTail.x
            if lowest .y > bone.restTail.y: lowest .y = bone.restTail.y
            if lowest .z > bone.restTail.z: lowest .z = bone.restTail.z

        return Vector((highest.x - lowest.x, highest.y - lowest.y, highest.z - lowest.z))
    def execute(self, context):
        scene = context.scene
        obj = context.active_object
        # check if active object is a mesh object
        if not obj or obj.type != 'MESH':
            self.report({'ERROR'}, "No selected mesh object!")
            return {'CANCELLED'}

        # check if it has one single face
        if len(obj.data.polygons) != 1:
            self.report({'ERROR'}, "The selected mesh object has to have exactly one quad!")
            return {'CANCELLED'}

        rl = scene.lightfield.row_length
        # use a degree angle here
        angle = degrees(scene.lightfield.angle)
        spacing = scene.lightfield.spacing
        # resolution of final renderings
        res = round(scene.render.resolution_x * (scene.render.resolution_percentage / 100.))
        width = self.getWidth(obj)

        # the offset between n pixels on the focal plane
        fplane_offset = (width / res) * spacing

        # vertices for the basemesh
        verts = []
        # the offset vector
        vec = self.getCamVec(obj, angle)
        # lower left coordinates of the grid
        sx = obj.location[0] - fplane_offset * int(rl / 2)
        sy = obj.location[1] - fplane_offset * int(rl / 2)
        z = obj.location[2]
        # position on the focal plane
        fplane_pos = Vector()
        for x in [sx + fplane_offset * i for i in range(rl)]:
            for y in [sy + fplane_offset * i for i in range(rl)]:
                fplane_pos.x = x
                fplane_pos.y = y
                fplane_pos.z = z
                # position of a vertex in a basemesh
                pos = fplane_pos + vec
                # pack coordinates flat into the vert list
                verts.append((pos.x, pos.y, pos.z))

        # setup the basemesh and add verts
        mesh = bpy.data.meshes.new(self.objName)
        mesh.from_pydata(verts, [], [])
        self.addMeshObj(mesh)

        return {'FINISHED'}
Beispiel #45
0
def Translate(mesh, vtx_weight_dict, shapekey_out, dx, dy, dz):
    # Purpose: translate vertices in the weight dict somewhere
    verts = shapekey_out.data
    vwd = vtx_weight_dict
    
    d = Vector((0,0,0))
    
    for i in range(len(verts)):
        if i in vwd:
            d.x = dx
            d.y = dy
            d.z = dz
            verts[i].co += vwd[i] * d
        else:
            continue
Beispiel #46
0
	def calcBranch(self, branch, angle=0):
		rotation = uniform(0, pi * 2)
		br = copy(branch) 
		a = br.a
		o = Vector([uniform(-1,1),uniform(-1,1),uniform(-1,1)]) 
		if a.x != 0:
			o.x = -(a.y * o.y + a.z * o.z) / a.x
		elif a.y != 0:
			o.y = -(a.x * o.x + a.z * o.z) / a.y
		elif a.z != 0:
			o.z = -(a.x * o.x + a.y * o.y) / a.z
		else:
			raise Exception("Invalid input: zero vector")
		o = norm(o)
		assert(inner_product(o) > .9999 or inner_product(o) < 1.0001)
		assert(o * a < 0.0001)
		br.a = rotation_mat(branch.a, rotation) * (rotation_mat(o, angle) * br.a)
		br.a = norm(vec_vec_mult(br.a, self.gradual_angle))
		return br
Beispiel #47
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
Beispiel #48
0
    def apply_location(self, user):
        for joint in user.joints.values():
            for obj in bpy.data.objects:
                if obj.type != "ARMATURE":
                    continue
                armature = obj
                if not armature.pose:
                    continue
                pose = armature.pose
                if not pose.bones:
                    continue
                bones = pose.bones
                if joint.name not in bones:
                    continue
                bone = bones[joint.name]
                if not bone:
                    continue

                location = Vector()
                location.x = joint.location.x
                location.y = joint.location.y
                location.z = joint.location.z

                parent = bone
                while not hasattr(parent, "parent"):
                    parent = parent.parent
                    if not parent:
                        continue
                    if not hasattr(parent, "location"):
                        continue
                    location.x -= parent.location.x
                    location.y -= parent.location.y
                    location.z -= parent.location.z

                bone.location = location

                if bpy.amk2b.recording_started:
                    bone.keyframe_insert(data_path="location", frame=bpy.context.scene.frame_current)
    def _frames_difference_vector(self, frames, attr_func):
        """ Calculates the difference Vector of attribute on the first and the last frame. """

        res = Vector((0.0, 0.0, 0.0))
        for i in (0, -1):
            #get attributes from frames[i]
            v = attr_func(frames[i])
            if i == 0:
                res.y -= v.y
                res.x -= v.x
                res.z -= v.z
            else:
                res.y += v.y
                res.x += v.x
                res.z += v.z

            if res.x > settings.max_x and res.x < -settings.max_x:
                res.y = 0
            if res.y > settings.max_y and res.y < -settings.max_y:
                res.y = 0
            if res.z > settings.max_z and res.z < -settings.max_z:
                res.z = 0
        return res
    def execute(self, context):
        scene = context.scene
        sp = scene.speaker

        scene_objects_set = set(scene.objects)
        obj = context.active_object
        # copy cursor location

        cursor_loc = scene.cursor_location.copy()
        # snap the cursor to the selected

        bpy.ops.view3d.snap_cursor_to_selected()
        channels = self.rows * self.cols

        # bpy.context for testing. Use context from Op, Panel method.

        originals = context.selected_objects.copy()
        # has the selected objects in it.
        c = {}

        c["scene"] = scene
        c["screen"] = context.screen
        c["area"] = context.area
        c["region"] = context.region
        c["active_object"] = None
        c["edit_object"] = None
        c["window"] = context.window
        # c["selected_bases"] = context.selected_bases.copy()
        # c["selected_editable_objects"] = context.selected_editable_objects.copy()
        # c["selected_bases"] = []
        c["selected_objects"] = originals
        dimensions = bbdim(selected_bbox(context))
        # Location of original unit
        location = scene.cursor_location.copy()

        st_handle = bpy.data.objects.new("ST_handle", None)
        st_handle["channels"] = channels
        scene.objects.link(st_handle)

        st_handle.matrix_world.translation = location
        st_handle["ST_Vis"] = 0
        handles = []
        new_objects = set(originals)
        vis = []
        # make duplicates
        for i in range(channels):
            scene.update()
            handle = bpy.data.objects.new("ch[%04d]" % i, None)
            scene.objects.link(handle)

            handle["ST_Vis"] = i  # the channel to drive with.
            handle.parent = st_handle
            handles.append(handle)
            # make the handle the objects parent if no parent else

            if i:
                scene_objects_set = set(scene.objects)
                bpy.ops.object.duplicate(c, 'INVOKE_DEFAULT', linked=False)
                scene.update()
                new_objects = set(scene.objects) - scene_objects_set
            vis.append((i, handle, new_objects))
        for i, handle, new_objects in vis:
            for o in new_objects:
                print(o, o.parent)
                if not o.parent or o.parent in handles:
                    o.parent = handle
                if not i or not o.animation_data:
                    continue  # drivers ok for ch0

                # get the drivers of o
                # have speaker as a var target
                # have CH0 as a variable
                drivers = o.animation_data.drivers
                drivers = [d for d in drivers for v in d.driver.variables for t in v.targets if t.id == sp]
                for d in drivers:
                    all_channels, args = get_driver_settings(d)
                    driver = d.driver
                    expr = driver.expression
                    for ch in all_channels:
                        if len(ch) == 3 and ch.endswith("0"):
                            all_channels.remove(ch)
                            newch = ch.replace("0", str(i))
                            expr = expr.replace(ch, newch)
                            all_channels.append(newch)
                            var = driver.variables.get(ch)
                            var.name = newch
                            var.targets[0].data_path = var.targets[0].data_path.replace(ch, newch)
                    driver.expression = driver_expr(expr,
                                               all_channels,
                                               args)

        # distribute

        # Properties
        rows = self.rows
        cols = self.cols

        offset = Vector(self.offset)
        offset.x = dimensions.x * offset.x
        offset.y = dimensions.y * offset.y
        offset.z = dimensions.z * offset.z

        # deselect all
        bpy.ops.object.select_all(action='DESELECT')
        self.handle = st_handle is not None
        self.handle_name = st_handle.name
        context.scene.objects.active = st_handle
        st_handle.select = True
        st_handle["VIS"] = 'GRID'

        # make an rna and make a grid
        vis_RNA = {
                   "name": self.handle_name,
                   "rows": self.rows,
                   "cols": self.cols,
                   "channels": channels,
                   "offset": {
                              "x": self.offset[0],
                              "y": self.offset[1],
                              "z": self.offset[2]
                              },
                   "dimensions": {
                              "x": dimensions[0],
                              "y": dimensions[1],
                              "z": dimensions[2],
                                }

                  }
        st_handle['_RNA_UI'] = {}
        st_handle['_RNA_UI']["VIS"] = vis_RNA

        # make a new edit item in the grids collection

        grid = context.scene.visualisers.grids.add()
        grid.name = st_handle.name
        grid.rows = self.rows
        grid.cols = self.cols
        grid.offset = self.offset

        return {'FINISHED'}
        # キーボードのQキーが押された場合は、オブジェクト並進移動モードを終了
        if event.type == 'Q' and event.value == 'PRESS':
            props.running = False
            print("サンプル3-10: 通常モードへ移行しました。")
            return {'FINISHED'}

//! [refer_prefs]
        if event.value == 'PRESS':
            value = Vector((0.0, 0.0, 0.0))
            if event.type == prefs.x_axis:
                value.x = 1.0 if not event.shift else -1.0
            if event.type == prefs.y_axis:
                value.y = 1.0 if not event.shift else -1.0
            if event.type == prefs.z_axis:
                value.z = 1.0 if not event.shift else -1.0
            # 選択中のオブジェクトを並進移動する
            bpy.ops.transform.translate(value=value)
//! [refer_prefs]

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        props = context.scene.tom_props
        if context.area.type == 'VIEW_3D':
            # 開始ボタンが押された時の処理
            if props.running is False:
                props.running = True
                # modal処理クラスを追加
                context.window_manager.modal_handler_add(self)
                print("サンプル3-2: オブジェクト並進移動モードへ移行しました。")
Beispiel #52
0
def scan(numberOfRays, max_distance, elementsPerRay, keep_render_setup, do_shading, rays_buffer, returns_buffer, ELEMENTS_PER_RETURN): 
    if ELEMENTS_PER_RETURN != 8:
        raise Exception("Scan interface incompatible")
    
    # Step 1: Scene to polygons / store face indices and materials
    tris = []
    faces = []
    face_array,obj_array,mat_array = scene_to_mesh()

    for idx,f in enumerate(face_array):
        tris.append(list(f[0]))
        tris.append(list(f[1]))
        tris.append(list(f[2]))
        faces.append([idx*3,idx*3+1,idx*3+2])

    # Step 2: Polygons to BVH tree
    scene_bvh = BVHTree.FromPolygons(tris, faces, all_triangles = True)

    # Step 3: Raycast rays
    scanner = bpy.context.scene.camera
    reflectivity_distance = scanner.ref_dist
    reflectivity_limit = scanner.ref_limit
    reflectivity_slope = scanner.ref_slope

    origin = Vector([0.0,0.0,0.0])
    direction = Vector([0.0,0.0,0.0])

    hit_indices = [-1]*numberOfRays

    for idx in range(numberOfRays):
        direction.x = rays_buffer[idx*elementsPerRay]
        direction.y = rays_buffer[idx*elementsPerRay+1]
        direction.z = rays_buffer[idx*elementsPerRay+2]
        
        if elementsPerRay>=6:
            origin.x = rays_buffer[idx*elementsPerRay+3]
            origin.y = rays_buffer[idx*elementsPerRay+4]
            origin.z = rays_buffer[idx*elementsPerRay+5]
        else:
            origin.x = bpy.context.scene.camera.location.x
            origin.y = bpy.context.scene.camera.location.y
            origin.z = bpy.context.scene.camera.location.z

        direction.rotate (scanner.matrix_world)

        (hit_loc, hit_normal, hit_idx, hit_distance) = scene_bvh.ray_cast(origin,direction,max_distance)

        valid_return = False
        if hit_loc:
            mat = mat_array[hit_idx]

            diffuse_intensity = 1.0
            if mat:
                diffuse_intensity = mat.diffuse_intensity

            #Calculate the required diffuse reflectivity of the material to create a return
            ref_limit = blensor_calculate_reflectivity_limit(hit_distance, reflectivity_distance, reflectivity_limit, reflectivity_slope)

            if diffuse_intensity > ref_limit:
                valid_return = True
                if mat:
                    color = mat.diffuse_color
                    returns_buffer[idx*ELEMENTS_PER_RETURN+5] = color.r
                    returns_buffer[idx*ELEMENTS_PER_RETURN+6] = color.g
                    returns_buffer[idx*ELEMENTS_PER_RETURN+7] = color.b
                else:
                    returns_buffer[idx*ELEMENTS_PER_RETURN+5] = 1.0
                    returns_buffer[idx*ELEMENTS_PER_RETURN+6] = 1.0
                    returns_buffer[idx*ELEMENTS_PER_RETURN+7] = 1.0

                returns_buffer[idx*ELEMENTS_PER_RETURN] = hit_distance
                returns_buffer[idx*ELEMENTS_PER_RETURN+1] = hit_loc.x
                returns_buffer[idx*ELEMENTS_PER_RETURN+2] = hit_loc.y
                returns_buffer[idx*ELEMENTS_PER_RETURN+3] = hit_loc.z

                obj = obj_array[hit_idx]
                name = obj.name
                returns_buffer[idx*ELEMENTS_PER_RETURN+4] = ord(name[0]) + (ord(name[1])<<8) + (ord(name[2])<<16) + (ord(name[3])<<24)  

                hit_indices[idx] = hit_idx

        if not valid_return:
            for r in range(ELEMENTS_PER_RETURN):
                returns_buffer[idx*ELEMENTS_PER_RETURN+r] = 0.0

    # Step 3: Shade rays
    # TODO: Implement material solver
    if do_shading:
        for idx,mat_idx in enumerate(hit_indices):
            if mat_idx >= 0:
                #shade hit point
                pass
Beispiel #53
0
	def from_object(model, obj, root):
		node = Mesh(name=obj.name)

		triangulated_object, created_temp_mesh = create_triangulated_mesh(obj)

		# apply rotation and scale transform to the object
		# this ensures that any modifications are baked to the vertices
		# before we output them to the file
		triangulated_object.select = True

		# This is used to transform the vertices and normals of the mesh.
		world_matrix = model.global_matrix * triangulated_object.matrix_world.copy()

		mesh = triangulated_object.to_mesh(bpy.context.scene, True, 'PREVIEW')

		# collect all blender materials used by this mesh
		for bmaterial in mesh.materials:
			mat = model.add_material(bmaterial)
			node.material_id = mat.index

		cache = VertexCache()

		bone_data = Mesh.process_armature(model, node, cache, obj)
		model.bone_data = bone_data

		weights = [[None]] * len(mesh.vertices)

		vertices = []

		mins = Vector((9999, 9999, 9999))
		maxs = Vector((-9999, -9999, -9999))

		# build a mapping from group index to bone index
		total_bones = len(bone_data.ordered_items) if bone_data else 0
		group_index_to_bone = [None] * total_bones
		for group in obj.vertex_groups:
			# convert group index to boneinfo.index
			boneinfo = bone_data.find_by_name(group.name)
			if not boneinfo:
				# It's possible to have vertex groups for bones which
				# may have been removed. Ignore these.
				continue

			group_index_to_bone[group.index] = boneinfo

		for index, mv in enumerate(mesh.vertices):
			position = world_matrix * mv.co
			vertices.extend([(
				position[0],
				position[1],
				position[2])])

			if position[0] < mins.x:
				mins.x = position[0]
			elif position[0] > maxs.x:
				maxs.x = position[0]

			if position[1] < mins.y:
				mins.y = position[1]
			elif position[1] > maxs.y:
				maxs.y = position[1]

			if position[2] < mins.z:
				mins.z = position[2]
			elif position[2] > maxs.z:
				maxs.z = position[2]

			# don't add out of range indices
			weights[index] = []
			for group_element in mv.groups:
				if group_element.group < total_bones:
					bone = group_index_to_bone[group_element.group]
					if bone and group_element.weight > 0.0:
						if len(weights[index]) < 4:
							weights[index].append({
								"bone": bone.name,
								"value": group_element.weight
								})
						#else:
						#	print("warning: dropping weight for bone '%s', %2.2f" % (bone.name, group_element.weight))


		node.mins = [mins.x, mins.y, mins.z]
		node.maxs = [maxs.x, maxs.y, maxs.z]

		mesh.calc_normals_split()

		normals = []
		for loop in mesh.loops:
			# transform normals
			normal = (world_matrix.to_3x3() * loop.normal).normalized()
			normals.append((normal[0], normal[1], normal[2]))
		mesh.free_normals_split()

		uvs = []
		if not mesh.uv_layers:
			uv_set = [(0.0, 0.0)] * len(mesh.loops)
			uvs.append(uv_set)
		else:
			for uvlayer in mesh.uv_layers:
				uv_set = []
				print("extracting uv layer: %s" % uvlayer.name)
				for uvloop in uvlayer.data:
					uv_set.append([uvloop.uv[0], 1.0-uvloop.uv[1]])
				uvs.append(uv_set)

		colors = []
		if not mesh.vertex_colors:
			# add a default color set
			color_set = ([(1.0, 1.0, 1.0, 1.0)] * len(mesh.loops))
			colors.append(color_set)
		else:
			for color_layer in mesh.vertex_colors:
				color_set = []
				print("extracting color layer: %s" % color_layer.name)
				for data in color_layer.data:
					color_set.append((data.color[0], data.color[1], data.color[2], 1.0))
				colors.append(color_set)

		if weights:
			print("total weights: %i, total vertices: %i" % (len(weights), len(vertices)))
			assert(len(weights) == len(vertices))

		# convert and copy geometry over to node
		cache.populate_with_geometry(vertices, normals, uvs, colors, mesh.loops, weights=weights)
		node.populate_with_vertex_cache(cache)

		# de-select the previously selected object
		triangulated_object.select = False

		if created_temp_mesh:
			# remove the triangulated object we created
			bpy.ops.object.mode_set(mode='OBJECT')
			bpy.context.scene.objects.unlink(triangulated_object)

		return node
Beispiel #54
0
def write_mesh(context, filepath, use_apply_modifiers, float_precision, include_normals, include_tangents, include_bitangents, include_uvs, include_colors, include_weights, bones_per_vertex, global_matrix, export_skeleton, export_materials, copy_images):

	# Allocate mesh data
	vertices = []
	vertex_set = set()
	triangles = []
	submeshes = []
	bounds_min = Vector((float("inf"), float("inf"), float("inf")))
	bounds_max = Vector((-float("inf"), -float("inf"), -float("inf")))
	armature = None

	# Determine vertex format
	vertex_format = "position"
	if include_uvs:
		vertex_format += " uv"
	if include_normals:
		vertex_format += " normal"
	if include_tangents:
		vertex_format += " tangent"
	if include_bitangents:
		vertex_format += " bitangent"
	if include_colors:
		vertex_format += " color"
	if include_weights:
		vertex_format += " indices%d weights%d" % (bones_per_vertex, bones_per_vertex)

	# Select objects to export
	object = context.object
	try:
		mesh = object.to_mesh(context.scene, use_apply_modifiers, "PREVIEW")
	except:
		return

	armature = object.parent

	bm = bmesh.new()
	bm.from_mesh(mesh)
	bm.transform(global_matrix * object.matrix_world)
	bmesh.ops.triangulate(bm, faces=bm.faces)
	bm.normal_update()

	uv_layer = bm.loops.layers.uv.active
	color_layer = bm.loops.layers.color.active
	deform_layer = bm.verts.layers.deform.active

	# Sort faces by material
	faces = bm.faces[:]
	faces.sort(key=lambda a: a.material_index)

	# Create empty submesh
	submesh = Submesh()
	previous_material_index = -1

	for face in faces:
		triangle_indices = []

		# Change material
		if face.material_index != previous_material_index:
			# Update primitive count of previous submesh
			submesh.primitive_count = len(triangles) - (submesh.start_index / 3)

			# Create a new submesh
			submesh = Submesh()
			submesh.material = object.material_slots[face.material_index].material
			submesh.start_index = len(triangles) * 3
			submeshes.append(submesh)

			previous_material_index = face.material_index

		for loop in face.loops:
			vert = loop.vert

			v = Vertex()
			v.position = vert.co.copy()

			if include_normals:
				if face.smooth:
					v.normal = vert.normal.copy()
				else:
					v.normal = face.normal.copy()

			if include_uvs and uv_layer is not None:
				v.uv = loop[uv_layer].uv.copy()
			if include_colors and color_layer is not None:
				v.color = loop[color_layer].color.copy()

			if include_tangents or include_bitangents:
				tangent_space = calculate_tangent_space(vert, uv_layer)
				v.tangent = tangent_space[0]
				v.bitangent = tangent_space[1]

			if include_weights and deform_layer is not None:
				# Sort bones by most influential
				sorted_groups = sorted(vert[deform_layer].items(), key=lambda item: item[1], reverse=True)

				# Set vertex bone weights and calculate sum
				weight_total = 0.0
				for i in range(min(bones_per_vertex, len(sorted_groups))):
					vertex_group = object.vertex_groups[sorted_groups[i][0]]
					bone_index = armature.data.bones.find(vertex_group.name)

					v.indices[i] = bone_index
					v.weights[i] = sorted_groups[i][1]
					weight_total += v.weights[i]

				# Normalize weights
				if weight_total > 0.0:
					v.weights *= 1.0 / weight_total

			if v not in vertex_set:
				vertex_set.add(v)
				triangle_indices.append(len(vertices))
				vertices.append(v)

				# Update bounds
				bounds_min.x = min(bounds_min.x, v.position.x)
				bounds_min.y = min(bounds_min.y, v.position.y)
				bounds_min.z = min(bounds_min.z, v.position.z)
				bounds_max.x = max(bounds_max.x, v.position.x)
				bounds_max.y = max(bounds_max.y, v.position.y)
				bounds_max.z = max(bounds_max.z, v.position.z)
			else:
				triangle_indices.append(vertices.index(v))

		triangles.append(triangle_indices)

	# Free BMesh
	bm.free()

	# Finalize last submesh
	submesh.primitive_count = len(triangles) - (submesh.start_index / 3)
	
	root_node = AttributeTreeNode()
	root_node.set_attribute("version", OGF_VERSION_STRING)

	mesh_node = root_node.create_child()
	mesh_node.set_attribute("type", "mesh")
	mesh_node.set_attribute("name", os.path.splitext(os.path.basename(filepath))[0])
	mesh_node.set_attribute("vertex_format", vertex_format)
	mesh_node.set_attribute("vertex_count", str(len(vertices)))

	# Write vertices
	vertices_attrib = ""
	for v in vertices:
		vertices_attrib += float3_format.format(float_precision, *v.position) + ' '
		if include_uvs:
			vertices_attrib += float2_format.format(float_precision, *v.uv) + ' '
		if include_normals:
			vertices_attrib += float3_format.format(float_precision, *v.normal) + ' '
		if include_tangents:
			vertices_attrib += float3_format.format(float_precision, *v.tangent.xyz) + ' '
		if include_bitangents:
			vertices_attrib += float3_format.format(float_precision, *v.bitangent.xyz) + ' '
		if include_colors:
			vertices_attrib += float3_format.format(float_precision, *v.color) + ' '
		if include_weights:
			for i in range(bones_per_vertex):
				vertices_attrib += "{} ".format(v.indices[i])
			for i in range(bones_per_vertex):
				vertices_attrib += float_format.format(float_precision, v.weights[i]) + ' '
	mesh_node.set_attribute("vertices", vertices_attrib)

	mesh_node.set_attribute("index_count", str(len(triangles) * 3))

	# Write indices
	indices_attrib = ""
	for t in triangles:
		indices_attrib += "{} {} {} ".format(*t)
	mesh_node.set_attribute("indices", indices_attrib)

	# Write bounds
	mesh_node.set_attribute("bounds_min", float3_format.format(float_precision, *bounds_min))
	mesh_node.set_attribute("bounds_max", float3_format.format(float_precision, *bounds_max))

	# Export skeleton
	if export_skeleton and object.parent is not None and object.parent.type == "ARMATURE":
		write_skeleton(filepath, float_precision, global_matrix, object.parent)
		mesh_node.set_attribute("skeleton", object.parent.name + ".skeleton")

	for submesh in submeshes:
		material_filename = submesh.material.name + ".material"

		submesh_node = mesh_node.create_child()
		submesh_node.set_attribute("type", "submesh")
		submesh_node.set_attribute("material", material_filename)
		submesh_node.set_attribute("primitive_type", "triangle_list")
		submesh_node.set_attribute("start_index", str(submesh.start_index))
		submesh_node.set_attribute("primitive_count", str(int(submesh.primitive_count)))

	file = open(filepath, "w", encoding="utf8", newline='\n')
	root_node.serialize(file)
	file.close()

	# Export materials
	if export_materials:
		for submesh in submeshes:
			write_material(filepath, copy_images, float_precision, submesh.material)
    def make_tetras(cls, vertices):
        ## 1    : 点群を包含する四面体を求める
        ##   1-1: 点群を包含する球を求める
        v_max = Vector((-999, -999, -999))
        v_min = Vector(( 999,  999,  999))
        for v in vertices:
            if v_max.x < v.x: v_max.x = v.x
            if v_max.y < v.y: v_max.y = v.y
            if v_max.z < v.z: v_max.z = v.z
            if v_min.x > v.x: v_min.x = v.x
            if v_min.y > v.y: v_min.y = v.y
            if v_min.z > v.z: v_min.z = v.z

        center = (v_max - v_min)*0.5

        r = max([(center-v).length for v in vertices]) ## 半径
        r += 0.1 ## ちょっとおまけ

        ## 1-2: 球に外接する四面体を求める
        v1 = Vector(( center.x
                    , center.y + 3.0*r
                    , center.z
                    ))

        v2 = Vector(( center.x - 2.0*math.sqrt(2)*r
                    , center.y - r
                    , center.z
                    ))

        v3 = Vector(( center.x + math.sqrt(2)*r
                    , center.y - r
                    , center.z + math.sqrt(6)*r
                    ))

        v4 = Vector(( center.x + math.sqrt(2)*r
                    , center.y - r
                    , center.z - math.sqrt(6)*r
                    ))

        outer = [v1, v2, v3, v4]
        tetras = []
        tetras.append(Tetrahedron(v1, v2, v3, v4))


        def to_identifier(tetra):
            vs = sorted(tetra.vertices, key=lambda v:v.x)
            a,b,c,d = vs
            return '{}/{}/{}//{}/{}/{}//{}/{}/{}//{}/{}/{}'.format( a.x,a.y,a.z
                                                                  , b.x,b.y,b.z
                                                                  , c.x,c.y,c.z
                                                                  , d.x,d.y,d.z
                                                                  )
        def __scan__(hash_tetras, hash_added, tetra):
            ide = to_identifier(tetra)
            if ide in hash_added:
                if ide in hash_tetras:
                    del hash_tetras[ide]
                return
            hash_tetras[ide] = tetra
            hash_added[ide] = True


        ## 幾何形状を動的に変化させるための一時リスト
        for v in vertices:
            hash_tetras = {}
            hash_added = {}

            tmp_tlist = []
            for t in tetras:
                if t.o is not None  and  t.r > (v - t.o).length:
                    tmp_tlist.append(t)

            for t1 in tmp_tlist:
                ## まずそれらを削除
                tetras.remove(t1)

                v1 = t1.vertices[0]
                v2 = t1.vertices[1]
                v3 = t1.vertices[2]
                v4 = t1.vertices[3]
                __scan__(hash_tetras, hash_added, Tetrahedron(v1, v2, v3, v))
                __scan__(hash_tetras, hash_added, Tetrahedron(v1, v2, v4, v))
                __scan__(hash_tetras, hash_added, Tetrahedron(v1, v3, v4, v))
                __scan__(hash_tetras, hash_added, Tetrahedron(v2, v3, v4, v))

            for t in hash_tetras.values():
                tetras.append( t )

        def cleanup(tetras, t4):
            for p1 in t4.vertices:
                for p2 in outer:
                    #if p1.x == p2.x and p1.y == p2.y and p1.z == p2.z:
                    if p1 == p2:
                        tetras.remove(t4)
                        return

        for t4 in tetras.copy():
            cleanup(tetras, t4)

        return tetras
Beispiel #56
0
 def execute(self, context):
     if self.sculpties == []:
         return {'CANCELLED'}
     sculpt_bb = {}
     gmin = None
     gmax = None
     edit_mode = context.mode == 'EDIT_MESH'
     if edit_mode:
         bpy.ops.object.editmode_toggle()
     if self.reset_origin:
         for obj in self.sculpties + self.objects:
             if 'MIRROR' not in [m.type for m in obj.modifiers]:
                 bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY',
                     center='MEDIAN')
     for obj in self.sculpties:
         mesh = obj.to_mesh(context.scene, True, 'RENDER')
         vmin, vmax = bounding_box(mesh)
         if not self.reset_origin:
             vmax.x = max(abs(vmin.x), abs(vmax.x))
             vmin.x = -vmax.x
             vmax.y = max(abs(vmin.y), abs(vmax.y))
             vmin.y = -vmax.y
             vmax.z = max(abs(vmin.z), abs(vmax.z))
             vmin.z = -vmax.z
         if self.aligned:
             if gmin is None:
                 gmin = Vector((vmin.x, vmin.y, vmin.z))
                 gmax = Vector((vmax.x, vmax.y, vmax.z))
             else:
                 gmin.x = min(gmin.x, vmin.x)
                 gmin.y = min(gmin.y, vmin.y)
                 gmin.z = min(gmin.z, vmin.z)
                 gmax.x = max(gmax.x, vmax.x)
                 gmax.y = max(gmax.y, vmax.y)
                 gmax.z = max(gmax.z, vmax.z)
         sculpt_bb[obj.name] = (vmin, vmax)
     if self.use_objects:
         for obj in self.objects:
             mesh = obj.to_mesh(context.scene, True, 'RENDER')
             vmin, vmax = bounding_box(mesh)
             if gmin is None:
                 gmin = Vector((vmin.x, vmin.y, vmin.z))
                 gmax = Vector((vmax.x, vmax.y, vmax.z))
             else:
                 gmin.x = min(gmin.x, vmin.x)
                 gmin.y = min(gmin.y, vmin.y)
                 gmin.z = min(gmin.z, vmin.z)
                 gmax.x = max(gmax.x, vmax.x)
                 gmax.y = max(gmax.y, vmax.y)
                 gmax.z = max(gmax.z, vmax.z)
         if not self.reset_origin:
             gmax.x = max(abs(gmin.x), abs(gmax.x))
             gmin.x = -gmax.x
             gmax.y = max(abs(gmin.y), abs(gmax.y))
             gmin.y = -gmax.y
             gmax.z = max(abs(gmin.z), abs(gmax.z))
             gmin.z = -gmax.z
     for obj_name in sculpt_bb:
         smin, smax = sculpt_bb[obj_name]
         if gmin is not None:
             if self.aligned:
                 vmin = Vector((gmin.x, gmin.y, gmin.z))
                 vmax = Vector((gmax.x, gmax.y, gmax.z))
             else:
                 vmin.x = min(gmin.x, smin.x)
                 vmin.y = min(gmin.y, smin.y)
                 vmin.z = min(gmin.z, smin.z)
                 vmax.x = max(gmax.x, smax.x)
                 vmax.y = max(gmax.y, smax.y)
                 vmax.z = max(gmax.z, smax.z)
             if self.optimise:
                 # try to improve bake range. Make sure that
                 # any increases don't go beyond the original mesh
                 f = floor((vmax.x - vmin.x) / (smax.x - smin.x))
                 if f > 1.0:
                     size = (vmax.x - vmin.x) * 0.5
                     center = vmin.x + size
                     vmin.x = center - size / f
                     vmax.x = center + size / f
                 f = floor((vmax.y - vmin.y) / (smax.y - smin.y))
                 if f > 1.0:
                     size = (vmax.y - vmin.y) * 0.5
                     center = vmin.y + size
                     vmin.y = center - size / f
                     vmax.y = center + size / f
                 f = floor((vmax.z - vmin.z) / (smax.z - smin.z))
                 if f > 1.0:
                     size = (vmax.z - vmin.z) * 0.5
                     center = vmin.z + size
                     vmin.z = center - size / f
                     vmax.z = center + size / f
         else:
             vmin = smin
             vmax = smax
         if self.red_scale != 100.0:
             red_range = vmax.x - vmin.x
             if self.red_scale == 0.0:
                 red_adjust = red_range / 2.0
             else:
                 new_range = red_range * 100.0 / self.red_scale
                 red_adjust = (new_range - red_range) / 2.0
             vmin.x -= red_adjust
             vmax.x += red_adjust
         if self.green_scale != 100.0:
             green_range = vmax.y - vmin.y
             if self.green_scale == 0.0:
                 green_adjust = green_range / 2.0
             else:
                 new_range = green_range * 100.0 / self.green_scale
                 green_adjust = (new_range - green_range) / 2.0
             vmin.y -= green_adjust
             vmax.y += green_adjust
         if self.blue_scale != 100.0:
             blue_range = vmax.z - vmin.z
             if self.blue_scale == 0.0:
                 blue_adjust = blue_range / 2.0
             else:
                 new_range = blue_range * 100.0 / self.blue_scale
                 blue_adjust = (new_range - blue_range) / 2.0
             vmin.z -= blue_adjust
             vmax.z += blue_adjust
         bake(bpy.data.objects[obj_name], context.scene,
             vmin, vmax, self.update_name)
     for a in context.window.screen.areas:
         for s in a.spaces:
             if s.type == 'IMAGE_EDITOR':
                 # force refresh for missing images set to generated
                 if s.image is not None:
                     t = bpy.data.images[s.image.name]
                     s.image = t
         if a.type == 'IMAGE_EDITOR':
             a.tag_redraw()
     if edit_mode:
         bpy.ops.object.editmode_toggle()
     if not self.no_dialog:
         context.scene['sculpty_bake'] = {
             'r': self.red_scale,
             'g': self.green_scale,
             'b': self.blue_scale,
             'ro': self.reset_origin,
             'uo': self.use_objects,
             'a': self.aligned,
             'o': self.optimise}
     return {'FINISHED'}
def main(self, context):
    obj = context.active_object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)

    face_sets = []

    faces = []

    force_orthogonal = self.properties.force_orthogonal
    method = self.properties.method

    # store data
    for f in bm.faces:
        if f.select:
            if method == 'AVERAGE':
                faces.append (f)

            elif method == 'INDIVIDUAL':
                face_sets.append ([f])

    if method == 'AVERAGE':
        face_sets.append (faces)

    for fs in face_sets:

        normal = Vector ()
        center = Vector ()

        for f in fs:
            normal += f.normal
            center += f.calc_center_median_weighted ()

        normal.normalize ()
        center /= len (fs)

        if force_orthogonal:
            x = abs (normal.x)
            y = abs (normal.y)
            z = abs (normal.z)

            if x > y and x > z:
                normal.x /= x
                normal.y = 0.0
                normal.z = 0.0

            if y > x and y > z:
                normal.x = 0.0
                normal.y /= y
                normal.z = 0.0

            if z > y and z > x:
                normal.x = 0.0
                normal.y = 0.0
                normal.z /= z

        for f in fs:
            for v in f.verts:
                d = geometry.distance_point_to_plane (v.co, center, normal)
                v.co -= normal * d

    bmesh.update_edit_mesh(me)
Beispiel #58
0
def recursive_aabb(facelist, parent, level):
    """ Recursively build a tree of aabb nodes, returns the root of the subtree.
    """
    # This code is heavily inspired by nwmax and Waylands original code
    if level > 20:
        raise RuntimeError("Max recursion depth reached when building aabb "
                           "tree. Look for duplicate faces.")

    bottom_left = Vector((10000, 10000, 10000))
    top_right = Vector((-10000, -10000, -10000))
    midpoints = Vector((0, 0, 0))
    # First we calculate the bounding box
    for face in facelist:
        for x, y, z in face["verts"]:
            if x < bottom_left.x:
                bottom_left.x = x
            if y < bottom_left.y:
                bottom_left.y = y
            if z < bottom_left.z:
                bottom_left.z = z

            if x > top_right.x:
                top_right.x = x
            if y > top_right.y:
                top_right.y = y
            if z > top_right.z:
                top_right.z = z
        midpoints += face["center"]

    midpoint = midpoints / len(facelist)

    bounding_box = {"co1": bottom_left[:], "co2": top_right[:],
                    "index": -1, "left": None,
                    "right": None, "parent": parent}

    ## If this is a leaf we're done
    if len(facelist) == 1:
        bounding_box["index"] = facelist[0]["index"]
        return bounding_box

    ## Otherwise we have to decide how to do the splits
    splits = {"x": {"left": [], "right": []},
              "y": {"left": [], "right": []},
              "z": {"left": [], "right": []}}

    #find the best split, which is the split where the two sides are balanced
    for face in facelist:
        if face["center"].x < midpoint.x:
            splits["x"]["left"].append(face)
        else:
            splits["x"]["right"].append(face)
        if face["center"].y < midpoint.y:
            splits["y"]["left"].append(face)
        else:
            splits["y"]["right"].append(face)
        if face["center"].z < midpoint.z:
            splits["z"]["left"].append(face)
        else:
            splits["z"]["right"].append(face)

    split = None

    #We calculate the difference between the two sides
    delta_x = abs(len(splits["x"]["right"]) - len(splits["x"]["left"]))
    delta_y = abs(len(splits["y"]["right"]) - len(splits["y"]["left"]))
    delta_z = abs(len(splits["z"]["right"]) - len(splits["z"]["left"]))

    # We pick the split where the difference between the splits are as small as possible
    if delta_x < delta_y and delta_x < delta_z:
        split = splits["x"]
    elif delta_y < delta_z:
        split = splits["y"]
    else:
        split = splits["z"]

    if split["left"]:
        bounding_box["left"] = recursive_aabb(split["left"], bounding_box, level + 1)
    if split["right"]:
        bounding_box["right"] = recursive_aabb(split["right"], bounding_box, level + 1)
    return bounding_box
Beispiel #59
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'}