Ejemplo n.º 1
0
//understand the edge vertex computation from [email protected]
//ASSUMPTION: eye is along z-axis
//vo: volume vertex coords model-space coords
//tx: texture vertex coords tex-space coords
//axis: axis to slice along world-space coords
void vRenderer::renderTexture3D(float sampleFrequency,GLdouble mv[16],float vo[8][3],float tx[8][3],float axis[3])
{
    float rv[8][3];     //the rotated volume (may include a scale)
    float maxval = -10; //(tmp)
    float minval = 10;
    int minvert = 0, maxvert = 0;
    GLdouble mvinv[16];
    int i, j, k;
    inverseMatrix(mvinv, mv); //invert model view matrix

    for(i=0; i<8; ++i){
	translateV3(rv[i], mv, vo[i]); //get the rotated vol coords
	//now get the max and min z in view space
	if(maxval < MAX(maxval, rv[i][2])){
	    maxval = MAX(maxval, rv[i][2]);
	    maxvert = i;
	}
	if(minval > MIN(minval, rv[i][2])){
	    minval = MIN(minval, rv[i][2]);
	    minvert = i;  //determine the starting corner for slicing
	}
    }

    //find the slice plane point 'sp' (initial) and the slice plane normal 'sn'
    //sp is the slice starting point, simply the vertex farthest from the eye
    float sp[3] = {vo[minvert][0], vo[minvert][1], vo[minvert][2]};
//    float sp[3] = {vo[maxvert][0], vo[maxvert][1], vo[maxvert][2]};
    float vpn[3];
    vpn[0] = axis[0]; vpn[1] = axis[1]; vpn[2] = axis[2];

    //now calculate sn which is the normalized vpn in the model space
    //ie where the orginal slices are stored
    float sn[3];
    translateV3(sn, mvinv, vpn); //move vpn to sn (model space);
    //now normalize this
    float normsn = (float)sqrt(sn[0]*sn[0] + sn[1]*sn[1] + sn[2]*sn[2]); //normalize
    sn[0]/=normsn;
    sn[1]/=normsn;
    sn[2]/=normsn;

    //now find the distance we need to slice (|max_vertex - min_vertex|)
    float maxd[3] = {0, 0, maxval}; //(tmp) only use z-coord (view space)
    float mind[3] = {0, 0, minval}; //(tmp) ditto	    (view space)
    float maxv[3], minv[3];	   //(tmp)
    translateV3(maxv, mvinv, maxd); //translate back to model space
    translateV3(minv, mvinv, mind); //ditto
    maxv[0] -= minv[0]; //subtract
    maxv[1] -= minv[1];
    maxv[2] -= minv[2];

    //now take the norm of this vector... we have the distance to be sampled
    //this distance is in the world space
    float dist = (float)sqrt(maxv[0]*maxv[0] + maxv[1]*maxv[1] + maxv[2]*maxv[2]);

#if defined(ADDCGGL) || defined(ADDARBGL)
    glColor4f(1.0f,1.0f,1.0f,0.01);
#else
    glColor4f(1.0f,1.0f,1.0f,0.1);
#endif

    GlErr("vRenderer","drawVA");

    //distance between samples
    float sampleSpacing = 1.0 / (myVolume->maxDim* sampleFrequency);
    float del[3] = {sn[0]*sampleSpacing, sn[1]*sampleSpacing, sn[2]*sampleSpacing};

    int samples = (int)((dist) / sampleSpacing);//(total distance to be sam	//highly un-optimized!!!!!!!!!
    float poly[6][3];   // for edge intersections
    float tcoord[6][3]; // for texture intersections
    float tpoly[6][3];  // for transformed edge intersections
    int edges;	       // total number of edge intersections

    //the dep texture should be scaled
    glBindTexture(GL_TEXTURE_3D, myVolume->texName);
    //sp:slice plane point
    //sn:the slice dirn to cut thru the volume
    //the above 2 are in world coord space

    for(i = 0 ; i < samples; ++i){ //for each slice
	//increment the slice plane point by the slice distance
//	sp[0] -= del[0];
//	sp[1] -= del[1];
//	sp[2] -= del[2];

	sp[0] += del[0];
	sp[1] += del[1];
	sp[2] += del[2];

	edges = 0;
	//now check each edge of the volume for intersection with..
	//the plane defined by sp & sn
	//front bottom edge
	edges += intersect(vo[0], vo[1], tx[0], tx[1], rv[0], rv[1], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//front left edge
	edges += intersect(vo[0], vo[2], tx[0], tx[2], rv[0], rv[2], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//front right edge
	edges += intersect(vo[1], vo[3], tx[1], tx[3], rv[1], rv[3], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//left bottom edge
	edges += intersect(vo[4], vo[0], tx[4], tx[0], rv[4], rv[0], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//right bottom edge
	edges += intersect(vo[1], vo[5], tx[1], tx[5], rv[1], rv[5], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//front top edge
	edges += intersect(vo[2], vo[3], tx[2], tx[3], rv[2], rv[3], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//back bottom edge
	edges += intersect(vo[4], vo[5], tx[4], tx[5], rv[4], rv[5], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//back left edge
	edges += intersect(vo[4], vo[6], tx[4], tx[6], rv[4], rv[6], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//back right edge
	edges += intersect(vo[5], vo[7], tx[5], tx[7], rv[5], rv[7], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//back top edge
	edges += intersect(vo[6], vo[7], tx[6], tx[7], rv[6], rv[7], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//left top edge
	edges += intersect(vo[2], vo[6], tx[2], tx[6], rv[2], rv[6], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);
	//right top edge
	edges += intersect(vo[3], vo[7], tx[3], tx[7], rv[3], rv[7], sp, sn,
			   poly[edges], tcoord[edges], tpoly[edges]);

	// B.M.E. Moret & H.D. Shapiro "P to NP" pp. 453

	float dx, dy, tt ,theta, cen[2];  //tt= TempTheta
	cen[0] = cen[1] = 0.0;
	int next;
	//rather than swap 3 arrays, only one?
	int order[6] ={0,1,2,3,4,5};

	// order[6] could be an extreemly inefficient way to do this
	for(j=0; j<edges; ++j){ //find the center of the points
	    cen[0] += tpoly[j][0];
	    cen[1] += tpoly[j][1];
	} //by averaging
	cen[0]/= edges;
	cen[1]/= edges;

	for(j=0; j<edges; ++j){ //for each vertex
	    theta = -10;	       //find one with largest angle from center..
	    next = j;
	    for (k= j; k<edges; ++k){
		//... and check angle made between other edges
		dx = tpoly[order[k]][0] - cen[0];
		dy = tpoly[order[k]][1] - cen[1];
		if( (dx == 0) && (dy == 0)){ //same as center?
		    next = k;
		    cout << "what teh " << endl;
		    break; //out of this for-loop
		}
		tt = dy/(ABS(dx) + ABS(dy)); //else compute theta [0-4]
		if( dx < 0.0 ) tt = (float)(2.0 - tt); //check quadrants 2&3
		else if( dy < 0.0 ) tt = (float)(4.0 + tt); //quadrant 4
		if( theta <= tt ){  //grab the max theta
		    next = k;
		    theta = tt;
		}
	    } //end for(k) angle checking
	    // i am using 'tt' as a temp
	    // swap polygon vertex ( is this better than another branch?)
	    // I am not sure wich is worse: swapping 3 vectors for every edge
	    // or: using an array to index into another array??? hmmm....
	    //   should have payed more attention in class
	    int tmp = order[j];
	    order[j] = order[next];
	    order[next] = tmp;

	} //end for(j) edge /angle sort
	renderSlice(edges, tcoord, poly, order);
	//}//end else compute convex hull
    }// end for(i) each slice
    //now draw each slice view

 }
Ejemplo n.º 2
0
int32_t SearcherWorker::run() {
    const char *pureString = NULL;
    uint32_t pureSize = 0;
    char *resData = NULL;
    uint32_t resSize = 0;
    char *resDetailData = NULL;
    int32_t resDetailSize = 0;
    int32_t ret = 0;
    MemPool *memPool = NULL;
    int64_t *pNid = NULL;
    commdef::ClusterResult *pClusterResult = NULL;
    queryparser::QueryRewriterResult *pQRWResult = NULL;
    queryparser::QPResult *pQueryResult = NULL;
    SearchResult *pSearchResult = NULL;
    statistic::StatisticResult *pStatisticResult = NULL;
    sort_framework::SortResult *pSortResult = NULL;
    ResultSerializer resultSerial;
    FRAMEWORK::Context context;
    FILE *pOutput = NULL;
    //check session status
    FRAMEWORK::session_status_t status = _session.getStatus();
    if (status == FRAMEWORK::ss_timeout) {
        handleTimeout();
        return KS_SUCCESS;
    }
    //get query infomation
    FRAMEWORK::Query &query = _session.getQuery();
    pureSize = query.getPureQuerySize();
    pureString = query.getPureQueryData();
    if (!pureString || pureSize == 0) {
        _session.setStatus(FRAMEWORK::ss_error);
        _session.response();
        return KS_EFAILED;
    }
    //set LogInfo level
    _session._logInfo._eRole = FRAMEWORK::sr_simple;
    //get MemPool from factory
    memPool = _memFactory.make((uint64_t)(getOwner()));
    if (memPool == NULL) {
        TWARN("Make mem pool failed!");
        return KS_EFAILED;
    }
    //create memory pool monitor
    MemMonitor memMonitor(memPool, _memLimit);
    memPool->setMonitor(&memMonitor);
    memMonitor.enableException();
    //initialize context class
    context.setMemPool(memPool);
	//initialize format processor
    _formatProcessor.init(memPool);
    //Deal with search proccess
    do{  
        if(_session.isHttp()){
            pQRWResult = NEW(memPool, queryparser::QueryRewriterResult)();
            if (pQRWResult == NULL) {
                TWARN("SEARCHER: new Result no mem");
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
        }
        pQueryResult = NEW(memPool, queryparser::QPResult)(memPool);
        pSearchResult = NEW(memPool, SearchResult);
        pStatisticResult = NEW(memPool, statistic::StatisticResult); 
        pSortResult = NEW(memPool, sort_framework::SortResult)(memPool);
        if(unlikely(!pQueryResult || !pSearchResult || !pStatisticResult
                    || !pSortResult)) {
            TWARN("SEARCHER: new Result no mem");
            _session.setStatus(FRAMEWORK::ss_error);
            break;
        }
        //add queryrewrite process
        if(_session.isHttp()){     
            ret = _qrewriter.doRewrite(&context, pureString, pureSize, pQRWResult);
            if (timeoutCheck && (_timeout > 0) && (_session.getLatencyTime() > _timeout)) {
                _session.setStatus(FRAMEWORK::ss_timeout);
                TWARN("SEARCHER: qrewriter.doRewrite function over time. query is %s", pureString);
                break;
            }
            if (unlikely(ret != KS_SUCCESS)) {
                _session.setStatus(FRAMEWORK::ss_error);
                TWARN("qrewriter.doRewrite function error. query is %s", pureString);                
                break;
            }
            pureString = pQRWResult->getRewriteQuery();
        }
        //end add
        ret = _qp.doParse(&context, pQueryResult, pureString);
        if (timeoutCheck && (_timeout > 0) && 
                (_session.getLatencyTime() > _timeout)) 
        {
            _session.setStatus(FRAMEWORK::ss_timeout);
            TWARN("SEARCHER: qp.doParse function over time. query is %s", pureString);
            break;
        }
        if (unlikely(ret != KS_SUCCESS)){
            TWARN("SEARCHER: queryparser doParse function error. query is %s", pureString);
            _session.setStatus(FRAMEWORK::ss_error);
            break;
        }

        // cache命中情况下, mempool reset时调用CacheResult析构函数,释放命中的节点,
        // 否则sortResult对节点内存的引用失效,变为野指针(bug#118631)
        {
            ret = _is.doQuery(&context, pQueryResult, &_sort, pSearchResult);
            if (timeoutCheck && (_timeout > 0) &&
                    (_session.getLatencyTime() > _timeout)) 
            {
                _session.setStatus(FRAMEWORK::ss_timeout);
                TWARN("SEARCHER: is.doQuery function over time. query is %s", pureString);
                break;
            }
            if (unlikely(ret != KS_SUCCESS)){
                TWARN("SEARCHER: search doQuery function error. query is %s", pureString);
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
            ret = _stat.doStatisticOnSearcher(&context, 
                    *(pQueryResult->getParam()),
                    pSearchResult, pStatisticResult);
            if (timeoutCheck && (_timeout > 0) &&
                    (_session.getLatencyTime() > _timeout)) 
            {
                _session.setStatus(FRAMEWORK::ss_timeout);
                TWARN("SEARCHER: doStatisticOnSearcher function over time. query is %s", pureString);
                break;
            }
            if (unlikely(ret != KS_SUCCESS)){
                TWARN("SEARCHER: statistic doStatisticOnSearcher function error. query is %s", pureString);
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
            ret = _sort.doProcess(context, *(pQueryResult->getParam()), 
                    *pSearchResult, *pSortResult);
            if (timeoutCheck && (_timeout > 0) &&
                    (_session.getLatencyTime() > _timeout))
            {
                _session.setStatus(FRAMEWORK::ss_timeout);
                TWARN("SEARCHER: sort.doProcess function over time. query is %s", pureString);
                break;
            }
            if (unlikely(ret)) {
                TWARN("SEARCHER: sort doProcess function error. query is %s", pureString);
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
        }


        pNid = NULL;
        //get docs return number
        int32_t num = pSortResult->getNidList(pNid);
        pClusterResult = NEW(memPool, commdef::ClusterResult)();

        if ( NULL == pClusterResult ){
            TWARN("SEARCHER: malloc from memPool failed ");
            _session.setStatus(FRAMEWORK::ss_error);
            break;            
        }

        memset(pClusterResult, 0x0, sizeof(commdef::ClusterResult));
        pClusterResult->_nDocsFound = pSortResult->getDocsFound();//pSearchResult->nDocFound;
        pClusterResult->_nEstimateDocsFound = pSortResult->getEstimateDocsFound();//pSearchResult->nEstimateDocFound;
        pClusterResult->_nDocsSearch = pSearchResult->nDocSearch;
        pClusterResult->_nDocsReturn = num;
        pClusterResult->_nDocsRestrict = pSearchResult->nEstimateDocFound;//pSearchResult->nDocFound;
        pClusterResult->_pStatisticResult = pStatisticResult;
        pClusterResult->_pSortResult = pSortResult;
        pClusterResult->_pQPResult = pQueryResult;
        pClusterResult->_ppDocuments = NULL;

        if(_session.isHttp() && _detail){

            if(!pClusterResult->_nDocsReturn){
                break;
            }  
            char* pid = NULL;
            uint32_t pid_size = 0;
            ret = get_nid_str(pNid, num, memPool, &pid, &pid_size);
            if(KS_SUCCESS != ret){
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }            
            ret = getDetailInfo(pid, pid_size, pureString, &resDetailData, &resDetailSize);
            if(KS_SUCCESS != ret){
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
            if(timeoutCheck && _timeout>0 && _session.getLatencyTime()>_timeout){
        		_session.setStatus(FRAMEWORK::ss_timeout); 
                break;
        	} 

            if (!translateV3(resDetailData, pClusterResult->_ppDocuments, (uint32_t &)pClusterResult->_nDocsReturn, memPool)) {
                _session.setStatus(FRAMEWORK::ss_error);
                break;
            }
        }
    } while (0);

    if(resDetailData)std::free(resDetailData);

    if(_session.isHttp() && _detail){
        //fromat result
        get_outfmt_type(pureString, pureSize);
        result_container_t container;
        container.pClusterResult = pClusterResult;
        container.cost = _session.getLatencyTime();
        if(_formatProcessor.frmt(_ofmt_type, container, &resData , &resSize) < 0){
            TERR("FORMATRESULT: format_processor process error!"); 
            _session.setStatus(FRAMEWORK::ss_error);
        }
    }
    else{     
        //serialize search result
        ret = resultSerial.serialClusterResult(pClusterResult,
                resData, resSize, "Z");
        if (ret != KS_SUCCESS) {
            _session.setStatus(FRAMEWORK::ss_error);
        }
    }
    //recycle mem pool
    context.getMemPool()->reset();
    _session.setResponseData(resData, resSize);
    _session.response();
    return KS_SUCCESS;
}