Example #1
0
bool Sketch::loadSvg(const char *path, Terrain *terrain)
{
    QFile file(path);
    if (!file.open(QFile::ReadOnly | QFile::Text)) {
      qWarning("Cannot open file");
      return false;
    }
    QString localName;
    QXmlStreamAttributes attributes;
    QXmlStreamReader *pXml = new QXmlStreamReader(&file);
    pXml->setNamespaceProcessing(false);
    while (!pXml->atEnd()) {
      switch (pXml->readNext()) {
          case QXmlStreamReader::StartElement:
            localName = pXml->name().toString();
            if (localName.compare("svg") == 0) {
                attributes = pXml->attributes();
                std::stringstream ss(attributes.value("viewBox").toString().toStdString());
                Eigen::Vector2i origin;
                ss >> origin[0] >> origin[1] >> camera_info_.screen_width >> camera_info_.screen_height;
            }
            if (localName.compare("path") == 0) {
              attributes = pXml->attributes();
              QStringRef data  = attributes.value("d");

              std::vector<Eigen::Vector2i> control_points;
              std::vector<Eigen::Vector2i> cur_points;
              int count = data.count();
              std::string cur_str;
              Eigen::Vector2i cur_point;

              for (int i = 0; i < count; ++i)
              {
                  char c = data.at(i).toLatin1();
                  switch (c) {
                    case 'M':
                    case 'C':
                      control_points.insert(control_points.end(),
                                            cur_points.begin(),
                                            cur_points.end());
                      cur_str.clear();
                      cur_points.clear();
                      break;
                    case ',':
                      cur_point[0] = round(atof(cur_str.c_str()));
                      cur_str.clear();
                      break;
                    case ' ':
                    case '\n':
                    case '\t':
                      if (cur_str.size() > 0)
                        {
                          cur_point[1] = camera_info_.screen_height-1-round(atof(cur_str.c_str()));
                          cur_points.push_back(cur_point);
                          cur_str.clear();
                        } else
                        {
                          control_points.insert(control_points.end(),
                                                cur_points.begin(),
                                                cur_points.end());
                          cur_str.clear();
                          cur_points.clear();
                        }
                      break;
                    default:
                      cur_str += c;
                      break;
                    }
              }
              if (cur_str.size() > 0)
                {
                  cur_point[1] = camera_info_.screen_height-1-atof(cur_str.c_str());
                  cur_points.push_back(cur_point);
                  control_points.insert(control_points.end(),
                                        cur_points.begin(),
                                        cur_points.end());
                  cur_str.clear();
                  cur_points.clear();
                }

              if (control_points.size() <= 2)
                continue;

              Stroke *stroke = new Stroke ();
              stroke->set_identifier(attributes.value("id").toString().toStdString());
              if (terrain == NULL)
                {
                  for (unsigned int i = 0; i < control_points.size(); ++i)
                    stroke->addControlPoint(Stroke::Point(control_points[i][0],  0.0f, control_points[i][1]));
                } else
                {
                  OfflineTerrainRenderer terrain_renderer(terrain);
                  terrain_renderer.setCameraInfo(camera_info());
                  std::vector<Eigen::Vector3f> unprojected_points;
                  terrain_renderer.unProject(control_points, unprojected_points);
                  for (unsigned int i = 0; i < unprojected_points.size(); ++i)
                    stroke->addControlPoint(unprojected_points[i]);
                }
              addStroke(stroke);
            }
            break;
         default:
            break;
      }
    }