예제 #1
0
static void
ply_boot_connection_send_answer (ply_boot_connection_t *connection,
                                 const char            *answer)
{
  uint32_t size;

  /* splash plugin isn't able to ask for password,
   * punt to client
   */
  if (answer == NULL)
    {
      if (!ply_write (connection->fd,
                      PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER,
                      strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER)))
        ply_error ("could not write bytes: %m");
    }
  else
    {
      size = strlen (answer);

      if (!ply_write (connection->fd,
                      PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER,
                      strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER)) ||
          !ply_write_uint32 (connection->fd,
                             size) ||
          !ply_write (connection->fd,
                      answer, size))
          ply_error ("could not write bytes: %m");

    }

}
예제 #2
0
void PLYDataWriter::write_vertices ( p_ply oply )
{
    for( unsigned int i = 0; i <  mesh->vertex_count(); i++ )
    {
        Vertex vert = mesh->get_vertex( i );
        ply_write ( oply, vert.x() );
        ply_write ( oply, vert.y() );
        ply_write ( oply, vert.z() );
    }
}
예제 #3
0
void PLYDataWriter::write_faces ( p_ply oply )
{
    for( unsigned int i = 0; i <  mesh->face_count(); i++ )
    {
        Face face = mesh->get_face( i );
        ply_write ( oply, face.model() );
        for ( int j = 0; j < face.model(); j++ )
        {
            ply_write ( oply, face[j] );
        }
    }
}
예제 #4
0
static bool
ply_boot_client_send_request (ply_boot_client_t         *client,
                              ply_boot_client_request_t *request)
{
  char *request_string;
  size_t request_size;

  assert (client != NULL);
  assert (request != NULL);

  request_string = ply_boot_client_get_request_string (client, request,
                                                       &request_size);
  if (!ply_write (client->socket_fd, request_string, request_size))
    {
      free (request_string);
      ply_boot_client_cancel_request (client, request);
      return false;
    }
  free (request_string);

  if (client->daemon_has_reply_watch == NULL)
    {
      assert (ply_list_get_length (client->requests_waiting_for_replies) == 0);
      client->daemon_has_reply_watch = 
          ply_event_loop_watch_fd (client->loop, client->socket_fd,
                                   PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
                                   (ply_event_handler_t)
                                   ply_boot_client_process_incoming_replies,
                                   NULL, client);
    }
  return true;
}
예제 #5
0
파일: convert.c 프로젝트: EricAlex/PDAL
/* read callback */
static int callback(p_ply_argument argument) {
    void *pdata;
    /* just pass the value from the input file to the output file */
    ply_get_argument_user_data(argument, &pdata, NULL);
    ply_write((p_ply) pdata, ply_get_argument_value(argument));
    return 1;
}
예제 #6
0
static void
ply_boot_connection_on_quit_complete (ply_boot_connection_t *connection)
{
  ply_trace ("quit complete");
  if (!ply_write (connection->fd,
                  PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK,
                  strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK)))
    {
      ply_error ("could not write bytes: %m");
    }
}
예제 #7
0
void
write_file()
{
  int i,j,k;
  PlyFile *ply;
  int num_elems;
  char *elem_name;

  /*** Write out the final PLY object ***/


  ply = ply_write (stdout, nelems, elist, file_type);


  /* describe what properties go into the vertex and face elements */

  ply_element_count (ply, "vertex", nverts);
  ply_describe_property (ply, "vertex", &vert_props[0]);
  ply_describe_property (ply, "vertex", &vert_props[1]);
  ply_describe_property (ply, "vertex", &vert_props[2]);
  ply_describe_property (ply, "vertex", &vert_props[3]);
  ply_describe_property (ply, "vertex", &vert_props[4]);
  ply_describe_property (ply, "vertex", &vert_props[5]);
  ply_describe_other_properties (ply, vert_other, offsetof(Vertex,other_props));

  ply_element_count (ply, "face", nfaces);
  ply_describe_property (ply, "face", &face_props[0]);
  ply_describe_other_properties (ply, face_other, offsetof(Face,other_props));

  ply_describe_other_elements (ply, other_elements);

  for (i = 0; i < num_comments; i++)
    ply_put_comment (ply, comments[i]);

  for (i = 0; i < num_obj_info; i++)
    ply_put_obj_info (ply, obj_info[i]);

  ply_header_complete (ply);

  /* set up and write the vertex elements */
  ply_put_element_setup (ply, "vertex");
  for (i = 0; i < nverts; i++)
    ply_put_element (ply, (void *) vlist[i]);

  /* set up and write the face elements */
  ply_put_element_setup (ply, "face");
  for (i = 0; i < nfaces; i++)
    ply_put_element (ply, (void *) flist[i]);

  ply_put_other_elements (ply);

  /* close the PLY file */
  ply_close (ply);
}
예제 #8
0
파일: PlyWriter.cpp 프로젝트: EricAlex/PDAL
void PlyWriter::done(PointTableRef table)
{
    if (!ply_add_element(m_ply, "vertex", m_pointCollector->size()))
    {
        std::stringstream ss;
        ss << "Could not add vertex element";
        throw pdal_error(ss.str());
    }
    auto dimensions = table.layout()->dims();
    for (auto dim : dimensions) {
        std::string name = Dimension::name(dim);
        e_ply_type plyType = getPlyType(Dimension::defaultType(dim));
        if (!ply_add_scalar_property(m_ply, name.c_str(), plyType))
        {
            std::stringstream ss;
            ss << "Could not add scalar property '" << name << "'";
            throw pdal_error(ss.str());
        }
    }
    if (!ply_add_comment(m_ply, "Generated by PDAL"))
    {
        std::stringstream ss;
        ss << "Could not add comment";
        throw pdal_error(ss.str());
    }
    if (!ply_write_header(m_ply))
    {
        std::stringstream ss;
        ss << "Could not write ply header";
        throw pdal_error(ss.str());
    }

    for (PointId index = 0; index < m_pointCollector->size(); ++index)
    {
        for (auto dim : dimensions)
        {
            double value = m_pointCollector->getFieldAs<double>(dim, index);
            if (!ply_write(m_ply, value))
            {
                std::stringstream ss;
                ss << "Error writing dimension '" << Dimension::name(dim) <<
                    "' of point number " << index;
                throw pdal_error(ss.str());
            }
        }
    }

    if (!ply_close(m_ply))
    {
        throw pdal_error("Error closing ply file");
    }
}
예제 #9
0
static void
ply_boot_connection_on_request (ply_boot_connection_t *connection)
{
  ply_boot_server_t *server;
  char *command, *argument;

  assert (connection != NULL);
  assert (connection->fd >= 0);

  server = connection->server;
  assert (server != NULL);

  if (!ply_boot_connection_read_request (connection,
                                         &command, &argument))
    {
      ply_trace ("could not read connection request");
      return;
    }

  if (!ply_boot_connection_is_from_root (connection))
    {
      ply_error ("request came from non-root user");

      if (!ply_write (connection->fd,
                      PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK,
                      strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK)))
        ply_error ("could not write bytes: %m");

      free (command);
      return;
    }

  if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE) == 0)
    {
      ply_trace ("got update request");
      if (server->update_handler != NULL)
        server->update_handler (server->user_data, argument, server);
      free (argument);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_INITIALIZED) == 0)
    {
      ply_trace ("got system initialized notification");
      if (server->system_initialized_handler != NULL)
        server->system_initialized_handler (server->user_data, server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_ERROR) == 0)
    {
      ply_trace ("got error notification");
      if (server->error_handler != NULL)
        server->error_handler (server->user_data, server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_SPLASH) == 0)
    {
      ply_trace ("got show splash request");
      if (server->show_splash_handler != NULL)
        server->show_splash_handler (server->user_data, server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HIDE_SPLASH) == 0)
    {
      ply_trace ("got hide splash request");
      if (server->hide_splash_handler != NULL)
        server->hide_splash_handler (server->user_data, server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_DEACTIVATE) == 0)
    {
      ply_trigger_t *deactivate_trigger;

      ply_trace ("got deactivate request");

      deactivate_trigger = ply_trigger_new (NULL);

      ply_trigger_add_handler (deactivate_trigger,
                               (ply_trigger_handler_t)
                               ply_boot_connection_on_deactivated,
                               connection);

      if (server->deactivate_handler != NULL)
        server->deactivate_handler (server->user_data, deactivate_trigger, server);

      free (argument);
      free (command);
      return;
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_REACTIVATE) == 0)
    {
      ply_trace ("got reactivate request");
      if (server->reactivate_handler != NULL)
        server->reactivate_handler (server->user_data, server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT) == 0)
    {
      bool retain_splash;
      ply_trigger_t *quit_trigger;

      retain_splash = (bool) argument[0];

      ply_trace ("got quit %srequest", retain_splash? "--retain-splash " : "");

      quit_trigger = ply_trigger_new (NULL);

      ply_trigger_add_handler (quit_trigger,
                               (ply_trigger_handler_t)
                               ply_boot_connection_on_quit_complete,
                               connection);

      if (server->quit_handler != NULL)
        server->quit_handler (server->user_data, retain_splash, quit_trigger, server);

      free(argument);
      free(command);
      return;
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD) == 0)
    {
      ply_trigger_t *answer;

      ply_trace ("got password request");

      answer = ply_trigger_new (NULL);
      ply_trigger_add_handler (answer,
                               (ply_trigger_handler_t)
                               ply_boot_connection_on_password_answer,
                               connection);

      if (server->ask_for_password_handler != NULL)
        server->ask_for_password_handler (server->user_data,
                                          argument,
                                          answer,
                                          server);
      /* will reply later
       */
      free(command);
      return;
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_CACHED_PASSWORD) == 0)
    {
      ply_list_node_t *node;
      ply_buffer_t *buffer;
      size_t buffer_size;
      uint32_t size;

      ply_trace ("got cached password request");

      buffer = ply_buffer_new ();

      node = ply_list_get_first_node (server->cached_passwords);

      ply_trace ("There are %d cached passwords",
                 ply_list_get_length (server->cached_passwords));

      /* Add each answer separated by their NUL terminators into
       * a buffer that we write out to the client
       */
      while (node != NULL)
        {
          ply_list_node_t *next_node;
          const char *password;

          next_node = ply_list_get_next_node (server->cached_passwords, node);
          password = (const char *) ply_list_node_get_data (node);

          ply_buffer_append_bytes (buffer,
                                   password,
                                   strlen (password) + 1);
          node = next_node;
        }

      buffer_size = ply_buffer_get_size (buffer);

      /* splash plugin doesn't have any cached passwords
      */
      if (buffer_size == 0)
        {
          if (!ply_write (connection->fd,
                          PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER,
                          strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER)))
              ply_error ("could not write bytes: %m");
        }
      else
        {
          size = buffer_size;

          ply_trace ("writing %d cached answers",
                     ply_list_get_length (server->cached_passwords));
          if (!ply_write (connection->fd,
                          PLY_BOOT_PROTOCOL_RESPONSE_TYPE_MULTIPLE_ANSWERS,
                          strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_MULTIPLE_ANSWERS)) ||
              !ply_write_uint32 (connection->fd,
                                 size) ||
              !ply_write (connection->fd,
                          ply_buffer_get_bytes (buffer), size))
              ply_error ("could not write bytes: %m");
        }

      ply_buffer_free (buffer);
      free(command);
      return;
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION) == 0)
    {
      ply_trigger_t *answer;

      ply_trace ("got question request");

      answer = ply_trigger_new (NULL);
      ply_trigger_add_handler (answer,
                               (ply_trigger_handler_t)
                               ply_boot_connection_on_question_answer,
                               connection);

      if (server->ask_question_handler != NULL)
        server->ask_question_handler (server->user_data,
                                          argument,
                                          answer,
                                          server);
      /* will reply later
       */
      free(command);
      return;
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_MESSAGE) == 0)
    {
      ply_trace ("got message request");
      if (server->display_message_handler != NULL)
        server->display_message_handler(server->user_data, argument, server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE) == 0)
    {
      ply_trigger_t *answer;

      ply_trace ("got keystroke request");

      answer = ply_trigger_new (NULL);
      ply_trigger_add_handler (answer,
                               (ply_trigger_handler_t)
                               ply_boot_connection_on_keystroke_answer,
                               connection);

      if (server->watch_for_keystroke_handler != NULL)
        server->watch_for_keystroke_handler (server->user_data,
                                          argument,
                                          answer,
                                          server);
      /* will reply later
       */
      free(command);
      return;
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE_REMOVE) == 0)
    {
      ply_trace ("got keystroke remove request");
      if (server->ignore_keystroke_handler != NULL)
        server->ignore_keystroke_handler (server->user_data,
                                          argument,
                                          server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PROGRESS_PAUSE) == 0)
    {
      ply_trace ("got progress pause request");
      if (server->progress_pause_handler != NULL)
        server->progress_pause_handler (server->user_data,
                                        server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PROGRESS_UNPAUSE) == 0)
    {
      ply_trace ("got progress unpause request");
      if (server->progress_unpause_handler != NULL)
        server->progress_unpause_handler (server->user_data,
                                          server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_NEWROOT) == 0)
    {
      ply_trace ("got newroot request");
      if (server->newroot_handler != NULL)
        server->newroot_handler(server->user_data, argument, server);
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HAS_ACTIVE_VT) == 0)
    {
      bool answer = false;

      ply_trace ("got has_active vt? request");
      if (server->has_active_vt_handler != NULL)
        answer = server->has_active_vt_handler(server->user_data, server);

      if (!answer)
        {
          if (!ply_write (connection->fd,
                          PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK,
                          strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK)))
            ply_error ("could not write bytes: %m");

          free(command);
          return;
        }
    }
  else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING) != 0)
    {
      ply_error ("received unknown command '%s' from client", command);

      if (!ply_write (connection->fd,
                      PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK,
                      strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK)))
        ply_error ("could not write bytes: %m");

      free(command);
      return;
    }

  if (!ply_write (connection->fd, 
                  PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK,
                  strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK)))
    {
      ply_error ("could not write bytes: %m");
    }
  free(command);
}
예제 #10
0
void write_ply(const std::string &filename, const MatrixXu &F,
               const MatrixXf &V, const MatrixXf &N, const MatrixXf &Nf, const MatrixXf &UV,
               const MatrixXf &C, const ProgressCallback &progress) {
    auto message_cb = [](p_ply ply, const char *msg) {
        cerr << "rply: " << msg << endl;
    };

    Timer<> timer;
    cout << "Writing \"" << filename << "\" (V=" << V.cols()
         << ", F=" << F.cols() << ") .. ";
    cout.flush();

    if (N.size() > 0 && Nf.size() > 0)
        throw std::runtime_error("Please specify either face or vertex normals but not both!");

    p_ply ply = ply_create(filename.c_str(), PLY_DEFAULT, message_cb, 0, nullptr);
    if (!ply)
        throw std::runtime_error("Unable to write PLY file!");

    ply_add_comment(ply, "Generated by Instant Meshes");
    ply_add_element(ply, "vertex", V.cols());
    ply_add_scalar_property(ply, "x", PLY_FLOAT);
    ply_add_scalar_property(ply, "y", PLY_FLOAT);
    ply_add_scalar_property(ply, "z", PLY_FLOAT);

    if (N.size() > 0) {
        ply_add_scalar_property(ply, "nx", PLY_FLOAT);
        ply_add_scalar_property(ply, "ny", PLY_FLOAT);
        ply_add_scalar_property(ply, "nz", PLY_FLOAT);
        if (N.cols() != V.cols() || N.rows() != 3)
            throw std::runtime_error("Vertex normal matrix has incorrect size");
    }

    if (UV.size() > 0) {
        ply_add_scalar_property(ply, "u", PLY_FLOAT);
        ply_add_scalar_property(ply, "v", PLY_FLOAT);
        if (UV.cols() != V.cols() || UV.rows() != 2)
            throw std::runtime_error("Texture coordinate matrix has incorrect size");
    }

    if (C.size() > 0) {
        ply_add_scalar_property(ply, "red", PLY_FLOAT);
        ply_add_scalar_property(ply, "green", PLY_FLOAT);
        ply_add_scalar_property(ply, "blue", PLY_FLOAT);
        if (C.cols() != V.cols() || (C.rows() != 3 && C.rows() != 4))
            throw std::runtime_error("Color matrix has incorrect size");
    }

    /* Check for irregular faces */
    std::map<uint32_t, std::pair<uint32_t, std::map<uint32_t, uint32_t>>> irregular;
    size_t nIrregular = 0;
    if (F.rows() == 4) {
        for (uint32_t f=0; f<F.cols(); ++f) {
            if (F(2, f) == F(3, f)) {
                nIrregular++;
                auto &value = irregular[F(2, f)];
                value.first = f;
                value.second[F(0, f)] = F(1, f);
            }
        }
    }

    ply_add_element(ply, "face", F.cols() - nIrregular + irregular.size());
    ply_add_list_property(ply, "vertex_indices", PLY_UINT8, PLY_INT);
    if (Nf.size() > 0) {
        ply_add_scalar_property(ply, "nx", PLY_FLOAT);
        ply_add_scalar_property(ply, "ny", PLY_FLOAT);
        ply_add_scalar_property(ply, "nz", PLY_FLOAT);
        if (Nf.cols() != F.cols() || Nf.rows() != 3)
            throw std::runtime_error("Face normal matrix has incorrect size");
    }
    ply_write_header(ply);

    for (uint32_t j=0; j<V.cols(); ++j) {
        for (uint32_t i=0; i<V.rows(); ++i)
            ply_write(ply, V(i, j));
        if (N.size() > 0) {
            for (uint32_t i=0; i<N.rows(); ++i)
                ply_write(ply, N(i, j));
        }
        if (UV.size() > 0) {
            for (uint32_t i=0; i<UV.rows(); ++i)
                ply_write(ply, UV(i, j));
        }
        if (C.size() > 0) {
            for (uint32_t i=0; i<std::min(3u, (uint32_t) C.rows()); ++i)
                ply_write(ply, C(i, j));
        }
        if (progress && j % 500000 == 0)
            progress("Writing vertex data", j / (Float) V.cols());
    }

    for (uint32_t f=0; f<F.cols(); ++f) {
        if (F.rows() == 4 && F(2, f) == F(3, f))
            continue;
        ply_write(ply, F.rows());
        for (uint32_t i=0; i<F.rows(); ++i)
            ply_write(ply, F(i, f));
        if (Nf.size() > 0) {
            for (uint32_t i=0; i<Nf.rows(); ++i)
                ply_write(ply, Nf(i, f));
        }
        if (progress && f % 500000 == 0)
            progress("Writing face data", f / (Float) F.cols());
    }

    for (auto item : irregular) {
        auto face = item.second;
        uint32_t v = face.second.begin()->first, first = v;
        ply_write(ply, face.second.size());
        while (true) {
            ply_write(ply, v);
            v = face.second[v];
            if (v == first)
                break;
        }
        if (Nf.size() > 0) {
            for (uint32_t i=0; i<Nf.rows(); ++i)
                ply_write(ply, Nf(i, face.first));
        }
    }

    ply_close(ply);
    cout << "done. (";
    if (irregular.size() > 0)
        cout << irregular.size() << " irregular faces, ";
    cout << "took " << timeString(timer.value()) << ")" << endl;
}
예제 #11
0
IGL_INLINE bool igl::writePLY(
  const std::string & filename,
  const Eigen::PlainObjectBase<DerivedV> & V,
  const Eigen::PlainObjectBase<DerivedF> & F,
  const Eigen::PlainObjectBase<DerivedN> & N,
  const Eigen::PlainObjectBase<DerivedUV> & UV,
  const bool ascii)
{
  // Largely based on obj2ply.c

  typedef struct Vertex
  {
    double x,y,z,w;          /* position */
    double nx,ny,nz;         /* surface normal */
    double s,t;              /* texture coordinates */
  } Vertex;

  typedef struct Face
  {
    unsigned char nverts;    /* number of vertex indices in list */
    int *verts;              /* vertex index list */
  } Face;

  PlyProperty vert_props[] =
  { /* list of property information for a vertex */
    {"x", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,x), 0, 0, 0, 0},
    {"y", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,y), 0, 0, 0, 0},
    {"z", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,z), 0, 0, 0, 0},
    {"nx", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,nx), 0, 0, 0, 0},
    {"ny", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,ny), 0, 0, 0, 0},
    {"nz", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,nz), 0, 0, 0, 0},
    {"s", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,s), 0, 0, 0, 0},
    {"t", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,t), 0, 0, 0, 0},
  };

  PlyProperty face_props[] =
  { /* list of property information for a face */
    {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts),
      1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)},
  };
  const bool has_normals = N.rows() > 0;
  const bool has_texture_coords = UV.rows() > 0;
  std::vector<Vertex> vlist(V.rows());
  std::vector<Face> flist(F.rows());
  for(size_t i = 0;i<(size_t)V.rows();i++)
  {
    vlist[i].x = V(i,0);
    vlist[i].y = V(i,1);
    vlist[i].z = V(i,2);
    if(has_normals)
    {
      vlist[i].nx = N(i,0);
      vlist[i].ny = N(i,1);
      vlist[i].nz = N(i,2);
    }
    if(has_texture_coords)
    {
      vlist[i].s = UV(i,0);
      vlist[i].t = UV(i,1);
    }
  }
  for(size_t i = 0;i<(size_t)F.rows();i++)
  {
    flist[i].nverts = F.cols();
    flist[i].verts = new int[F.cols()];
    for(size_t c = 0;c<(size_t)F.cols();c++)
    {
      flist[i].verts[c] = F(i,c);
    }
  }

  const char * elem_names[] = {"vertex","face"};
  FILE * fp = fopen(filename.c_str(),"w");
  if(fp==NULL)
  {
    return false;
  }
  PlyFile * ply = ply_write(fp, 2,elem_names,
      (ascii ? PLY_ASCII : PLY_BINARY_LE));
  if(ply==NULL)
  {
    return false;
  }

  std::vector<PlyProperty> plist;
  plist.push_back(vert_props[0]);
  plist.push_back(vert_props[1]);
  plist.push_back(vert_props[2]);
  if (has_normals)
  {
    plist.push_back(vert_props[3]);
    plist.push_back(vert_props[4]);
    plist.push_back(vert_props[5]);
  }
  if (has_texture_coords)
  {
    plist.push_back(vert_props[6]);
    plist.push_back(vert_props[7]);
  }
  ply_describe_element(ply, "vertex", V.rows(),plist.size(),
    &plist[0]);

  ply_describe_element(ply, "face", F.rows(),1,&face_props[0]);
  ply_header_complete(ply);
  int native_binary_type = get_native_binary_type2();
  ply_put_element_setup(ply, "vertex");
  for(const auto v : vlist)
  {
    ply_put_element(ply, (void *) &v, &native_binary_type);
  }
  ply_put_element_setup(ply, "face");
  for(const auto f : flist)
  {
    ply_put_element(ply, (void *) &f, &native_binary_type);
  }

  ply_close(ply);
  for(size_t i = 0;i<(size_t)F.rows();i++)
  {
    delete[] flist[i].verts;
  }
  return true;
}
	bool save(const std::string& filename) {
		if(map_ == nil) {
			Logger::err("PlyMeshSave") << "mesh is null" << std::endl ;
			return false ;
		}

		p_ply ply = ply_create(filename.c_str(), PLY_LITTLE_ENDIAN, nil, 0, nil) ;

		if(ply == nil) {
			Logger::err("PlyMeshSave") << filename << ": could not open" << std::endl ;
			return false ;
		}

		//////////////////////////////////////////////////////////////////////////

		if (!ply_add_comment(ply, "saved by [email protected]")) {
			Logger::err("PlyMeshSave") << "unable to add comment" << std::endl ;
			ply_close(ply) ;
			return false ;
		}

		int num_v = map_->size_of_vertices();
		if (!ply_add_element(ply, "vertex", num_v)) {
			Logger::err("PlyMeshSave") << "unable to add element \'vertex\'" << std::endl ;
			ply_close(ply) ;
			return false ;
		}
		
		e_ply_type length_type, value_type;
		length_type = value_type = static_cast<e_ply_type>(-1);
		std::string pos[3] = { "x", "y", "z" };
		for (unsigned int i=0; i<3; ++i) {
			if (!ply_add_property(ply, pos[i].c_str(), PLY_FLOAT, length_type, value_type)) {
				Logger::err("PlyMeshSave") << "unable to add property \'" << pos[i] << "\'" << std::endl ;
				ply_close(ply) ;
				return false ;
			}
		}

		MapVertexAttribute<Color> vertex_color;
		vertex_color.bind_if_defined(const_cast<Map*>(map_), "color") ;
		if (vertex_color.is_bound()) {
			std::string color[4] = { "red", "green", "blue", "alpha" };
			for (unsigned int i=0; i<4; ++i) {
				if (!ply_add_property(ply, color[i].c_str(), PLY_UCHAR, length_type, value_type)) {
					Logger::err("PlyMeshSave") << "unable to add property \'" << color[i] << "\'" << std::endl ;
					ply_close(ply) ;
					return false ;
				}
			}
		}
		
		int num_f = map_->size_of_facets();
		if (!ply_add_element(ply, "face", num_f)) {
			Logger::err("PlyMeshSave") << "unable to add element \'face\'" << std::endl ;
			ply_close(ply) ;
			return false ;
		}
		if (!ply_add_property(ply, "vertex_indices", PLY_LIST, PLY_UCHAR, PLY_INT)) {
			Logger::err("PlyMeshSave") << "unable to add property \'vertex_indices\'" << std::endl ;
			ply_close(ply) ;
			return false ;
		}

		if(!ply_write_header(ply)) {
			Logger::err("PlyMeshSave") << filename << ": invalid PLY file" << std::endl ;
			ply_close(ply) ;
			return false ;
		}

		//////////////////////////////////////////////////////////////////////////
		
		FOR_EACH_VERTEX_CONST(Map, map_, it) {
			const vec3& p = it->point();
			ply_write(ply, p.x);
			ply_write(ply, p.y);
			ply_write(ply, p.z);
			if (vertex_color.is_bound()) {
				const Color& c = vertex_color[it];
				double r = c.r() * color_mult_;	ogf_clamp(r, 0.0, 255.0);
				double g = c.g() * color_mult_;	ogf_clamp(g, 0.0, 255.0);
				double b = c.b() * color_mult_;	ogf_clamp(b, 0.0, 255.0);
				double a = c.a() * color_mult_; ogf_clamp(a, 0.0, 255.0);
				ply_write(ply, r);
				ply_write(ply, g);
				ply_write(ply, b);
				ply_write(ply, a);
			}
		}

		// ply files numbering starts with 0
		Attribute<Map::Vertex, int> vertex_id(map_->vertex_attribute_manager());
		MapEnumerator::enumerate_vertices(const_cast<Map*>(map_), vertex_id, 0);
		FOR_EACH_FACET_CONST(Map, map_, it) {
			ply_write(ply, it->nb_vertices());
			Map::Halfedge* h = it->halfedge();
			do 
			{
				int id = vertex_id[h->vertex()];
				ply_write(ply, id);
				h = h->next();
			} while (h != it->halfedge());
		}
예제 #13
0
/*******************************************************************************
 *         Name:  main
 *  Description:  
 ******************************************************************************/
int main( void ) {
	int i;

	/* Create new PLY file. */
	p_ply oply = ply_create( "new.ply", PLY_ASCII, NULL, 0, NULL );
	if ( !oply ) {
		fprintf( stderr, "ERROR: Could not create »new.ply«\n" );
		return EXIT_FAILURE;
	}

	/* Add object information to PLY. */
	if ( !ply_add_obj_info( oply, "This is just a test." ) ) {
		fprintf( stderr, "ERROR: Could not add object info.\n" );
		return EXIT_FAILURE;
	}

	/* Add a comment, too. */
	if ( !ply_add_comment( oply, "Just some comment…" ) ) {
		fprintf( stderr, "ERROR: Could not add comment.\n" );
		return EXIT_FAILURE;
	}

	/* Add vertex element. We want to add 9999 vertices. */
	if ( !ply_add_element( oply, "vertex", 99999 ) ) {
		fprintf( stderr, "ERROR: Could not add element.\n" );
		return EXIT_FAILURE;
	}

	/* Add vertex properties: x, y, z, r, g, b */
	if ( !ply_add_property( oply, "x",     PLY_FLOAT, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "y",     PLY_FLOAT, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "z",     PLY_FLOAT, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "red",   PLY_UCHAR, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "green", PLY_UCHAR, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "blue",  PLY_UCHAR, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	/* Write header to file */
	if ( !ply_write_header( oply ) ) {
		fprintf( stderr, "ERROR: Could not write header.\n" );
		return EXIT_FAILURE;
	}

	/* Now we generate random data to add to the file: */
	srand ( time( NULL ) );

	for ( i = 0; i < 99999; i++ ) {
		ply_write( oply, (double) ( rand() % 10000 ) / 10.0 ); /* x */
		ply_write( oply, (double) ( rand() % 10000 ) / 10.0 ); /* y */
		ply_write( oply, (double) ( rand() % 10000 ) / 10.0 ); /* z */
		ply_write( oply, rand() % 256 ); /* red   */
		ply_write( oply, rand() % 256 ); /* blue  */
		ply_write( oply, rand() % 256 ); /* green */
	}

	if ( !ply_close( oply ) ) {
		fprintf( stderr, "ERROR: Could not close file.\n" );
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;

}
예제 #14
0
bool WritePlyFile(const std::string &filename, int nTriangles,
                  const int *vertexIndices, int nVertices, const Point3f *P,
                  const Vector3f *S, const Normal3f *N, const Point2f *UV) {
    p_ply plyFile =
        ply_create(filename.c_str(), PLY_DEFAULT, PlyErrorCallback, 0, nullptr);
    if (plyFile != nullptr) {
        ply_add_element(plyFile, "vertex", nVertices);
        ply_add_scalar_property(plyFile, "x", PLY_FLOAT);
        ply_add_scalar_property(plyFile, "y", PLY_FLOAT);
        ply_add_scalar_property(plyFile, "z", PLY_FLOAT);
        if (N != nullptr) {
            ply_add_scalar_property(plyFile, "nx", PLY_FLOAT);
            ply_add_scalar_property(plyFile, "ny", PLY_FLOAT);
            ply_add_scalar_property(plyFile, "nz", PLY_FLOAT);
        }
        if (UV != nullptr) {
            ply_add_scalar_property(plyFile, "u", PLY_FLOAT);
            ply_add_scalar_property(plyFile, "v", PLY_FLOAT);
        }
        if (S != nullptr)
            Warning("PLY mesh in \"%s\" will be missing tangent vectors \"S\".",
                    filename.c_str());

        ply_add_element(plyFile, "face", nTriangles);
        ply_add_list_property(plyFile, "vertex_indices", PLY_UINT8, PLY_INT);
        ply_write_header(plyFile);

        for (int i = 0; i < nVertices; ++i) {
            ply_write(plyFile, P[i].x);
            ply_write(plyFile, P[i].y);
            ply_write(plyFile, P[i].z);
            if (N) {
                ply_write(plyFile, N[i].x);
                ply_write(plyFile, N[i].y);
                ply_write(plyFile, N[i].z);
            }
            if (UV) {
                ply_write(plyFile, UV[i].x);
                ply_write(plyFile, UV[i].y);
            }
        }

        for (int i = 0; i < nTriangles; ++i) {
            ply_write(plyFile, 3);
            ply_write(plyFile, vertexIndices[3 * i]);
            ply_write(plyFile, vertexIndices[3 * i + 1]);
            ply_write(plyFile, vertexIndices[3 * i + 2]);
        }
        ply_close(plyFile);
        return true;
    }
    return false;
}