Пример #1
0
void Loaders::t3DSLoader::ComputeNormals(t3DModel *pModel)
{
    CVector3 vVector1, vVector2, vNormal, vPoly[3];

    if (pModel->numOfObjects <= 0)
        return;

    for (int index = 0; index < pModel->numOfObjects; index++)
    {
        t3DObject *pObject = &(pModel->pObject[index]);

        CVector3 *pNormals        = new CVector3 [pObject->numOfFaces];
        CVector3 *pTempNormals    = new CVector3 [pObject->numOfFaces];
        pObject->pNormals         = new CVector3 [pObject->numOfVerts];

        for (int i=0; i < pObject->numOfFaces; i++)
        {
            vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];
            vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];
            vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];

            vVector1 = Vector(vPoly[0], vPoly[2]);
            vVector2 = Vector(vPoly[2], vPoly[1]);

            vNormal  = Cross(vVector1, vVector2);
            pTempNormals[i] = vNormal;
            vNormal.unitMultiply(1);

            pNormals[i] = vNormal;
        }

        CVector3 vSum(0.0, 0.0, 0.0);
        CVector3 vZero = vSum;
        int shared = 0;

        for (int i = 0; i < pObject->numOfVerts; i++)
        {
            for (int j = 0; j < pObject->numOfFaces; j++)
            {
                if (pObject->pFaces[j].vertIndex[0] == i ||
                    pObject->pFaces[j].vertIndex[1] == i ||
                    pObject->pFaces[j].vertIndex[2] == i)
                {
                    vSum = vSum + pTempNormals[j];
                    shared++;
                }
            }

            pObject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared));

            pObject->pNormals[i].unitMultiply(1);

            vSum = vZero;
            shared = 0;
        }

        delete [] pTempNormals;
        delete [] pNormals;
    }
}
void C3DSLoader::ComputeNormals(t3DModel *pModel)   
{      
	Vector3 vVector1, vVector2, vNormal, vPoly[3];   
  
	if(pModel->numOfObjects <= 0)   
		return;   
 
	for(int index = 0; index < pModel->numOfObjects; index++)   
	{        
		t3DObject *pObject = &(pModel->pObject[index]);   

		Vector3 *pNormals       = new Vector3 [pObject->numOfFaces];   
		Vector3 *pTempNormals   = new Vector3 [pObject->numOfFaces];   
		pObject->pNormals        = new Vector3 [pObject->numOfVerts];   
   
		for(int i=0; i < pObject->numOfFaces; i++)   
		{  
			vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];   
			vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];   
			vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];   

			vVector1 = vPoly[0] - vPoly[2];          
			vVector2 = vPoly[2] - vPoly[1];               
			vNormal  = vVector1.crossProduct(vVector2);   
			pTempNormals[i] = vNormal;                     
			vNormal  = vNormal.normalize();              
			pNormals[i] = vNormal;                       
		}   

		Vector3 vSum(0.0,0.0,0.0);   
		Vector3 vZero = vSum;   
		int shared=0;   
   
		for (int i = 0; i < pObject->numOfVerts; i++)            
		{   
			for (int j = 0; j < pObject->numOfFaces; j++) 
			{                                              
				if (pObject->pFaces[j].vertIndex[0] == i ||    
					pObject->pFaces[j].vertIndex[1] == i ||    
					pObject->pFaces[j].vertIndex[2] == i)   
				{      
					vSum = vSum + pTempNormals[j];   
					shared++;                                  
				}   
			}         
			pObject->pNormals[i] = vSum / float(-shared);   

			pObject->pNormals[i] = pObject->pNormals[i].normalize();     
			vSum = vZero;                                  
			shared = 0;                                        
		}   
		delete [] pTempNormals;   
		delete [] pNormals;   
	}   
}   
Пример #3
0
/* -------------------------------------
 * FindH
 * IN
 * func:  Function to be minimized.
 * nRow:  Number of rows (length) of x.
 * N_max: Maximum number of CG iterates.
 * TOL:   Minimum size for gradient of f.
 * OUT
 * x: Local minimum of func.
 * -------------------------------------
 */
double * findHSLM(double (*func)(double*, int), double *x,
                  double** s, double** y,
                  int nRow, int m, int k, int N_max){
  double *q, *r, *alpha, *rho, *Bd, *r_cg, *d, *z, *r_new;
  double beta, beta_cg, alpha_cg, epsilon;
  int i, state, j;
  // Calculate gradient.
  r = q = gradCentralDiff(func, x, nRow);
  // Initialize variables
  alpha = (double*) malloc(nRow * sizeof(double));
  rho   = (double*) malloc(nRow * sizeof(double));
  state = min(k, m);
  // Fill in rho
  for(i = 0; i < state; i++){
    rho[i] = 1 / (dotProd(y[i], s[i], nRow));
  }
  // First Loop
  for(i = (state - 1); i > 0; i--){
    alpha[i] = rho[i] * dotProd(s[i], q, nRow);
    q        = vSum(q, vProd(y[i], -alpha[i], nRow), nRow);
  }
  /*
   * -----------------------------------
   * ########### CG Iteration ##########
   * -----------------------------------
   * Outputs: r
   */
  // Initialize: epsilon, d, r_cg, z
  epsilon = min(.5, sqrt(norm(q, nRow))) * norm(q, nRow);
  d    = vProd(q,  1, nRow);
  r_cg = vProd(q,  1, nRow);
  z    = vProd(q,  0, nRow);
  for(j = 0; j < N_max; j++){
    Bd = hessCentralDiff(func, x, d, nRow);
    // Check if d'Bd <= 0 i.e. d is a descent direction.
    if(dotProd(d, Bd, nRow) <= 0){
      if(j == 0){
        r = d;
        break;
      }else{
        r = z;
        break;
      }
    }
    // alpha_j = rj'rj/d_j'Bd_j
    alpha_cg = dotProd(r_cg, r_cg, nRow) / dotProd(d, Bd, nRow);
    // z_{j+1} = z_j + alpha_j*d_j
    z        = vSum(z, vProd(d, alpha_cg, nRow), nRow);
    // r_{j+1} = r_j + alpha_j*B_kd_j
    r_new = vSum(r_cg, vProd(Bd, alpha_cg, nRow), nRow);
    if(norm(r_new, nRow) < epsilon){
      r = z;
      break;
    }
    // Update beta, d, r_cg.
    beta_cg = dotProd(r_new, r_new, nRow) / dotProd(r_cg, r_cg, nRow);
    d       = vSum(vProd(r_new, -1, nRow),
                   vProd(d, beta_cg, nRow), nRow);
    r_cg    = r_new;
  }
  /* -----------------------------------
   * ######### CG Iteration End ########
   * -----------------------------------
   */

  // Second Loop
  for(i = 0; i < state; i ++){
    beta  = rho[i] * dotProd(y[i], r, nRow);
    r     = vSum(r, vProd(s[i], (alpha[i] - beta), nRow), nRow);
  }
  // Memory release.
  free(alpha);
  free(rho);
  // Return result.
  return r;
}
Пример #4
0
/* -------------------------------------
 * LBFGS
 * IN
 * func:  Function to be minimized.
 * nRow:  Number of rows (length) of x.
 * N_max: Maximum number of CG iterates.
 * TOL:   Minimum size for gradient of f.
 * OUT
 * x: Local minimum of func.
 * -------------------------------------
 */
double * SLM_LBFGS(double (* func)(double*, int),
                   int nRow, int m, double TOL, int N_max, int verbose){
  // Variable declaration.
  double **s, **y;
  double *x, *grad, *p, *x_new, *grad_new;
  double alpha, norm_grad0;
  int i, k, MAX_ITER, exploredDataPoints;
  // Space allocation.
  x = (double *)malloc(nRow * sizeof(double));
  s = (double **)malloc((nRow*m) * sizeof(double));
  y = (double **)malloc((nRow*m) * sizeof(double));
  // Initialize x.
  for(i = 0; i < nRow; i++){
    x[i] = ((double) rand() / INT_MAX) ;
  }
  // Stochastic Mode
  if(stocMode){
    exploredDataPoints = 0;
    //printf("\nRUNNING STOCASTIC MODE\n");
    SAMPLE      = rand() % (int)(MAX_FILE_ROWS * sampProp);
    create_sample(0);
    exploredDataPoints += SAMPLE;
  }

  // Until Convergence or MAX_ITER.
  MAX_ITER = 6e6;
  grad     = gradCentralDiff(func, x, nRow);
  // Update s, y.
  k = 0;
  // Initial norm of gradient.
  norm_grad0 = norm(grad, nRow);
  while(norm(grad, nRow) > TOL*(1 + norm_grad0) && ((run_logistic*exploredDataPoints + ((1 - run_logistic)*k)) < MAX_ITER)){
    if(stocMode){
      printf("\nRUNNING STOCASTIC MODE\n");
      SAMPLE      = rand() % (int)(MAX_FILE_ROWS * sampProp);
      create_sample(k);
      exploredDataPoints += SAMPLE;
    }

    // p = -Hgrad(f)
    if(k > 0){
      p = vProd(findHSLM(func, x, s,
                         y, nRow, m,
                         k, N_max),
                -1, nRow);
    }else{
      p = vProd(grad, -1, nRow);
    }
    // Alpha that statifies Wolfe conditions.
    alpha    = backTrack(func, x, p, nRow, verbose);
    x_new    = vSum(x, vProd(p, alpha, nRow), nRow);
    //imprimeTit("X_NEW");
    //imprimeMatriz(x_new, 1, nRow);
    grad_new = gradCentralDiff(func, x_new, nRow);
    //imprimeTit("GRAD_NEW");
    //imprimeMatriz(grad_new, 1, nRow);
    // Update s, y.
    updateSY(s, y, vProd(p, alpha, nRow),
             vSum(grad_new, vProd(grad, -1, nRow), nRow), m, k);

    // ---------------- PRINT ------------------- //
    if(verbose){
      if(stocMode){
        printf("\n ITER = %d; f(x) = %.10e ; "
               "||x|| = %.10e ; ||grad|| =  %.10e ; "
               "||p|| =  %.10e ; sTy =  %.10e ; "
               "alpha = %.10e; explored data points = %d; precision = %fl ",
               k,
               func(x, nRow),
               norm(x, nRow),
               norm(grad, nRow),
               norm(p, nRow),
               dotProd(s[(int)min(k , (m - 1))],
                       y[(int)min(k , (m - 1))], nRow),
               alpha,
               exploredDataPoints,
               class_precision(x, nRow, 0));

      }else{
      printf("\n ITER = %d; f(x) = %.10e ; "
             "||x|| = %.10e ; ||grad|| =  %.10e ; "
             "||p|| =  %.10e ; sTy =  %.10e ; "
             "alpha = %.10e",
             k,
             func(x, nRow),
             norm(x, nRow),
             norm(grad, nRow),
             norm(p, nRow),
             dotProd(s[(int)min(k , (m - 1))],
                     y[(int)min(k , (m - 1))], nRow),
             alpha);
      }
    }
    // ---------------- PRINT ------------------- //y
    // Update k, x, grad.
    x    = x_new;
    grad = grad_new;
    k    = k + 1;
  }
  free(grad);
  free(s);
  free(y);
  return x;
}
Пример #5
0
int radTApplication::SetUpPolyhedronsFromBaseFacePolygonsTri(double zc, const char* strOrient, TVector2d* arPoints2d, int lenArPoints2d, TVector2d* arTriVertPt, int numTriVertPt, int* arTriVertInd, int numTri, double*** arPtrTrfParInExtrSteps, char** arStrTrfOrderInExtrSteps, int* arNumTrfInExtrSteps, int NumSteps, double avgCur, double* arMagnCompInExtrSteps, char frame, radThg& hgOut)
{
	if((arTriVertPt == 0) || (numTriVertPt <= 0) || (arTriVertInd == 0) || (numTri <= 0)) return 0;
	if((arPtrTrfParInExtrSteps == 0) || (arStrTrfOrderInExtrSteps == 0) || (arNumTrfInExtrSteps == 0) || (NumSteps <= 0)) return 0;

	TVector2d *arTriVertPt1=0, *arTriVertPt2=0;
	int resOK = 0;

	try
	{
		radTGroup* pGroup = new radTGroup();
		if(pGroup == 0) { Send.ErrorMessage("Radia::Error900"); throw 0;}
		radThg hgLoc(pGroup);

		arTriVertPt1 = new TVector2d[numTriVertPt];
		TVector2d *t_arTriVertPt1 = arTriVertPt1, *t_arTriVertPt = arTriVertPt;
		for(int i=0; i<numTriVertPt; i++) *(t_arTriVertPt1++) = *(t_arTriVertPt++);

		arTriVertPt2 = new TVector2d[numTriVertPt];

		//radTPolygon *pBaseFacePgn1 = new radTPolygon(arPoints2d, lenArPoints2d), *pBaseFacePgn2=0;
		//pBaseFacePgn1->CoordZ = 0;

		//radTPolygon genBaseFacePgn1(arPoints2d, lenArPoints2d); //, *pBaseFacePgn2=0;
		//genBaseFacePgn1.CoordZ = 0;
		//radTPolygon genBaseFacePgn2(arPoints2d, lenArPoints2d); //, *pBaseFacePgn2=0;
		//genBaseFacePgn2.CoordZ = 0;

		TVector3d vCenPointRot1(0,0,0);

		radTrans trfInitBaseOrient, trfInitBaseTransl;
		trfInitBaseOrient.SetupRotationToPermutAxes(vCenPointRot1, 'Z', *strOrient);
		//to find appropriate rotation taking into account direction of polygon normal !!!
		//trfInitBaseOrient.SetupRotation(vCenPointRot1, vEZ, vBaseNorm);

		TVector3d vCenPointTransl(0,0,zc);
		vCenPointTransl = trfInitBaseOrient.TrPoint(vCenPointTransl);
		trfInitBaseTransl.SetupTranslation(vCenPointTransl);

		radTrans auxIntermedTrans, auxTotTrans, auxTrans0;
		auxTrans0.SetupIdent();
		if(frame > 0)
		{//Lab frame
			auxTrans0.TrMult(trfInitBaseOrient, 'R');
			auxTrans0.TrMult(trfInitBaseTransl, 'L');
		}

		//TVector3d vNormFace1(0,0,1), vCenPointBaseFace1(pBaseFacePgn1->CentrPoint.x, pBaseFacePgn1->CentrPoint.y, zc);
		TVector3d vNormFace1(0,0,1); //, vCenPointBaseFace1(genBaseFacePgn1.CentrPoint.x, genBaseFacePgn1.CentrPoint.y, zc);
		int NumSteps_mi_1 = NumSteps - 1;

		for(int j=0; j<NumSteps; j++)
		{
			double **arPtrTrfParInCurExtrStep = arPtrTrfParInExtrSteps[j];
			char *arStrTrfOrderInCurExtrStep = arStrTrfOrderInExtrSteps[j];
			int numTrfInCurExtrStep = arNumTrfInExtrSteps[j];
			if((arPtrTrfParInCurExtrStep == 0) || (arStrTrfOrderInCurExtrStep == 0) || (numTrfInCurExtrStep <= 0)) continue;

			//pBaseFacePgn2 = new radTPolygon(*pBaseFacePgn1);
			//radTPolygon genBaseFacePgn2(genBaseFacePgn1);

			TVector2d *t_arTriVertPt1 = arTriVertPt1, *t_arTriVertPt2 = arTriVertPt2;
			for(int i=0; i<numTriVertPt; i++) *(t_arTriVertPt2++) = *(t_arTriVertPt1++);

			auxTotTrans.SetupIdent();

			for(int k=0; k<numTrfInCurExtrStep; k++)
			{
				double *pCurTrfPar = arPtrTrfParInCurExtrStep[k];
				if(pCurTrfPar == 0) continue;

				char cTypeCurTrf = arStrTrfOrderInCurExtrStep[k];
				if((cTypeCurTrf == 'r') || (cTypeCurTrf == 'R'))
				{
					TVector3d vRotCen(*pCurTrfPar, *(pCurTrfPar+1), *(pCurTrfPar+2));
					TVector3d vRotAxis(*(pCurTrfPar+3), *(pCurTrfPar+4), *(pCurTrfPar+5));
					auxIntermedTrans.SetupRotation(vRotCen, vRotAxis, *(pCurTrfPar+6));
					auxTotTrans.TrMult(auxIntermedTrans, 'L');
				}
				else if((cTypeCurTrf == 't') || (cTypeCurTrf == 'T'))
				{
					TVector3d vTransl(*pCurTrfPar, *(pCurTrfPar+1), *(pCurTrfPar+2));
					auxIntermedTrans.SetupTranslation(vTransl);
					auxTotTrans.TrMult(auxIntermedTrans, 'L');
				}
				else if((cTypeCurTrf == 'h') || (cTypeCurTrf == 'H'))
				{
					//any homothety is applied to a face before space transformations
					//to check if this should be improved
					//pBaseFacePgn2->ApplyHomothety(*pCurTrfPar, *(pCurTrfPar+1), *(pCurTrfPar+2)); //ApplyHomothety(double kxH, double kyH, double phi)

					double kxH = *pCurTrfPar, kyH = *(pCurTrfPar+1), phi = *(pCurTrfPar+2);
					
					//genBaseFacePgn2.ApplyHomothety(kxH, kyH, phi); //ApplyHomothety(double kxH, double kyH, double phi)

					//TVector2d &CenPointBase2 = genBaseFacePgn2.CentrPoint;
					TVector2d vSum(0,0);
					for(int jjj=0; jjj<lenArPoints2d; jjj++) vSum += arPoints2d[jjj];
					TVector2d CenPointBase2 = (1./lenArPoints2d)*vSum;

					if((kxH != 0) && (kyH != 0))
					{
						double cosPhi = cos(phi), sinPhi = sin(phi);
						TVector2d vHomLocX(cosPhi, sinPhi), vHomLocY(-sinPhi, cosPhi);
						for(int ip=0; ip<numTriVertPt; ip++)
						{
							TVector2d vRelVertex = arTriVertPt2[ip] - CenPointBase2;
							arTriVertPt2[ip] = CenPointBase2 + ((kxH*(vHomLocX*vRelVertex))*vHomLocX) + ((kyH*(vHomLocY*vRelVertex))*vHomLocY);
						}
					}
				}
			}
			radTrans *pBaseFaceTrf1 = new radTrans(auxTrans0);

			if(frame == 0) auxTrans0.TrMult(auxTotTrans, 'R'); //local frame
			else auxTrans0.TrMult(auxTotTrans, 'L'); //laboratory frame

			radTrans *pBaseFaceTrf2 = new radTrans(auxTrans0); //check for memory leak !!!
			radTHandle<radTrans> hTrf1(pBaseFaceTrf1), hTrf2(pBaseFaceTrf2);

			double *pMagComp = 0;
			if(arMagnCompInExtrSteps != 0) pMagComp = arMagnCompInExtrSteps + j*3;

			TVector2d arTreePt1[3], arTreePt2[3];
			int *t_arTriVertInd = arTriVertInd;
			for(int itr=0; itr<numTri; itr++)
			{
				arTreePt1[0] = arTriVertPt1[*t_arTriVertInd]; arTreePt2[0] = arTriVertPt2[*(t_arTriVertInd++)];
				arTreePt1[1] = arTriVertPt1[*t_arTriVertInd]; arTreePt2[1] = arTriVertPt2[*(t_arTriVertInd++)];
				arTreePt1[2] = arTriVertPt1[*t_arTriVertInd]; arTreePt2[2] = arTriVertPt2[*(t_arTriVertInd++)]; 
				radTPolygon *pBaseFaceTri1 = new radTPolygon(arTreePt1, 3);
				//pBaseFaceTri1->CoordZ = genBaseFacePgn1.CoordZ;
				radTPolygon *pBaseFaceTri2 = new radTPolygon(arTreePt2, 3);
				//pBaseFaceTri2->CoordZ = genBaseFacePgn2.CoordZ;

				//this doesn't take into account direction of normals and eventual intersection of the faces
				radTHandle<radTPolygon> hPgn1(pBaseFaceTri1), hPgn2(pBaseFaceTri2);
				radTHandlePgnAndTrans hPgnTrf1(hPgn1, hTrf1), hPgnTrf2(hPgn2, hTrf2);
				//create polyhedron here from pBaseFacePgn1, pBaseFaceTrf1, pBaseFacePgn2, pBaseFaceTrf2
				radTPolyhedron *pCurStepPlhdr = new radTPolyhedron(hPgnTrf1, hPgnTrf2, avgCur, pMagComp);
				if(pCurStepPlhdr == 0) { Send.ErrorMessage("Radia::Error900"); throw 0;}
				if(pCurStepPlhdr->SomethingIsWrong) { delete pCurStepPlhdr; throw 0;}

				radThg hgCurStepPlhdr(pCurStepPlhdr);
				pGroup->AddElement(AddElementToContainer(hgCurStepPlhdr), hgCurStepPlhdr);
			}

			//if(j < NumSteps_mi_1)
			//{
			//	//pBaseFacePgn1 = new radTPolygon(*pBaseFacePgn2);
			//	genBaseFacePgn1 = genBaseFacePgn2;
			////	//- treat frame (0- local, otherwise "laboratory");
			////	//if(frame == 0) pBaseFaceTrf1 = new radTrans(*pBaseFaceTrf1); //leave base trf always the same if Frame->Loc ??
			////	//else pBaseFaceTrf1 = new radTrans(*pBaseFaceTrf2); //change base trf if Frame->Lab

			////	if(frame == 0) pBaseFaceTrf1 = new radTrans(*pBaseFaceTrf2); //change base trf if Frame->Loc
			////	else pBaseFaceTrf1 = new radTrans(*pBaseFaceTrf1); //leave base trf always the same if Frame->Lab
			//}
		}
		if(frame == 0)
		{
			auxTrans0.SetupIdent();
			auxTrans0.TrMult(trfInitBaseOrient, 'R');
			auxTrans0.TrMult(trfInitBaseTransl, 'L');
			
			double relTol = 1.E-12; //to ensure correct operation on 32-bit OS
			if(!auxTrans0.IsIdent(relTol))
			{
				radTrans* TransPtr = new radTrans(auxTrans0);
				if(TransPtr == 0) { Send.ErrorMessage("Radia::Error900"); return 0;}
				radThg hgTrf(TransPtr);
				((radTg3d*)(hgLoc.rep))->AddTransform(1, hgTrf);
			}
		}

		hgOut = hgLoc;
		resOK = 1;
	}
	catch(...)
	{
		Initialize(); //return 0;
		resOK = 0;
	}
	if(arTriVertPt1 != 0) delete[] arTriVertPt1;
	if(arTriVertPt2 != 0) delete[] arTriVertPt2;
	return resOK;
}
// 计算顶点法线量
void C3DSModel::ComputeNormals(void)
{
	Vector3 v1,v2, vNormal,vPoly[3];

	// 如果没有3ds对象则直接返回
	if (m_3DModel.numOfObjects <= 0)
		return;

	t3DObject *obj;
	int		  *index;

	for(int nOfObj=0; nOfObj<m_3DModel.numOfObjects; nOfObj++)
	{
		obj = &m_3DModel.pObject[nOfObj];
		Vector3 *pNormals		= new Vector3 [obj->numOfFaces];
		Vector3 *pTempNormals	= new Vector3 [obj->numOfFaces];
		obj->pNormals			= new Vector3 [obj->numOfVerts];

		for(int nOfFace=0; nOfFace<obj->numOfFaces; nOfFace++)
		{
			index = obj->pFaces[nOfFace].vertIndex;
			// 三角形的3个顶点
			vPoly[0] = obj->pVerts[index[0]];
			vPoly[1] = obj->pVerts[index[1]];
			vPoly[2] = obj->pVerts[index[2]];
			// 计算这个三角形的法线量
			v1 = vPoly[0]-vPoly[1];
			v2 = vPoly[2]-vPoly[1];
			vNormal  = Cross(v1, v2);

			pTempNormals[nOfFace] = vNormal;					// 保存未单位化的法向量
			vNormal  = Normalize(vNormal);						// 单位化法向量
			pNormals[nOfFace] = vNormal;						// 增加到法向量数组列表
		}
		Vector3 vSum(0.0, 0.0, 0.0);
		Vector3 vZero(0.0, 0.0, 0.0);
		int shared=0;

		for (int nOfVert = 0; nOfVert < obj->numOfVerts; nOfVert++)			// 遍历所有顶点
		{
			for (int nOfFace = 0; nOfFace < obj->numOfFaces; nOfFace++)		// 遍历包含该顶点的面
			{
				if (obj->pFaces[nOfFace].vertIndex[0] == nOfVert || 
					obj->pFaces[nOfFace].vertIndex[1] == nOfVert || 
					obj->pFaces[nOfFace].vertIndex[2] == nOfVert)
				{
					vSum = vSum+pTempNormals[nOfFace];
					shared++;
				}
			}      
			
			obj->pNormals[nOfVert] = vSum/float(-shared);

			obj->pNormals[nOfVert] = Normalize(obj->pNormals[nOfVert]);	

			vSum = vZero;
			shared = 0;
		}
	
		delete [] pTempNormals;
		delete [] pNormals;
	}

}
Пример #7
0
// Get bounds according to different distance metrics
int getBounds(float* S1r, float* S2r, const short& B, const Rset& R, float& lb, float& ub, const string dist) {
  
  // Get |A+|
  float* Apv = new float[B];
  vSub(S1r + B*(R.hi[1]), S1r + B*(R.lo[0]-1), B, &Apv);
  float  Ap = vSum(Apv,B) + EPS; // |A+|
  
  // Get |k+|
  float* Bpv = new float[B];
  vSub(S2r + B*(R.hi[3]), S2r + B*(R.lo[2]-1), B, &Bpv);
  float Bp = vSum(Bpv, B) + EPS; // |B+|
      
  // Get |A-|
  float  Am = EPS; // |A-|
  float* Amv = new float[B];
  if (R.lo[1] >= R.hi[0]) {
    vSub(S1r + B*(R.lo[1]), S1r + B*(R.hi[0]-1), B, &Amv);
    Am += vSum(Amv, B);
  } else {
    memset(Amv, 0, sizeof(float)*B);
  }
  
  // Get |B-|
  float  Bm = EPS;
  float* Bmv = new float[B];
  if (R.lo[3] >= R.hi[2]) {
    vSub(S2r + B*(R.lo[3]), S2r + B*(R.hi[2]-1), B, &Bmv);
    Bm += vSum(Bmv, B);
  } else {
    memset(Bmv, 0, sizeof(float)*B);
  }

  lb = 0.0f; 
  ub = 0.0f;
  short i;
  if (dist.compare("l1")==0) {
    for (i=0; i<B; i++) {
      lb += max(Amv[i]/Ap, Bmv[i]/Bp) - min(Apv[i]/Am, Bpv[i]/Bm);
      ub += max(Apv[i]/Am, Bpv[i]/Bm) - min(Amv[i]/Ap, Bmv[i]/Bp);
    }
  
  } else if (dist.compare("l2")==0) {
    for (i=0; i<B; i++) {
      lb += pow(max(0.0f, max(Amv[i]/Ap, Bmv[i]/Bp) - min(Apv[i]/Am, Bpv[i]/Bm)), 2.0f);
      ub += pow(max(Apv[i]/Am, Bpv[i]/Bm) - min(Amv[i]/Ap, Bmv[i]/Bp), 2.0f);
    }
  } else if (dist.compare("X2")==0) {
    for (i=0; i<B; i++) {
      lb += pow(max(0.0f, max(Amv[i]/Ap, Bmv[i]/Bp) - min(Apv[i]/Am, Bpv[i]/Bm)), 2.0f) \
              / (Apv[i]/Am + Bpv[i]/Bm + EPS);
      ub += pow(max(Apv[i]/Am, Bpv[i]/Bm) - min(Amv[i]/Ap, Bmv[i]/Bp), 2.0f) \
              / (Amv[i]/Ap + Bmv[i]/Bp + EPS);
    }
  } else if (dist.compare("int")==0) {
    for (i=0; i<B; i++) {
      lb -= min(Apv[i]/Am, Bpv[i]/Bm);
      ub -= min(Amv[i]/Ap, Bmv[i]/Bp);
    }
  }
  
  delete[] Apv; 
  delete[] Bpv;
  delete[] Amv;
  delete[] Bmv;
  return 0;
}