Beispiel #1
0
 def scale_st(self, x, y, debug):
     x_slop = math.fabs(self.x1 - self.x2) * 0.05
     y_slop = math.fabs(self.y1 - self.y2) * 0.05
     if self.x1 < self.x2:
         if x < (self.x1 - x_slop) or x > (self.x2 + x_slop):
             raise ExportError(
                 "ERROR: UV coordinates %f,%f are out of bounds (%s) - X normal case!"
                 % (x, y, debug))
     else:
         if x < (self.x2 - x_slop) or x > (self.x1 + x_slop):
             raise ExportError(
                 "ERROR: UV coordinates %f,%f are out of bounds (%s) - X flip case!"
                 % (x, y, debug))
     if self.y1 < self.y2:
         if y < (self.y1 - y_slop) or y > (self.y2 + y_slop):
             raise ExportError(
                 "ERROR: UV coordinates %f,%f are out of bounds (%s) - Y normal case!"
                 % (x, y, debug))
     else:
         if y < (self.y2 - y_slop) or y > (self.y1 + y_slop):
             raise ExportError(
                 "ERROR: UV coordinates %f,%f are out of bounds (%s) - Y flip case!"
                 % (x, y, debug))
     return (interp(self.x1, self.s1, self.x2, self.s2,
                    x), interp(self.y1, self.t1, self.y2, self.t2, y))
Beispiel #2
0
def locate_root(path):
    hierarchy = path.split('/')
    for known_folder in [['Custom Scenery',1], ['Global Scenery',1], ['default scenery',2]]:
        if known_folder[0] in hierarchy:
            idx = hierarchy.index(known_folder[0])
            return ('/'.join(hierarchy[:(idx+1-known_folder[1])]),'/'.join(hierarchy[:(idx+2)]))
    raise ExportError("X-Plane folder not found.  Your blender file must be INSIDE a scenery package!")
Beispiel #3
0
def export_any_bone(file, name, x, y, z, dx, dy, dz):
    if has_prefix(name, 'EL'):
        cmd="BONE_INTERSECTION_EDGE_LEFT"
        metrics=strip_prefix(name,'EL')
    elif has_prefix(name, 'ER'):
        cmd="BONE_INTERSECTION_EDGE_RIGHT"
        metrics=strip_prefix(name,'ER')
    elif has_prefix(name, 'AL'):
        cmd="BONE_APPROACH_LEFT"
        metrics=strip_prefix(name,'AL')
    elif has_prefix(name, 'AR'):
        cmd="BONE_APPROACH_RIGHT"
        metrics=strip_prefix(name,'AR')
    else:
        raise ExportError("Bone %s - I cannot parse this prefix" % name)
    metrics = metrics.replace(",",".",3)
    nums = metrics.split()
    if len(nums) != 3:
        raise ExportError("Bone %s - I cannot parse these numbers: %s" % (name, metrics))
    file.write("%s %d %f %f     %f %f %f   %f %f %f\n" % (cmd, int(nums[0]),float(nums[1]),float(nums[2]),  x,z,-y,   dx,dz,-dy))
Beispiel #4
0
def child_obj_name(wrapper, all):
    choices = getChildren(wrapper, all)
    for c in choices:
        nm = strip_suffix(c.name)
        # For Alex - skip LD1
        if nm[-3:] != 'LD1':
            if c.getType() == 'Mesh':
                return c.name
            if c.getType() == 'Empty':
                return c.name
    raise ExportError("ERROR: could not find real physical name for obj %s." %
                      wrapper.name)
    return wrapper.name[3:]
Beispiel #5
0
 def add_face(self, f, owner):
     mm = owner.getMatrix('localspace')
     np = Prim(f)
     for v, uv in map(None, f.verts, f.uv):
         if f.smooth:
             vt = VT(xform_fixed(v, mm), xform_no(v, mm), uv, [])
         else:
             vt = VT(xform_fixed(v, mm), xform_no(f, mm), uv, [])
         vts = str(vt)
         if vts in self.idx:
             np.idx.append(self.idx[vts])
         else:
             self.idx[vts] = len(self.vlist)
             np.idx.append(len(self.vlist))
             self.vlist.append(vt)
     if len(f.verts) != 3 and len(f.verts) != 4:
         raise ExportError("Mesh %s has a face that isn't a tri or quad." %
                           owner.name)
     if not (f.mode & Mesh.FaceModes.INVISIBLE):
         if len(f.verts) == 3: self.idx_count += 3
         else: self.idx_count += 6
         self.faces.append(np)
Beispiel #6
0
def get_fgon(mesh):
    vert_list = []
    for e in mesh.edges:
        if (e.flag & Mesh.EdgeFlags.FGON) == 0:
            v_term = e.v1.index
            v_now = e.v2.index
            v_prev = v_term
            #print "start with %d " % v_term
            vert_list.append(v_term)
            while v_term != v_now:
                #print v_now
                vert_list.append(v_now)
                v_next = next_fgon_edge(mesh, v_prev, v_now)
                if v_next == -1:
                    print "ERROR: bad fgon %s" % o.name
                    break
                v_prev = v_now
                v_now = v_next
            break
    else:
        raise ExportError("ERROR: mesh %s apparently has no non-FGON edges?" %
                          o.name)
    return vert_list
Beispiel #7
0
def out_obj(obj,file,oname, mode, xyz,xr,yr,zr,spans,span_length,ctr):
    oname = get_prop(obj,'external', oname)
    graded = has_prop(obj,'graded')
    cmd="OBJECT_DRAPED"
    if graded:
        cmd="OBJECT_GRADED"

    if mode == "DIST":
        repeat_len=(spans-1) * span_length
        if repeat_len <= 0.0 or span_length <= 0.0:
            raise ExportError("Object has repeat interval that is not positive: %s/%s" % (obj.parent.name,obj.name))
        start_offset=xyz[1]
        end_offset = min(start_offset,span_length-start_offset)
        while end_offset > span_length:
            end_offset = end_offset - span_length
        if end_offset < 1.0:
            end_offset = span_length
    else:
        repeat_len=span_length
        start_offset=xyz[1]
        end_offset=xyz[1]

    # note: this used to use the road modeled length as period.  But this sucks for Alex because he would have to model only ONE unit of road to get the right
    # pylon wavelength.  Then his end cap and pylon would overlap which would be visually undesireable.
    file.write("%s %s %s\t%f %f %f %f %f %f %f/%f %f/%f" % (cmd,mode,oname,
        xyz[0]-ctr,xyz[0]-ctr,
        round(zr * 180 / 3.14159265),
        round(zr * 180 / 3.14159265),
        repeat_len,repeat_len,
        start_offset,end_offset,
        start_offset,end_offset))
    if has_prop(obj,'obj_show_level'):
        file.write(" %s" % get_prop(obj,'obj_show_level',''))
    file.write("\n")
    obj_keys = ['OBJECT_FREQ', 'OBJECT_ALT' ];
    emit_properties(file, obj, obj_keys)
    return graded
Beispiel #8
0
def parse_spelling_info(lines, info):
    cur_floor = ''
    for (line_no, line) in enumerate(lines):
        lclean = line.split('#')[0].strip()
        token = lclean.split()
        if len(token) == 0: continue
        if len(token) >= 2 and token[0].upper() == 'FLOOR':
            floor_id = token[1]
            if floor_id in info:
                raise ExportError("Duplicate floor cmd on line %d: %s" %
                                  (line_no, line))
            info[floor_id] = []
            cur_floor = floor_id
        elif len(token) >= 6 and token[0].upper() == 'WALL':
            if not cur_floor in info:
                raise ExportError(
                    "Wall token found but no floor defined, line %d: %s" %
                    (line_no, line))
            info[cur_floor].append(
                [token[5], [token[1], token[2], token[3], token[4]]])
        elif len(token) >= 5 and token[0].upper() == 'WALL_RULE':
            if not cur_floor in info:
                raise ExportError(
                    "Wall token found but no floor defined, line %d: %s" %
                    (line_no, line))
            info[cur_floor][-1][1].append(
                [token[1], token[2], token[3], token[4]])
        elif len(token) >= 2 and token[0].upper() == 'SPELLING':
            if not cur_floor in info:
                raise ExportError(
                    "Spelling token found but no floor defined, line %d: %s" %
                    (line_no, line))
            if len(info[cur_floor]) == 0:
                raise ExportError(
                    "Spelling token found but floor has no walls so far, line %d: %s"
                    % (line_no, line))
            info[cur_floor][-1].append(token[1:])
        else:
            raise ExportError("Unknown text file contents: %s at line %d." %
                              (line, line_no))
Beispiel #9
0
def lib_fac_name(obj, theme):
    if has_prop(obj, 'external'):
        return get_prop(obj, 'external', obj.name)
    else:
        raise ExportError("ERROR: The facade %s has no external property." %
                          obj.name)
Beispiel #10
0
def export_edge_bone(file, degree, finger, x, y, z, meta_rect):
    l=meta_rect[0]
    b=meta_rect[1]
    r=meta_rect[2]
    t=meta_rect[3]
    cx = (l+r)*0.5
    cy = (b+t)*0.5

    if degree == 3:
        if y > cy:
            corner = 0
        else:
            corner = 2
    else:
        if x < cx:
            if y < cy:
                corner=0
            else:
                corner=1
        else:
            if y < cy:
                corner=3
            else:
                corner=2
    if degree == 2:
        if corner == 3: corner = 0
        elif corner == 2: corner = 1

    corner_next = (corner + 1) % degree

    if finger == corner:
        is_right = 0
    elif finger == corner_next:
        is_right = 1
    else:
        raise ExportError("Junction references a finger that is not appropriate for its corner. finger = %d, corner = %d, degree = %d" % (finger, corner, degree))

    if degree == 3:
        if corner == 0:
            off_1 = t-y
            off_2 = l-x
        elif corner == 2:
            off_1 = x-l
            off_2 = b-y

        if finger == 0:
            dx = -1
            dz = 0
        elif finger == 1:
            dx = 0
            dz = -1
        elif finger == 2:
            dx = 0
            dz = 1
    else:
        if corner == 0:
            off_1 = x-l
            off_2 = b-y
        elif corner == 1:
            off_1 = t-y
            off_2 = l-x
        elif corner == 2:
            off_1 = r-x
            off_2 = y-t
        elif corner == 3:
            off_1 = y-b
            off_2 = x-r

        if finger == 0:
            dx = 0
            dz = 1
        elif finger == 1:
            dx = -1
            dz = 0
        elif finger == 2:
            dx = 0
            dz = -1
        elif finger == 3:
            dx = 1
            dz = 0

    off_1 = round(off_1,5)
    off_2 = round(off_2,2)
    x = round(x,5)
    y = round(y,5)
    z = round(z,5)

    if is_right:
        file.write("BONE_INTERSECTION_EDGE_RIGHT %d %f %f   %f %f %f %f %f %f\n" %( corner, off_1, off_2, x, z, -y, dx, 0, dz))
    else:
        file.write("BONE_INTERSECTION_EDGE_LEFT %d %f %f   %f %f %f %f %f %f\n" %( corner, off_1, off_2, x, z, -y, dx, 0, dz))
def export_hier(parent, all, root, depth):
    total = 0
    kids = getChildren(parent, all)
    objs = filter_objects(kids, 'Empty', 'OBJ')
    objs += filter_objects(kids, 'Empty', 'VRT')
    objs += filter_objects(kids, 'Empty', 'END')
    objs += filter_objects(kids, 'Empty', 'BGN')

    grps = filter_objects(kids, 'Empty', 'GRP')
    for g in grps:
        total = total + export_hier(g, all, root, depth + 1)

    # Alex does NOT want the outer-most OBJs to be exported.  His projects
    # apparently contain lots of random objects floating around.
    # This if statement could be nuked to restore the old behavior.
    # The current impl lets free objects out if there simply are no groups.

    #if depth > 0:					#This would STRICTLY skip free objs.
    if depth > 0 or len(
            grps) == 0:  #This takes free objs if there are no groups.
        for o in objs:
            n = strip_suffix(o.name)[3:]
            n = get_prop(o, 'rname', n)
            n += '.obj'
            partial = get_prop(o, 'path', '.')
            export_path = os.path.join(partial, n)
            export_path = os.path.join(root, export_path)
            if not os.path.exists(os.path.dirname(export_path)):
                os.makedirs(os.path.dirname(export_path))
            try:
                (sim, pack) = locate_root(export_path)
            except ExportError, e:
                pack = None
            exporter = OBJexport8(export_path)
            exporter.additive_lod = 1
            my_parts = getGrandChildren(o, all)
            #if self.debug:
            #	for p in my_parts:
            #		print " object export %s will export DB %s" % (oname, p.name)
            prefix = ''
            parts = partial.count('/') + 1
            if partial == '.': parts = 0
            for n in range(parts):
                prefix += '../'
            exporter.openFile(my_parts, o, prefix)
            exporter.writeHeader()
            if has_prop(o, 'vname'):
                if pack == None:
                    raise ExportError(
                        "Illegal vname directive on %s - blender file is not in a scenery pack."
                        % o.name)
                exporter.file.write(
                    "EXPORT %s.obj %s\n" %
                    (strip_suffix(get_prop(o, 'vname', o.name)),
                     os.path.normpath(export_path[len(pack) + 1:])))
            if has_prop(o, 'vname1'):
                exporter.file.write(
                    "EXPORT %s.obj %s\n" %
                    (strip_suffix(get_prop(o, 'vname1', o.name)),
                     os.path.normpath(export_path[len(pack) + 1:])))
            if has_prop(o, 'vname2'):
                exporter.file.write(
                    "EXPORT %s.obj %s\n" %
                    (strip_suffix(get_prop(o, 'vname2', o.name)),
                     os.path.normpath(export_path[len(pack) + 1:])))
            exporter.writeObjects(my_parts)
            total = total + 1
Beispiel #12
0
    def export_ag_tile(self, obj, ann_list, all, lib_root, valid_ids):
        if self.debug:
            print "Exporting ag tile based on empty obj %s." % obj.name
        name = obj.name
        if valid_ids != None:
            if not name.isdigit():
                raise ExportError(
                    "ERROR: tile %s has a name that is not a vaild numeric tile ID."
                    % name)
            self.file.write("\nTILE_ID %s\n" % name)
            valid_ids.append(name)
        else:
            self.file.write("\n# Tile: %s\n" % name)
        # Pass 1.  Work up an OBJ master list for indexing, and find the tile boundaries.
        has_tile = 0

        objs = filter_objects(ann_list, 'Empty', 'OBJ')
        facs = filter_objects(ann_list, 'Mesh', 'FAC')
        tiles = filter_objects(ann_list, 'Mesh', 'TILE')
        trees = filter_objects(ann_list, 'Mesh', 'TREE')
        trlns = filter_objects(ann_list, 'Mesh', 'TRLN')
        pins = filter_objects(ann_list, 'Lamp', 'PIN')
        metas = filter_objects(ann_list, 'Mesh', 'META')

        if self.debug:
            print "   %d annotations, %d objs, %d faces, %d tiles, %d trees, %d tree lines, %d pins" % (
                len(ann_list), len(objs), len(facs), len(tiles), len(trees),
                len(trlns), len(pins))

        if len(tiles) != 1:
            raise ExportError("ERROR: tile %s has %d tile objects." %
                              (obj.name, len(tiles)))
            return

        tt = TILE(tiles[0])

        tt.write_tile_header(self.file)

        #
        # ATTACHED OBJECTS
        #
        for o in objs:
            #Ben says: this used to have an anti-dupe logic using a layer check...but...that should NOT be necessary!
            #One OBJ for each export.
            oname = lib_obj_name(o, self.theme, lib_root)
            #xr=tt.scale_s(o.LocX)
            #yr=tt.scale_t(o.LocY)
            loc = o.getMatrix('localspace').translationPart()
            (xr, yr) = tt.scale_st(loc[0], loc[1], o.name)
            if has_prop(o, "STEP"):
                agl_span = 0
                step = get_prop(o, "step", 1.0)
                delta_agl = o.getMatrix('localspace').translationPart()[2]
                scraper_parts = getGrandChildren(o, all)
                for s in scraper_parts:
                    mm = s.getMatrix('localspace')
                    if s.getType() == 'Mesh':
                        mesh = s.getData(mesh=True)
                        for v in mesh.verts:
                            vt = xform(v, mm)
                            agl_span = max(vt[2], agl_span)
                self.file.write("OBJ_SCRAPER %f %f %f %d %f %f %s" %
                                (xr, yr, make_degs(-o.RotZ),
                                 self.obj_name_list.index(oname), agl_span,
                                 agl_span + delta_agl, step))
            elif has_prop(o, "DELTA"):
                self.file.write(
                    "OBJ_DELTA %f %f %f %s %d" %
                    (xr, yr, make_degs(-o.RotZ), get_prop(
                        o, "DELTA", 0.0), self.obj_name_list.index(oname)))
            elif has_prop(o, "GRADED"):
                self.file.write("OBJ_GRADED %f %f %f %d" %
                                (xr, yr, make_degs(-o.RotZ),
                                 self.obj_name_list.index(oname)))
            else:
                self.file.write("OBJ_DRAPED %f %f %f %d" %
                                (xr, yr, make_degs(-o.RotZ),
                                 self.obj_name_list.index(oname)))
            if has_prop(o, 'show_level'):
                self.file.write(" %s" % get_prop(o, 'show_level', ''))
            self.file.write("\n")

        #
        # TREE LINES
        #
        for o in trlns:
            mesh = o.getData(mesh=True)
            mm = o.getMatrix('localspace')
            if len(mesh.faces) != 1:
                raise ExportError("ERROR: mesh %s has %d faces." %
                                  (o.name, len(mesh.faces)))
                continue
            f = mesh.faces[0]
            if len(f.v) != 4:
                raise ExportError("ERROR: mesh %s has %d vertices." %
                                  (o.name, len(f.v)))
            v0 = xform(f.v[0], mm)
            v1 = xform(f.v[1], mm)
            v2 = xform(f.v[2], mm)
            v3 = xform(f.v[3], mm)
            exp_layer_name = strip_prefix(o.name, 'TRLN')
            if near_zero(v0[2]) and near_zero(v1[2]):
                out_trln(self.file, v0, v1, tt, exp_layer_name)
            elif near_zero(v1[2]) and near_zero(v2[2]):
                out_trln(self.file, v1, v2, tt, exp_layer_name)
            elif near_zero(v2[2]) and near_zero(v3[2]):
                out_trln(self.file, v2, v3, tt, exp_layer_name)
            elif near_zero(v3[2]) and near_zero(v0[2]):
                out_trln(self.file, v3, v0, tt, exp_layer_name)
            else:
                raise ExportError(
                    "ERROR: Tree line seems to have no zero intersect" %
                    o.name)
        #
        # INDIVIDUAL TREES
        #
        for o in trees:
            mesh = o.getData(mesh=True)
            loc = o.getMatrix('localspace').translationPart()
            (xr, yr) = tt.scale_st(loc[0], loc[1], o.name)
            hi = 0
            lo = 0
            mm = o.getMatrix('localspace')
            for f in mesh.faces:
                if len(f.v) != 4:
                    raise ExportError(
                        "ERROR: the tree %s has a face that is not four-sided."
                        % o.name)
                v0 = xform(f.v[0], mm)
                v1 = xform(f.v[1], mm)
                v2 = xform(f.v[2], mm)
                v3 = xform(f.v[3], mm)
                if near_zero(v0[2]) and near_zero(v1[2]):
                    out_tree(self.file, xr, yr, v0, v1, make_degs(-o.RotZ),
                             strip_prefix(o.name, 'TREE'))
                    break
                elif near_zero(v1[2]) and near_zero(v2[2]):
                    out_tree(self.file, xr, yr, v1, v2, make_degs(-o.RotZ),
                             strip_prefix(o.name, 'TREE'))
                    break
                elif near_zero(v2[2]) and near_zero(v3[2]):
                    out_tree(self.file, xr, yr, v2, v3, make_degs(-o.RotZ),
                             strip_prefix(o.name, 'TREE'))
                    break
                elif near_zero(v3[2]) and near_zero(v0[2]):
                    out_tree(self.file, xr, yr, v3, v0, make_degs(-o.RotZ),
                             strip_prefix(o.name, 'TREE'))
                    break
                else:
                    print v0, v1, v2, v3
                    raise ExportError(
                        "ERROR: Tree %s seems to have non zero intersect" %
                        o.name)
        #
        # FACADES
        #
        for o in facs:
            mesh = o.getData(mesh=True)
            idx = self.fac_name_list.index(lib_fac_name(o, self.theme))
            # We are going to find one non-fgon edge (that is, an edge not internal to the triangulation of the fgon) and
            # then loop around edge connectivity to find the perimeter.  There MIGHT be a blender way to do this with indexing,
            # but for the small number of edges we have, screw it...next_fgon_edge is O(N)
            if not is_really_fgon(mesh):
                if len(mesh.faces) != 1 or len(mesh.faces[0].verts) != 4:
                    raise ExportError("Mesh %s is not an fgon." % mesh.name)
            vert_list = get_fgon(mesh)
            if fgon_cw(vert_list, mesh):
                vert_list.reverse()

            if len(vert_list) < 2:
                raise ExportError("ERROR: mesh %s has too few vertices." %
                                  o.name)
                continue
            mm = o.getMatrix('localspace')
            v = mesh.verts[0]
            vt = xform(v, mm)
            h = vt[2]

            # Rotate the vertex list to have all but one zero interception first.  This ensures that all non-zero
            # are continuous; for fence-style facades, this means we won't have the end, then circulate to the beginning.
            n = 0
            found_any_near_zero = 0
            for ii, i in enumerate(vert_list):
                if near_zero(xform(mesh.verts[i], mm)[2]):
                    n = ii
                    found_any_near_zero = 1
            if n != 0:
                vert_list[:] = vert_list[n:] + vert_list[:n]

            # What the hell is THIS?  Well, if we have a FENCE style facade, the fgon-cw test above is going to produce CRAP because
            # the facade isn't co-planar.  So: take the first face and compare its normal in the order we traverse it (e.g. grabbing its 4
            # verts as they pass by in the stream) to the real face normal.  If the user flipped the face, flip the stream.
            if found_any_near_zero:
                v_our_order = []
                f = mesh.faces[0]
                for i in vert_list:
                    if face_has_vert_index(f, i):
                        v_our_order.append(i)
                n = TriangleNormal(mesh.verts[v_our_order[0]].co,
                                   mesh.verts[v_our_order[1]].co,
                                   mesh.verts[v_our_order[2]].co)
                if f.no.dot(n) < 0:
                    vert_list.reverse()

            # Nuke zero intercepts so that fences are now 'just the fence'.
            vert_list[:] = [
                v for v in vert_list
                if not near_zero(xform(mesh.verts[v], mm)[2])
            ]

            wlist = []
            for i in xrange(1, len(vert_list)):
                v1 = vert_list[i - 1]
                v2 = vert_list[i]
                for f in mesh.faces:
                    if face_has_vert_index(f, v1) and face_has_vert_index(
                            f, v2):
                        if f.mode & Mesh.FaceModes.TILES:
                            wlist.append(1)
                        else:
                            wlist.append(0)
                        break
                else:
                    raise ExportError("Internal error: we never found a face.")

            wlist.append(0)

            if sum(wlist) > 0:
                self.file.write("FAC_WALLS %d %f" % (idx, h))
                for x, i in enumerate(vert_list):
                    v = mesh.verts[i]
                    vt = xform(v, mm)
                    #print vt
                    (xr, yr) = tt.scale_st(vt[0], vt[1], o.name)
                    self.file.write(" %f %f %d" % (xr, yr, wlist[x]))
                self.file.write("\n")
            else:
                self.file.write("FAC %d %f" % (idx, h))
                for i in vert_list:
                    v = mesh.verts[i]
                    vt = xform(v, mm)
                    #print vt
                    (xr, yr) = tt.scale_st(vt[0], vt[1], o.name)
                    self.file.write(" %f %f" % (xr, yr))
                self.file.write("\n")
        #
        # PINS
        #
        for o in pins:
            loc = o.getMatrix('localspace').translationPart()
            (xr, yr) = tt.scale_st(loc[0], loc[1], o.name)
            self.file.write("%s %f %f\n" %
                            (strip_prefix(o.name, 'PIN'), xr, yr))
        #
        # Meta-rects
        #
        for o in metas:
            mesh = o.getData(mesh=True)
            if len(mesh.faces) != 1:
                raise ExportError(
                    "ERROR: meta object %s does not have one face." % o.name)
                break
            f = mesh.faces[0]
            if len(f.verts) != 4:
                raise ExportError(
                    "ERROR: face for meta object %s does not have four sides."
                    % o.name)
                break
            mm = o.getMatrix('localspace')
            v0 = xform(f.v[0], mm)
            v1 = xform(f.v[1], mm)
            v2 = xform(f.v[2], mm)
            v3 = xform(f.v[3], mm)
            WWS = 4.25
            if strip_prefix(o.name, 'META').lower() == 'block_edge':
                self.file.write("EDGE_MAX %f %f %f %f\n" % (tt.scale_stst(
                    min(v0[0], v1[0], v2[0], v3[0]) - WWS,
                    min(v0[1], v1[1], v2[1], v3[1]) - WWS,
                    max(v0[0], v1[0], v2[0], v3[0]) + WWS,
                    max(v0[1], v1[1], v2[1], v3[1]) + WWS, o.name)))
            else:
                self.file.write("%s " % strip_prefix(o.name, 'META'))
                self.file.write(
                    "%f %f %f %f\n" %
                    tt.scale_stst(min(v0[0], v1[0], v2[0], v3[0]),
                                  min(v0[1], v1[1], v2[1], v3[1]),
                                  max(v0[0], v1[0], v2[0], v3[0]),
                                  max(v0[1], v1[1], v2[1], v3[1]), o.name))
Beispiel #13
0
    def export_chain(self, obj, scene):
        if self.debug: print "Exporting chain based on empty obj %s." % obj.name
        # First pass: pull out all segments.  Hels us find real lenght
        max_len=0
        name=strip_suffix(obj.name[3:])


        annotations = getChildren(obj,scene)
        segs = filter_objects(annotations,'Mesh', '')
        objs = filter_objects(annotations,'Empty','OBJ')
        obj2 = filter_objects(annotations,'Mesh','OBJ')
        ends = filter_objects(annotations,'Empty','END')
        end2 = filter_objects(annotations,'Mesh','END')
        bgns = filter_objects(annotations,'Empty','BGN')
        bgn2 = filter_objects(annotations,'Mesh','BGN')
        vrts = filter_objects(annotations,'Empty','VRT')
        vrt2 = filter_objects(annotations,'Mesh','VRT')
        cars = filter_objects(annotations,'Empty','CAR')
        car2 = filter_objects(annotations,'Mesh','CAR')
        objs.extend(obj2)
        ends.extend(end2)
        bgns.extend(bgn2)
        vrts.extend(vrt2)
        cars.extend(car2)

        bounds = []

        for s in segs:
            if 1 in s.layers or 2 in s.layers or 3 in s.layers:
                if not s in objs and not s in ends and not s in bgns and not s in cars and not s in vrts:
                    mesh=s.getData(mesh=True)
                    mm=s.getMatrix('localspace')
                    for v in mesh.verts:
                        vc=xform(v,mm)
                        if len(bounds) == 0:
                            bounds.extend(vc)
                            bounds.extend(vc)
                        else:
                            for n in [0,1,2]:
                                bounds[n  ] = min(bounds[n  ],vc[n])
                                bounds[n+3] = max(bounds[n+3],vc[n])

        rwidth = abs(round(bounds[3] - bounds[0],4))
        rlength = abs(round(bounds[4] - bounds[1],4))
        rwidth = float(get_prop(obj,'width',str(rwidth)))
        rgb = get_prop(obj, 'RGB', "1 1 1")

        num_lengths=1
        if has_prop(obj,'spans'):
            num_lengths=float(get_prop(obj,'spans','1'))
        else:
            num_lengths = guess_spans(rlength, bgns, ends, objs)
        rlength /= num_lengths
        self.file.write("\n#%s (%d spans)\n" % (get_prop(obj,'NAME',obj.name[3:]), num_lengths))
        self.file.write("ROAD_TYPE %s %.4f %.4f 0 %s\n" % (name.split('.')[0], rwidth, rlength, rgb))
        if has_prop(obj,'ROAD_CENTER'):
            bounds[0] = -float(get_prop(obj,'ROAD_CENTER',str(rwidth*0.5)))
        elif has_prop(obj,'width'):
            bounds[0] = -(rwidth*0.5)
        self.file.write("ROAD_CENTER %f\n" % -bounds[0])
        road_keys = ['REQUIRE_EVEN', 'SHOW_LEVEL' ];
        emit_properties(self.file, obj, road_keys)
        self.last_scale = 0

        general_mode='DRAPED'

        for s in segs:
            if 1 in s.layers or 2 in s.layers or 3 in s.layers:
                if not s in objs and not s in ends and not s in bgns and not s in cars and not s in vrts:
                    surf=get_prop(s,'surface','asphalt')
                    mesh=s.getData(mesh=True)
                    mm=s.getMatrix('localspace')
                    for f in mesh.faces:
                        if f.mode & Mesh.FaceModes.TWOSIDE:
                            n=len(f.v)
                            if n != 4:
                                raise ExportError("   found degenerate wires with %d verts in mesh %s." % (n, s.name))
                            else:
                                v=f.verts
                                uv=f.uv
                                for idx in range(0,4):
                                    max_len = max(max_len,round(v[idx].co[1]))

                                v0=xform(f.v[0],mm)
                                v1=xform(f.v[1],mm)
                                v2=xform(f.v[2],mm)
                                v3=xform(f.v[3],mm)

                                y_min = min(v1[2],v2[2],v3[2],v0[2])
                                y_max = max(v1[2],v2[2],v3[2],v0[2])
                                x = v1[0]
                                self.file.write("WIRE 0 20000\t%f %f %f\n" % ((x - bounds[0]) / rwidth, y_max, 1.0 - y_min / y_max))
                        else:
                            #if f.image.filename[:2] != '//':
                            #	raise ExportError("The image %s is not using a relative path.  It is needed by obj %s." % (f.image.name, obj.name))
                            #if not f.image.has_data:
                            #	f.image.reload()
                            #if not f.image.has_data:
                            #	raise ExportError("The image %s is not loaded - perhaps the texture is misisng; it is needed by obj %s." % (f.image.name, obj.name))
                            #(width,height)=f.image.getSize()
                            mat=mesh.materials[f.mat]
                            im = mat.textures[0].tex.image
                            if not im.has_data:
                                raise ExportError("The image %s is not loaded - perhaps the texture is misisng; it is needed by obj %s." % (im.name, obj.name))

                            (width,height)=im.getSize()
                            #graded = has_prop(obj,'graded')
                            graded = 1
                            if f.mode & Mesh.FaceModes.TILES:
                                graded = 0
                            poly_os = 1
                            if graded:
                                general_mode='GRADED'
                                poly_os = 0
                            shader_idx=self.shaders.shader_idx(mesh,f)
                            hard_face = f.mode & Mesh.FaceModes.DYNAMIC
                            n=len(f.v)
                            if n != 4:
                                raise ExportError("   found degenerate face with %d verts in mesh %s." % (n, s.name))
                            else:
                                if width != self.last_scale:
                                    self.last_scale = width
                                    self.file.write("SCALE %d\n" % width)
                                v=f.verts
                                uv=f.uv
                                for idx in range(0,4):
                                    max_len = max(max_len,round(v[idx].co[1]))

                                v0=xform(f.v[0],mm)
                                v1=xform(f.v[1],mm)
                                v2=xform(f.v[2],mm)
                                v3=xform(f.v[3],mm)

                                if near_zero(v0[1]) and near_zero(v1[1]):
                                    out_seg(self.file, name, s.layers, shader_idx,width,hard_face,surf,graded,v0,v1, v2, uv[0],uv[1],uv[2],bounds[0],rlength)
                                elif near_zero(v1[1]) and near_zero(v2[1]):
                                    out_seg(self.file, name, s.layers, shader_idx,width,hard_face,surf,graded,v1,v2, v3, uv[1],uv[2],uv[3],bounds[0],rlength)
                                elif near_zero(v2[1]) and near_zero(v3[1]):
                                    out_seg(self.file, name, s.layers, shader_idx,width,hard_face,surf,graded,v2,v3, v0, uv[2],uv[3],uv[0],bounds[0],rlength)
                                elif near_zero(v3[1]) and near_zero(v0[1]):
                                    out_seg(self.file, name, s.layers, shader_idx,width,hard_face,surf,graded,v3,v0, v1, uv[3],uv[0],uv[1],bounds[0],rlength)
                                else:
                                    # Map merges xyz vert obj and uv tuples into one big mess of pairs, which for with pair
                                    # iterator then pulls apart.  Python does not do for a,b in x, y: apparently.
                                    for v, uv in map(None, f.verts, f.uv):
                                        print v0
                                        print v1
                                        print v2
                                        print v3
                                        print uv[0], uv[1]
                                    raise ExportError( "I was not able to pull apart this face (in mesh %s)." % s.name)
                                seg_keys = ['SEGMENT_NORMALS']
                                emit_properties(self.file, s, seg_keys)


        for o in objs:
            if 1 in o.layers or 2 in o.layers or 3 in o.layers:
                oname = self.lib_lookup(strip_prefix(o.name,'OBJ'))
                if num_lengths < 2:
                    raise ExportError( "%s: This distance-baesd object can't be used on a one-span segment: %s." % (obj.name, o.name))
                if out_obj(o, self.file,oname,  "DIST", o.getMatrix('localspace').translationPart(), o.RotX, o.RotY, o.RotZ, num_lengths,rlength,bounds[0]):
                    general_mode='GRADED'
        for o in bgns:
            if 1 in o.layers or 2 in o.layers or 3 in o.layers:
                oname = self.lib_lookup(strip_prefix(o.name,'BGN'))
                if out_obj(o, self.file,oname,  "BEGIN", o.getMatrix('localspace').translationPart(), o.RotX, o.RotY, o.RotZ, num_lengths,rlength,bounds[0]):
                    general_mode='GRADED'
        for o in ends:
            if 1 in o.layers or 2 in o.layers or 3 in o.layers:
                oname = self.lib_lookup(strip_prefix(o.name,'END'))
                if out_obj(o, self.file,oname, "END", o.getMatrix('localspace').translationPart(), o.RotX, o.RotY, o.RotZ, num_lengths,rlength,bounds[0]):
                    general_mode='GRADED'
        for o in vrts:
            if 1 in o.layers or 2 in o.layers or 3 in o.layers:
                oname = self.lib_lookup(strip_prefix(o.name,'VRT'))
                if out_obj(o, self.file,oname, "VERT", o.getMatrix('localspace').translationPart(), o.RotX, o.RotY, o.RotZ, num_lengths,rlength,bounds[0]):
                    general_mode='GRADED'
        for o in cars:
            if 1 in o.layers or 2 in o.layers or 3 in o.layers:
                oname = self.lib_lookup(strip_prefix(o.name,'CAR'))
                out_car(o, self.file,oname, o.getMatrix('localspace').translationPart(), o.RotX, o.RotY, o.RotZ)

        o = obj
        while o != None:
            do_macros(self.file,o,0,-bounds[0],rwidth,general_mode)
            o = o.parent
Beispiel #14
0
def export_fac(fac, all, dir):
    print "Exporting %s " % fac.name

    text = text_for_obj(fac.name)
    info = {}
    if len(text) != 0:
        parse_spelling_info(text, info)

    fname = strip_prefix(fac.name, 'FAC') + '.fac'

    partial = get_prop(fac, 'path', '.')

    prefix = ''
    parts = partial.count('/') + 1
    if partial == '.': parts = 0
    for n in range(parts):
        prefix += '../'

    export_path = os.path.join(partial, fname)
    export_path = os.path.join(path, export_path)
    if not os.path.exists(os.path.dirname(export_path)):
        os.makedirs(os.path.dirname(export_path))

    print export_path
    fi = open(export_path, 'w')
    if len(text) > 0:
        fi.write("A\n1000\nFACADE\n\n")
    else:
        fi.write("A\n800\nFACADE\n\n")
    fac_props = []
    is_graded = 0
    fac_keys = [
        'RING', 'HARD_WALL', 'HARD_ROOF', 'DOUBLED', 'FLOORS_MIN',
        'FLOORS_MAX', 'LAYER_GROUP', 'LAYER_GROUP_DRAPED'
    ]
    accum_properties(fac, fac_keys, fac_props)
    for p in fac_props:
        fi.write("%s\n" % p)
    if has_prop(fac, 'GRADED'):  # avoid using prop data in file
        fi.write("GRADED\n")
        is_graded = 1
    if has_prop(fac, 'vname'):
        (sim, pack) = locate_root(export_path)
        fi.write("EXPORT %s.fac %s\n" %
                 (strip_suffix(get_prop(fac, 'vname', fac.name)),
                  os.path.normpath(export_path[len(pack) + 1:])))

    zoning_types = [
        'ind_high_solid', 'ind_low_solid', 'urban_med_solid', 'urban_com_solid'
    ]
    tall_zoning_types = ['urban_high_solid']

    block_widths = [7.5, 15, 22.5, 30, 45, 60, 75, 90]
    arch_heights = [24, 32, 999]
    height_max_for_arch = {24: 24, 32: 40, 999: 999}
    block_heights = [[8, 10], [10, 16], [16, 24], [24, 32], [32, 40], [40, 80],
                     [80, 120], [120, 999]]
    legal_block_heights = [8, 10, 16, 24, 32, 40, 80, 120, 999]
    block_depths = [30, 60, 90]

    num_fac_spelling_props = 0
    for p in [
            'WIDTH_MIN', 'WIDTH_MAX', 'HEIGHT_MIN', 'HEIGHT_MAX', 'DEPTH',
            'BLOCK_HEIGHT', 'BLOCK_VARIANT'
    ]:
        if has_prop(fac, p):
            num_fac_spelling_props = num_fac_spelling_props + 1

    if num_fac_spelling_props != 0 and num_fac_spelling_props != 7:
        raise ExportError("You only have some facade tags placed.  Typo?  %s" %
                          fac.name)

    if num_fac_spelling_props == 7:
        (sim, pack) = locate_root(export_path)
        width_min = float(get_prop(fac, 'WIDTH_MIN', 0))
        width_max = float(get_prop(fac, 'WIDTH_MAX', 0))
        height_min = float(get_prop(fac, 'HEIGHT_MIN', 0))
        height_max = float(get_prop(fac, 'HEIGHT_MAX', 0))
        depth = get_prop(fac, 'DEPTH', '')
        arch_height = get_prop(fac, 'BLOCK_HEIGHT', '')
        # Alex hack alert: I've made it accept either commas or whitespace as separators, by the only method I could find - I apologise for the mess.
        if ',' in depth:
            depth_list = map(float, depth.split(','))
        else:
            depth_list = map(float, depth.split())
        if ',' in arch_height:
            arch_list = map(float, arch_height.split(','))
        else:
            arch_list = map(float, arch_height.split())
        if ',' in get_prop(fac, 'BLOCK_VARIANT', ''):
            var_list = map(toupper,
                           get_prop(fac, 'BLOCK_VARIANT', '').split(','))
        else:
            var_list = map(toupper, get_prop(fac, 'BLOCK_VARIANT', '').split())
        zone_filter = get_prop(fac, 'ZONE', '')
        if zone_filter == '':
            zone_filter = []
        else:
            if ',' in zone_filter:
                zone_filter = zone_filter.split(',')
            else:
                zone_filter = zone_filter.split()
        fallback = get_prop(fac, 'FALLBACK', '')
        if fallback == '1':
            fallback = '_FALLBACK'
        else:
            fallback = '_PRIMARY'
        density = get_prop(fac, 'DENSITY', '1.0')

        my_exp = os.path.normpath(export_path[len(pack) + 1:])

        num_exp = 0

        for d in block_depths:
            if float(d) in depth_list:
                for w in block_widths:
                    if w >= width_min and w <= width_max:
                        for z in zoning_types:
                            if zone_filter_match(z, zone_filter):
                                # ALEX - comment this back in to raise an error if a facade is too tall for the low zoning types but
                                # is hitting one of their buckets anyway.  When you put FLOORS_MIN in place this check shuts up, because
                                # you have FORCED the building to be tall enough to be non-silly even though the DSF says "10 meters, really!"
                                #if height_min > 10.0 and not has_prop(fac,'FLOORS_MIN'):
                                #	raise ExportError("The facade %s matches the non-tall zoning type %s.\nIt has no minimum floor directive but needs to be taller than 10m." % (fac.name, z))
                                if 'A' in var_list:
                                    fi.write(
                                        "EXPORT%s %s lib/g10/autogen/%s_%dx%da.fac\t\t%s\n"
                                        % (fallback, density, z, w, d, my_exp))
                                    num_exp = num_exp + 1
                                if 'B' in var_list:
                                    fi.write(
                                        "EXPORT%s %s lib/g10/autogen/%s_%dx%db.fac\t\t%s\n"
                                        % (fallback, density, z, w, d, my_exp))
                                    num_exp = num_exp + 1

                        for z in tall_zoning_types:
                            if zone_filter_match(z, zone_filter):
                                for bh in block_heights:
                                    if bh[0] >= height_min and bh[
                                            1] <= height_max:
                                        for ah in arch_heights:
                                            if float(ah) in arch_list and bh[
                                                    1] <= height_max_for_arch[
                                                        float(ah)]:
                                                #ALEX - comment these lines back in to fail export if the min/max height don't fall on bucket
                                                # boundaries.
                                                #if not height_min in legal_block_heights:
                                                #	raise ExportError("The facade %s has an illegal height min %f." % (fac.name, height_min))
                                                #if not height_max in legal_block_heights:
                                                #	raise ExportError("The facade %s has an illegal height max %f." % (fac.name, height_max))
                                                if 'A' in var_list:
                                                    fi.write(
                                                        "EXPORT%s %s lib/g10/autogen/%s_%d_%dx%dx%da.fac\t\t%s\n"
                                                        % (fallback, density,
                                                           z, ah, w, bh[1], d,
                                                           my_exp))
                                                    num_exp = num_exp + 1
                                                if 'B' in var_list:
                                                    fi.write(
                                                        "EXPORT%s %s lib/g10/autogen/%s_%d_%dx%dx%db.fac\t\t%s\n"
                                                        % (fallback, density,
                                                           z, ah, w, bh[1], d,
                                                           my_exp))
                                                    num_exp = num_exp + 1

        # This checks that we put at least ONE generated export directive in.  If we have none, that's probably a typo.
        if num_exp == 0:
            raise ExportError(
                "The facade %s has export bucketing tags but failed to fit in ANY bucket.  This is probably a tagging mistake."
                % fac.name)

    roof_images = []
    wall_images = []
    roof_meshes = []
    wall_meshes = []
    objs = []

    find_objs_recursive(fac, all, objs)
    find_images_recursive(fac, all, roof_images, wall_images, roof_meshes,
                          wall_meshes)
    if len(roof_images) > 1:
        raise ExportError("We found %d roof images." % len(roof_images))
    if len(wall_images) > 1:
        raise ExportError("We found %d wall images." % len(wall_images))

    # Ben says: disable this for now - we do want a roof with draped walls for fence around a draped parking lot (roof height = 0)
    #if len(roof_images) > 0 and not is_graded: raise ExportError("You cannot use a roof in a draped facade!")

    shader_keys = [
        'TWO_SIDED', 'NO_BLEND', 'SPECULAR', 'BUMP_LEVEL', 'NO_SHADOW',
        'DECAL', 'DECAL_RGBA', 'DECAL_KEYED', 'DECAL_PARAMS',
        'DECAL_PARAMS_PROJ', 'TEXTURE_DETAIL', 'NO_ALPHA', 'DITHERED_ALPHA',
        'DECAL_LIB'
    ]

    if len(wall_images) > 0:
        wt = blender_relative_path(wall_images[0].getFilename())
        fi.write("SHADER_WALL\n")
        fi.write("TEXTURE %s\n" % (prefix + wt))
        core = get_core_texture(wt)
        if tex_exists(core + "_NML.png"):
            fi.write("TEXTURE_NORMAL 1.0 %s_NML.png\n" % (prefix + core))
        elif tex_exists(core + "_NML.dds"):
            fi.write("TEXTURE_NORMAL 1.0 %s_NML.dds\n" % (prefix + core))
        if tex_exists(core + "_LIT.png"):
            fi.write("TEXTURE_LIT %s_LIT.png\n" % (prefix + core))
        elif tex_exists(core + "_LITL.dds"):
            fi.write("TEXTURE_LIT %s_LIT.dds\n" % (prefix + core))

        shader_props = []
        accum_properties(fac, shader_keys, shader_props)
        for p in shader_props:
            fi.write("%s\n" % p)

    if len(roof_images) > 0:
        fi.write("SHADER_ROOF\n")
        rt = blender_relative_path(roof_images[0].getFilename())
        fi.write("TEXTURE %s\n" % (prefix + rt))
        core = get_core_texture(rt)
        if tex_exists(core + "_NML.png"):
            fi.write("TEXTURE_NORMAL 1.0 %s_NML.png\n" % (prefix + core))
        elif tex_exists(core + "_NML.dds"):
            fi.write("TEXTURE_NORMAL 1.0 %s_NML.dds\n" % (prefix + core))
        if tex_exists(core + "_LIT.png"):
            fi.write("TEXTURE_LIT %s_LIT.png\n" % (prefix + core))
        elif tex_exists(core + "_LIT.dds"):
            fi.write("TEXTURE_LIT %s_LIT.dds\n" % (prefix + core))

        roof_empty = fac
        for o in all:
            if o.parent == fac and toupper(strip_suffix(
                    o.name)) == 'ROOF_PROPS':
                roof_empty = o
        shader_props = []
        accum_properties(roof_empty, shader_keys, shader_props)
        for p in shader_props:
            fi.write("%s\n" % p)

    if len(text) > 0 and len(roof_images):
        if len(roof_meshes) == 0:
            raise ExportError(
                "Internal error - we found a roof image but no roof mesh!")
        x_min = y_min = s_min = t_min = 9999
        x_max = y_max = s_max = t_max = -9999
        mm = roof_meshes[0][1].getMatrix('localspace')
        for f in roof_meshes[0][0].faces:
            for v in f.verts:
                vv = xform_fixed(v, mm)
                x_min = min(x_min, vv[0])
                x_max = max(x_max, vv[0])
                y_min = min(y_min, vv[1])
                y_max = max(y_max, vv[1])
            for v in f.uv:
                s_min = min(s_min, v[0])
                s_max = max(s_max, v[0])
                t_min = min(s_min, v[1])
                t_max = max(s_max, v[1])
        fi.write("ROOF_SCALE %f %f\n\n" % ((x_max - x_min) / (s_max - s_min),
                                           (y_max - y_min) / (t_max - t_min)))

    obj_idx = {}
    for o in objs:
        if not has_prop(o, 'external'):
            raise ExportError("Object %s has no external property." % o.name)
        k = get_prop(o, 'external', o.name)
        if not k in obj_idx:
            il = len(obj_idx)
            fi.write("OBJ %s\n" % k)
            obj_idx[k] = il

    floors = getChildren(fac, all)
    floors.sort(lambda x, y: cmp(x.name.lower(), y.name.lower()))
    for f in floors:
        if has_prefix(f.name, 'LOD'):
            export_lod(f, all, fi)
        elif has_prefix(f.name, 'SCR'):
            export_scraper(f, all, fi, os.path.join(dir, partial), prefix)
        elif not toupper(strip_suffix(f.name)) == 'ROOF_PROPS':
            if not strip_suffix(f.name) in info:
                raise ExportError("Floor %s is not defined in the text file." %
                                  f.name)
            export_floor(f, all, fi, info[strip_suffix(f.name)], obj_idx, objs)

    fi.close()
Beispiel #15
0
    def __init__(self, obj):
        mesh = obj.getData(mesh=True)
        self.s1 = 9999
        self.s2 = -9999
        self.t1 = 9999
        self.t2 = -9999
        self.x1 = 9999
        self.x2 = -9999
        self.y1 = 9999
        self.y2 = -9999
        self.s_cuts = []
        self.t_cuts = []
        self.s_slop = []
        self.t_slop = []
        self.tile_count = len(mesh.faces)
        self.crop = []
        self.normal_scale = get_prop(obj, 'TEXTURE_NORMAL', '1.0')
        self.detail_scale = get_prop(obj, 'TEXTURE_DETAIL', '1.0')
        self.terrain_scale = get_prop(obj, 'TEXTURE_TERRAIN', '1.0')
        self.hide_tile = has_prop(obj, 'HIDE_TILE')
        self.share_y = has_prop(obj, 'SHARE_Y')
        self.more_props = []
        tile_keys = ['DECAL_LIB', 'DITHER_ALPHA']
        for t in tile_keys:
            if has_prop(obj, t):
                self.more_props.append("%s %s" % (t, get_prop(obj, t, '')))

        x1f = 9999
        x2f = -9999
        y1f = 9999
        y2f = -9999

        mm = obj.getMatrix('localspace')
        scaling = mm.scalePart()
        if scaling[0] < 0.9 or scaling[1] < 0.9 or scaling[2] < 0.9:
            raise ExportError("ERROR: object %s has scaling!" % obj.name)
        for f in mesh.faces:
            (self.tex_width, self.tex_height) = f.image.getSize()
            for v, uv in map(None, f.v, f.uv):
                vt = xform(v, mm)
                self.x1 = min(self.x1, vt[0])
                self.x2 = max(self.x2, vt[0])
                self.y1 = min(self.y1, vt[1])
                self.y2 = max(self.y2, vt[1])

                if (uv[0] < self.s1):
                    self.s1 = uv[0]
                    x1f = vt[0]
                if (uv[0] > self.s2):
                    self.s2 = uv[0]
                    x2f = vt[0]
                if (uv[1] < self.t1):
                    self.t1 = uv[1]
                    y1f = vt[1]
                if (uv[1] > self.t2):
                    self.t2 = uv[1]
                    y2f = vt[1]

                if not round(uv[0] * self.tex_width, 1) in self.s_cuts:
                    self.s_cuts.append(round(uv[0] * self.tex_width, 1))
                if not round(uv[1] * self.tex_height, 1) in self.t_cuts:
                    self.t_cuts.append(round(uv[1] * self.tex_height, 1))

            # This is a big nasty mess.  Basically we have to guess whether the author is
            # trying to make a trivial tile (tri or quad), a grid (for AG blocks) or an FGON
            # (for cropped blocks).
            # So: the fgon case happens when we have multiple faces AND at least one interior (fgon flagged) edge.
            # The trivial case happens when we have one face of degree 3 or 4.
            is_fgon = len(mesh.faces) > 1 and is_really_fgon(mesh)
            is_trivial = len(mesh.faces) == 1 and (len(f.v) == 3
                                                   or len(f.v) == 4)
            if is_trivial or is_fgon:
                # CROP LOGIC.  Get the fgon, write out the crop boundry.
                crop_raw = get_fgon(mesh)
                if fgon_cw(crop_raw, mesh):
                    crop_raw.reverse()
                #print "raw on %s got %d edges" % ( obj.name, len(crop_raw))
                self.crop = []
                for i in crop_raw:
                    v = mesh.verts[i]
                    vt = xform(v, mm)
                    self.crop.append(vt)
            else:
                #$ AG Block logic.  Look for two-sided tiles, use to mark slop!
                if (f.mode & Mesh.FaceModes.TWOSIDE) == 0:
                    smin = min(f.uv[0][0], f.uv[1][0], f.uv[2][0], f.uv[3][0])
                    tmin = min(f.uv[0][1], f.uv[1][1], f.uv[2][1], f.uv[3][1])
                    if not round(smin * self.tex_width, 1) in self.s_slop:
                        self.s_slop.append(round(smin * self.tex_width, 1))
                    if not round(tmin * self.tex_height, 1) in self.t_slop:
                        self.t_slop.append(round(tmin * self.tex_height, 1))
        if x1f > x2f:
            (self.x1, self.x2) = (self.x2, self.x1)
        if y1f > y2f:
            (self.y1, self.y2) = (self.y2, self.y1)

        f = mesh.faces[0]
        self.tex_name = blender_relative_path(f.image.getFilename())
        self.tex_scale = (self.x2 - self.x1) / (self.s2 - self.s1)
        self.s1 *= self.tex_width
        self.s2 *= self.tex_width
        self.t1 *= self.tex_height
        self.t2 *= self.tex_height
        self.s_cuts.sort()
        self.t_cuts.sort()
        self.s_slop.append(self.s_cuts[-1])
        self.t_slop.append(self.t_cuts[-1])
        self.rotation = get_prop(obj, "ROTATION", 0)
        aspect = ((self.s2 - self.s1) *
                  (self.y2 - self.y1)) / ((self.t2 - self.t1) *
                                          (self.x2 - self.x1))
        if aspect < 0.8 or aspect > 1.2:
            if aspect < -1.2 or aspect > -0.8:
                raise ExportError(
                    "WARNING: aspect ratio of tile %s is not 1:1." % obj.name)
Beispiel #16
0
def export_scraper(obj, all, fi, dir, prefix):
    if not has_prop(obj, 'STEP'):
        raise ExportError("Object %s does not have a step property." %
                          obj.name)
    if not has_prop(obj, 'FLOORS'):
        raise ExportError("Object %s does not have a floors property." %
                          obj.name)
    pairs = getChildren(obj, all)
    pairs.sort(lambda x, y: cmp(x.name.lower(), y.name.lower()))
    model_pairs = []
    delta_agl = 0
    agl_span = 0
    for p in pairs:
        kids = getChildren(p, all)
        base = None
        tower = None
        pad = None
        pins = []
        for k in kids:
            if has_prefix(k.name, 'BASE'):
                if base != None:
                    raise ExportError(
                        "There are two bases in this scraper: %s and %s." %
                        (k.name, base.name))
                base = k
            elif has_prefix(k.name, 'TWR'):
                if tower != None:
                    raise ExportError(
                        "There are two towers in this scraper: %s and %s." %
                        (k.name, tower.name))
                tower = k
            elif has_prefix(k.name, 'PAD'):
                if pad != None:
                    raise ExportError(
                        "There are two pads in this scraper: %s and %s." %
                        (k.name, pad.name))
                pad = k
            elif has_prefix(k.name, 'PIN'):
                ploc = k.getMatrix('localspace').translationPart()
                pins.append(ploc[0])
                pins.append(ploc[1])
        if base == None:
            raise ExportError("There is no base in the scaper %s." % obj.name)
        if tower == None and pad != None:
            raise ExportError("You cannot use a pad without a tower in %s." %
                              obj.name)
        #if tower == None: raise ExportError("There is no tower in the scaper %s." % obj.name)
        delta_agl = 0
        delta_pad = 0
        base_x = 0
        base_z = 0
        base_r = 0
        tower_x = 0
        tower_z = 0
        tower_r = 0
        pad_x = 0
        pad_z = 0
        pad_r = 0
        # basen = name of obj, basep = fully qualified path to export, basek = all real children of obj, basel = library path or None if non-lib.
        basen = get_prop(base, 'rname', strip_prefix(base.name,
                                                     'BASE')) + '.obj'
        basep = dir + '/' + basen
        basek = getGrandChildren(base, all)
        basel = None
        bases = get_prop(base, 'show_level', '1 1')
        if has_prop(base, 'external'):
            basel = get_prop(base, 'external', None)

        if tower != None:
            towern = get_prop(tower, 'rname', strip_prefix(tower.name,
                                                           'TWR')) + '.obj'
            towerp = dir + '/' + towern
            towerk = getGrandChildren(tower, all)
            towerl = None
            if has_prop(tower, 'external'):
                towerl = get_prop(tower, 'external', None)
            towers = get_prop(tower, 'show_level', '1 1')
        else:
            towern = ""
            towerp = ""
            towerk = []
            towerl = None
            towers = '1 1'
        if pad != None:
            padn = get_prop(pad, 'rname', strip_prefix(pad.name,
                                                       'PAD')) + '.obj'
            padp = dir + '/' + padn
            padk = getGrandChildren(pad, all)
            padl = None
            if has_prop(pad, 'external'):
                padl = get_prop(pad, 'external', None)
            pads = get_prop(pad, 'show_level', '1 1')
        else:
            padn = ""
            padp = ""
            padk = []
            padl = None
            pads = '1 1'

        base_x = base.getMatrix('localspace').translationPart()[0]
        base_z = -base.getMatrix('localspace').translationPart()[1]
        base_r = make_degs(-base.RotZ)

        #print basen, towern
        #print basep, towerp
        #print basek, towerk
        if basel == None:
            exp_base = OBJexport8(basep)
            exp_base.additive_lod = 1
            exp_base.us_mat = 0
            exp_base.openFile(basek, base, prefix)
            exp_base.writeHeader()
            exp_base.writeObjects(basek)

        if tower != None:
            delta_agl = tower.getMatrix('localspace').translationPart()[2]
            tower_x = tower.getMatrix('localspace').translationPart()[0]
            tower_z = -tower.getMatrix('localspace').translationPart()[1]
            tower_r = make_degs(-tower.RotZ)
            if towerl == None:
                exp_tower = OBJexport8(towerp)
                exp_tower.additive_lod = 1
                exp_tower.us_mat = 0
                exp_tower.openFile(towerk, tower, prefix)
                exp_tower.writeHeader()
                exp_tower.writeObjects(towerk)

            if pad != None:
                delta_pad = pad.getMatrix('localspace').translationPart(
                )[2] - tower.getMatrix('localspace').translationPart()[2]
                pad_x = pad.getMatrix('localspace').translationPart()[0]
                pad_z = -pad.getMatrix('localspace').translationPart()[1]
                pad_r = make_degs(-pad.RotZ)
                if padl == None:
                    exp_pad = OBJexport8(padp)
                    exp_pad.additive_lod = 1
                    exp_pad.us_mat = 0
                    exp_pad.openFile(padk, pad, prefix)
                    exp_pad.writeHeader()
                    exp_pad.writeObjects(padk)

        agl_span = 0
        for o in towerk:
            mm = o.getMatrix('localspace')
            if o.getType() == 'Mesh':
                mesh = o.getData(mesh=True)
                for v in mesh.verts:
                    vt = xform_fixed(v, mm)
                    agl_span = max(vt[2], agl_span)
        if len(towerk) == 0:
            # fallback case - no tower, take HEIGHT_MIN/MAX TAGS
            height_min = float(get_prop(obj, 'HEIGHT_MIN', 0))
            height_max = float(get_prop(obj, 'HEIGHT_MAX', 0))
            agl_span = height_min
            delta_agl = height_max - height_min

        if basel != None: basen = basel
        if padl != None: padn = padl
        if towerl != None: towern = towerl

        model_pairs.append([[basen, base_x, base_z, base_r, bases],
                            [towern, tower_x, tower_z, tower_r, towers],
                            [padn, pad_x, delta_pad, pad_z, pad_r, pads],
                            pins])

    fi.write("FACADE_SCRAPER %f %f %s %s\n" %
             (agl_span, agl_span + delta_agl, get_prop(
                 obj, 'STEP', '4'), get_prop(obj, 'FLOORS', '2')))
    for m in model_pairs:
        print m
        fi.write("FACADE_SCRAPER_MODEL_OFFSET %f %f %f %s %s" %
                 (m[0][1], m[0][2], m[0][3], m[0][0], m[0][4]))

        if m[1][0] == "":
            fi.write(" 0 0 0 - 1 1 ")
        else:
            fi.write(" %f %f %f %s %s " %
                     (m[1][1], m[1][2], m[1][3], m[1][0], m[1][4]))
        for p in m[3]:
            fi.write(" %f" % -p)
        fi.write("\n")
        if m[2][0] != "":
            fi.write("FACADE_SCRAPER_PAD %f %f %f %f %s %s\n" %
                     (m[2][1], m[2][2], m[2][3], m[2][4], m[2][0], m[2][5]))
Beispiel #17
0
def export_lod(lod, all, fi):
    fi.write("LOD %s\n" % get_prop(lod, 'LOD', strip_prefix(lod.name, 'LOD')))
    kids = getChildren(lod, all)
    kids.sort(lambda x, y: cmp(x.name.lower(), y.name.lower()))
    for k in kids:
        mi = mesh_cut_info(k)
        has_lrbt = 0
        if has_prop(k, 'lrbt'):
            has_lrbt = 1
            lrbt_string = get_prop(k, 'lrbt', '')
            if ',' in lrbt_string:
                lrbt_strings = lrbt_string.split(',')
            else:
                lrbt_strings = lrbt_string.split()
            if len(lrbt_strings) != 4:
                raise ExportError(
                    "LOD object %s has mal-formed lrbt property %s" %
                    (k.name, lrbt_string))
            lrbt = [
                float(lrbt_strings[0]),
                float(lrbt_strings[1]),
                float(lrbt_strings[2]),
                float(lrbt_strings[3])
            ]
            total_h = len(mi[3]) - 1
            total_v = len(mi[4]) - 1
            if (lrbt[0] + lrbt[1]) > total_h:
                raise ExportError(
                    "Facade %s has %d left, %d right, but only %d total h panels."
                    % (k.name, lrbt[0], lrbt[1], total_h))
            if (lrbt[2] + lrbt[3]) > total_v:
                raise ExportError(
                    "Facade %s has %d bottom, %d top, but only %d total v panels."
                    % (k.name, lrbt[2], lrbt[3], total_v))
            if has_prop(k, 'ROOF_SLOPE') and lrbt[3] < 1:
                raise ExportError(
                    "Facade %s has roof slope but no top layers. Check lrbt property!"
                    % k.name)
        #print "bounds: %f,%f,%f  tex: %f,%f  uv bounds: %f,%f depth %f" % (mi[0],mi[1],mi[2],mi[7],mi[8],mi[9],mi[10], mi[11])
        fi.write("TEX_SIZE %f %f\n" % (mi[7], mi[8]))
        if has_prefix(k.name, 'WALL'):
            fi.write("WALL %s\n" %
                     get_prop(k, 'WALL', strip_prefix(k.name, 'WALL')))
            if has_prop(k, 'WALL_RULE'):
                fi.write("WALL_RULE %s\n" % get_prop(k, 'WALL_RULE', ''))
            if has_prop(k, 'ROOF_SLOPE'):
                if has_prop(k, 'SLANT') and get_prop(k, 'SLANT', '1') == '0':
                    fi.write("ROOF_SLOPE %s\n" %
                             get_prop(k, 'ROOF_SLOPE', '0'))
                else:
                    fi.write("ROOF_SLOPE %s SLANT\n" %
                             get_prop(k, 'ROOF_SLOPE', '0'))
            s_range = mi[9]
            t_range = mi[10]
            fi.write("SCALE %f %f\n" % (mi[0] / s_range, mi[2] / t_range))
            if mi[11] < 0.0:
                fi.write("BASEMENT_DEPTH %f\n" %
                         (-mi[11] * mi[8] * mi[10] / mi[2]))
            cuts = ['LEFT', 'CENTER', 'RIGHT']
            idx = 0
            if sum(mi[5]) == 1:
                idx = 1
            for n in xrange(1, len(mi[3])):
                nn = n - 1
                if has_lrbt:
                    idx = 1
                    if nn < lrbt[0]: idx = 0
                    if nn >= (total_h - lrbt[1]): idx = 2
                fi.write("%s %f %f\n" % (cuts[idx], mi[3][nn], mi[3][n]))
                if mi[5][n] != mi[5][nn]:
                    idx = idx + 1
            cuts = ['BOTTOM', 'MIDDLE', 'TOP']
            idx = 0
            for n in xrange(1, len(mi[4])):
                nn = n - 1
                if has_prop(k, 'ROOF_SLOPE'):
                    if n == (len(mi[4]) - 1):
                        idx = 2
                if has_lrbt:
                    idx = 1
                    if nn < lrbt[2]: idx = 0
                    if nn >= (total_v - lrbt[3]): idx = 2
                fi.write("%s %f %f\n" % (cuts[idx], mi[4][nn], mi[4][n]))
                if mi[6][n] != mi[6][nn]:
                    idx = idx + 1
        else:
            if len(mi[3]) != 3 or len(mi[4]) != 3:
                raise ExportError("Roof is not cut into four quads.")
            fi.write("ROOF_SCALE %f %f %f %f %f %f %f %f\n" %
                     (mi[3][0], mi[4][0], mi[3][1], mi[4][1], mi[3][2],
                      mi[4][2], mi[0], mi[1]))
Beispiel #18
0
def export_floor(obj, all, fi, info, obj_idx, objs):
    fi.write("\nFLOOR %s\n" % obj.name)
    kids = getChildren(obj, all)
    roofs = filter_objects(kids, 'Mesh', 'ROOF')
    segs = filter_objects(kids, 'Empty', 'SEG')
    crvs = filter_objects(kids, 'Empty', 'CRV')

    #------- EXTRACT ROOF HEIGHTS FROM ALL ROOF OBJECTS -------
    all_roofs = []
    for r in roofs:
        max_height = 0
        mm = r.getMatrix('localspace')
        mesh = r.getData(mesh=True)
        two_sided = 0
        x_min = 9999
        y_min = 9999
        for f in mesh.faces:
            for i in [0, 1, 2]:
                vv = xform_fixed(f.v[i], mm)
                max_height = max(vv[2], max_height)
                x_min = min(x_min, f.v[i].co[0])
                y_min = min(y_min, f.v[i].co[1])
            if f.mode & Mesh.FaceModes.TWOSIDE:
                two_sided = 1
        all_roofs.append([r, max_height, two_sided, x_min, y_min])

    all_roofs.sort(lambda x, y: cmp(x[1], y[1]))

    for rr in all_roofs:
        r = rr[0]
        roof_h = []
        mm = r.getMatrix('localspace')
        mesh = r.getData(mesh=True)
        for f in mesh.faces:
            vv = xform_fixed(f.v[0], mm)
            if not vv[2] in roof_h:
                roof_h.append(vv[2])
        if len(roof_h) > 0:
            roof_h.sort()
            fi.write("ROOF_HEIGHT")
            for h in roof_h:
                fi.write(" %f" % round(h, 3))
            fi.write("\n")
            if rr[2] and rr[1] != 0.0:
                fi.write("TWO_SIDED_ROOF\n")
            for o in objs:
                if o.parent == r:
                    oi = obj_idx[get_prop(o, 'external', o.name)]
                    loc = o.getMatrix('localspace').translationPart()
                    fi.write("ROOF_OBJ_HEADING %d %f %f %f" %
                             (oi, loc[0] - rr[3], loc[1] - rr[4],
                              make_degs(-o.RotZ)))
                    if has_prop(o, 'show_level'):
                        fi.write(" %s" % get_prop(o, 'show_level', ''))
                    fi.write("\n")

    seg_map = {}
    crv_map = {}
    for s in segs:
        i = int(strip_prefix(s.name, 'SEG'))
        if i in seg_map:
            raise ExportError(
                "The segment %s re-uses a segment index number." % s.name)
        seg_map[i] = s
    for s in crvs:
        i = int(strip_prefix(s.name, 'CRV'))
        if i in crv_map:
            raise ExportError(
                "The curved segment %s re-uses a segment index number." %
                s.name)
        crv_map[i] = s

    for i in xrange(len(segs)):
        if not i in seg_map:
            raise ExportError(
                "The floor %s is missing a segment, index number %d." %
                (obj.name, i))
        export_wall2(seg_map[i], all, fi, obj_idx)

    for i in xrange(len(crvs)):
        if not i in crv_map:
            raise ExportError(
                "The floor %s is missing a curved segment, index number %d." %
                (obj.name, i))
        export_wall2(crv_map[i], all, fi, obj_idx)

    if len(info) == 0:
        raise ExportError("There are no walls defined for floor %s" %
                          (obj.name))

    if len(seg_map) != len(crv_map):
        raise ExportError(
            "There are a different number of curved and flat segments. %d curved, %d flat."
            % (len(crv_map), len(seg_map)))

    for w in info:
        fi.write("WALL %s %s %s %s %s\n" %
                 (w[1][0], w[1][1], w[1][2], w[1][3], w[0]))
        if len(w) == 2:
            raise ExportError(
                "There are no spellings defined for a wall in %s." %
                (obj.name))
        for r in w[1][4:]:
            fi.write("WALL_RULE %s %s %s %s\n" % (r[0], r[1], r[2], r[3]))
        for s in w[2:]:
            fi.write("SPELLING")
            for ss in s:
                idx = int(ss)
                if idx < 0 or idx >= len(segs):
                    raise ExportError(
                        "Wall %s %s %s has a spelling with index %d that is out of range."
                        % (w[0], w[1], w[2], idx))
                fi.write(" %s" % ss)
            fi.write("\n")
Beispiel #19
0
    def export_plug(self, obj, scene):
        if self.debug: print "Exporting plug based on armature obj %s." % obj.name

        plug_keys = ['JUNCTION_DRAPED', 'JUNCTION_GRADED', 'JUNCTION_EMBANKED', 'JUNCTION_BRIDGE',
                    'JUNCTION_COMPOSITE_CORNER', 'JUNCTION_COMPOSITE_APPROACH', 'JUNCTION_COMPOSITE_CENTER', 'BEZIER_OFFSET', 'JUNCTION_MINIMA', 'MAX_SHEAR', 'CUTBACK' ];
        self.file.write("# Junction %s.\n" % obj.name)
        emit_properties(self.file, obj, plug_keys)

        degree = 0
        for label in ['JUNCTION_DRAPED', 'JUNCTION_GRADED', 'JUNCTION_EMBANKED', 'JUNCTION_BRIDGE']:
            if has_prop(obj,label):
                degree = int(get_prop(obj,label,'0'))
        if has_prop(obj,'JUNCTION_COMPOSITE_CORNER'): degree = 2
        if has_prop(obj,'JUNCTION_COMPOSITE_APPROACH'): degree = 4
        if has_prop(obj,'JUNCTION_COMPOSITE_CENTER'): degree = 1

        for p in obj.getAllProperties():
            if strip_suffix(p.name.upper()) == 'MATCH':
                mn = get_road_match(p.data)
                if mn == None:
                    mn = str(p.data)
                mn_cut = mn.split()
                for i in range(0,len(mn_cut),2):
                    if not mn_cut[i] in ['io', 'in', 'out']:
                        raise ExportError( "%s: This matching directive is illegal: %s" % (obj.name, mn))
                self.file.write("MATCH %s\n" % mn)

        annotations = getChildren(obj,scene)
        meshes = filter_objects(annotations,'Mesh', '')

        meta_rect = [ 0, 0, 10, 10 ];
        for m in meshes:
            if has_prefix(m.name,'META'):
                mesh=m.getData(mesh=True)
                meta_rect[0] = meta_rect[2] = mesh.verts[0].co[0]
                meta_rect[1] = meta_rect[3] = mesh.verts[0].co[1]
                for v in mesh.verts:
                    meta_rect[0] = min(meta_rect[0],v.co[0])
                    meta_rect[2] = max(meta_rect[2],v.co[0])
                    meta_rect[1] = min(meta_rect[1],v.co[1])
                    meta_rect[3] = max(meta_rect[3],v.co[1])

        if degree < 1:
            raise ExportError( "%s: this junctions degree could not be determined." % obj.name)

        arm=obj.getData()

        bone_ct=0
        bone_idx=dict()

        annotations = getChildren(obj,scene)
        objs = filter_objects(annotations,'Empty','OBJ')

        for bn, bone in arm.bones.items():
            bh = bone.head['ARMATURESPACE']
            bt = bone.tail['ARMATURESPACE']
            if has_prefix(bn,'BEZ'):
                bone_len = bone_length_to_me(bone)
                self.file.write("BONE_BEZIER %s %f   %f %f %f  %f %f %f\n" % (strip_prefix(bn,'BEZ'), bone_len, bh[0], bh[2], -bh[1], bt[0]-bh[0],bt[2]-bh[2],bh[1]-bt[1]))
            elif has_prefix(bn,'EDG'):
                finger = int(strip_prefix(bn,'EDG'))
                export_edge_bone(self.file,degree, finger, bh[0],bh[1],bh[2], meta_rect)
            elif has_prefix(bn,'APP'):
                if not has_prop(obj,'JUNCTION_COMPOSITE_APPROACH') and not has_prop(obj,'JUNCTION_COMPOSITE_CENTER'):
                    raise ExportError( "%s: You cnanot use approach bones except on a composite app or center piece: %s", (obj.name % bn))
                export_app_bone(self.file,bh[0],bh[1],bh[2], meta_rect)
            else:
                export_any_bone(self.file,bn,bh[0],bh[1],bh[2],bt[0]-bh[0],bt[1]-bh[1],bt[2]-bh[2])
            bone_idx[bn]=bone_ct
            bone_ct+=1

        vert_list=[]

        shader_idx=-1
        lod_now=-1
        surf_now=None
        up_verts=[]
        vti = []

        for o in meshes:
            if not has_prefix(o.name,'META'):
                mesh=o.getData(mesh=True)

                for f in mesh.faces:

                    while len(vti) < len(mesh.verts):
                        vti.append([])

                    for v, uv in reversed(map(None, f.verts, f.uv)):
                        weight_list = mesh.getVertexInfluences(v.index)
                        if len(weight_list) == 0: raise ExportError( "ERROR: plug/byt %s  OB %s mesh %s is missing its vertex weighting." % (obj.name, o.name, mesh.name))
                        weight_list.sort(key=lambda w: w[1], reverse=True)
                        for w in weight_list:
                            w[0] = bone_idx[w[0]]
                        want_up=False
                        if not v in up_verts:
                            for e in mesh.edges:
                                if (e.flag & Mesh.EdgeFlags.SEAM):
                                    for vv in e:
                                        if vv == v:
                                            want_up = True
                                            up_verts.append(v)

                        vt=VT(v.co,v.no,uv,weight_list, want_up)
                        #print "checking vert %d against: " % v.index
                        #print vti[v.index]
                        for j in vti[v.index]:
                            if vt.equals(vert_list[j]):
                                #print "found it at %d" % j
                                break
                        else:
                            vti[v.index].append(len(vert_list))
                            #print "Adding - new list is."
                            #print vti[v.index]
                            vert_list.append(vt)
        for v in vert_list:
            self.file.write(str(v))

        for o in meshes:
            if not has_prefix(o.name,'META'):
                mesh=o.getData(mesh=True)
                for f in mesh.faces:
                    if len(f.verts) != 3 and len(f.verts) != 4:
                        raise ExportError( "ERROR: %d verts in face.\n" % len(f.verts))
                    else:
                        this_idx = self.shaders.shader_idx(mesh, f)
                        this_lod = far_lod_from_layers(o.layers)
                        this_surf = "none"
                        if not (f.mode & Mesh.FaceModes.DYNAMIC):
                            this_surf = get_prop(o,'surface','asphalt')
                        if this_idx != shader_idx or this_lod != lod_now or this_surf != surf_now:
                            self.file.write("JUNC_SHADER %d %d %s\n" % (this_idx, int(this_lod), this_surf ))
                        shader_idx = this_idx
                        lod_now = this_lod
                        surf_now = this_surf
                        if len(f.verts) == 3:
                            self.file.write("TRI ")
                        else:
                            self.file.write("QUAD ")
                        for v, uv in reversed(map(None, f.verts, f.uv)):
                            weight_list = mesh.getVertexInfluences(v.index)
                            weight_list.sort(key=lambda w: w[1], reverse=True)
                            for w in weight_list:
                                w[0] = bone_idx[w[0]]
                            vt=VT(v.co,v.no,uv,weight_list, v in up_verts)
                            #print "Try to match v %d (%s) against. " % (v.index, str(vt))
                            #print vti[v.index]
                            for j in vti[v.index]:
                                #print " trying %d (%s)." % (j, str(vert_list[j]))
                                if vt.equals(vert_list[j]):
                                    self.file.write(" %d" % j)
                                    break
                            else:
                                raise ExportError("ERROR: mesh indexing failed for BYT.")

                        self.file.write("\n")

        for o in objs:
            bn = o.parentbonename
            bidx = bone_idx[bn]
            oname = strip_prefix(o.name,'OBJ')
            oname = get_prop(o,'external', oname)
            draped = not has_prop(o,'graded')
            if oname[-4:] != '.obj':
                oname += '.obj'
            #print oname
            #print "Obj is at: %f, %f, %f" % (o.LocX, o.LocY, o.LocZ)
            #print "Transform:"
            xyz=o.getMatrix('localspace').translationPart()
            self.file.write("JUNC_OBJECT %f %f %f   %f %d  %d 1.0   0 0 0 0 0 0 %s" % (xyz[0], xyz[2], -xyz[1], round(-o.RotZ * 180 / 3.14159265), draped, bidx, oname))
            if has_prop(o,'obj_show_level'):
                self.file.write(" %s" % get_prop(o,'obj_show_level',''))
            self.file.write("\n")
            obj_keys = ['OBJECT_ALT', 'OBJECT_FREQ' ]
            emit_properties(self.file, o, obj_keys)

            for p in o.getAllProperties():
                if strip_suffix(p.name.upper()) == 'MACRO':
                    self.file.write("%s" % get_macro(p.data))

        do_macros(self.file,obj,0,0,0,'DRAPED')
Beispiel #20
0
    def export_ag_file(self, obj, scene):
        if self.debug: print "Starting export of %s" % obj.name
        want_groups = 0
        self.obj_name_list = []
        self.fac_name_list = []

        real_name = strip_suffix(obj.name[3:])
        suffix = '.' + obj.name[0:3].lower()

        export_name = os.path.join(self.path, real_name + suffix)

        print 'Starting AG export to ' + export_name

        is_ags = False

        if not checkFile(export_name):
            return

        if has_prefix(obj.name, 'agb'):
            self.file = open(export_name, 'w')
            self.file.write("A\n1000\nAG_BLOCK\n\n")
        elif has_prefix(obj.name, 'ags'):
            self.file = open(export_name, 'w')
            self.file.write("A\n1000\nAG_STRING\n\n")
            is_ags = True
        elif has_prefix(obj.name, 'agp'):
            self.file = open(export_name, 'w')
            self.file.write("A\n1000\nAG_POINT\n\n")
        else:
            if not obj.name[0:3].upper() in ['OBJ', 'BGN', 'END', 'VRT']:
                print "ERROR: object %s is of unknown type." % obj.name
            return

        vname = get_prop(obj, 'vname', real_name)
        vname1 = get_prop(obj, 'vname1', real_name)
        vname2 = get_prop(obj, 'vname2', real_name)

        want_tile_ids = has_prop(obj, 'tile_ids')

        lib_root = get_prop(obj, 'lib_root', def_lib_root)

        self.file.write("EXPORT %s/%s/%s %s/%s\n\n" %
                        (lib_root, self.theme, vname + suffix, self.theme,
                         real_name + suffix))
        if vname != vname1:
            self.file.write("EXPORT %s/%s/%s %s/%s\n\n" %
                            (lib_root, self.theme, vname1 + suffix, self.theme,
                             real_name + suffix))
        if vname != vname2 and vname1 != vname2:
            self.file.write("EXPORT %s/%s/%s %s/%s\n\n" %
                            (lib_root, self.theme, vname2 + suffix, self.theme,
                             real_name + suffix))

        top_level_objects = getChildren(obj, scene.objects)
        top_level_objects.sort(key=sort_obj_by_name)

        # we also grab any 'surplus' objects floating around at the 'tile/variant' level.
        # these will NOT be used as annotations but for OBJs we still run the export.  This gets
        # Alex (1) more files out on disk and (2) the EXPORT name in the .agp for copying to
        # library.txt with a shell script.
        # we have to recurse to get only OUR annotations per file - otherwise we get cross-talk between tiles, which is bad.
        variants = getChildren(obj, scene.objects)
        annotations = []
        for v in variants:
            annotations += getChildren(v, scene.objects)
        annotations_real = getAllDepth(2, scene.objects)
        objs = filter_objects(annotations, 'Empty', 'OBJ')
        facs = filter_objects(annotations, 'Mesh', 'FAC')
        tiles = filter_objects(annotations, 'Mesh', 'TILE')
        objs += filter_objects(variants, 'Empty', 'OBJ')

        # objs += filter_objects(extras,'Empty','OBJ')

        print "For AG %s" % obj.name
        for v in variants:
            print "Foudn variant %s" % v.name
        for a in annotations:
            print "Found annotation %s" % a.name
        for r in annotations_real:
            print "Real annotation: %s" % r.name
        for o in objs:
            print "found obj container %s" % o.name

        if len(tiles) == 0:
            raise ExportError(
                "ERROR: no tiles were found in the AG export file %s." %
                obj.name)
            return

        tt = TILE(tiles[0])

        ag_keys = [
            'HIDE_TILES', 'TILE_LOD', 'LAYER_GROUP', 'CROP', 'MINIMUM_OVERLAP',
            'VEGETATION', 'CREASE_ANGLE', 'CAPS', 'FILL_LAYER', 'SLOPE_LIMIT',
            'OVERLAP_H', 'OVERLAP_V', 'SPELLING_S', 'SPELLING_T', 'CORNER',
            'SPELLING'
        ]
        global_props = []
        accum_properties(obj, ag_keys, global_props)

        text_props = text_for_obj(obj.name)

        for o in facs:
            fname = lib_fac_name(o, self.theme)
            if not fname in self.fac_name_list:
                self.fac_name_list.append(fname)
                # Ben says: facades are ALWAYS external, do NOT run facade exporter here.
                #self.file.write("EXPORT %s/%s/%s.fac %s/objects/%s.fac\n" % (lib_root, self.theme, fname, self.theme,fname))

        #
        # OBJ GENERATION
        #
        # Now is a good time to export OBJs for any attached OBJS...why not?
        #
        obj_exp_list = []  # List of real files for export.
        obj_lib_list = [
        ]  # List of virtual->real path pairs for export lib entries.
        for o in objs:
            lname = lib_obj_name(o, self.theme, lib_root)
            if not lname in self.obj_name_list:
                self.obj_name_list.append(lname)
            # if an OBJ is tagged external, don't go writing the OBJ; that means we're using something that already exists.
            if not has_prop(o, 'external'):
                l = o.name.rfind('.')
                export_name = strip_suffix(child_obj_name(
                    o, scene.objects)) + '.obj'
                export_path = os.path.join(self.objdir, export_name)
                if not export_name in obj_exp_list:
                    exporter = OBJexport8(export_path)
                    exporter.additive_lod = 1
                    exporter.use_mat = 0
                    my_parts = getGrandChildren(o, scene.objects)
                    exporter.openFile(my_parts, o, '../')
                    exporter.writeHeader()
                    exporter.writeObjects(my_parts)
                    # don't double-accume obj-name list because it is used to build the obj index table!!
                    obj_exp_list.append(export_name)
                else:
                    if self.debug:
                        print "Skipping second export of OBJ %s (%s)" % (
                            lname, export_name)
                if not [lname, export_name] in obj_lib_list:
                    if o.name[0:7] != 'OBJcom_':
                        self.file.write("EXPORT %s %s/objects/%s\n" %
                                        (lname, self.theme, export_name))
                    obj_lib_list.append([lname, export_name])
                else:
                    if self.debug:
                        print "Skipping second lib entry of OBJ %s (%s)" % (
                            lname, export_name)
            else:
                if self.debug: print "Skipping external OBJ %s" % lname
        self.file.write("\n")

        #
        # Write headers
        #
        tt.write_tex_header(self.file)
        if has_prop(obj, 'macro'):
            macro = get_macro(get_prop(obj, 'macro', ''))
            if macro != None:
                self.file.write(macro)
            else:
                raise ExportError("WARNING: missing macro %s." %
                                  get_prop(obj, 'macro', ''))
        self.file.write("\n")
        for g in global_props:
            self.file.write("%s\n" % g)
        self.file.write("\n")
        for n in self.obj_name_list:
            self.file.write("OBJECT %s\n" % n)
        for n in self.fac_name_list:
            self.file.write("FACADE %s\n" % n)
        self.file.write("\n")

        tile_list = []

        #
        # TILE ANNOTATION EXPORT
        #
        for o in top_level_objects:
            if not has_prefix(o.name, 'obj'):
                if is_ags and want_tile_ids:
                    self.export_ag_tile(o, getChildren(o, scene.objects),
                                        scene.objects, lib_root, tile_list)
                else:
                    self.export_ag_tile(o, getChildren(o, scene.objects),
                                        scene.objects, lib_root, None)

        for g in text_props:
            self.file.write("%s\n" % g)

        print tile_list

        self.file.close
        if self.log:
            r = Draw.PupMenu('|'.join([a[0] for a in self.log]))
#
# See ReadMe-XPlane2Blender.html for usage.
#

import Blender
from Blender import Draw, Window
from XPlaneExport import OBJexport7, ExportError

if Window.EditMode(): Window.EditMode(0)
try:
    obj = None
    scene = Blender.Scene.GetCurrent()

    baseFileName = Blender.Get('filename')
    l = baseFileName.lower().rfind('.blend')
    if l == -1: raise ExportError('Save this .blend file first')
    baseFileName = baseFileName[:l]
    obj = OBJexport7(baseFileName + '.obj', __version__, False)
    obj.export(scene)
except ExportError, e:
    for o in scene.objects:
        o.select(0)
    if e.objs:
        layers = []
        if isinstance(e.objs, tuple):
            (o, mesh, faces) = e.objs
            o.select(1)
            layers = o.layers
            for f in mesh.faces:
                f.sel = 0
            if faces:
Beispiel #22
0
def decode(obj):
    properties = obj.getAllProperties()
    objname = obj.name

    #setup default manipulator attribute values
    manip_iscommand_br	= False
    manip_is_push_tk	= False
    manip_is_toggle_tk	= False
    manip_command_br	= "<command>"
    manip_cursor_br	= "<cursor>"
    manip_x_br		= "<x>"
    manip_y_br		= "<y>"
    manip_z_br		= "<z>"
    manip_val1_br	= "<val1>"
    manip_val2_br	= "<val2>"
    manip_dref_br	= "<dref>"
    manip_tooltip_br	= "<tooltip>"

    manip_bone_name_br	= "" #--leave this blank by default, if its not blank the code will try and find the bone name

    for prop in properties:
        if( prop.name == "mnp_iscommand" ):	manip_iscommand_br	= prop.data #--expects a boolean value
        if( prop.name == "mnp_command" ):	manip_command_br	= prop.data.strip()
        if( prop.name == "mnp_cursor" ):	manip_cursor_br		= prop.data.strip()
        if( prop.name == "mnp_dref" ):		manip_dref_br		= prop.data.strip()
        if( prop.name == "mnp_tooltip" ):	manip_tooltip_br	= prop.data.strip()
        if( prop.name == "mnp_bone" ):		manip_bone_name_br	= prop.data.strip()
        if( prop.name == "mnp_v1" ):		manip_val1_br		= str(prop.data)
        if( prop.name == "mnp_v2" ):		manip_val2_br		= str(prop.data)
        if( prop.name == "mnp_is_push" ):	manip_is_push_tk	= prop.data
        if( prop.name == "mnp_is_toggle" ):	manip_is_toggle_tk	= prop.data

    # BR's weird scheme: if there is NO mnp_bone there is no manip, get out.  But the magic
    # bone names arm_ are place-holders - they're not REAL armatures, it's just a place-holder
    # to make the export work.

    if manip_bone_name_br == "":
        return anim_decode(obj)

    if( manip_bone_name_br != "" and manip_bone_name_br != "arm_" ):
        obj_manip_armature_br = Blender.Object.Get( manip_bone_name_br )
        if( obj_manip_armature_br != None ):
            obj_manip_armature_data_br = obj_manip_armature_br.getData()
            obj_manip_bone_br = obj_manip_armature_data_br.bones.values()[0]

            vec_tail = obj_manip_bone_br.tail['ARMATURESPACE']
            vec_arm = [obj_manip_armature_br.LocX, obj_manip_armature_br.LocY, obj_manip_armature_br.LocZ]

            #blender Y = x-plane Z, transpose
            manip_x_br = str( round(vec_tail[0],3) )
            manip_y_br = str( round(vec_tail[2],3) )
            manip_z_br = str( round(-vec_tail[1],3) ) #note: value is inverted.

            #self.file.write( str( vec_tail ) + "\n" )
            #self.file.write( str( vec_arm ) + "\n" )

    data = ""

    if( manip_iscommand_br ):
        #wiki def: ATTR_manip_command <cursor> <command> <tooltip>
        data = ("ATTR_manip_command %s %s %s" % (manip_cursor_br,
                                                 manip_command_br,
                                                 manip_tooltip_br))
    elif( manip_is_push_tk):
        data = ("ATTR_manip_push %s %s %s %s" % (manip_cursor_br,
                                                 manip_val1_br,
                                                 manip_val2_br,
                                                 manip_dref_br))
    elif( manip_is_toggle_tk):
        data = ("ATTR_manip_toggle %s %s %s %s" % (manip_cursor_br,
                                                   manip_val1_br,
                                                   manip_val2_br,
                                                   manip_dref_br))
    else:
        #wiki def: ATTR_manip_drag_axis <cursor> <x> <y> <z> <value1> < value2> <dataref> <tooltip>
        data = ("ATTR_manip_drag_axis %s %s %s %s %s %s %s %s" % (manip_cursor_br,
                                                                  manip_x_br,
                                                                  manip_y_br,
                                                                  manip_z_br,
                                                                  manip_val1_br,
                                                                  manip_val2_br,
                                                                  manip_dref_br,
                                                                  manip_tooltip_br))

    if data.find("<x>") != -1:
        print properties
        raise ExportError("%s: Manipulator '%s' is incomplete but was still exported." % (objname, data))

    return data