def writeVectors(writer):
  context = writer.context
  canvas = context.canvas
  mapTo3d = context.mapTo3d
  warp_dem = context.warp_dem
  renderer = QgsMapRenderer()

  layerProperties = {}
  for itemType in [ObjectTreeItem.ITEM_POINT, ObjectTreeItem.ITEM_LINE, ObjectTreeItem.ITEM_POLYGON]:
    for layerId, properties in context.properties[itemType].iteritems():
      if properties.get("visible", False):
        layerProperties[layerId] = properties

  for layerId, properties in layerProperties.iteritems():
    layer = QgsMapLayerRegistry().instance().mapLayer(layerId)
    if layer is None:
      continue
    geom_type = layer.geometryType()
    prop = VectorPropertyReader(context.objectTypeManager, layer, properties)
    obj_mod = context.objectTypeManager.module(prop.mod_index)
    if obj_mod is None:
      qDebug("Module not found")
      continue

    # write layer object
    lyr = {"name": layer.name(), "f": []}
    lyr["type"] = {QGis.Point: "point", QGis.Line: "line", QGis.Polygon: "polygon"}.get(geom_type, "")
    lyr["q"] = 1    #queryable
    lyr["objType"] = prop.type_name

    # make list of field names
    writeAttrs = properties.get("checkBox_ExportAttrs", False)
    fieldNames = None
    if writeAttrs:
      fieldNames = []
      fields = layer.pendingFields()
      for i in range(fields.count()):
        fieldNames.append(fields[i].name())

    hasLabel = False
    if writeAttrs:
      attIdx = properties.get("comboBox_Label", None)
      if attIdx is not None:
        labelHeight = properties.get("labelHeightWidget", [0] * 3)
        lyr["l"] = {"i": attIdx, "ht": int(labelHeight[0]), "v": float(labelHeight[2]) * mapTo3d.multiplierZ}
        hasLabel = True

    # wreite layer object
    writer.writeLayer(lyr, fieldNames)

    # initialize symbol rendering
    layer.rendererV2().startRender(renderer.rendererContext(), layer.pendingFields() if apiChanged23 else layer)

    feat = Feature(layer, prop)
    transform = QgsCoordinateTransform(layer.crs(), context.crs)
    wkt = str(context.crs.toWkt())
    request = QgsFeatureRequest().setFilterRect(transform.transformBoundingBox(canvas.extent(), QgsCoordinateTransform.ReverseTransform))
    for f in layer.getFeatures(request):
      feat.clearGeometry()
      feat.setQgsFeature(f)

      geom = f.geometry()
      geom_type == geom.type()
      wkb_type = geom.wkbType()
      if geom_type == QGis.Point:
        if prop.useZ():
          for pt in pointsFromWkb25D(geom.asWkb(), transform):
            feat.addPoint(mapTo3d.transform(pt[0], pt[1], pt[2] + prop.relativeHeight(f)))
          obj_mod.write(writer, feat)
        else:
          if geom.isMultipart():
            points = geom.asMultiPoint()
          else:
            points = [geom.asPoint()]

          for point in points:
            pt = transform.transform(point)
            if prop.isHeightRelativeToSurface():
              # get surface elevation at the point and relative height
              h = warp_dem.readValue(wkt, pt.x(), pt.y()) + prop.relativeHeight(f)
            else:
              h = prop.relativeHeight(f)
            feat.addPoint(mapTo3d.transform(pt[0], pt[1], h))
          obj_mod.write(writer, feat)

      elif geom_type == QGis.Line:
        if prop.useZ():
          for line in linesFromWkb25D(geom.asWkb(), transform):
            points = []
            for pt in line:
              h = pt[2] + prop.relativeHeight(f)
              points.append(mapTo3d.transform(pt[0], pt[1], h))
            feat.addLine(points)
          obj_mod.write(writer, feat)
        else:
          if geom.isMultipart():
            lines = geom.asMultiPolyline()
          else:
            lines = [geom.asPolyline()]
          for line in lines:
            points = []
            for pt_orig in line:
              pt = transform.transform(pt_orig)
              if prop.isHeightRelativeToSurface():
                h = warp_dem.readValue(wkt, pt.x(), pt.y()) + prop.relativeHeight(f)
              else:
                h = prop.relativeHeight(f)
              points.append(mapTo3d.transform(pt.x(), pt.y(), h))
            feat.addLine(points)
          obj_mod.write(writer, feat)

      elif geom_type == QGis.Polygon:
        useCentroidHeight = True
        labelPerPolygon = True

        if geom.isMultipart():
          polygons = geom.asMultiPolygon()
        else:
          polygons = [geom.asPolygon()]

        if hasLabel and not labelPerPolygon:
          centroidHeight = 0
          pt = transform.transform(geom.centroid().asPoint())
          if prop.isHeightRelativeToSurface():
            centroidHeight = warp_dem.readValue(wkt, pt.x(), pt.y()) + prop.relativeHeight(f)
          else:
            centroidHeight = prop.relativeHeight(f)
          feat.addCentroid(mapTo3d.transform(pt.x(), pt.y(), centroidHeight))

        for polygon in polygons:
          if useCentroidHeight or hasLabel:
            centroidHeight = 0
            pt = transform.transform(QgsGeometry.fromPolygon(polygon).centroid().asPoint())
            if prop.isHeightRelativeToSurface():
              centroidHeight = warp_dem.readValue(wkt, pt.x(), pt.y()) + prop.relativeHeight(f)
            else:
              centroidHeight = prop.relativeHeight(f)
            if hasLabel and labelPerPolygon:
              feat.addCentroid(mapTo3d.transform(pt.x(), pt.y(), centroidHeight))

          boundaries = []
          points = []
          # outer boundary
          for pt_orig in polygon[0]:
            pt = transform.transform(pt_orig)
            if useCentroidHeight:
              h = centroidHeight
            elif prop.isHeightRelativeToSurface():
              h = warp_dem.readValue(wkt, pt.x(), pt.y()) + prop.relativeHeight(f)
            else:
              h = prop.relativeHeight(f)
            points.append(mapTo3d.transform(pt.x(), pt.y(), h))
          boundaries.append(points)
          # inner boundaries
          for inBoundary in polygon[1:]:
            points = []
            for pt_orig in inBoundary:
              pt = transform.transform(pt_orig)
              if useCentroidHeight:
                h = centroidHeight
              elif prop.isHeightRelativeToSurface():
                h = warp_dem.readValue(wkt, pt.x(), pt.y()) + prop.relativeHeight(f)
              else:
                h = prop.relativeHeight(f)
              points.append(mapTo3d.transform(pt.x(), pt.y(), h))
            points.reverse()    # to counter clockwise direction
            boundaries.append(points)
          feat.addPolygon(boundaries)
        obj_mod.write(writer, feat)

      # stack attributes in writer
      if writeAttrs:
        writer.addAttributes(f.attributes())
    # write attributes
    if writeAttrs:
      writer.writeAttributes()

    layer.rendererV2().stopRender(renderer.rendererContext())

  # write materials
  writer.materialManager.write(writer)