VRGeometryPtr loadPly(string filename) { GeoUInt8PropertyRecPtr Type = GeoUInt8Property::create(); GeoUInt32PropertyRecPtr Length = GeoUInt32Property::create(); GeoPnt3fPropertyRecPtr Pos = GeoPnt3fProperty::create(); GeoVec3fPropertyRecPtr Norms = GeoVec3fProperty::create(); GeoVec3fPropertyRecPtr Cols = GeoVec3fProperty::create(); GeoUInt32PropertyRecPtr Indices = GeoUInt32Property::create(); SimpleMaterialRecPtr Mat = SimpleMaterial::create(); GeoVec2fPropertyRecPtr Tex = GeoVec2fProperty::create(); Mat->setLit(false); Mat->setDiffuse(Color3f(0.8,0.8,0.6)); Mat->setAmbient(Color3f(0.4, 0.4, 0.2)); Mat->setSpecular(Color3f(0.1, 0.1, 0.1)); ifstream file(filename.c_str()); string line; list<element> elements; while (getline(file, line)) { if (line == "end_header") break; auto data = splitString(line, ' '); if (data[0] == "element") elements.push_back( element(data[1], toInt(data[2]) ) ); if (data[0] == "property") { if (data.size() == 3) elements.back().properties.push_back( property(data[1], data[2]) ); else elements.back().properties.push_back( property(data[1], data[2]) ); } } int N = 0; for (auto e : elements) N += e.N; VRProgress progress("load PLY " + filename, N); for (auto e : elements) { if (e.type == "vertex") { Vec3f p, n; Vec3i c; Vec2f t; bool doP = 0, doN = 0, doC = 0, doT = 0; for (int i=0; i<e.N; i++) { progress.update(1); getline(file, line); istringstream iss(line); for (auto prop : e.properties) { if (prop.name == "x") { iss >> p[0]; doP = 1; } if (prop.name == "y") { iss >> p[1]; doP = 1; } if (prop.name == "z") { iss >> p[2]; doP = 1; } if (prop.name == "nx") { iss >> n[0]; doN = 1; }
void VRStroke::strokeProfile(vector<Vec3f> profile, bool closed, bool lit) { mode = 0; this->profile = profile; this->closed = closed; this->lit = lit; GeoUInt8PropertyRecPtr Type = GeoUInt8Property::create(); GeoUInt32PropertyRecPtr Length = GeoUInt32Property::create(); GeoPnt3fPropertyRecPtr Pos = GeoPnt3fProperty::create(); GeoVec3fPropertyRecPtr Norms = GeoVec3fProperty::create(); GeoVec3fPropertyRecPtr Colors = GeoVec3fProperty::create(); GeoUInt32PropertyRecPtr Indices = GeoUInt32Property::create(); bool doCaps = closed && profile.size() > 1; Vec3f z = Vec3f(0,0,1); if (profile.size() == 1) Type->addValue(GL_LINES); else Type->addValue(GL_QUADS); clearChildren(); for (uint i=0; i<paths.size(); i++) { vector<Vec3f> pnts = paths[i]->getPositions(); vector<Vec3f> directions = paths[i]->getDirections(); vector<Vec3f> up_vectors = paths[i]->getUpvectors(); vector<Vec3f> cols = paths[i]->getColors(); Vec3f _p; for (uint j=0; j<pnts.size(); j++) { Vec3f p = pnts[j]; Vec3f n = directions[j]; Vec3f u = up_vectors[j]; Vec3f c = cols[j]; Matrix m; MatrixLookAt(m, Vec3f(0,0,0), n, u); // add new profile points && normals for (uint k=0; k<profile.size(); k++) { Vec3f tmp = profile[k]; m.mult(tmp, tmp); Pos->addValue(p+tmp); tmp.normalize(); Norms->addValue(tmp); Colors->addValue(c); } if (j==0 && profile.size() > 1) continue; // add line if (profile.size() == 1) { int N = Pos->size(); Indices->addValue(N-2); Indices->addValue(N-1); } else { // add quad for (uint k=0; k<profile.size()-1; k++) { int N1 = Pos->size() - 2*profile.size() + k; int N2 = Pos->size() - profile.size() + k; Indices->addValue(N1); Indices->addValue(N2); Indices->addValue(N2+1); Indices->addValue(N1+1); //cout << "\nN1N2 " << N1 << " " << N2 << " " << N2+1 << " " << N1+1 << flush; } if (closed) { int N0 = Pos->size() - 2*profile.size(); int N1 = Pos->size() - profile.size() - 1; int N2 = Pos->size() - 1; Indices->addValue(N1); Indices->addValue(N2); Indices->addValue(N1+1); Indices->addValue(N0); //cout << "\nN1N2 " << N1 << " " << N2 << " " << N1+1 << " " << N0 << flush; } } } } Length->addValue(Indices->size()); // caps if (doCaps) { int Nt = 0; for (uint i=0; i<paths.size(); i++) { vector<Vec3f> pnts = paths[i]->getPositions(); vector<Vec3f> directions = paths[i]->getDirections(); vector<Vec3f> up_vectors = paths[i]->getUpvectors(); vector<Vec3f> cols = paths[i]->getColors(); Matrix m; // first cap Vec3f p = pnts[0]; Vec3f n = directions[0]; Vec3f u = up_vectors[0]; Vec3f c = cols[0]; int Ni = Pos->size(); Pos->addValue(p); Norms->addValue(-n); Colors->addValue(c); MatrixLookAt(m, Vec3f(0,0,0), n, u); for (uint k=0; k<profile.size(); k++) { Vec3f tmp = profile[k]; m.mult(tmp, tmp); Pos->addValue(p+tmp); Norms->addValue(-n); Colors->addValue(c); } for (uint k=1; k<=profile.size(); k++) { int j = k+1; if (k == profile.size()) j = 1; Indices->addValue(Ni); Indices->addValue(Ni+k); Indices->addValue(Ni+j); Nt+=3; } // last cap int N = pnts.size()-1; Ni = Pos->size(); p = pnts[N]; n = directions[N]; u = up_vectors[N]; c = cols[N]; Pos->addValue(p); Norms->addValue(n); Colors->addValue(c); MatrixLookAt(m, Vec3f(0,0,0), n, u); for (uint k=0; k<profile.size(); k++) { Vec3f tmp = profile[k]; m.mult(tmp, tmp); Pos->addValue(p+tmp); Norms->addValue(n); Colors->addValue(c); } for (uint k=1; k<=profile.size(); k++) { int j = k+1; if (k == profile.size()) j = 1; Indices->addValue(Ni); Indices->addValue(Ni+j); Indices->addValue(Ni+k); Nt+=3; } } Type->addValue(GL_TRIANGLES); Length->addValue(Nt); // caps triangles } SimpleMaterialRecPtr Mat = SimpleMaterial::create(); GeometryRecPtr g = Geometry::create(); g->setTypes(Type); g->setLengths(Length); g->setPositions(Pos); g->setNormals(Norms); g->setColors(Colors); g->setIndices(Indices); g->setMaterial(Mat); Mat->setLit(lit); setMesh(g); // test for ccw faces /*TriangleIterator it(getMesh()); while (!it.isAtEnd()) { Vec3f p0 = Vec3f(it.getPosition(0)); Vec3f p1 = Vec3f(it.getPosition(1)); Vec3f p2 = Vec3f(it.getPosition(2)); Vec3f n0 = it.getNormal(0); Vec3f n1 = it.getNormal(1); Vec3f n2 = it.getNormal(2); Vec3f np1 = (p1-p0).cross(p2-p0); Vec3f np2 = n0+n1+n2; np2.normalize(); cout << " face orientation " << np1.dot(np2) << endl; ++it; }*/ }
void VRStroke::strokeProfile(vector<Vec3f> profile, bool closed, bool lit) { mode = 0; this->profile = profile; this->closed = closed; this->lit = lit; GeoUInt8PropertyRecPtr Type = GeoUInt8Property::create(); GeoUInt32PropertyRefPtr Length = GeoUInt32Property::create(); GeoPnt3fPropertyRecPtr Pos = GeoPnt3fProperty::create(); GeoVec3fPropertyRefPtr Norms = GeoVec3fProperty::create(); GeoVec3fPropertyRefPtr Colors = GeoVec3fProperty::create(); GeoUInt32PropertyRefPtr Indices = GeoUInt32Property::create(); Vec3f z = Vec3f(0,0,1); if (profile.size() == 1) Type->addValue(GL_LINES); else Type->addValue(GL_QUADS); clearChildren(); for (uint i=0; i<paths.size(); i++) { vector<Vec3f> pnts = paths[i]->get(); vector<Vec3f> norms = paths[i]->getNormals(); vector<Vec3f> cols = paths[i]->getColors(); Vec3f _p; for (uint j=0; j<pnts.size(); j++) { Vec3f p = pnts[j]; Vec3f n = norms[j]; Vec3f c = cols[j]; //float ca = n.dot(z); Matrix m; //MatrixLookAt(m, Vec3f(0,0,0), n, z.cross(n)); MatrixLookAt(m, Vec3f(0,0,0), n, Vec3f(0,1,0)); // add new profile points and normals for (uint k=0; k<profile.size(); k++) { Vec3f tmp = profile[k]; m.mult(tmp, tmp); Pos->addValue(p+tmp); tmp.normalize(); Norms->addValue(tmp); Colors->addValue(c); } if (j==0 and profile.size() > 1) continue; // add line if (profile.size() == 1) { int N = Pos->size(); Indices->addValue(N-2); Indices->addValue(N-1); } else { // add quad for (uint k=0; k<profile.size()-1; k++) { int N1 = Pos->size() - 2*profile.size() + k; int N2 = Pos->size() - profile.size() + k; Indices->addValue(N1); Indices->addValue(N2); Indices->addValue(N2+1); Indices->addValue(N1+1); //cout << "\nN1N2 " << N1 << " " << N2 << " " << N2+1 << " " << N1+1 << flush; } if (closed) { int N0 = Pos->size() - 2*profile.size(); int N1 = Pos->size() - profile.size() - 1; int N2 = Pos->size() - 1; Indices->addValue(N1); Indices->addValue(N2); Indices->addValue(N1+1); Indices->addValue(N0); //cout << "\nN1N2 " << N1 << " " << N2 << " " << N1+1 << " " << N0 << flush; } } } } Length->addValue(Indices->size()); SimpleMaterialRecPtr Mat = SimpleMaterial::create(); GeometryRecPtr g = Geometry::create(); g->setTypes(Type); g->setLengths(Length); g->setPositions(Pos); g->setNormals(Norms); g->setColors(Colors); g->setIndices(Indices); g->setMaterial(Mat); Mat->setLit(lit); VRGeometry* geo = new VRGeometry("stroke"); geo->setMesh(g); addChild(geo); }