/** Return the number of loops of one particular polygon. An \c EIndexError exception is thrown if \a poly is out of range. */ int PolyhedronGeom::getNumLoops(int poly) const { if ((poly<0) || (poly>=getNumPolys())) throw EIndexError("Poly index out of range."); return polys[poly]->size(); }
/** Set the number of loops for one particular poly. An \c EIndexError exception is thrown if \a poly is out of range. */ void PolyhedronGeom::setNumLoops(int poly, int num) { if ((poly<0) || (poly>=getNumPolys())) throw EIndexError("Poly index out of range."); if (num<0) num=0; Poly* polygon = polys[poly]; // Number of loops before the modification int prevsize = polygon->size(); // Number of vertices removed (this number is used to adjust the constraint // size for facevarying variables) int lostverts = 0; int i; // Delete loops if the number of loops was decreased if (num<prevsize) { for(i=num; i<prevsize; i++) { // Add the number of verts in the loop lostverts += (*polygon)[i]->size(); // Delete the loop delete (*polygon)[i]; } } // Resize loop list polygon->resize(num); // Allocate new loops... // (the new loops have no verts, so lostverts doesn't have to be modified) for(i=prevsize; i<num; i++) { (*polygon)[i] = new VertexLoop(); } // Update the size constraint for facevarying variables... // Todo: This probably shouldn't be done for every single modification // again and again... UserSizeConstraint* usc = dynamic_cast<UserSizeConstraint*>(faceVaryingSizeConstraint.get()); // std::cout<<"LOSTVERTS: "<<lostverts<<std::endl; if (usc!=0) usc->setSize(usc->getSize()-lostverts); }
/** Convert to TriMesh */ void PolyhedronGeom::convert(GeomObject* target) { TriMeshGeom* tm = dynamic_cast<TriMeshGeom*>(target); vec3d* vertsptr = verts.dataPtr(); // Index of the corresponding facevarying (or facevertex) variable int facevarindex = 0; int i, j; // Check if the target geom is really a TriMesh if (tm==0) { throw ENotImplementedError("Conversion not supported by the PolyhedronGeom"); } // No tesselation object allocated yet? Then do so once and for all... if (tess==0) { tess = gluNewTess(); if (tess==0) return; } PolyTriangulation polyTriangulation(*this); // Remove any existing variable in the trimesh... tm->deleteAllVariables(); dataMemManager.setDataSize(3*sizeof(GLdouble)+2*sizeof(int)); gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (TessCallback)(&onTessBegin_triangulation)); gluTessCallback(tess, GLU_TESS_END_DATA, (TessCallback)(&onTessEnd_triangulation)); gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (TessCallback)(&onTessVertex_triangulation)); gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); gluTessProperty(tess, GLU_TESS_TOLERANCE, 0); gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); // Iterate over all polygons... for(i=0; i<getNumPolys(); i++) { dataMemManager.reset(); gluTessBeginPolygon(tess, &polyTriangulation); // Iterate over all loops of polygon i... for(j=0; j<getNumLoops(i); j++) { gluTessBeginContour(tess); LoopIterator it = loopBegin(i, j); LoopIterator itend = loopEnd(i, j); vec3d* v; for( ; it!=itend; it++) { int vidx = (*it); v = vertsptr + vidx; GLdouble* loc = (GLdouble*)dataMemManager.newDataPtr(); loc[0] = v->x; loc[1] = v->y; loc[2] = v->z; int* data = (int*)(loc+3); data[0] = vidx; // Vertex index data[1] = facevarindex; // facevarying variable index gluTessVertex(tess, loc, data); facevarindex++; } gluTessEndContour(tess); } gluTessEndPolygon(tess); polyTriangulation.polyFinished(); } polyTriangulation.initTriMesh(*tm); }
/** Draw the polyhedron. */ void PolyhedronGeom::drawGL() { // No tesselation object allocated yet? Then do so once and for all... if (tess==0) { tess = gluNewTess(); if (tess==0) return; } // Set flag to 0 (i.e. no variables are present so far) tess_data_flag = 0; PrimVarAccess<vec3d> normals(*this, std::string("N"), NORMAL, 1, std::string("Nfaces")); PrimVarAccess<double> texcoords(*this, std::string("st"), FLOAT, 2, std::string("stfaces")); PrimVarAccess<vec3d> colors(*this, std::string("Cs"), COLOR, 1, std::string("Csfaces")); vec3d* N; vec3d* Cs; GLfloat glcol[4] = {0,0,0,1}; double* st; vec3d* vertsptr = verts.dataPtr(); int i,j; int nfloats=3; // Check which variables has to be passed to the vertex callback // (this is the case when mode is > 2) if (normals.mode>2) { tess_data_flag |= 0x01; nfloats += 3; } if (texcoords.mode>2) { tess_data_flag |= 0x02; nfloats += 2; } if (colors.mode>2) { tess_data_flag |= 0x04; nfloats += 3; } dataMemManager.setDataSize(nfloats*sizeof(GLdouble)); gluTessCallback(tess, GLU_TESS_BEGIN, (TessCallback)(&onTessBegin)); gluTessCallback(tess, GLU_TESS_END, (TessCallback)(&onTessEnd)); gluTessCallback(tess, GLU_TESS_VERTEX, (TessCallback)(&onTessVertex)); gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); gluTessProperty(tess, GLU_TESS_TOLERANCE, 0); gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); // Iterate over all polygons... for(i=0; i<getNumPolys(); i++) { dataMemManager.reset(); // No normals? Then a face normal has to be calculated... if (normals.mode==0) { vec3d Ng; computeNormal(i, Ng); glNormal3d(Ng.x, Ng.y, Ng.z); } // Process uniform variables... if (normals.onFace(N)) glNormal3d(N->x, N->y, N->z); if (texcoords.onFace(st)) glTexCoord2dv(st); if (colors.onFace(Cs)) { glcol[0] = GLfloat(Cs->x); glcol[1] = GLfloat(Cs->y); glcol[2] = GLfloat(Cs->z); glMaterialfv(GL_FRONT, GL_DIFFUSE, glcol); } gluTessBeginPolygon(tess, 0); // Iterate over all loops of polygon i... for(j=0; j<getNumLoops(i); j++) { gluTessBeginContour(tess); LoopIterator it = loopBegin(i, j); LoopIterator itend = loopEnd(i, j); vec3d* v; for( ; it!=itend; it++) { int vidx = (*it); v = vertsptr + vidx; GLdouble* data = (GLdouble*)dataMemManager.newDataPtr(); GLdouble* p = data+3; data[0] = v->x; data[1] = v->y; data[2] = v->z; if (normals.onVertex(vidx, N)) { p[0] = N->x; p[1] = N->y; p[2] = N->z; p += 3; } if (texcoords.onVertex(vidx, st)) { p[0] = st[0]; p[1] = st[1]; p += 2; } if (colors.onVertex(vidx, Cs)) { p[0] = Cs->x; p[1] = Cs->y; p[2] = Cs->z; } gluTessVertex(tess, data, data); } gluTessEndContour(tess); } gluTessEndPolygon(tess); } /* for(i=0; i<getNumPolys(); i++) { for(j=0; j<getNumLoops(i); j++) { LoopIterator it = loopBegin(i, j); LoopIterator itend = loopEnd(i, j); vec3d* v; glBegin(GL_LINE_LOOP); for( ; it!=itend; it++) { v = vertsptr + (*it); glVertex3d(v->x, v->y, v->z); } glEnd(); } }*/ }
void GA::start(QPixmap *dpix, QPixmap *opix){ /// Get the right image pixmap to draw on and the left image pixmap to compare to drawing = dpix; original = opix; myPop = new Population(popSize, getDNALength(), getDNAcrossedLength(), getPolyPts(),getNumPolys(), opix, dpix); genCount = 0; /// Population has now been initialised /// Set a time which keeps calling the function update /// update stops timer, executes itself, then starts timer again. QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(gaUpdate())); timer.setInterval(10); /// every 10msec means update() is executed 100 times every second timer.start(); //gaUpdate(); }