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"); } }
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() ); } }
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] ); } } }
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; }
/* 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; }
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"); } }
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); }
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"); } }
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); }
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; }
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()); }
/******************************************************************************* * 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; }
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; }