void VRAdjacencyGraph::compNeighbors() { vertex_neighbor_params.clear(); vertex_neighbors.clear(); auto sgeo = geo.lock(); if (!sgeo) return; map< int, map<int, int> > tmpdict; for (TriangleIterator it = TriangleIterator(sgeo->getMesh()->geo); !it.isAtEnd(); ++it) { int i0 = it.getPositionIndex(0); int i1 = it.getPositionIndex(1); int i2 = it.getPositionIndex(2); auto reg = [&](int j0, int j1, int j2) { if ( tmpdict.count(j0) == 0 ) tmpdict[j0] = map<int, int>(); if ( tmpdict[j0].count(j1) == 0 ) tmpdict[j0][j1] = 0; if ( tmpdict[j0].count(j2) == 0 ) tmpdict[j0][j2] = 0; tmpdict[j0][j1] += 1; tmpdict[j0][j2] += 1; }; reg(i0,i1,i2); reg(i1,i0,i2); reg(i2,i0,i1); } int N = sgeo->getMesh()->geo->getPositions()->size(); vertex_neighbor_params.resize(2*N); for (auto i : tmpdict) vertex_neighbor_params[2*i.first+1] = i.second.size(); int kN = 0; for (int i = 0; i < N; i++) { vertex_neighbor_params[2*i] = kN; kN += vertex_neighbor_params[2*i+1]; } vertex_neighbors.resize(kN); for (auto i : tmpdict) { int o = vertex_neighbor_params[2*i.first]; int k = 0; for (auto j : i.second) { vertex_neighbors[o+k] = j.first; k++; } } }
void VRAdjacencyGraph::compTriLoockup() { edge_triangle_loockup.clear(); auto sgeo = geo.lock(); if (!sgeo) return; for (TriangleIterator it = TriangleIterator(sgeo->getMesh()->geo); !it.isAtEnd(); ++it) { triangle t; t.v1 = it.getPositionIndex(0); t.v2 = it.getPositionIndex(1); t.v3 = it.getPositionIndex(2); auto reg = [&](int j0, int j1) { if (edge_triangle_loockup.count(j0) == 0) edge_triangle_loockup[j0] = map<int, vector<triangle> >(); if (edge_triangle_loockup[j0].count(j1) == 0) edge_triangle_loockup[j0][j1] = vector<triangle>(); edge_triangle_loockup[j0][j1].push_back(t); }; reg(t.v1,t.v2); reg(t.v2,t.v1); reg(t.v1,t.v3); reg(t.v3,t.v1); reg(t.v2,t.v3); reg(t.v3,t.v2); } }
// Converts geometry to a polyhedron && applies the geometry node's world transform to the polyhedron. // OpenSG geometry data isn't transformed itself but has an associated transform core. Both are unified for CGAL. CGAL::Polyhedron* CSGGeometry::toPolyhedron(GeometryRecPtr geometry, Matrix worldTransform, bool& success) { TriangleIterator it; auto gpos = geometry->getPositions(); // fix flat triangles (all three points aligned) for (it = TriangleIterator(geometry); !it.isAtEnd() ;++it) { vector<Pnt3f> p(3); vector<Vec3f> v(3); Vec3i vi = Vec3i(it.getPositionIndex(0), it.getPositionIndex(1), it.getPositionIndex(2)); for (int i=0; i<3; i++) p[i] = it.getPosition(i); v[0] = p[2]-p[1]; v[1] = p[2]-p[0]; v[2] = p[1]-p[0]; float A = (v[2].cross(v[1])).length(); if (A < 1e-16) { // small area, flat triangle? cout << "small area " << A << endl; for (int i=0; i<3; i++) cout << " pi " << p[i] << " vi " << vi[i] << " L " << v[i].squareLength() << endl; if (v[0].squareLength() < 1e-8) continue; // check if two points close, then ignore if (v[1].squareLength() < 1e-8) continue; if (v[2].squareLength() < 1e-8) continue; int im = 0; for (int i=1; i<3; i++) if (v[i].squareLength() > v[im].squareLength()) im = i; int j = (im+1)%3; cout << "set p[" << j << "] = " << p[j] << " with index i[" << im << "] = " << vi[im] << endl; gpos->setValue(p[j], vi[im]); for (int i=0; i<3; i++) p[i] = it.getPosition(i); cout << " result: " << endl; for (int i=0; i<3; i++) cout << " pi " << p[i] << endl; } } vector<CGAL::Point> positions; vector<size_t> indices; vector<Vec3f> pos; vector<int> inds; size_t curIndex = 0; // Convert triangles to cgal indices and vertices for (it = TriangleIterator(geometry); !it.isAtEnd() ;++it) { vector<size_t> IDs(3); for (int i=0; i<3; i++) IDs[i] = isKnownPoint( it.getPosition(i) ); for (int i=0; i<3; i++) { if (IDs[i] == numeric_limits<size_t>::max()) { Vec3f p = Vec3f(it.getPosition(i)); pos.push_back(p); positions.push_back( CGAL::Point(p[0], p[1], p[2]) ); IDs[i] = curIndex; //cout << "add point " << curIndex << " " << osgPos << endl; size_t *curIndexPtr = new size_t; *curIndexPtr = curIndex; oct->add(OcPoint(p[0], p[1], p[2]), curIndexPtr); curIndex++; } } //cout << "add triangle " << IDs[0] << " " << IDs[1] << " " << IDs[2] << endl; if (IDs[0] == IDs[1] || IDs[0] == IDs[2] || IDs[1] == IDs[2]) continue; // ignore flat triangles for (int i=0; i<3; i++) indices.push_back(IDs[i]); for (int i=0; i<3; i++) inds.push_back(IDs[i]); } // Cleanup for (void* o : oct->getData()) delete (size_t*)o; delete oct; oct = new Octree(THRESHOLD); // Construct the polyhedron from raw data success = true; CGAL::Polyhedron *result = new CGAL::Polyhedron(); PolyhedronBuilder<CGAL::HalfedgeDS> builder(positions, indices); result->delegate(builder); if (!result->is_closed()) { success = false; cout << "Error: The polyhedron is not a closed mesh!" << endl; create(GL_TRIANGLES, pos, pos, inds); setWorldMatrix(worldTransform); createSharedIndex(mesh); calcVertexNormals(mesh, 0.523598775598 /*30 deg in rad*/); getMaterial()->setFrontBackModes(GL_FILL, GL_NONE); } // Transform the polyhedron with the geometry's world transform matrix applyTransform(result, worldTransform); return result; }