QColor MeshGenerator::getVRLutColor(uchar *volData, int dlen, int depth, int nextra, QVector3D pos, QVector3D normal, uchar *lut, bool lookInside, QVector3D globalPos) { // go a bit deeper and start QVector3D vpos = pos + normal; // -- find how far deep we can go int nd = 0; for(int n=0; n<=depth; n++) { int i = vpos.x(); int j = vpos.y(); int k = vpos.z(); if (i > m_nZ-1 || j > m_nY-1 || k > dlen+2*nextra-1 || i < 0 || j < 0 || k < 0) // gone out break; nd ++; vpos += normal; } // now start collecting the samples vpos = pos + normal; QVector3D gpos = globalPos + normal; Vec rgb = Vec(0,0,0); float tota = 0; for(int ns=0; ns<=nd; ns++) { int i = vpos.x(); int j = vpos.y(); int k = vpos.z(); i = qBound(0, i, m_nZ-1); j = qBound(0, j, m_nY-1); k = qBound(0, k, dlen+2*nextra-1); Vec po0 = Vec(m_dataMin.x+gpos.x(), m_dataMin.y+gpos.y(), gpos.z()); Vec po = po0*m_samplingLevel; bool ok=true; if (ok) { ushort v, gr; if (m_voxelType == 0) { v = volData[k*m_nY*m_nZ + j*m_nZ + i]; gr = 0; } else { v = ((ushort*)volData)[k*m_nY*m_nZ + j*m_nZ + i]; gr = v%256; v = v/256; } // QMessageBox::information(0, "", QString("vrlut : %1 %2 %3 : %4").\ // arg(i).arg(j).arg(k).arg(v)); float a = lut[4*(256*gr + v)+3]/255.0f; float r = lut[4*(256*gr + v)+0]*a; float g = lut[4*(256*gr + v)+1]*a; float b = lut[4*(256*gr + v)+2]*a; if (m_blendPresent) { for(int ci=0; ci<m_crops.count(); ci++) { if (m_crops[ci].cropType() > CropObject::Displace_Displace && m_crops[ci].cropType() < CropObject::Glow_Ball) { float viewMix = m_crops[ci].checkBlend(po); int tfSet = m_crops[ci].tfset(); tfSet *= 256*256*4; float a1 = lut[tfSet+4*(256*gr + v)+3]/255.0f; float r1 = lut[tfSet+4*(256*gr + v)+0]*a1; float g1 = lut[tfSet+4*(256*gr + v)+1]*a1; float b1 = lut[tfSet+4*(256*gr + v)+2]*a1; r = (1-viewMix)*r + viewMix*r1; g = (1-viewMix)*g + viewMix*g1; b = (1-viewMix)*b + viewMix*b1; a = (1-viewMix)*a + viewMix*a1; } } } if (m_pathBlendPresent) { for(int ci=0; ci<m_paths.count(); ci++) { if (m_paths[ci].blend()) { float viewMix = m_paths[ci].checkBlend(po); int tfSet = m_paths[ci].blendTF(); tfSet *= 256*256*4; float a1 = lut[tfSet+4*(256*gr + v)+3]/255.0f; float r1 = lut[tfSet+4*(256*gr + v)+0]*a1; float g1 = lut[tfSet+4*(256*gr + v)+1]*a1; float b1 = lut[tfSet+4*(256*gr + v)+2]*a1; r = (1-viewMix)*r + viewMix*r1; g = (1-viewMix)*g + viewMix*g1; b = (1-viewMix)*b + viewMix*b1; a = (1-viewMix)*a + viewMix*a1; } } } // apply tag colors if (m_useTagColors) { Vec pp = po0 - m_dataMin; int ppi = pp.x/m_pruneLod; int ppj = pp.y/m_pruneLod; int ppk = pp.z/m_pruneLod; ppi = qBound(0, ppi, m_pruneX-1); ppj = qBound(0, ppj, m_pruneY-1); ppk = qBound(0, ppk, m_pruneZ-1); int mopidx = ppk*m_pruneY*m_pruneX + ppj*m_pruneX + ppi; int tag = m_pruneData[3*mopidx + 2]; // channel 2 has tag information if (tag > 0) { Vec tc = Vec(m_tagColors[4*tag+0], m_tagColors[4*tag+1], m_tagColors[4*tag+2]); float tagOp = m_tagColors[4*tag+3]/255.0f; tc *= tagOp; r = (1-tagOp)*r + tagOp*tc.x; g = (1-tagOp)*g + tagOp*tc.y; b = (1-tagOp)*b + tagOp*tc.z; a = qMax(tagOp, a); } } rgb = (1-a)*rgb + Vec(r,g,b)/255.0f; tota = (1-a)*tota + a; //rgb += Vec(r,g,b)/255.0f; //tota += a; } vpos += normal; gpos += normal; } // if (tota < 0.01) tota = 1.0; // rgb /= tota; rgb *= 255; QColor col = QColor(rgb.x, rgb.y, rgb.z, 255*tota); return col; }
inline Vec operator-(Vec u) { return Vec(x - u.x, y - u.y, z - u.z); }
inline Vec operator/(float s) { return Vec(x/s, y/s, z/s); }
Vec operator%(Vec&b){return Vec(y*b.z-z*b.y,z*b.x-x*b.z,x*b.y-y*b.x);}
var StrassenDMM(Var A,Var B,size_t m,size_t p,size_t n,size_t bound)//m为M行数,n为N列数,p为n行数,bound为递归下界 { if(m<=bound||n<=bound||p<=bound) return Matrix::Dot(A,B); else { var A11=Take(A,1,m/2,1,p/2); var A12=Take(A,1,m/2,p/2+1,p); var A21=Take(A,m/2+1,m,1,p/2); var A22=Take(A,m/2+1,m,p/2+1,p); var B11=Take(B,1,p/2,1,n/2); var B12=Take(B,1,p/2,n/2+1,n); var B21=Take(B,p/2+1,p,1,n/2); var B22=Take(B,p/2+1,p,n/2+1,n); var S1=Matrix::Add(A21,A22); var S2=Matrix::Sub(S1,A11); var S3=Matrix::Sub(A11,A21); var S4=Matrix::Sub(A12,S2); var T1=Matrix::Sub(B12,B11); var T2=Matrix::Sub(B22,T1); var T3=Matrix::Sub(B22,B12); var T4=Matrix::Sub(T2,B21); var P1=Matrix::StrassenDMM(A11,B11,m/2,p/2,n/2,bound); var P2=Matrix::StrassenDMM(A12,B21,m/2,p/2,n/2,bound); var P3=Matrix::StrassenDMM(S4,B22,m/2,p/2,n/2,bound); var P4=Matrix::StrassenDMM(A22,T4,m/2,p/2,n/2,bound); var P5=Matrix::StrassenDMM(S1,T1,m/2,p/2,n/2,bound); var P6=Matrix::StrassenDMM(S2,T2,m/2,p/2,n/2,bound); var P7=Matrix::StrassenDMM(S3,T3,m/2,p/2,n/2,bound); var U1=Matrix::Add(P1,P2); var U2=Matrix::Add(P1,P6); var U3=Matrix::Add(U2,P7); var U4=Matrix::Add(U2,P5); var U5=Matrix::Add(U4,P3); var U6=Matrix::Sub(U3,P4); var U7=Matrix::Add(U3,P5); var r=Vec(m); for (size_t i=0;i<m;++i) { var &c=At(r,i); c=Vec(n); } for (size_t i=0;i<m/2;++i) { for (size_t j=0;j<n/2;++j) { Entry(r,i,j)=Entry(U1,i,j); } } for (size_t i=0;i<m/2;++i) { for (size_t j=n/2;j<n;++j) { Entry(r,i,j)=Entry(U5,i,j-n/2); } } for (size_t i=m/2;i<m;++i) { for (size_t j=0;j<n/2;++j) { Entry(r,i,j)=Entry(U6,i-m/2,j); } } for (size_t i=m/2;i<m;++i) { for (size_t j=n/2;j<n;++j) { Entry(r,i,j)=Entry(U7,i-m/2,j-n/2); } } return r; } }
enum Refl_t { DIFF, SPEC, REFR }; // material types, used in radiance() struct Sphere { double rad; // radius Vec p, e, c; // position, emission, color Refl_t refl; // reflection type (DIFFuse, SPECular, REFRactive) Sphere(double rad_, Vec p_, Vec e_, Vec c_, Refl_t refl_): rad(rad_), p(p_), e(e_), c(c_), refl(refl_) {} double intersect(const Ray &r) const { // returns distance, 0 if nohit Vec op = p-r.o; // Solve t^2*d.d + 2*t*(o-p).d + (o-p).(o-p)-R^2 = 0 double t, eps=1e-4, b=op.dot(r.d), det=b*b-op.dot(op)+rad*rad; if (det<0) return 0; else det=sqrt(det); return (t=b-det)>eps ? t : ((t=b+det)>eps ? t : 0); } }; Sphere spheres[] = {//Scene: radius, position, emission, color, material Sphere(1e5, Vec( 1e5+1,40.8,81.6), Vec(),Vec(.75,.25,.25),DIFF),//Left Sphere(1e5, Vec(-1e5+99,40.8,81.6),Vec(),Vec(.25,.25,.75),DIFF),//Rght Sphere(1e5, Vec(50,40.8, 1e5), Vec(),Vec(.75,.75,.75),DIFF),//Back Sphere(1e5, Vec(50,40.8,-1e5+170), Vec(),Vec(), DIFF),//Frnt Sphere(1e5, Vec(50, 1e5, 81.6), Vec(),Vec(.75,.75,.75),DIFF),//Botm Sphere(1e5, Vec(50,-1e5+81.6,81.6),Vec(),Vec(.75,.75,.75),DIFF),//Top Sphere(16.5,Vec(27,16.5,47), Vec(),Vec(1,1,1)*.999, SPEC),//Mirr Sphere(16.5,Vec(73,16.5,78), Vec(),Vec(1,1,1)*.999, REFR),//Glas Sphere(600, Vec(50,681.6-.27,81.6),Vec(12,12,12), Vec(), DIFF) //Lite }; inline double clamp(double x){ return x<0 ? 0 : x>1 ? 1 : x; } inline int toInt(double x){ return int(pow(clamp(x),1/2.2)*255+.5); } inline bool intersect(const Ray &r, double &t, int &id){ double n=sizeof(spheres)/sizeof(Sphere), d, inf=t=1e20; for(int i=int(n);i--;) if((d=spheres[i].intersect(r))&&d<t){t=d;id=i;} return t<inf;
Vec operator*(double b) const { return Vec(x*b,y*b,z*b); }
int main(int argc, char *argv[]){ int w,h,samples; double radius; double xposition, yposition, zposition; double xcolor, ycolor, zcolor; double xemission,yemission,zemission; int material; //height and width of frame scanf("%d %d",&w,&h); //number of samples scanf("%d",&samples); for(int i=0;i<objects;++i){ scanf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %d",&radius,&xposition,&yposition,&zposition,&xcolor,&ycolor,&zcolor,&xemission,&yemission,&zemission,&material); spheres[i].radius=radius; spheres[i].position.x=xposition; spheres[i].position.y=yposition; spheres[i].position.z=zposition; spheres[i].light.x=xemission; spheres[i].light.y=yemission; spheres[i].light.z=zemission; spheres[i].object_color.x=xcolor; spheres[i].object_color.y=ycolor; spheres[i].object_color.z=zcolor; spheres[i].type_of_reflection=material; //printf("hi%lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %d\n",radius,xposition,yposition,zposition,xcolor,ycolor,zcolor,xemission,yemission,zemission,material); } Vec camera_origin; camera_origin.x=50; camera_origin.y=52; camera_origin.z=295.6; Vec camera_direction; camera_direction.x=0; camera_direction.y=-0.042612; camera_direction.z=-1; Ray cam; cam.origin =camera_origin; cam.direction =norm(camera_direction); Vec cx; cx.x = w*0.5/h; cx.y = 0; cx.z = 0; Vec cy=norm(cross(cx,cam.direction))*0.5; Vec r; Vec *image=new Vec[w*h]; for (int y=0; y<h; y++){ for (int x=0; x<w; x++) { //if(x%10==0) //fprintf(stderr,"."); int sy=0, i=(h-y-1)*w+x; int sx=1;r=Vec(); for (int s=0; s<samples; s++){ Vec d = cx*( (0.75 + x)/w - .5) + cy*( ( 0.25 + y)/h - .5) + cam.direction; Ray rr0; rr0.origin = cam.origin+d*140; rr0.direction = norm(d); r = r + calculate_light(rr0,0)*(1./samples); } image[i].x = image[i].x + (normalize_0_1(r.x)); image[i].y = image[i].y + (normalize_0_1(r.y)); image[i].z = image[i].z + (normalize_0_1(r.z)); //not working properly so made the function normalize double temp1; if(r.x<0) temp1=0; else if(r.x>1) temp1=1; else temp1=r.x; // image[i].x = image[i].x + temp1; double temp2; if(r.y<0) temp2=0; else if(r.y>1) temp2=1; else temp2=r.y; // image[i].y = image[i].y + temp2; double temp3; if(r.z<0) temp3=0; else if(r.z>1) temp3=1; else temp3=r.z; // image[i].z = image[i].z + temp3; } if(y%10==0)fprintf(stderr,"."); } //print_image(c,w,h); //estimate of maximum value of colour for normalization double max = -999999999; for(int i=0;i<w*h;++i){ if(image[i].x>max) max = image[i].x; if(image[i].y>max) max = image[i].y; if(image[i].z>max) max = image[i].z; } //find the normalization constant double n_c = 255/max; // printf("%lf\n",n_c ); printf( "P3\n%d %d\n%d\n", w, h, 255); for (int i=0; i<w*h; i++){ printf("%0.0f %0.0f %0.0f \n", (image[i].x)*n_c, (image[i].y)*n_c, (image[i].z)*n_c); } }
void Displacements::computeField(int gridSquareSize, int fitMethod, int lRotate, int rRotate) { CreateTimer(allTimer); printf("\nComputing field for selection..\n"); // Get faces and points of selected part Vector<int> selectedFaces = skeleton->getSelectedFaces(true); StdList<Face*> meshFaces = stair.mostBaseMesh()->getFacesFromIndices(selectedFaces); Vector<int> points = SET_TO_VECTOR(stair.mostBaseMesh()->getVerticesFromFaces(selectedFaces)); // Convert selected skeleton part into points in space Vector<Vec> skeletonPoints = skeleton->getSelectedSkeletonPoints(); // Make sure we have a smooth and nicely sampled spine while((int)skeletonPoints.size() < gridSquareSize) { skeleton->smoothSelectedEdges(4); skeletonPoints = skeleton->getSelectedSkeletonPoints(); } // Compute length by traveling spine float gridLength = 0; for(int i = 0; i < (int)skeletonPoints.size() - 1; i++) gridLength += Vec(skeletonPoints[i] - skeletonPoints[i+1]).norm(); // Figure out maximum point on base surface to use as radius (there might be a faster way) HistogramFloat histogram (1); skeleton->sampleProjectPoints(0.75f, stair.mostBaseMesh(), points, &histogram); float radius = histogram.Average(); if(radius <= 0.0f) radius = stair.mostDetailedMesh()->radius * 0.1; // just in case... CreateTimer(gridTimer); // CREATE GRID grid = Grid(skeletonPoints, radius, gridLength, gridSquareSize, &stair, meshFaces,lRotate, rRotate); printf(".Grid time (%d ms).", (int)gridTimer.elapsed()); CreateTimer(fitTimer); // FIT GRID switch(fitMethod) { case 1: // Fit using cross sections grid.FitCrossSections(); break; case 2: // Fit cylinder grid.FitCylinder( ); break; default: grid.FitNothing( ); break; } printf(".Fit time (%d ms).", (int)fitTimer.elapsed()); CreateTimer(gridifyTimer); // Assign detailed mesh points into cylindrical grid cells grid.Gridify( selectedFaces ); isReady = true; printf(".total Gridify time = %d ms\n", (int)gridifyTimer.elapsed()); printf("\n\nField time = %d ms\n=======\n", (int)allTimer.elapsed()); }
void ClipGrabber::mouseMoveEvent(QMouseEvent* const event, Camera* const camera) { if (!m_pressed) return; QPoint delta = event->pos() - m_prevPos; //Vec voxelScaling = Global::voxelScaling(); Vec voxelScaling = Vec(1,1,1); Vec tang = m_tang; Vec xaxis = m_xaxis; Vec yaxis = m_yaxis; if (event->buttons() != Qt::LeftButton) { tang = VECDIVIDE(tang, voxelScaling); xaxis = VECDIVIDE(xaxis, voxelScaling); yaxis = VECDIVIDE(yaxis, voxelScaling); Vec trans(delta.x(), -delta.y(), 0.0f); // Scale to fit the screen mouse displacement trans *= 2.0 * tan(camera->fieldOfView()/2.0) * fabs((camera->frame()->coordinatesOf(Vec(0,0,0))).z) / camera->screenHeight(); // Transform to world coordinate system. trans = camera->frame()->orientation().rotate(trans); //Vec voxelScaling = Global::voxelScaling(); Vec voxelScaling = Vec(1,1,1); trans = VECDIVIDE(trans, voxelScaling); if (event->modifiers() & Qt::ControlModifier || event->modifiers() & Qt::MetaModifier) { if (moveAxis() < MoveY0) { float vx = trans*m_xaxis; if (moveAxis() == MoveX0) setScale1(scale1() + 0.05*vx); else setScale1(scale1() - 0.05*vx); } else if (moveAxis() < MoveZ) { float vy = trans*m_yaxis; if (moveAxis() == MoveY0) setScale2(scale2() + 0.05*vy); else setScale2(scale2() - 0.05*vy); } } else { if (moveAxis() < MoveY0) { float vx = trans*xaxis; trans = vx*xaxis; } else if (moveAxis() < MoveZ) { float vy = trans*yaxis; trans = vy*yaxis; } else if (moveAxis() == MoveZ) { float vz = trans*tang; trans = vz*tang; } translate(trans); } } else { bool ctrlOn = (event->modifiers() & Qt::ControlModifier || event->modifiers() & Qt::MetaModifier); if (moveAxis() == MoveZ && !ctrlOn) { Vec axis; axis = (delta.y()*camera->rightVector() + delta.x()*camera->upVector()); rotate(axis, qMax(qAbs(delta.x()), qAbs(delta.y()))); } else { Vec axis; if (moveAxis() < MoveY0) axis = xaxis; else if (moveAxis() < MoveZ) axis = yaxis; else axis = tang; //Vec voxelScaling = Global::voxelScaling(); Vec voxelScaling = Vec(1,1,1); Vec pos = VECPRODUCT(position(), voxelScaling); float r = size(); Vec trans(delta.x(), -delta.y(), 0.0f); Vec p0 = camera->projectedCoordinatesOf(pos); p0 = Vec(p0.x, p0.y, 0); Vec c0 = pos + r*axis; c0 = camera->projectedCoordinatesOf(c0); c0 = Vec(c0.x, c0.y, 0); Vec perp = c0-p0; perp = Vec(-perp.y, perp.x, 0); perp.normalize(); float angle = perp * trans; rotate(axis, angle); } } m_prevPos = event->pos(); }
void Constraint::drawTorsion() { Vec a(m_atoms[0]->getPosition()); Vec b(m_atoms[1]->getPosition()); Vec c(m_atoms[2]->getPosition()); Vec d(m_atoms[3]->getPosition()); Vec e(a+c-b); Vec f(d+b-c); GLShape::Tube(a, b, s_tubeRadius, s_tubeResolution); GLShape::Tube(c, b, s_tubeRadius, s_tubeResolution); GLShape::Tube(a, e, s_tubeRadius, s_tubeResolution); GLShape::Tube(c, e, s_tubeRadius, s_tubeResolution); GLShape::Tube(d, c, s_tubeRadius, s_tubeResolution); GLShape::Tube(b, c, s_tubeRadius, s_tubeResolution); GLShape::Tube(d, f, s_tubeRadius, s_tubeResolution); GLShape::Tube(b, f, s_tubeRadius, s_tubeResolution); GLShape::Sphere(e, s_tubeRadius, s_tubeResolution); GLShape::Sphere(f, s_tubeRadius, s_tubeResolution); Vec cb(c-b); // Align the frame z-axis to the cb bond Quaternion orientation(Vec(0.0,0.0,1.0), cb); Frame frame(b+0.5*cb, orientation); // Now determine the frame coordinates of a and // rotate it so that it aligns with the frame y-axis Vec fa(frame.coordinatesOf(a).unit()); frame.rotate(Quaternion(Vec(0.0,0.0,1.0), atan2(fa.y,fa.x))); glPushMatrix(); glMultMatrixd(frame.matrix()); double radius(0.5); double angle(Layer::Atom::torsion(m_atoms[0], m_atoms[1], m_atoms[2], m_atoms[3])); angle = angle * M_PI / 180.0; GLShape::Torus(radius, s_tubeRadius, s_tubeResolution, angle); glPopMatrix(); glEnable(GL_BLEND); glDisable(GL_LIGHTING); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4fv(m_color); glBegin(GL_QUAD_STRIP); glVertex3f(a.x, a.y, a.z); glVertex3f(e.x, e.y, e.z); glVertex3f(b.x, b.y, b.z); glVertex3f(c.x, c.y, c.z); glVertex3f(f.x, f.y, f.z); glVertex3f(d.x, d.y, d.z); glEnd(); /* glBegin(GL_TRIANGLE_STRIP); glVertex3f(a.x, a.y, a.z); glVertex3f(c.x, c.y, c.z); glVertex3f(b.x, b.y, b.z); glVertex3f(d.x, d.y, d.z); glEnd(); */ glEnable(GL_LIGHTING); glDisable(GL_BLEND); }
WhiteBall::WhiteBall(const Point & pos) :Ball(pos, Vec(-0.1, -0.1, 0.0), BallGUI(wAmbient, wSpecular), false) { textureInit(); }
// Build KD tree for tris void KDNode::build(std::vector<Triangle*> &tris, int depth){ leaf = false; triangles = std::vector<Triangle*>(); left = NULL; right = NULL; box = AABBox(); if (tris.size() == 0) return; if (depth > 25 || tris.size() <= 6) { triangles = tris; leaf = true; box = tris[0]->get_bounding_box(); for (long i=1; i<tris.size(); i++) { box.expand(tris[i]->get_bounding_box()); } left = new KDNode(); right = new KDNode(); left->triangles = std::vector<Triangle*>(); right->triangles = std::vector<Triangle*>(); return; } box = tris[0]->get_bounding_box(); Vec midpt = Vec(); double tris_recp = 1.0/tris.size(); for (long i=1; i<tris.size(); i++) { box.expand(tris[i]->get_bounding_box()); midpt = midpt + (tris[i]->get_midpoint() * tris_recp); } std::vector<Triangle*> left_tris; std::vector<Triangle*> right_tris; int axis = box.get_longest_axis(); for (long i=0; i<tris.size(); i++) { switch (axis) { case 0: midpt.x >= tris[i]->get_midpoint().x ? right_tris.push_back(tris[i]) : left_tris.push_back(tris[i]); break; case 1: midpt.y >= tris[i]->get_midpoint().y ? right_tris.push_back(tris[i]) : left_tris.push_back(tris[i]); break; case 2: midpt.z >= tris[i]->get_midpoint().z ? right_tris.push_back(tris[i]) : left_tris.push_back(tris[i]); break; } } if (tris.size() == left_tris.size() || tris.size() == right_tris.size()) { triangles = tris; leaf = true; box = tris[0]->get_bounding_box(); for (long i=1; i<tris.size(); i++) { box.expand(tris[i]->get_bounding_box()); } left = new KDNode(); right = new KDNode(); left->triangles = std::vector<Triangle*>(); right->triangles = std::vector<Triangle*>(); return; } left = new KDNode(); right = new KDNode(); left->build(left_tris, depth+1); right->build(right_tris, depth+1); return; }
void MeshGenerator::generateMesh(int nSlabs, QStringList volumeFiles, QString flnm, int depth, QGradientStops vstops, int fillValue, bool checkForMore, bool lookInside, Vec voxelScaling, QList<Vec> clipPos, QList<Vec> clipNormal, QList<CropObject> crops, QList<PathObject> paths, uchar *lut, int chan, bool avgColor) { bool saveIntermediate = false; int bpv = 1; if (m_voxelType > 0) bpv = 2; int nbytes = bpv*m_nY*m_nZ; // if (nSlabs > 1) // { // QStringList sl; // sl << "No"; // sl << "Yes"; // bool ok; // QString okstr = QInputDialog::getItem(0, "Save slab files", // "Save slab files in .ply format.\nFiles will not be collated together to create a unified mesh for the whole sample.", // sl, 0, false, &ok); // if (ok && okstr == "Yes") // saveIntermediate = true; // } QGradientStops lutstops; for(int i=0; i<255; i++) { QColor col(lut[4*i+0], lut[4*i+1], lut[4*i+2], lut[4*i+3]); lutstops << QGradientStop((float)i/(float)255.0f, col); } bool trim = (qRound(m_dataSize.x) < m_height || qRound(m_dataSize.y) < m_width || qRound(m_dataSize.z) < m_depth); bool clipPresent = (clipPos.count() > 0); m_cropPresent = false; m_tearPresent = false; m_blendPresent = false; for(int ci=0; ci<m_crops.count(); ci++) { if (crops[ci].cropType() < CropObject::Tear_Tear) m_cropPresent = true; else if (crops[ci].cropType() < CropObject::View_Tear) m_tearPresent = true; else if (m_crops[ci].cropType() > CropObject::Displace_Displace && m_crops[ci].cropType() < CropObject::Glow_Ball) m_blendPresent = true; } m_pathCropPresent = false; m_pathBlendPresent = false; for (int i=0; i<m_paths.count(); i++) { if (m_paths[i].blend()) m_pathBlendPresent = true; if (m_paths[i].crop()) m_pathCropPresent = true; } int nextra = depth; int blockStep = m_nX/nSlabs; //----------------------------- int nvols = volumeFiles.count(); //----------------------------- for (int volnum=0; volnum < nvols; volnum++) { //if (nvols > 1) { m_vfm->setBaseFilename(volumeFiles[volnum]); uchar *vslice = m_vfm->getSlice(0); } m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText(QString("\nProcessing file %1 of %2 : %3\n").\ arg(volnum+1).arg(nvols).arg(m_vfm->fileName())); for (int nb=0; nb<nSlabs; nb++) { m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText(QString(" Processing slab %1 of %2\n").arg(nb+1).arg(nSlabs)); int d0 = nb*blockStep; int d1 = qMin(m_nX-1, (nb+1)*blockStep); int dlen = d1-d0+1; int d0z = d0 + qRound(m_dataMin.z); int d1z = d1 + qRound(m_dataMin.z); uchar *extData; if (m_voxelType == 0) extData = new uchar[(dlen+2*nextra)*m_nY*m_nZ]; else extData = new uchar[2*(dlen+2*nextra)*m_nY*m_nZ]; // ushort uchar *cropped = new uchar[nbytes]; uchar *tmp = new uchar[nbytes]; int i0 = 0; for(int i=d0z-nextra; i<=d1z+nextra; i++) { m_meshProgress->setValue((int)(100.0*(float)(i0/(float)(dlen+2*nextra)))); qApp->processEvents(); int iv = qBound(0, i, m_depth-1); uchar *vslice = m_vfm->getSlice(iv); memset(cropped, 0, nbytes); if (!trim) memcpy(tmp, vslice, nbytes); else { int wmin = qRound(m_dataMin.y); int hmin = qRound(m_dataMin.x); if (m_voxelType == 0) { for(int w=0; w<m_nY; w++) for(int h=0; h<m_nZ; h++) tmp[w*m_nZ + h] = vslice[(wmin+w)*m_height + (hmin+h)]; } else { for(int w=0; w<m_nY; w++) for(int h=0; h<m_nZ; h++) ((ushort*)tmp)[w*m_nZ + h] = ((ushort*)vslice)[(wmin+w)*m_height + (hmin+h)]; } } int jk = 0; for(int j=0; j<m_nY; j++) for(int k=0; k<m_nZ; k++) { Vec po = Vec(m_dataMin.x+k, m_dataMin.y+j, iv); bool ok = true; // we don't want to scale before pruning // no mop pruning po *= m_samplingLevel; if (ok && clipPresent) ok = StaticFunctions::getClip(po, clipPos, clipNormal); if (ok && m_cropPresent) ok = checkCrop(po); if (ok && m_pathCropPresent) ok = checkPathCrop(po); if (ok && m_blendPresent) { ushort v; if (m_voxelType == 0) v = tmp[j*m_nZ + k]; else v = ((ushort*)tmp)[j*m_nZ + k]; ok = checkBlend(po, v, lut); } if (ok && m_pathBlendPresent) { ushort v; if (m_voxelType == 0) v = tmp[j*m_nZ + k]; else v = ((ushort*)tmp)[j*m_nZ + k]; ok = checkPathBlend(po, v, lut); } if (ok) //cropped[jk] = mop; // nop mop pruning cropped[jk] = 255; else cropped[jk] = 0; jk ++; } if (m_voxelType == 0) { for(int j=0; j<m_nY*m_nZ; j++) { if (cropped[j] == 0) tmp[j] = 0; } } else { for(int j=0; j<m_nY*m_nZ; j++) { if (cropped[j] == 0) ((ushort*)tmp)[j] = 0; } } // tmp now clipped and contains raw data memcpy(extData + bpv*i0*m_nY*m_nZ, tmp, nbytes); i0++; } delete [] tmp; delete [] cropped; m_meshProgress->setValue(100); qApp->processEvents(); //------------ if (m_tearPresent) { uchar *data0 = new uchar[(dlen+2*nextra)*m_nY*m_nZ]; uchar *data1 = extData; memcpy(data0, data1, (dlen+2*nextra)*m_nY*m_nZ); applyTear(d0, d1, nextra, data0, data1, true); delete [] data0; } //------------ //-------------------------------- // ---- set border voxels to fillValue if (fillValue >= 0) { uchar *v = extData; i0 = 0; for(int i=d0z-nextra; i<=d1z+nextra; i++) { int iv = qBound(0, i, m_depth-1); int i0dx = i0*m_nY*m_nZ; if (iv <= qRound(m_dataMin.z) || iv >= qRound(m_dataMax.z)) { if (m_voxelType == 0) memset(v + i0dx, fillValue, m_nY*m_nZ); else { for(int fi=0; fi<m_nY*m_nZ; fi++) ((ushort*)v)[i0*m_nY*m_nZ + fi] = fillValue; } } else { if (m_voxelType == 0) { for(int j=0; j<m_nY; j++) v[i0dx + j*m_nZ] = fillValue; for(int j=0; j<m_nY; j++) v[i0dx + j*m_nZ + m_nZ-1] = fillValue; for(int k=0; k<m_nZ; k++) v[i0dx + k] = fillValue; for(int k=0; k<m_nZ; k++) v[i0dx + (m_nY-1)*m_nZ + k] = fillValue; } else { for(int j=0; j<m_nY; j++) ((ushort*)v)[i0dx + j*m_nZ] = fillValue; for(int j=0; j<m_nY; j++) ((ushort*)v)[i0dx + j*m_nZ + m_nZ-1] = fillValue; for(int k=0; k<m_nZ; k++) ((ushort*)v)[i0dx + k] = fillValue; for(int k=0; k<m_nZ; k++) ((ushort*)v)[i0dx + (m_nY-1)*m_nZ + k] = fillValue; } } i0++; } } //-------------------------------- m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText(" Generating Color ...\n"); for(int ni=0; ni<m_nverts; ni++) { m_meshProgress->setValue((int)(100.0*(float)ni/(float)m_nverts)); qApp->processEvents(); float v[3]; v[0] = m_vlist[ni]->x/voxelScaling.x/m_scaleModel; v[1] = m_vlist[ni]->y/voxelScaling.y/m_scaleModel; v[2] = m_vlist[ni]->z/voxelScaling.z/m_scaleModel; if (v[2] > d0 && v[2] <= d1) { // QMessageBox::information(0, "", QString("%1 %2 %3\n%4 %5 %6\n%7 %8"). \ // arg(v[0]).arg(v[1]).arg(v[2]). \ // arg(m_vlist[ni]->x).arg(m_vlist[ni]->y).arg(m_vlist[ni]->z). \ // arg(d0).arg(d1)); uchar *volData = extData; QColor col; QVector3D pos, normal; pos = QVector3D(v[0], v[1], v[2]-d0 + nextra); normal = QVector3D(-m_vlist[ni]->nx, -m_vlist[ni]->ny, -m_vlist[ni]->nz); col = getVRLutColor(volData, dlen, depth, nextra, pos, normal, lut, lookInside, QVector3D(v[0], v[1], v[2])); if (col.alphaF() > 0) { float r = col.red()/255.0f; float g = col.green()/255.0f; float b = col.blue()/255.0f; float a = col.alphaF(); // tinge with lutcolor QColor col0 = vstops[255*(float)(volnum+1)/(float)nvols].second; float aa = col0.alphaF(); float tr = col0.red()/255.0f; float tg = col0.green()/255.0f; float tb = col0.blue()/255.0f; r = (1.0-aa)*r + aa*a*tr; g = (1.0-aa)*g + aa*a*tg; b = (1.0-aa)*b + aa*a*tb; vcolor[3*ni+0] = (1-a)*vcolor[3*ni+0] + r; vcolor[3*ni+1] = (1-a)*vcolor[3*ni+1] + g; vcolor[3*ni+2] = (1-a)*vcolor[3*ni+2] + b; } } } m_meshProgress->setValue(100); delete [] extData; } // loop over slabs // if (nvols > 1) // save intermediate files // { // QString plyflnm = flnm; // plyflnm.chop(3); // plyflnm += QString("%1.ply").arg((int)volnum, (int)nvols/10+2, 10, QChar('0')); // // for(int ni=0; ni<m_nverts; ni++) // { // m_vlist[ni]->r = 255*vcolor[3*ni+0]; // m_vlist[ni]->g = 255*vcolor[3*ni+1]; // m_vlist[ni]->b = 255*vcolor[3*ni+2]; // } // savePLY(plyflnm); // } }// loop over files for(int ni=0; ni<m_nverts; ni++) { m_vlist[ni]->r = 255*vcolor[3*ni+0]; m_vlist[ni]->g = 255*vcolor[3*ni+1]; m_vlist[ni]->b = 255*vcolor[3*ni+2]; } savePLY(flnm); m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText("Mesh saved in "+flnm); QMessageBox::information(0, "", QString("Mesh saved in "+flnm)); }
/** Get a Vector in a particular column as a non-const * Vector. This is fail if the column has currently only a * non-const Vector stored. */ inline SmartPtr<Vector> GetVectorNonConst(Index i) { ObjectChanged(); return Vec(i); }
void Interface :: onMouseDrag(){ // if (key.alt) enable(Mode::CamArb); // if (key.caps) enable(Mode::CamTrack); // static Biv B; static float nx; static float ny; static float tdx; static float tdy; static Rot ra = Rot::xy; static Rot rb = Rot::xz; static Rot rc = Rot::yz; //relative top left (0.0 - .002 or so); float dx = mouse.dx; float dy = mouse.dy; //changed //current position relative to top left (0.0 - 1.0) float cx = mouse.pos[0];//mouse.xrel; float cy = mouse.pos[1];//mouse.yrel;//changed //Accumulated Movement nx += dx; //+ or -? ny += dy; //Temporary Accumulated Movement tdx = mouse.newClick ? 0 : tdx + dx; //+ or -? tdy = mouse.newClick ? 0 : tdy + dy; mouse.dragAccum = Vec(nx,ny,0); //total dvector since program launch mouse.drag = Vec(tdx,tdy,0); //vector from last click and hold to current position mouse.dragCat = Op::sp( mouse.drag, !scene().cat() ); //rotate drag by inverse concatenated orientation mouse.dragBivCat = vd().z ^ mouse.dragCat; mouse.dragBiv = Vec::z ^ mouse.drag; //( Vec ( nx, ny, 0 ) ); // nx*-1 ? Vec v1 = mouse.pos; Vec v2 = mouse.move; Vec v = v1 - Vec(camera().pos()); Vec rel ( .5-cx, .5-cy, 0.0 ); Vec nn ( nx, ny, 0.0 ); mouse.newClick = 0; int mdir = 0; if ( fabs(tdx) > fabs(tdy) ) mdir = tdx > 0 ? MouseData::Right : MouseData::Left; else if ( fabs(tdx) < fabs(tdy) ) mdir = tdy > 0 ? MouseData::Up : MouseData::Down; mouse.gesture = mdir; if (keyboard.alt) { mouseModelTransform(1.0, true); } else if (keyboard.shift) { mouseCamTranslate(1.0, true); } else if (keyboard.ctrl){ mouseCamSpin(1.0,true); } // //Camera Itself Does not Move Position, but glMatrices move via camera's rotor // //i.e. in arb mode the camera orientation itself doesn't move, just the mvm underneath // if (mMode & Mode::CamArb){ // Rot tr = Gen::rot( mouse.dragBiv ); // camera().mvm(tr); // or -tr? // } // // //In Tilt Mode the Camera Rotates Up and Down, Left and Right // if (mMode & Mode::CamTilt){ // Vec mv = GL::unproject(glv.mouse().x(), glv.mouse().y(), 0, camera()); // B = Biv(Vec::z ^ Vec(nx,ny,0)); // rb = Gen::rot_biv(B); // } // // if (mMode & Mode::CamTrack){ // float xm = glv.mouse().dx() / scene().width(); // float ym = glv.mouse().dy() / scene().height(); // Vec dv = camera().x() * xm + camera().y() * ym; // camera().pos() += dv; // } }
Vec subset(int start, int end){ return Vec(ptr + start, end - start); }
//=================================================== // PathRenderer::trace (private) // evaluate outgoing radiance at a given point Vec PathRenderer::trace(Ray const& R, unsigned int depth, bool seeLight, bool debug) { // Stop tracing when the maximum depth is reached /*if (depth >= m_params->maxDepth) { return Vec(0.f,0.f,0.f); }*/ Intersection isect; Vec Li, E, Ambient; Ray Rp = R; Vec C = Vec(1.f, 1.f, 1.f); float u1, u2; for (unsigned int i = 0; i < 5; ++i) { //=========================================== // find intersection if (!m_scene->findIntersection(Rp, &isect)) { // no intersection, add contribution of ambient light // and terminate path Li += C * m_scene->evalAmbient(Rp.D); break; } //=========================================== // add emissive component and continue path E = isect.primitive->getEmittance(); // skip sampling if the object is emissive if (!(E == nullVec)) { Li += C * (seeLight ? E : Vec(0.f,0.f,0.f)); break; } //=========================================== // Material sampling float pdfResult; Vec WiW; int bxdfType; Material const *material = isect.primitive->getMaterial(); material->init(isect); //=========================================== // Next path m_bxdfSampler->getNext2D(u1, u2); Vec Ci = material->sample(isect, u1, u2, WiW, pdfResult, bxdfType); //=========================================== // Russian roulette termination if (depth >= 3) { float pterm = std::max(C.x(), std::max(C.y(), C.z())); if (frand(0.f, 1.f) > pterm) { // terminate break; } else { C *= 1.f / pterm; } } //=========================================== // Direct lighting if (m_params->directLightingOnly) { if (!(bxdfType & BxDF_SPECULAR)) { Li += C * evaluateDirectLighting(isect); } break; } seeLight = true; if (!(bxdfType & BxDF_SPECULAR) && m_params->explicitLightSampling) { Li += C * evaluateDirectLighting(isect); seeLight = false; } C *= Ci; Rp.O = isect.P; Rp.D = WiW; } return Li; }
Vec operator-(const Vec &b) const { return Vec(x-b.x,y-b.y,z-b.z); }
void GLViewer::init() { oldZValue = 0.0; gravityForce = 1.6666; // restoreStateFromFile(); setMouseTracking(true); glLineWidth(3.0); glPointSize(10.1); camera()->setZClippingCoefficient (1.0f); camera()->setIODistance (20.0f); // m_camera_frame = new ManipulatedCameraFrame(); this->m_camera_constraint = new CameraConstraint(camera()); // m_camera_constraint->setTranslationConstraintType(AxisPlaneConstraint::PLANE); //m_camera_constraint->setTranslationConstraintDirection(Vec(1.0f, 1.0f, 1.0f)); m_camera_constraint->setRotationConstraintType(AxisPlaneConstraint::PLANE); m_camera_constraint->setRotationConstraintDirection(Vec(0.001f ,0.001f, 0.0f)); camera()->frame ()->setSpinningSensitivity (0.0); //camera()->frame ()->setSpinningSensitivity(0); camera()->frame ()->setRotationSensitivity(0.25f); camera()->frame ()->setTranslationSensitivity(0.25f); camera()->frame ()->setConstraint(m_camera_constraint); camera()->frame()->setOrientation (0.714989,-0.0573572,-0.00334217,-0.696771); camera()->frame()->setPosition (0.181669,6.60265,-1.25621); // camera()->setFrame(m_camera_frame); this->m_world_constraint = new WorldConstraint(); // m_world_constraint->setTranslationConstraintType(AxisPlaneConstraint::AXIS); // m_world_constraint->setTranslationConstraintDirection(Vec(1.0f, 0.0, 0.0)); m_world_constraint->setRotationConstraintType(AxisPlaneConstraint::AXIS); m_world_constraint->setRotationConstraintDirection(Vec(0.0, 0.0, 1.0f)); m_frame.setTranslationSensitivity(1.0f); //m_frame.setOrientation(0.312498, 0.0328202, -0.054013, 0.947813); m_frame.setOrientation (0.714989,-0.0573572,-0.00334217,-0.696771); m_frame.setRotationSensitivity(0.75f); m_frame.setSpinningSensitivity(0.75f); m_frame.setConstraint(m_world_constraint); //camera()->frame()->setOrientation(-0.308071, -0.774754, 0.510504, 0.21032 ); // camera()->frame()->setOrientation(0.0268112, -0.900378, 0.430649, 0.0560555); // m_camera_frame->setConstraint(m_camera_constraint); //m_camera_frame->setPosition(Vec(-1339.98, -2474.59, -2001.8 )); // camera()->setPosition(Vec(-1339.98, -1474.59, -2001.8 )); // camera()->setViewDirection(Vec(-0.0956168, 0.783527, 0.613957)); // camera()->setPosition(Vec(0, 0, 0)); // QWheelEvent* wheelevent = new QWheelEvent(QPoint(0, 0), 5, Qt::NoButton, Qt::NoModifier, Qt::Vertical); // QGLViewer::wheelEvent(wheelevent); //camera()->frame()->setSpinningSensitivity(0.0); // camera()->frame()->setOrientation(0.312498, 0.0328202, -0.054013, 0.947813); setManipulatedFrame(&m_frame); // this->camera()->frame()->setConstraint(m_world_constraint); // m_frame.setConstraint(m_world_constraint); setMouseBinding(Qt::NoModifier, Qt::LeftButton, CAMERA, ROTATE, false); //setMouseBinding(Qt::NoModifier, Qt::LeftButton, CAMERA, ROTATE, false); setMouseBinding(Qt::NoModifier, Qt::RightButton, CAMERA, TRANSLATE, false); /* setMouseBinding(Qt::RightButton, CAMERA, NO_MOUSE_ACTION); setWheelBinding(Qt::ControlModifier, CAMERA, NO_MOUSE_ACTION); setWheelBinding(Qt::ShiftModifier, CAMERA, NO_MOUSE_ACTION); setWheelBinding(Qt::AltModifier, CAMERA, NO_MOUSE_ACTION); setMouseBinding(Qt::LeftButton, FRAME, NO_MOUSE_ACTION); setMouseBinding(Qt::MidButton | Qt::LeftButton, CAMERA, NO_MOUSE_ACTION); setMouseBinding(Qt::MidButton, FRAME, NO_MOUSE_ACTION); */ // setMouseBinding(Qt::MidButton, CAMERA, true, NO_MOUSE_ACTION); //this->camera()->setViewDirection(qglviewer::Vec(1.0, 10.0, 8.0)); this->showEntireScene(); // this->update(); }
Vec mult(const Vec &b) const { return Vec(x*b.x,y*b.y,z*b.z); }
const Vec operator -(const Mpoint&p1, const Pt &p2){ return Vec (p1.get_coord().X - p2.X,p1.get_coord().Y - p2.Y,p1.get_coord().Z - p2.Z ); }
Vec operator+(const Vec &b) const { return Vec(x+b.x,y+b.y,z+b.z); }
private: TecBezierTrace tec_; TecPIDTrace tec_pid_; // static Mission_DriftTurn instance_; LocalState local_status_; }; //Mission_DriftTurn Mission_DriftTurn::instance_; const Vec Mission_DriftTurn::patternLR_[] = { // 左右(ルートa) Vec(0, 0, true), Vec(237, 255, true), Vec(0, 435, true), Vec(-228,595,true),Vec(25,860,true), }; const S16 Mission_DriftTurn::patternLR_num_ = sizeof Mission_DriftTurn::patternLR_ / sizeof Mission_DriftTurn::patternLR_[0]; const S32 Mission_DriftTurn::patternLR_time_[] = { 2000, 2000, // [msec] }; const Vec Mission_DriftTurn::patternRL_[] = { // 右左(ルートb) Vec(0, 0, true), Vec(-237, 255, true), Vec(0, 435, true), Vec(228,595,true),Vec(25,860,true), }; const S16 Mission_DriftTurn::patternRL_num_ = sizeof Mission_DriftTurn::patternRL_ / sizeof Mission_DriftTurn::patternRL_[0]; const S32 Mission_DriftTurn::patternRL_time_[] = { 2000, 2000, // [msec] };
inline Vec operator+(Vec u) { return Vec(x + u.x, y + u.y, z + u.z); }
Vec eval(Vec const& N, Vec const& in, Vec const& out, Vec const& color) const { return Vec(0.f, 0.f, 0.f); }
inline Vec operator*(float s) { return Vec(x*s, y*s, z*s); }
void draw_solid_tube (double len, double rt, double rb, int nfaces, bool smooth, bool texture, GsImage& img) { glEnable(GL_COLOR_MATERIAL); if(App->wireframe){glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);} else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_NORMALIZE); if(texture) { glEnable(GL_TEXTURE_2D); img.ogl_bind_texture(); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else glDisable(GL_TEXTURE_2D); if ( rb<=0 ) rb=MINRADIUS; if ( rt<=0 ) rt=MINRADIUS; if ( nfaces<3 ) nfaces = 3; glColor3f(1.0, 1.0, 1.0); // compute vertical axis: double dang = (2.0*PI)/double(nfaces); double ang = 0; // we will use len as half the length: len = len/2; // initial points: double ibx=rb, iby=-len, ibz=0; // bottom double itx=rt, ity=+len, itz=0; // top // current points start as the initial points: double cbx=ibx, cby=iby, cbz=ibz; // bottom double ctx=itx, cty=ity, ctz=itz; // top // declare the "next points" to form the cylinder lines: double nbx, nby, nbz; // bottom double ntx, nty, ntz; // top // declare variables for texture usage double tx = 1.0; double tnext = -( 1.0 / nfaces ); //declare vector variables Vec u, v, w, p, q, r; // compute the points all around body: int i=1; while(i <= nfaces) { // rotate the current points: if ( i<nfaces ) // normal rotation for intermediate points { ang += dang; double ca = cos(ang); double sa = sin(ang); nbx=ca*rb; nby=cby; nbz=sa*rb; ntx=ca*rt; nty=cty; ntz=sa*rt; } else // to make a perfect closure, the last points are exactly the first ones { nbx=ibx; nby=iby; nbz=ibz; ntx=itx; nty=ity; ntz=itz; } //Calculating vectors and normals for upper and lower parts u = Vec( (ntx - ctx), (nty - cty), (ntz - ctz) ); v = Vec( (0 - ctx), (len - cty), (0 - ctz) ); w = cross(v, u); w.normalize(); //Normal for faces p = Vec( (nbx - cbx), (nby - cby), (nbz - cbz) ); q = Vec( (ctx - cbx), (cty - cby), (ctz - cbz) ); r = cross(q, p); r.normalize(); //Start drawing glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); if(!smooth && !texture) { glBegin ( GL_TRIANGLES ); //draw top polygons glNormal3d(w.x, w.y, w.z); glVertex3d(ctx, cty, ctz); glVertex3d(ntx, nty, ntz); glVertex3d(0, len, 0); //draw bottom polygons glNormal3d(-w.x, -w.y, -w.z); glVertex3d(cbx, cby, cbz); glVertex3d(nbx, nby, nbz); glVertex3d(0, -len, 0); glEnd(); //draw faces glBegin(GL_QUADS); glNormal3d(r.x, r.y, r.z); glVertex3d(ctx, cty, ctz); glVertex3d(ntx, nty, ntz); glVertex3d(nbx, nby, nbz); glVertex3d(cbx, cby, cbz); glEnd(); } if(smooth && !texture) { glBegin ( GL_TRIANGLES ); //draw top polygons glNormal3d(ctx, cty, ctz); glVertex3d(ctx, cty, ctz); glNormal3d(ntx, nty, ntz); glVertex3d(ntx, nty, ntz); glNormal3d(0, len, 0); glVertex3d(0, len, 0); //draw bottom polygons glNormal3d(cbx, cby, cbz); glVertex3d(cbx, cby, cbz); glNormal3d(nbx, nby, nbz); glVertex3d(nbx, nby, nbz); glNormal3d(0, -len, 0); glVertex3d(0, -len, 0); //draw faces glNormal3d(ctx, cty, ctz); glVertex3d(ctx, cty, ctz); glNormal3d(ntx, nty, ntz); glVertex3d(ntx, nty, ntz); glNormal3d(cbx, cby, cbz); glVertex3d(cbx, cby, cbz); glNormal3d(cbx, cby, cbz); glVertex3d(cbx, cby, cbz); glNormal3d(nbx, nby, nbz); glVertex3d(nbx, nby, nbz); glNormal3d(ntx, nty, ntz); glVertex3d(ntx, nty, ntz); glEnd(); } if(texture) { //draw faces glBegin(GL_QUADS); glTexCoord2f(tx, 0); glVertex3d(ctx, cty, ctz); glTexCoord2f(tx + tnext, 0); glVertex3d(ntx, nty, ntz); glTexCoord2f(tx + tnext, 1); glVertex3d(nbx, nby, nbz); glTexCoord2f(tx, 1); glVertex3d(cbx, cby, cbz); glEnd(); glDisable(GL_TEXTURE_2D); glBegin ( GL_TRIANGLES ); //draw top polygons glVertex3d(ctx, cty, ctz); glVertex3d(ntx, nty, ntz); glVertex3d(0, len, 0); //draw bottom polygons glVertex3d(cbx, cby, cbz); glVertex3d(nbx, nby, nbz); glVertex3d(0, -len, 0); glEnd(); glEnable(GL_TEXTURE_2D); } // update current points: cbx=nbx; cby=nby; cbz=nbz; ctx=ntx; cty=nty; ctz=ntz; tx += tnext; // increment side counter: i++; } // done glEnd(); }
inline Vec operator-(void) { return Vec(-x, -y, -z); }
QString MeshGenerator::start(VolumeFileManager *vfm, int nX, int nY, int nZ, Vec dataMin, Vec dataMax, QString prevDir, Vec voxelScaling, int samplingLevel, QList<Vec> clipPos, QList<Vec> clipNormal, QList<CropObject> crops, QList<PathObject> paths, uchar *lut, int pruneLod, int pruneX, int pruneY, int pruneZ, QVector<uchar> pruneData, QVector<uchar> tagColors) { m_vfm = vfm; m_voxelType = m_vfm->voxelType(); m_depth = nX; m_width = nY; m_height = nZ; m_dataMin = dataMin; m_dataMax = dataMax; m_dataSize = m_dataMax - m_dataMin + Vec(1,1,1); m_nX = qMin(int(m_dataSize.z), m_depth); m_nY = qMin(int(m_dataSize.y), m_width); m_nZ = qMin(int(m_dataSize.x), m_height); m_crops = crops; m_paths = paths; m_pruneLod = pruneLod; m_pruneX = pruneX; m_pruneY = pruneY; m_pruneZ = pruneZ; m_pruneData = pruneData; m_tagColors = tagColors; m_samplingLevel = samplingLevel; // pruneLod that we get is wrt the original sized volume. // set pruneLod to reflect the selected sampling level. m_pruneLod = qMax((float)m_nX/(float)m_pruneZ, qMax((float)m_nY/(float)m_pruneY, (float)m_nZ/(float)m_pruneX)); // QMessageBox::information(0, "", QString("%1 %2 %3\n%4 %5 %6\n%7").\ // arg(m_nX).arg(m_nY).arg(m_nZ).\ // arg(m_pruneZ).arg(m_pruneY).arg(m_pruneX).\ // arg(m_pruneLod)); bool doBorder = false; if (qRound(m_dataSize.x) < m_height || qRound(m_dataSize.y) < m_width || qRound(m_dataSize.z) < m_depth) doBorder = true; if (clipPos.count() > 0 || m_crops.count() > 0 || m_paths.count() > 0) doBorder = true; int depth, fillValue; bool checkForMore; bool lookInside; QGradientStops stops; int chan; bool avgColor; if (! getValues(depth, fillValue, checkForMore, lookInside, stops, doBorder, chan, avgColor)) return ""; m_meshLog = new QTextEdit; m_meshProgress = new QProgressBar; QVBoxLayout *meshLayout = new QVBoxLayout; meshLayout->addWidget(m_meshLog); meshLayout->addWidget(m_meshProgress); QWidget *meshWindow = new QWidget; meshWindow->setWindowTitle("Drishti - Mesh Repainting Using Voxel Values"); meshWindow->setLayout(meshLayout); meshWindow->show(); meshWindow->resize(700, 300); float memGb = 0.5; memGb = QInputDialog::getDouble(0, "Use memory", "Max memory we can use (GB)", memGb, 0.1, 1000, 2); qint64 gb = 1024*1024*1024; qint64 memsize = memGb*gb; // max memory we can use (in GB) qint64 canhandle = memsize/15; qint64 gsize = qPow((double)canhandle, 0.333); m_meshLog->insertPlainText(QString("Can handle data with total grid size of %1 : typically %2^3\nOtherwise slabs method will be used. Mesh is generated for each slab and then joined together.\n\n"). \ arg(canhandle).arg(gsize)); m_meshLog->insertPlainText("\n\n"); m_meshLog->insertPlainText(QString("Volume Size : %1 %2 %3\n").\ arg(m_depth). arg(m_width). arg(m_height)); m_meshLog->insertPlainText(QString("DataMin : %1 %2 %3\n").\ arg(m_dataMin.z). arg(m_dataMin.y). arg(m_dataMin.x)); m_meshLog->insertPlainText(QString("DataMax : %1 %2 %3\n").\ arg(m_dataMax.z). arg(m_dataMax.y). arg(m_dataMax.x)); m_meshLog->insertPlainText(QString("DataSize : %1 %2 %3\n").\ arg(m_dataSize.z). arg(m_dataSize.y). arg(m_dataSize.x)); m_meshLog->insertPlainText("\n\n"); m_meshLog->insertPlainText(QString("Grid size : %1 %2 %3\n").\ arg(m_nX).arg(m_nY).arg(m_nZ)); //---- import the mesh --- QString inflnm = QFileDialog::getOpenFileName(0, "Load mesh to repaint", prevDir, "*.ply"); if (inflnm.size() == 0) { meshWindow->close(); return ""; } if (!loadPLY(inflnm)) { meshWindow->close(); return ""; } //---------------------------- //---- export the mesh --- QString outflnm = QFileDialog::getSaveFileName(0, "Export mesh", prevDir, "*.ply"); if (outflnm.size() == 0) { meshWindow->close(); return ""; } //---------------------------- int nSlabs = 1; qint64 reqmem = m_nX; reqmem *= m_nY*m_nZ*20; nSlabs = qMax(qint64(1), reqmem/memsize + 1); // QMessageBox::information(0, "", QString("Number of Slabs : %1 : %2 %3").\ // arg(nSlabs).arg(reqmem).arg(memsize)); QStringList volumeFiles; #ifndef Q_OS_MACX volumeFiles = QFileDialog::getOpenFileNames(0, "Load volume files for timeseries data, otherwise give CANCEL", prevDir, "NetCDF Files (*.pvl.nc)", 0, QFileDialog::DontUseNativeDialog); #else volumeFiles = QFileDialog::getOpenFileNames(0, "Load volume files for timeseries data, otherwise give CANCEL", prevDir, "NetCDF Files (*.pvl.nc)", 0); #endif int nvols = volumeFiles.count(); if (nvols == 0) volumeFiles << m_vfm->fileName(); generateMesh(nSlabs, volumeFiles, outflnm, depth, stops, fillValue, checkForMore, lookInside, voxelScaling, clipPos, clipNormal, crops, paths, lut, chan, avgColor); meshWindow->close(); return outflnm; }