Example #1
0
VOID
SwapSplayLinks (
    IN PRTL_SPLAY_LINKS Link1,
    IN PRTL_SPLAY_LINKS Link2
    )

{
    PRTL_SPLAY_LINKS *Parent1ChildPtr;
    PRTL_SPLAY_LINKS *Parent2ChildPtr;

    /*
      We have the following situation


             Parent1            Parent2
                |                  |
                |                  |
              Link1              Link2
               / \                / \
              /   \              /   \
            LC1   RC1          LC2   RC2

      where one of the links can possibly be the root and one of the links
      can possibly be a direct child of the other.  Without loss of
      generality we'll make link2 be the possible and root and link1 be
      the possible child.
    */

    if ((RtlIsRoot(Link1)) || (RtlParent(Link2) == Link1)) {
        SwapPointers(Link1, Link2);
    }

    //
    //  The four cases we need to handle are
    //
    //  1. Link1 is not a child of link2 and link2 is not the root
    //  2. Link1 is not a child of link2 and link2 is     the root
    //  3. Link1 is     a child of link2 and link2 is not the root
    //  4. Link1 is     a child of link2 and link2 is     the root
    //
    //
    //  Each case will be handled separately
    //

    if (RtlParent(Link1) != Link2) {

        if (!RtlIsRoot(Link2)) {

            //
            //  Case 1 the initial steps are:
            //
            //  1. get both parent child pointers
            //  2. swap the parent child pointers
            //  3. swap the parent pointers
            //

            Parent1ChildPtr = ParentsChildPointerAddress(Link1);
            Parent2ChildPtr = ParentsChildPointerAddress(Link2);

            SwapPointers(*Parent1ChildPtr, *Parent2ChildPtr);

            SwapPointers(Link1->Parent, Link2->Parent);

        } else {

            //
            //  Case 2 the initial steps are:
            //
            //  1. Set link1's parent child pointer to link2
            //  2. Set parent pointer of link2 to link1's parent
            //  3. Set parent pointer of link1 to be itself
            //

            Parent1ChildPtr = ParentsChildPointerAddress(Link1);
            *Parent1ChildPtr = Link2;

            Link2->Parent = Link1->Parent;

            Link1->Parent = Link1;

        }

        //
        //  Case 1 and 2 common steps are:
        //
        //  1. swap the child pointers
        //

        SwapPointers(Link1->LeftChild, Link2->LeftChild);
        SwapPointers(Link1->RightChild, Link2->RightChild);

    } else { // RtlParent(Link1) == Link2

        if (!RtlIsRoot(Link2)) {

            //
            //  Case 3 the initial steps are:
            //
            //  1. Set Link2's parent child pointer to link1
            //  2. Set Link1's parent pointer to parent of link2
            //

            Parent2ChildPtr = ParentsChildPointerAddress(Link2);
            *Parent2ChildPtr = Link1;

            Link1->Parent = Link2->Parent;

        } else {

            //
            //  Case 4 the initial steps are:
            //
            //  1. Set Link1's parent pointer to be link1
            //

            Link1->Parent = Link1;

        }

        //
        //  Case 3 and 4 common steps are:
        //
        //  1. Swap the child pointers
        //  2. if link1 was a left child (i.e., RtlLeftChild(Link1) == Link1)
        //     then set left child of link1 to link2
        //     else set right child of link1 to link2
        //

        SwapPointers(Link1->LeftChild, Link2->LeftChild);
        SwapPointers(Link1->RightChild, Link2->RightChild);

        if (Link1->LeftChild == Link1) {
            Link1->LeftChild = Link2;
        } else {
            Link1->RightChild = Link2;
        }

    }

    //
    //  Case 1, 2, 3, 4 common (and final) steps are:
    //
    //  1. Fix the parent pointers of the left and right children
    //

    if (Link1->LeftChild  != NULL) {Link1->LeftChild->Parent  = Link1;}
    if (Link1->RightChild != NULL) {Link1->RightChild->Parent = Link1;}
    if (Link2->LeftChild  != NULL) {Link2->LeftChild->Parent  = Link2;}
    if (Link2->RightChild != NULL) {Link2->RightChild->Parent = Link2;}
}
/* 
 * "propagation" makes the forward of the acoustic wave
 * vm: velocity model data
 * Xi, Yi, Zi: velocity model dimensions n3, n2, n1
 * dx, dy, dz: spatial resolution
 * tr: source/seismic traces data
 * Ti: number of samples per data source/seismic trace
 * dt: temporal resolution
 * trc: coordinates of source/seismic traces
 * Ntr: number of source/seismic traces
 * wri: write the current wavefield in a binary file at each wri timesteps. wri=0 means do not write
 * wffn: wavefield record file name
 * bw: border width
 */
void propagation(float *vel, unsigned int localXi, unsigned int localYi, int Yi, int Zi, float dx, float dy, float dz, float *tr, unsigned short Ti, float dt, int *trc, int Ntr, int wri, char *wffn, int bw, int my_rank, unsigned int shotNumber, unsigned int iMax) {
  int xbi, ybi, zbi, ti, c, ntr; // auxiliary variables
  unsigned long localXbi, localYbi, Ybi, Zbi, indb, ivb;
  float fdx, fdy, fdz; // auxiliary variables
  u_t u; // wavefield
  char fileName [40];
  FILE *wff2; // Wavefield record file
  //float cx[ncx] = {-2.847222222, 1.6, -0.2, 0.025396825, -0.001785714}; // coefficients of the finite difference in x
  //float cy[ncy] = {-2.847222222, 1.6, -0.2, 0.025396825, -0.001785714}; // coefficients of the finite difference in y
  //float cz[ncz] = {-2.847222222, 1.6, -0.2, 0.025396825, -0.001785714}; // coefficients of the finite difference in z

  float cx[ncx] = {-205.0/72.0, 1.6, -0.2, 8.0/315.0, -1.0/560.0}; // coefficients of the finite difference in x
  float cy[ncy] = {-205.0/72.0, 1.6, -0.2, 8.0/315.0, -1.0/560.0}; // coefficients of the finite difference in y
  float cz[ncz] = {-205.0/72.0, 1.6, -0.2, 8.0/315.0, -1.0/560.0}; // coefficients of the finite difference in z

  FILE *wff = fopen(wffn,"wb"); // Wafield record file
  
  // Check the opening file
  if (!wff) {
    printf("Failed opening file.\n");
    return;
  }
  
  // Auxiliary variables initialization
  localXbi = localXi + 2*bw;
  localYbi = localYi + 2*bw;
  Ybi = Yi + 2*bw;
  Zbi = Zi + 2*bw;
  
  // Memory allocation
  u.pn = (float *) calloc(localXbi*localYbi*Zbi,sizeof(float));
  if (u.pn == NULL) {
    printf("Memory allocation failed: u.pn.\n");
    return;      
  }
  u.cur = (float *) calloc(localXbi*localYbi*Zbi,sizeof(float));
  if (u.cur == NULL) {
    printf("Memory allocation failed: u.cur.\n");
    return;      
  }

  printf("u Size: %lu\n", localXbi*localYbi*Zbi);
  printf("Rank: %d\tComputando tiro = %u\n", my_rank, shotNumber);
  printf("Ti = %d\n", Ti);
  fflush(stdout);
  
  //float velMax2 = 0;
  // Propagation
  for (ti = 0; ti < Ti; ti++) {
    for (xbi = ncx-1; xbi < localXbi-ncx+1; xbi++) {
      for (ybi = ncy-1; ybi < localYbi-ncy+1; ybi++) {
        for (zbi = ncz-1; zbi < Zbi-ncz+1; zbi++) {
          indb = xbi*localYbi*Zbi + ybi*Zbi + zbi;

          fdx = cx[0]*u.cur[indb];
          fdy = cy[0]*u.cur[indb];
          fdz = cz[0]*u.cur[indb];

          for (c = 1; c < ncx; c++) {
            fdx += cx[c]*(u.cur[indb + c*localYbi*Zbi] + u.cur[indb - c*localYbi*Zbi]);
          }
          for (c = 1; c < ncy; c++) {
            fdy += cy[c]*(u.cur[indb + c*Zbi] + u.cur[indb - c*Zbi]);
          }
          for (c = 1; c < ncz; c++) {
            fdz += cz[c]*(u.cur[indb + c] + u.cur[indb - c]);
          }

          fdx *= 1/(dx*dx);
          fdy *= 1/(dy*dy);
          fdz *= 1/(dz*dz);
          
	  ivb = xbi*Ybi*Zbi + ybi*Zbi + zbi;
	  /*if(ti == 0 && velMax2 < vel[ivb])
	  {
		velMax2 = vel[ivb];
		iMax = ivb;
	  }*/

          u.pn[indb] = 2*u.cur[indb] - u.pn[indb] + vel[ivb]*(fdx + fdy + fdz);	 
	  //if(u.pn[indb] != 0 && ti < 3)
	  //{
	//	printf("Ti: %d\tu.pn[%lu] = %.3f\n", ti, indb, u.pn[indb]);
	  //}
          if(zbi == bw && xbi == 57 && ybi == 63)
	  {
    		u.pn[indb] = 100;
	  }
	  //if(indb == (trc[0]+bw)*localYbi*Zbi + (trc[1]+bw)*Zbi + trc[2]+bw)
	  /*if(indb == iMax)
	  {
	  	//printf("fdx: %.3f\tfdy: %.3f\tfdz: %.3f\tvel[%lu] = %.3f\n", fdx, fdy, fdz, ivb, vel[ivb]);
	  }*/
        }
      }
    }
    //printf("Rank: %d\tTi: %d\tti = %d\n", my_rank, Ti, ti);


    // Source/seismic traces
    // Corrigir trc, ivb
    // Verificar indices
    /*for (ntr = 0; ntr < Ntr; ntr++) {
      indb = (trc[ntr*3]+bw)*localYbi*Zbi + (trc[ntr*3+1]+bw)*Zbi + trc[ntr*3+2]+bw;
      ivb = (trc[ntr*3]+bw)*Ybi*Zbi + (trc[ntr*3+1]+bw)*Zbi + (trc[ntr*3+2]+bw);
      //printf("Antes  Sub Rank: %d\tTi = %d\tti = %d\tu.pn[%lu] = %.3f\n", my_rank, Ti, ti, indb, u.pn[indb]);
      u.pn[indb] -= vel[ivb]*tr[ntr*Ti + ti];
      printf("Rank: %d\tTi = %d\tti = %d\tu.pn[%lu] = %.3f\n", my_rank, Ti, ti, indb, u.pn[indb]);
    }*/
    
    
    //printf("Rank: %d\tti = %d\tu.pn[%lu] = %.3f\n", my_rank, ti, indb, u.pn[indb]);

    SwapPointers(&u.pn, &u.cur);

    // Write wavefield in a file
    if (wri != 0) {
      if ((ti+1)%wri == 0) {
        sprintf(fileName, "./pDireta/direta_%d_%d.bin", shotNumber,ti);	
	wff2 = fopen(fileName,"wb"); 
	
        for (xbi = bw; xbi < localXbi-bw; xbi++) {
          for (ybi = bw; ybi < localYbi-bw; ybi++) {
	    //printf("u atual: %.3f\n", u.cur[xbi*localYbi*Zbi + ybi*Zbi + bw]); 
            if (fwrite(&u.cur[xbi*localYbi*Zbi + ybi*Zbi + bw], sizeof(float), Zi, wff2) != Zi) {
              printf("Failed writing wavefield file\n");
              return;
            }
          }
        }
	fclose(wff2);
      }
    }
  }
  
  // Free memory
  free(u.pn);
  free(u.cur);
  fclose(wff);
}
Example #3
0
VOID
TriSwapSplayLinks (
    IN PTRI_SPLAY_LINKS Link1,
    IN PTRI_SPLAY_LINKS Link2
    )

{
    PULONG Parent1ChildRef;
    PULONG Parent2ChildRef;

    PULONG Child1ParSibRef;
    PULONG Child2ParSibRef;

    //
    //  We have the following situation
    //
    //
    //         Parent1            Parent2
    //            |                  |
    //            |                  |
    //          Link1              Link2
    //           / \                / \
    //          /   \              /   \
    //        LC1   RC1          LC2   RC2
    //
    //  where one of the links can possibly be the root and one of the links
    //  can possibly be a direct child of the other, or can be connected
    //  via their sibling pointers.  Without loss of generality we'll make
    //  link2 be the possible and root and link1 be the possible child, or
    //  link2 have a parsib pointer to link1
    //

    if ((TriIsRoot(Link1)) ||
        (TriParent(Link2) == Link1) ||
        (MakeIntoPointer(Link1->Refs.ParSib) == Link2)) {

        SwapPointers(Link1, Link2);

    }

    //
    //  The cases we need to handle are
    //
    //  1. Link1 is not a child of link2, link2 is not the root, and they are not siblings
    //  2. Link1 is not a child of link2, link2 is not the root, and they are     siblings
    //
    //  3. Link1 is not a child of link2, link2 is     the root
    //
    //  4. Link1 is an only child of link2, and link2 is not the root
    //  5. Link1 is an only child of link2, and link2 is     the root
    //
    //  6. Link1 is a left child of link2 (has a sibling), and link2 is not the root
    //  7. Link1 is a left child of link2 (has a sibling), and link2 is     the root
    //
    //  8. Link1 is a right child of link2 (has a sibling), and link2 is not the root
    //  9. Link1 is a right child of link2 (has a sibling), and link2 is     the root
    //
    //  Each case will be handled separately
    //

    if (TriParent(Link1) != Link2) {

        if (!TriIsRoot(Link2)) {

            if (MakeIntoPointer(Link2->Refs.ParSib) != Link1) {

                //
                //  Case 1 - Link1 is not a child of link2,
                //           Link2 is not the root, and
                //           they are not siblings
                //

                Parent1ChildRef = TriAddressOfBackRefViaParent(Link1);
                Child1ParSibRef = TriAddressOfBackRefViaChild(Link1);
                Parent2ChildRef = TriAddressOfBackRefViaParent(Link2);
                Child2ParSibRef = TriAddressOfBackRefViaChild(Link2);
                SwapUlongs(Link1->Refs.Child, Link2->Refs.Child);
                SwapUlongs(Link1->Refs.ParSib, Link2->Refs.ParSib);
                SetRefViaPointer(Parent1ChildRef, Link2);
                SetRefViaPointer(Parent2ChildRef, Link1);
                SetRefViaPointer(Child1ParSibRef, Link2);
                SetRefViaPointer(Child2ParSibRef, Link1);

            } else {

                //
                //  Case 2 - Link1 is not a child of link2,
                //           Link2 is not the root, and
                //           they are siblings
                //

                Child1ParSibRef = TriAddressOfBackRefViaChild(Link1);
                Parent2ChildRef = TriAddressOfBackRefViaParent(Link2);
                Child2ParSibRef = TriAddressOfBackRefViaChild(Link2);
                SwapUlongs(Link1->Refs.Child, Link2->Refs.Child);
                SetRefViaPointer(Child1ParSibRef, Link2);
                SetRefViaPointer(Child2ParSibRef, Link1);
                *Parent2ChildRef = MakeIntoLeftChildRef(Link1);
                Link2->Refs.ParSib = Link1->Refs.ParSib;
                Link1->Refs.ParSib = MakeIntoSiblingRef(Link2);

            }

        } else {

            //
            //  Case 3 - Link1 is not a child of link2, and
            //           Link2 is the root
            //

            Parent1ChildRef = TriAddressOfBackRefViaParent(Link1);
            Child1ParSibRef = TriAddressOfBackRefViaChild(Link1);
            Child2ParSibRef = TriAddressOfBackRefViaChild(Link2);
            SwapUlongs(Link1->Refs.Child, Link2->Refs.Child);
            Link2->Refs.ParSib = Link1->Refs.ParSib;
            Link1->Refs.ParSib = MakeIntoParentRef(Link1);
            SetRefViaPointer(Child1ParSibRef, Link2);
            SetRefViaPointer(Child2ParSibRef, Link1);
            SetRefViaPointer(Parent1ChildRef, Link2);

        }

    } else { // TriParent(Link1) == Link2

        if (MakeIntoPointer(Link2->Refs.Child) == Link1 &&
            MakeIntoPointer(Link1->Refs.ParSib) == Link2) { // Link1 is an only child

            if (!TriIsRoot(Link2)) {

                //
                //  Case 4 - Link1 is an only child of link2, and
                //           Link2 is not the root
                //

                Child1ParSibRef = TriAddressOfBackRefViaChild(Link1);
                Parent2ChildRef = TriAddressOfBackRefViaParent(Link2);
                SetRefViaPointer(Child1ParSibRef, Link2);
                SetRefViaPointer(Parent2ChildRef, Link1);
                Link1->Refs.ParSib = Link2->Refs.ParSib;
                Link2->Refs.ParSib = MakeIntoParentRef(Link1);
                SwapRefsButKeepFlags(Link1->Refs.Child, Link2->Refs.Child);
                SetRefViaPointer(&Link1->Refs.Child, Link2);

            } else {

                //
                //  Case 5 - Link1 is an only child of link2, and
                //           Link2 is the root
                //

                Child1ParSibRef = TriAddressOfBackRefViaChild(Link1);
                SetRefViaPointer(Child1ParSibRef, Link2);
                Link1->Refs.ParSib = MakeIntoParentRef(Link1);
                Link2->Refs.ParSib = MakeIntoParentRef(Link1);
                SwapRefsButKeepFlags(Link1->Refs.Child, Link2->Refs.Child);
                SetRefViaPointer(&Link1->Refs.Child, Link2);

            }

        } else if (TriIsLeftChild(Link1)) {  // and link1 has a sibling

            if (!TriIsRoot(Link2)) {

                //
                //  Case 6 - Link1 is a left child of link2 (has a sibling), and
                //           Link2 is not the root
                //

                Child1ParSibRef = TriAddressOfBackRefViaChild(Link1);
                Parent2ChildRef = TriAddressOfBackRefViaParent(Link2);
                Child2ParSibRef = TriAddressOfBackRefViaChild(Link2);
                SetRefViaPointer(Child1ParSibRef, Link2);
                SetRefViaPointer(Parent2ChildRef, Link1);
                SetRefViaPointer(Child2ParSibRef, Link1);
                Link2->Refs.Child = Link1->Refs.Child;
                Link1->Refs.Child = MakeIntoLeftChildRef(Link2);
                SwapUlongs(Link1->Refs.ParSib, Link2->Refs.ParSib);

            } else {

                //
                //  Case 7 - Link1 is a left child of link2 (has a sibling), and
                //           Link2 is the root
                //

                Child1ParSibRef = TriAddressOfBackRefViaChild(Link1);
                Child2ParSibRef = TriAddressOfBackRefViaChild(Link2);
                SetRefViaPointer(Child1ParSibRef, Link2);
                SetRefViaPointer(Child2ParSibRef, Link1);
                Link2->Refs.Child = Link1->Refs.Child;
                Link1->Refs.Child = MakeIntoLeftChildRef(Link2);
                Link2->Refs.ParSib = Link1->Refs.ParSib;
                Link1->Refs.ParSib = MakeIntoParentRef(Link1);

            }

        } else { // TriIsRightChild(Link1) and Link1 has a sibling

            if (!TriIsRoot(Link2)) {

                //
                //  Case 8 - Link1 is a right child of link2 (has a sibling), and
                //           Link2 is not the root
                //

                Parent1ChildRef = TriAddressOfBackRefViaParent(Link1);
                Child1ParSibRef = TriAddressOfBackRefViaChild(Link1);
                Parent2ChildRef = TriAddressOfBackRefViaParent(Link2);
                SetRefViaPointer(Parent1ChildRef, Link2);
                SetRefViaPointer(Child1ParSibRef, Link2);
                SetRefViaPointer(Parent2ChildRef, Link1);
                SwapUlongs(Link1->Refs.Child, Link2->Refs.Child);
                Link1->Refs.ParSib = Link2->Refs.ParSib;
                Link2->Refs.ParSib = MakeIntoParentRef(Link1);

            } else {

                //
                //  Case 9 - Link1 is a right child of link2 (has a sibling), and
                //           Link2 is the root
                //

                Parent1ChildRef = TriAddressOfBackRefViaParent(Link1);
                Child1ParSibRef = TriAddressOfBackRefViaChild(Link1);
                SetRefViaPointer(Parent1ChildRef, Link2);
                SetRefViaPointer(Child1ParSibRef, Link2);
                SwapUlongs(Link1->Refs.Child, Link2->Refs.Child);
                Link1->Refs.ParSib = MakeIntoParentRef(Link1);
                Link1->Refs.ParSib = MakeIntoParentRef(Link1);

            }

        }

    }

}
void MeshParameterization::GenerateTriangleTexelData()
{
#if ENABLE_DEBUG_DEGENERATES
	
	map< float, blah > s_DegenerateList;
#endif
	//Generate texel data per triangle
	const float uIncrement = 1.f/(float)m_TexSize;
	const float vIncrement = 1.f/(float)m_TexSize;
	const float uHalfIncrement = uIncrement*.5f;
	const float vHalfIncrement =  vIncrement*.5f;
	ParameterizationVertex * p0;
	ParameterizationVertex * p1;
	ParameterizationVertex * p2;
	//0 is smallest y value
	//1 is smallest x value that's not 0
	TriangleTextureMapping toAdd;
	Vec3 barycentric;
	float u;
	float uMax;
	for( int i = 0; i < (int)m_Faces->size(); i++ )
	{
		TriangleFace &tri = (*m_Faces)[ i ];
		bool DangerTriangle = false;
		//get verts
		p0 = &(*m_CollapsedMesh)[ tri.index[ 0 ] ];
		p1 = &(*m_CollapsedMesh)[ tri.index[ 1 ] ];
		p2 = &(*m_CollapsedMesh)[ tri.index[ 2 ] ];
		
		NormalizeUV( p1->generatedU );
		NormalizeUV( p1->generatedV );
		NormalizeUV( p2->generatedU );
		NormalizeUV( p2->generatedV );
		NormalizeUV( p0->generatedU );
		NormalizeUV( p0->generatedV );
		if( p0->generatedV > p1->generatedV )
		{
			SwapPointers( &p0, &p1 ); 
		}
		if( p0->generatedV > p2->generatedV )
		{ 
			SwapPointers( &p0, &p2 );
		}
		if( p1->generatedU > p2->generatedU )
		{
			SwapPointers( &p1, &p2 ); 
		}			
		//find slopes
		float slope1, slope2, slope3, slope4;
		bool undefinedSlope[4];
		undefinedSlope[0] = false;
		undefinedSlope[1] = false;
		undefinedSlope[2] = false;
		undefinedSlope[3] = false;
		if( fabs( p0->generatedV - p1->generatedV ) <= EPSILON_ZERO )
		{ 
			undefinedSlope[0] = true; 
		}
		if( fabs( p0->generatedV - p2->generatedV ) <= EPSILON_ZERO )
		{ 
			undefinedSlope[1] = true;
		}
		if( fabs( p1->generatedV - p2->generatedV ) <= EPSILON_ZERO )
		{
			undefinedSlope[2] = true; 
		}
		if( fabs( p2->generatedV - p1->generatedV ) <= EPSILON_ZERO )
		{ 
			undefinedSlope[3] = true;
		}
		slope1 = ( p0->generatedU - p1->generatedU )/(p0->generatedV - p1->generatedV );
		slope2 = ( p0->generatedU - p2->generatedU )/(p0->generatedV - p2->generatedV );
		slope3 = ( p1->generatedU - p2->generatedU )/(p1->generatedV - p2->generatedV );
		slope4 = ( p2->generatedU - p1->generatedU )/(p2->generatedV - p1->generatedV );
		float maxV = ( p1->generatedV > p2->generatedV ) ? p1->generatedV : p2->generatedV;
		float maxU = ( p0->generatedU > p2->generatedU ) ? p0->generatedU : p2->generatedU;
		maxU += uIncrement;
		maxV += vHalfIncrement;
		for( float v = p0->generatedV - vHalfIncrement; v <= maxV ; v += vIncrement )
		{
			if( p1->generatedV >= v &&
				p2->generatedV >= v )
			{
				//find endpoints of scanline				
				u = undefinedSlope[0] ?  p1->generatedU : p1->generatedU + slope1*( v - p1->generatedV ) - uHalfIncrement;
				uMax = undefinedSlope[1] ? p2->generatedU : p2->generatedU + slope2*( v - p2->generatedV ) + uHalfIncrement;
			}
			else if( p2->generatedV <= v )
			{
				//find endpoints of scanline
				u = undefinedSlope[0] ? p1->generatedU : p1->generatedU + slope1*( v - p1->generatedV )- uHalfIncrement;
				uMax = undefinedSlope[3] ? p2->generatedU : p1->generatedU + slope4*( v - p1->generatedV ) + uHalfIncrement;
			}
			else // p1->v is smaller than v, we're need a new edge
			{
				//find endpoints of scanline
				u =  undefinedSlope[2] ? p1->generatedU : p2->generatedU + slope3*( v - p2->generatedV ) - uHalfIncrement;
				uMax =  undefinedSlope[1] ? p2->generatedU : p2->generatedU + slope2*( v - p2->generatedV ) + uHalfIncrement;
			}
			if( u > uMax ){ float temp = u; u = uMax; uMax = temp; }
			uMax = min( uMax, maxU );
			float umin = min( p1->generatedU, p0->generatedU - uIncrement);
			u = max( u, umin);
			for( ; u <= uMax; u+= uIncrement )
			{
				//we have u and v, get barycentric: 				
				//check if slope will be undefined
				float qX, qY;
				float slopeBC, b2, b1, slope;
				float slopeDenom = u - p0->generatedU;
				float slopeDenom2 = p1->generatedU - p2->generatedU;
				if( slopeDenom == 0 &&
					slopeDenom2 != 0)
				{
                    //vertical line, we know x coordinate
					slopeBC = ( p1->generatedV - p2->generatedV )/( p1->generatedU - p2->generatedU );
					b2 = p1->generatedV - slopeBC*p1->generatedU;
					//solve for y with known x coordinate
					qX = p0->generatedU;
					qY = slopeBC*qX + b2;
				}else if( slopeDenom2 != 0 &&
					slopeDenom != 0 )
				{
					slope = ( v - p0->generatedV )/slopeDenom;
					//find other slope, will never be undefined
					slopeBC = ( p1->generatedV - p2->generatedV )/( p1->generatedU - p2->generatedU );
					//now solve for intersect
					b1 = v - slope*u;
					b2 = p1->generatedV - slopeBC*p1->generatedU;
					qX = ( b1 - b2 )/(slopeBC - slope);
					qY = slope*qX + b1;
					//now find length for bary
				}else if( slopeDenom2 == 0 && slopeDenom != 0 )
				{
					slope = ( v - p0->generatedV )/slopeDenom;
					//now solve for intersect
					b1 = v - slope*u;
					qX = p2->generatedU;
					qY = slope*qX + b1;
					//now find length for bary
				}else //both equal 0
				{
					//this should never happen!
					OutputDebugString("Slopes of two triangle sides are both zero!!!\n");
					qX = p2->generatedU;
					qY = p2->generatedV;
				}
				barycentric.z = Vec2Length( p1->generatedU - qX, p1->generatedV - qY );
				barycentric.y = Vec2Length( p2->generatedU - qX, p2->generatedV - qY );
				//now find t to balance these out at q on p
				float ratio =  Vec2Length( qX - u, qY - v ) 
								/Vec2Length( u - p0->generatedU, v - p0->generatedV);
                barycentric.x = ( barycentric.y + barycentric.z )*ratio;

				float normalize = barycentric.x + barycentric.y + barycentric.z;
				if( normalize != 0 )
				{
					barycentric.x /= normalize;
					barycentric.y /= normalize;
					barycentric.z /= normalize;

					toAdd.localSpaceCoord = p0->originalPosition*barycentric.x + 
											p1->originalPosition*barycentric.y + 
											p2->originalPosition*barycentric.z;		
					
					if( toAdd.localSpaceCoord.x != toAdd.localSpaceCoord.x )
					{
						DangerTriangle = true;
						//OutputDebugString( "DANGER WILL ROBINSON\n");
					}
					toAdd.localNormal = p0->normal*barycentric.x + 
										p1->normal*barycentric.y + 
										p2->normal*barycentric.z;
					
					toAdd.u = (int)( u*(float)m_TexSize );
					toAdd.v = (int)( v*(float)m_TexSize );
					if( toAdd.localSpaceCoord.x == toAdd.localSpaceCoord.x &&
						toAdd.u >= 0 && toAdd.u < m_TexSize &&
						toAdd.v >= 0 && toAdd.v < m_TexSize )
					{
						tri.m_Pixels.push_back( toAdd );
					}
				}
									
			}
			static int numcont = 0;
			numcont++;
			if( DangerTriangle &&
				numcont < 200 )
			{
				ADDLINEPARAMS LineParam;
				static CHashString h(_T("none"));
				LineParam.name = &h;
				LineParam.blue = 0;
				LineParam.green = 0;
				LineParam.red = 255;
				LineParam.start = p0->originalPosition;
				LineParam.end = p1->originalPosition;
				//static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID();
				//EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam );
				LineParam.start = p0->originalPosition;
				LineParam.end = p2->originalPosition;
				//EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam );
				LineParam.start = p2->originalPosition;
				LineParam.end = p1->originalPosition;
				//EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam );
			}
		}
		//test code
#if ENABLE_DEBUG_DEGENERATES
		Vec3 edge1 = Vec3( p0->generatedU, p0->generatedV, 0 ) - Vec3( p1->generatedU, p1->generatedV, 0 );
		Vec3 edge2 = Vec3( p0->generatedU, p0->generatedV, 0 ) - Vec3( p2->generatedU, p2->generatedV, 0 );
		float lengthA = edge1.Length();
		float lengthB = (Vec3( p1->generatedU, p1->generatedV, 0 ) - Vec3( p2->generatedU, p2->generatedV, 0 )).Length();
		float lengthC = edge2.Length();
		float halfPerimeter = (lengthA + lengthB + lengthC)*.500f;
		float area = halfPerimeter*( halfPerimeter - lengthA )*(halfPerimeter - lengthB )*(halfPerimeter - lengthC);
		area = sqrt( area );
		float numPixels = (float)tri.m_Pixels.size();
		edge1.Normalize();
		edge2.Normalize();
		float flatTriangle = edge2.Dot( edge1 );
		//if( fabs( flatTriangle ) < .7f)
		{
			area *= (float)(m_TexSize*m_TexSize);
			float areaRatio = numPixels/area;
			if( areaRatio < .8f ) //half the uv pixels aren't generate?!#!
			{
				blah ref;
				ref.area = area;
				ref.pixels = (int)numPixels;
				ref.index = i;
				s_DegenerateList.insert( pair< float, blah >( numPixels, ref ) );
			}
		}
#endif
		if( tri.m_Pixels.size() < 2)
		{
			//something wrong here
			//OutputDebugString("Degenerate Triangle\n");
			//OutputVector( p0->originalPosition, "p0" );
			//OutputVector( p1->originalPosition, "p1" );
			//OutputVector( p2->originalPosition, "p2" );
			//int a = 0;
		}
	}	
#if ENABLE_DEBUG_DEGENERATES
	static char buf[1024];
	for( map< float, blah >::iterator iter = s_DegenerateList.begin();
		iter != s_DegenerateList.end();
		++iter )
	{
		blah &ref = iter->second;
		TriangleFace &tri = (*m_Faces)[ ref.index  ];
		//get verts
		p0 = &(*m_CollapsedMesh)[ tri.index[ 0 ] ];
		p1 = &(*m_CollapsedMesh)[ tri.index[ 1 ] ];
		p2 = &(*m_CollapsedMesh)[ tri.index[ 2 ] ];		
		//sprintf( buf, "Degenerate Triangle with area: %f, pixels: %d, index: %d \n", ref.area, ref.pixels, ref.index );
		//OutputDebugString( buf );
		//OutputVector( p0->originalPosition, "p0" );
		//OutputVector( p1->originalPosition, "p1" );
		//OutputVector( p2->originalPosition, "p2" );
		ADDLINEPARAMS LineParam;
		static CHashString h(_T("none"));
		LineParam.name = &h;
		LineParam.blue = 0;
		LineParam.green = 0;
		LineParam.red = 255;
		LineParam.start = p0->originalPosition;
		LineParam.end = p1->originalPosition;
		static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID();
		EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam );
		LineParam.start = p0->originalPosition;
		LineParam.end = p2->originalPosition;
		static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID();
		EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam );
		LineParam.start = p2->originalPosition;
		LineParam.end = p1->originalPosition;
		static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID();
		EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam );
	}
#endif
}