void init_LUMINANCE_UBYTE( vl::Actor* actor, vl::Image* img, vl::fvec3 scale = vl::fvec3(10.0f, 10, 10.0f), int threshold_min = 32, int threshold_max = 255, const TF& transfer_func = TransferRGBA_255() ) { if (img->type() != vl::IT_UNSIGNED_BYTE || img->format() != vl::IF_LUMINANCE) { vl::Log::error("init_LUMINANCE_UBYTE() error:\n" + img->print() ); return; } vl::ref<vl::Geometry> geometry; vl::ref<vl::ArrayFloat3> points; vl::ref<vl::DrawElementsUInt> draw_elements; vl::ref<vl::ArrayFloat3> eye_space_points; eye_space_points = new vl::ArrayFloat3; geometry = new vl::Geometry; points = new vl::ArrayFloat3; vl::ref<vl::ArrayFloat3> norms = new vl::ArrayFloat3; draw_elements = new vl::DrawElementsUInt(vl::PT_POINTS); vl::ref<vl::ArrayUByte4> color = new vl::ArrayUByte4; geometry->setVertexArray( points.get() ); geometry->setNormalArray( norms.get() ); geometry->setColorArray( color.get() ); geometry->drawCalls()->push_back( draw_elements.get() ); int point_count = 0; for(int index = 0, z=0; z<img->depth(); ++z) { for(int y=0; y<img->height(); ++y) { for(int x=0; x<img->width(); ++x, ++index) { int val = img->pixels()[ x + y*img->pitch() + z*img->height()*img->pitch() ]; if ( val >= threshold_min && val <= threshold_max) ++point_count; } } } #ifndef NDEBUG vl::Log::print(vl::Say("original points = %6.0nK\n") << img->depth() * img->height() * img->width() / 1000.0f ); vl::Log::print(vl::Say("accepted points = %6.0nK\n") << point_count / 1000.0f); vl::Log::print(vl::Say("simplif. ratio = %n%%\n") << (1.0f - (float)point_count / (img->depth() * img->height() * img->width())) * 100.0f ); #endif points->resize( point_count ); norms->resize( point_count ); draw_elements->indexBuffer()->resize( point_count ); color->resize( point_count ); for(int index = 0, z=0; z<img->depth(); ++z) { for(int y=0; y<img->height(); ++y) { for(int x=0; x<img->width(); ++x) { int val = img->pixels()[ x + y*img->pitch() + z*img->height()*img->pitch() ]; if ( val >= threshold_min && val <= threshold_max) { float tx = (float)x / ( img->width() -1 ); float ty = (float)y / ( img->height()-1 ); float tz = (float)z / ( img->depth() -1 ); points->at(index) = vl::fvec3(tx*scale.x() - scale.x()*0.5f, ty*scale.y() - scale.y()*0.5f, tz*scale.z() - scale.z()*0.5f); // compute normal int x1 = x-1; int x2 = x+1; int y1 = y-1; int y2 = y+1; int z1 = z-1; int z2 = z+1; x2 = x2 > img->width() -1 ? img->width() -1 : x2; y2 = y2 > img->height() -1 ? img->height()-1 : y2; z2 = z2 > img->depth() -1 ? img->depth() -1 : z2; x1 = x1 < 0 ? 0 : x1; y1 = y1 < 0 ? 0 : y1; z1 = z1 < 0 ? 0 : z1; float vx1 = img->pixels()[ x1 + y*img->pitch() + z*img->height()*img->pitch() ]; float vx2 = img->pixels()[ x2 + y*img->pitch() + z*img->height()*img->pitch() ]; float vy1 = img->pixels()[ x + y1*img->pitch() + z*img->height()*img->pitch() ]; float vy2 = img->pixels()[ x + y2*img->pitch() + z*img->height()*img->pitch() ]; float vz1 = img->pixels()[ x + y*img->pitch() + z1*img->height()*img->pitch() ]; float vz2 = img->pixels()[ x + y*img->pitch() + z2*img->height()*img->pitch() ]; vl::fvec3 normal(vx1-vx2, vy1-vy2, vz1-vz2); normal.normalize(); norms->at(index) = normal; unsigned char r=0,g=0,b=0,a=0; transfer_func(img->pixels()[x + y*img->pitch() + z*img->height()*img->pitch()], r,g,b,a); color->at(index) = vl::ubvec4(r,g,b,a); draw_elements->indexBuffer()->at(index) = index; ++index; } } } } actor->setLod(0, geometry.get()); geometry->setDisplayListEnabled(false); geometry->setBufferObjectEnabled(true); if (vl::Has_GL_ARB_vertex_buffer_object) { color->bufferObject()->setBufferData(vl::BU_STATIC_DRAW); points->bufferObject()->setBufferData(vl::BU_STATIC_DRAW); norms->bufferObject()->setBufferData(vl::BU_STATIC_DRAW); draw_elements->indexBuffer()->bufferObject()->setBufferData(vl::BU_DYNAMIC_DRAW); } eye_space_points->resize( points->size() ); }
vl::fvec3 CoreFunctions::getNewPointPosition(vl::fvec3 pPoint1, vl::fvec3 pPoint2, float pValueX) { float maxDistance; float partDistance; float multiplier; float valueY; float valueZ; if (pPoint1.x() > pPoint2.x()) { vl::fvec3 tmpPoint = pPoint1; pPoint1 = pPoint2; pPoint2 = tmpPoint; } maxDistance = computeDistance(pPoint1.x(), pPoint2.x()); partDistance = computeDistance(pPoint1.x(), pValueX); multiplier = partDistance / maxDistance; maxDistance = computeDistance(pPoint1.y(), pPoint2.y()); partDistance = maxDistance * multiplier; if (pPoint1.y() < pPoint2.y()) { valueY = pPoint1.y() + partDistance; } else { valueY = pPoint1.y() - partDistance; } maxDistance = computeDistance(pPoint1.z(), pPoint2.z()); partDistance = maxDistance * multiplier; if (pPoint1.z() < pPoint2.z()) { valueZ = pPoint1.z() + partDistance; } else { valueZ = pPoint1.z() - partDistance; } return vl::fvec3(pValueX, valueY, valueZ); }