Esempio n. 1
0
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++; }
    }
}
Esempio n. 2
0
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;
}