void do_bump_map(
		//const eiScalar i_bumpValue,
		//const eiScalar i_bumpDepth,
		const normal& i_normalCamera,
		normal& o_outNormal )
	{
		eiScalar LOW = -1.0f, HEIGHT=1.0f;
		eiScalar offset = clamp(bumpValue(), LOW, HEIGHT) * abs(bumpDepth());

		//Du_offset=d(offset)/du, Dv_offset=d(offset)/dv
		eiScalar Du_offset, Dv_offset;
		eiScalar DbumpValue_du, DbumpValue_dv;
		eiScalar DbumpDepth_du, DbumpDepth_dv;		
		Du(bumpValue, DbumpValue_du);
		Dv(bumpValue, DbumpValue_dv);
		Du(bumpDepth, DbumpDepth_du);
		Dv(bumpDepth, DbumpDepth_dv);
		Du_offset = D_clamp(bumpValue(), LOW,HEIGHT) * DbumpValue_du      * abs(bumpDepth()) 
			        + clamp(bumpValue(), LOW,HEIGHT) * D_abs(bumpDepth()) * DbumpDepth_du;
		Dv_offset = D_clamp(bumpValue(), LOW,HEIGHT) * DbumpValue_dv      * abs(bumpDepth()) 
			        + clamp(bumpValue(), LOW,HEIGHT) * D_abs(bumpDepth()) * DbumpDepth_dv;
		/*
		These scale factors are a bit experimental. The constant is to roughly
		match maya's bump mapping. The part about dPdu/dPdv ensures that the
		bump's scale does not depend on the underlying parametrization of the
		patch (the use of Du and Dv below introduce that) and that it happens
		in object space. Note that maya's handling of object space appears to
		be slightly broken since an enlarged sphere will have the same bump as
		a sphere with its control points moved outwards by a scale, somehow.
		*/
		matrix toLocal = to_object();
		eiScalar uscale = 1.0f / len(&(dPdu() * toLocal)) * 6.0f;
		eiScalar vscale = 1.0f / len(&(dPdv() * toLocal)) * 6.0f;

		vector gu = vector(1.0f, 0.0f, Du_offset * uscale);
		vector gv = vector(0.0f, 1.0f, Dv_offset * vscale);
		normal n = normal(gu ^ gv);

		vector basisz = normalize(i_normalCamera);
		vector basisx = normalize((basisz ^ dPdu()) ^ basisz);
		vector basisy = normalize((basisz ^ dPdv()) ^ basisz);

		o_outNormal = normal(
			n.x * basisx + n.y * basisy + n.z * basisz);

		o_outNormal = normalize(o_outNormal);
	}
void OpticalFlow::baseCalculate(cv::Mat& Im1, cv::Mat& Im2, flowUV& UV, const OpticalFlowParams& params){
	int rows = Im1.rows;
	int cols = Im1.cols;

	FlowOperator flowOp(rows, cols);
	FArray X0(2 * rows * cols, false);	

	FArray dUdV(2 * rows * cols, true, 0);
	cv::Mat Ix1(rows, cols, OPTFLOW_TYPE);
	cv::Mat Iy1(rows, cols, OPTFLOW_TYPE); 
	cv::Mat Ix(rows, cols, OPTFLOW_TYPE);
	cv::Mat Iy(rows, cols, OPTFLOW_TYPE); 
	getDXsCV(Im1, Ix1, Iy1);
	for (int i = 0; i < params.getIters(); ++i){
		cv::Mat Ix2(rows, cols, OPTFLOW_TYPE);
		cv::Mat Iy2(rows, cols, OPTFLOW_TYPE); 
		cv::Mat It(rows, cols, OPTFLOW_TYPE); 

		cv::Mat im2Warpped(rows, cols, Im1.type());
		WarpImage(Im2, UV.getU(), UV.getV(), im2Warpped);	
		
		getDXsCV(im2Warpped, Ix2, Iy2);
		Ix = params.getWeightedDeriveFactor() * (Ix1 + Ix2);
		Iy = params.getWeightedDeriveFactor() * (Iy1 + Iy2);
		cv::subtract(im2Warpped, Im1, It);

		if (params.getDisplayDerivativs()){
			cv::imshow("Derivative Ix", Ix);
			cv::imshow("Derivative Iy", Iy);
			cv::waitKey(1);
		}
		
		cv::Mat Du(rows, cols, OPTFLOW_TYPE, cv::Scalar(0));
		cv::Mat Dv(rows, cols, OPTFLOW_TYPE, cv::Scalar(0));


		for (int j = 0; j < params.getLinearIters(); ++j){
#if OPTFLOW_VERBOSE
			cout << "solving Ax=b with SOR ";
			clock_t start = std::clock();	
#endif		
			flowOp.construct(UV, Du, Dv, Ix, Iy, It, params);
			
			memcpy(X0.ptr, UV.getU().data, rows * cols * sizeof(float));
			memcpy(X0.ptr + (rows * cols), UV.getV().data, rows * cols * sizeof(float));
			//UtilsDebug::printCRSSparseMat(flowOp.getA(), "aaaa.txt");
			if (params.getCheckResidualTolerance()){
				LinearSolver::sparseMatSor(flowOp.getA(), X0 ,dUdV, flowOp.getb(), params.getOverRelaxation(), params.getSorIters(), params.getResidualTolerance());
			}else{
				//LinearSolver::multigrid(10,10,flowOp.getA(),flowOp.getb(), params.getResidualTolerance(), dUdV, 20, 20, LinearSolver::vCycle);
				LinearSolver::sparseMatSorNoResidual(flowOp.getA(), X0 ,dUdV, flowOp.getb(), params.getOverRelaxation(), params.getSorIters());
			}
#if OPTFLOW_VERBOSE
		std::cout<<" --- "<< (std::clock() - start) / (double)CLOCKS_PER_SEC <<'\n';
#endif

#if OPTFLOW_DEBUG
			for(int i = 0; i < dUdV.size(); ++i){
				if (!(dUdV.ptr[i] == dUdV.ptr[i])){
					cout << "ERROR - NAN";
				}
			}
#endif

			UtilsMat::clamp(dUdV, -1, 1);

			memcpy(Du.data, dUdV.ptr, rows * cols * sizeof(float));
			memcpy(Dv.data, dUdV.ptr + (rows * cols), rows * cols * sizeof(float));
			
			flowUV UV0(UV);
			UV.getU() += Du;
			UV.getV() += Dv;

			cv::Mat tmpU, tmpV;
			UV.getU().copyTo(tmpU);
			UV.getV().copyTo(tmpV);

			WeightedMedianFilter::computeMedianFilter(UV.getU(), UV.getV(), Im1, Im2, params.getMedianFilterRadius());

			Du = UV.getU() - UV0.getU();
			Dv = UV.getV() - UV0.getV();

			UV0.getU().copyTo(UV.getU());
			UV0.getV().copyTo(UV.getV());

			UV0.getU() += Du;
			UV0.getV() += Dv;
			if (params.isDisplay())
				UtilsFlow::DrawFlow(UV0.getU(), UV0.getV(), "Flow");
		}
		UV.getU() += Du;
		UV.getV() += Dv;
	}
}
Example #3
0
NurbsSurfaceSP<T,N> NurbsSurfaceSP<T,N>::generateParallel(T d) const {
  NurbsSurfaceSP<T,N> p(*this) ;

  Vector< Point_nD<T,N> > offset(this->P.rows()*this->P.cols()) ;
  Vector<T> ur(this->P.rows()*this->P.cols()) ;
  Vector<T> vr(this->P.rows()*this->P.cols()) ;
  Vector_INT Du(this->P.rows()*this->P.cols()) ;
  Vector_INT Dv(this->P.rows()*this->P.cols()) ;

  Du.reset(0) ;
  Dv.reset(0) ;

  int i,j,no ;

  no = 0 ;

  for(i=0;i<this->P.rows();++i)
    for(j=0;j<this->P.cols();++j){
      Point_nD<T,N> norm ;
      norm = normal(maxAtU_[i],maxAtV_[j]) ;
      if(norm.x() == T(0) && 
	 norm.y() == T(0) &&
	 norm.z() == T(0)){
	// normal is undefined there...
	// compute an average and find a suitable normal
	const T delta = 0.00001 ;
	// must handle the corner cases
	int ok = 0 ; 
	if(i==0 && j==0){
	  norm = normal(maxAtU_[i]+delta,maxAtV_[j]) ;
	  norm += normal(maxAtU_[i],maxAtV_[j]+delta) ;
	  norm /= T(2) ;
	  ok = 1 ;
	}
	if(i==this->P.rows()-1 && j==this->P.cols()-1){
	  norm = normal(maxAtU_[i]-delta,maxAtV_[j]) ;
	  norm += normal(maxAtU_[i],maxAtV_[j]-delta) ;
	  norm /= T(2) ;
	  ok = 1 ;
	}
	if(i==0 && j==this->P.cols()-1){
	  norm = normal(maxAtU_[i]-delta,maxAtV_[j]) ;
	  norm += normal(maxAtU_[i],maxAtV_[j]+delta) ;
	  norm /= T(2) ;
	  ok = 1 ;
	}
	if(i==this->P.rows()-1 && j==0){
	  norm = normal(maxAtU_[i]-delta,maxAtV_[j]) ;
	  norm += normal(maxAtU_[i],maxAtV_[j]+delta) ;
	  norm /= T(2) ;
	  ok = 1 ;
	}
	if(!ok){
	  T nt = 1.0 ; 
	  while(norm.x() == T(0) && 
	     norm.y() == T(0) &&
	     norm.z() == T(0)){
	    if( nt*d >(this->U[this->U.n()-1]-this->U[0])){
#ifdef USE_EXCEPTION
	      throw NurbsComputationError();
#else
	      Error error("generateParallel");
	      error << "Can't compute a normal point.\n" ;
	      error.fatal() ;
#endif
	    }
	    T u1,u2,v1,v2 ;
	    if(i==0 || i==this->P.rows()-1){
	      u1 = u2 = maxAtU_[i] ;
	      v1 = maxAtV_[j]+ nt*delta ;
	      v2 = maxAtV_[j]- nt*delta ;
	      if(v1>this->V[this->V.n()-1]) v1 = this->V[this->V.n()-1] ;
	      if(v2<this->V[0]) v2 = this->V[0] ;
	      norm = normal(u1,v1);
	      norm += normal(u2,v2) ;
	      norm /= 2 ; 
	    }
	    else{
	      u1 = maxAtU_[i]- nt*delta ;
	      u2 = maxAtU_[i]+ nt*delta ;
	      v1 = v2 = maxAtV_[j] ;
	      if(u1 < this->U[0]) u1 = this->U[0] ;
	      if(u2 > this->U[this->U.n()-1]) u2 = this->U[this->U.n()-1] ;

	      T u3,v3 ;
	      u3 = maxAtU_[i] ;
	      if(j==0)
		v3 = maxAtV_[j]+ nt*delta ;
	      else
		v3 = maxAtV_[j]- nt*delta ;

	      if(v3<this->V[0]) v3 = this->V[0] ;
	      if(v3>this->V[this->V.n()-1]) v3 = this->V[this->V.n()-1] ;

	      norm = normal(u1,v1);
	      norm += normal(u2,v2) ;
	      norm += normal(u3,v3) ;
	      norm /= 3 ; 
	    }
	    nt *= 10.0 ; 
	  }
	}
      }
      Point_nD<T,N> unit = norm.unitLength();
      unit *= d ;
      //HPoint_nD<T,N> offset(unit ) ;
      //offset.w() = 0.0 ; 
      //p.modSurfCPby(i,j,offset) ;
      Du[no] = i ;
      Dv[no] = j ;
      offset[no] = unit ;
      ++no ;
    }

  p.movePoint(maxAtU_,maxAtV_,offset,Du,Dv) ;

  return p ;
}