コード例 #1
0
ファイル: EditPoly.cpp プロジェクト: Joincheng/lithtech
//determines if this polygon lies entirely within a single plane
bool CEditPoly::IsCoplanar()
{
	//run through all the points, projecting them onto the normal. The
	//value should be relatively the same for all the points
	if(NumVerts() < 4)
	{
		//if we have 3 or less points, we mathmatically have to be coplanar, so just bail to
		//prevent mathmatical errors from causing problems
		return true;
	}

	//the epsilon value that we allow points to stray from the plane
	static const float kfPlaneEpsilon = 0.01f;

	LTVector vNormal = Normal();

	CReal fDist = m_pBrush->m_Points[Index(0)].Dot(Normal());

	for(uint32 nCurrPt = 1; nCurrPt < NumVerts(); nCurrPt++)
	{
		CReal fTestDist = m_pBrush->m_Points[Index(nCurrPt)].Dot(Normal());

		fTestDist -= fDist;

		if((fTestDist < -kfPlaneEpsilon) || (fTestDist > kfPlaneEpsilon))
		{
			return false;
		}
	}

	return true;
}
コード例 #2
0
ファイル: BasePoly.cpp プロジェクト: Joincheng/lithtech
void CBasePoly::GetCenterPoint( CVector &centerPt )
{
	centerPt.Init( 0.0f, 0.0f, 0.0f );
	for(uint32 i=0; i < NumVerts(); i++ )
		centerPt += Pt(i);

	centerPt /= (CReal)NumVerts();
}
コード例 #3
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 Copy all the vertices and triangle of another TIN to this one.
 This is a simple join.  No attempt is made to share vertices or any other integration.
 It is further assumed that the two TINs have compatible coordinate systems.
 */
void vtTin::AppendFrom(const vtTin *pTin)
{
	const size_t verts = pTin->NumVerts();
	const size_t tris = pTin->NumTris();

	// Preallocate (for efficiency)
	m_vert.SetMaxSize(m_vert.GetSize() + verts + 1);
	m_z.reserve(m_vert.GetSize() + verts + 1);
	m_tri.reserve(m_tri.size() + (tris*3) + 1);

	// Remember the starting point for vertex indices
	const int base = NumVerts();

	// Simple, naive copy of vertices and triangles
	DPoint2 p;
	float z;
	for (size_t i = 0; i < verts; i++)
	{
		pTin->GetVert(i, p, z);
		AddVert(p, z);
	}
	for (size_t i = 0; i < tris; i++)
	{
		const int *tri = pTin->GetAtTri(i);
		AddTri(base+tri[0], base+tri[1], base+tri[2]);
	}
	ComputeExtents();
}
コード例 #4
0
int CDispInfo::ApplyTerrainMod_Speculative(
    ITerrainMod *pMod,
    CSpeculativeTerrainModVert *pSpeculativeVerts,
    int nMaxVerts )
{
    int nModified = 0;

    if( nMaxVerts == 0 )
        return 0;

    int nVerts = NumVerts();
    for( int iVert=0; iVert < nVerts; iVert++ )
    {
        if( m_AllowedVerts.Get( iVert ) )
        {
            pSpeculativeVerts[nModified].m_vNew = m_Verts[iVert].m_vPos;
            Vector &vOriginalPos = m_Verts[iVert].m_vOriginalPos;

            if( pMod->ApplyMod( pSpeculativeVerts[nModified].m_vNew, vOriginalPos ) )
            {
                pSpeculativeVerts[nModified].m_vOriginal = vOriginalPos;
                pSpeculativeVerts[nModified].m_vCurrent = m_Verts[iVert].m_vPos;
                ++nModified;


                if( nModified >= nMaxVerts )
                    break;
            }
        }
    }

    return nModified;
}
コード例 #5
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 * Write the TIN to a TIN (.itf) file (VTP-defined format).
 */
bool vtTin::Write(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	char *wkt;
	OGRErr err = m_proj.exportToWkt(&wkt);
	if (err != OGRERR_NONE)
	{
		fclose(fp);
		return false;
	}
	int proj_len = strlen(wkt);
	int data_start = 5 + 4 + 4 + 4 + + 4 + proj_len + 32 + 4 + 4;

	int i;
	int verts = NumVerts();
	int tris = NumTris();

	fwrite("tin02", 5, 1, fp);	// version 2
	fwrite(&verts, 4, 1, fp);
	fwrite(&tris, 4, 1, fp);
	fwrite(&data_start, 4, 1, fp);
	fwrite(&proj_len, 4, 1, fp);
	fwrite(wkt, proj_len, 1, fp);
	OGRFree(wkt);

	// version 2 of the format has extents: left, top, right, bottom, min z, max h
	fwrite(&m_EarthExtents.left, sizeof(double), 4, fp);
	fwrite(&m_fMinHeight, sizeof(float), 1, fp);
	fwrite(&m_fMaxHeight, sizeof(float), 1, fp);

	// room for future extention: you can add fields here, as long as you
	// increase the data_start offset above accordingly

	// count progress
	int count = 0, total = verts + tris;

	// write verts
	for (i = 0; i < verts; i++)
	{
		fwrite(&m_vert[i].x, 8, 2, fp);	// 2 doubles
		fwrite(&m_z[i], 4, 1, fp);		// 1 float

		if (progress_callback && (++count % 100) == 0)
			progress_callback(count * 99 / total);
	}
	// write tris
	for (i = 0; i < tris; i++)
	{
		fwrite(&m_tri[i*3], 4, 3, fp);	// 3 ints

		if (progress_callback && (++count % 100) == 0)
			progress_callback(count * 99 / total);
	}

	fclose(fp);
	return true;
}
コード例 #6
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 * Because the TIN triangles refer to their vertices by index, it's possible
 * to have some vertices which are not referenced.  Find and remove those
 * vertices.
 * \return The number of unused vertices removed.
 */
int vtTin::RemoveUnusedVertices()
{
	size_t verts = NumVerts();
	std::vector<bool> used;
	used.resize(verts, false);

	// Flag all the vertices that are used
	size_t tris = NumTris();
	for (size_t i = 0; i < tris; i++)
	{
		used[m_tri[i*3]] = true;
		used[m_tri[i*3+1]] = true;
		used[m_tri[i*3+2]] = true;
	}

	// Remove all the vertices that weren't flagged
	int count = 0;
	for (size_t i = 0; i < verts;)
	{
		if (!used[i])
		{
			// Remove vertex
			RemVert(i);
			used.erase(used.begin()+i);
			verts--;
			count++;
		}
		else
			i++;
	}
	return count;
}
コード例 #7
0
ファイル: EditPoly.cpp プロジェクト: Joincheng/lithtech
//determines the surface area of the polygon
CReal CEditPoly::GetSurfaceArea()
{
	//accumulate the area occupied by each triangle
	CReal fArea = 0.0f;

	uint32 nNumPts = NumVerts();

	//safety first...
	if(nNumPts < 3)
		return 0.0f;

	//fan out from vertex 0 to all other verts
	LTVector vFanPt = m_pBrush->m_Points[Index(0)];

	for(uint32 nCurrPt = 1; nCurrPt < nNumPts - 1; nCurrPt++)
	{
		//get the two edges
		LTVector vEdge1 = m_pBrush->m_Points[Index(nCurrPt)] - vFanPt;
		LTVector vEdge2 = m_pBrush->m_Points[Index(nCurrPt + 1)] - vFanPt;

		//the cross product gives us the area of the rect, so we want to add
		//half of that
		fArea += vEdge1.Cross(vEdge2).Mag() / 2;
	}

	return fArea;
}
コード例 #8
0
ファイル: BasePoly.cpp プロジェクト: Joincheng/lithtech
bool CBasePoly::IsValid()
{
	for( uint32 i=0; i < NumVerts(); i++ )
		if( m_Indices[i] >= m_pBrush->m_Points )
			return false;

	return true;
}
コード例 #9
0
ファイル: BasePoly.cpp プロジェクト: Joincheng/lithtech
bool CBasePoly::PointInPoly( const LTVector &point )
{
	CReal		area;

	for(uint32 i=0; i < NumVerts(); i++ )
	{
		area = g_TriArea2( Normal(), Pt(i), NextPt(i), point );
		if( area > 0 )
			return false;
	}

	return true;
}
コード例 #10
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 * Write the TIN to a Wavefront OBJ file.  Note that we write X and Y as
 * geographic coordinates, but OBJ only supports single-precision floating
 * point values, so it may lose some precision.
 */
bool vtTin::WriteOBJ(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	int i, count = 0;
	const int verts = NumVerts();
	const int tris = NumTris();
	const int total = verts + tris;

	fprintf(fp, "####\n");
	fprintf(fp, "#\n");
	fprintf(fp, "# OBJ File Generated by VTBuilder\n");
	fprintf(fp, "#\n");
	fprintf(fp, "####\n");
	fprintf(fp, "# Object %s\n", fname);
	fprintf(fp, "#\n");
	fprintf(fp, "# Vertices: %d\n", verts);
	fprintf(fp, "# Faces: %d\n", tris);
	fprintf(fp, "#\n");
	fprintf(fp, "####\n");

	// write verts
	for (i = 0; i < verts; i++)
	{
		fprintf(fp, "v %lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	fprintf(fp, "# %d vertices, 0 vertices normals\n", verts);
	fprintf(fp, "\n");

	// write tris
	for (i = 0; i < tris; i++)
	{
		// Here is     triangle definition (zero based)  A B C ...
		// the indices in the file are 1-based, so add 1
		fprintf(fp, "f %d %d %d\n", m_tri[i*3+0]+1, m_tri[i*3+1]+1, m_tri[i*3+2]+1);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	fprintf(fp, "# %d faces, 0 coords texture\n", tris);
	fprintf(fp, "\n");
	fprintf(fp, "# End of File\n");
	fclose(fp);
	return true;
}
コード例 #11
0
ファイル: chull.c プロジェクト: sleitner/cart
void DumpVerts2IFrIT(const char *filename, tVertex verts)
{
  int j, ntemp, ntot;
  float w;
  tVertex v;
  FILE *F;

  if(verts == NULL) return;

  ntot = NumVerts(verts);

  F = fopen(filename,"w");
  if(F == NULL)
    {
      cart_error("Unable to open file %s for writing.\n",filename);
    }
  
  ntemp = sizeof(int);     fwrite(&ntemp,sizeof(int),1,F);
  ntemp = ntot;            fwrite(&ntemp,sizeof(int),1,F);
  ntemp = sizeof(int);     fwrite(&ntemp,sizeof(int),1,F);

  ntemp = 6*sizeof(float); fwrite(&ntemp,sizeof(int),1,F);
  w = 0.0;                 fwrite(&w,sizeof(float),1,F);
  w = 0.0;                 fwrite(&w,sizeof(float),1,F);
  w = 0.0;                 fwrite(&w,sizeof(float),1,F);
  w = num_grid;            fwrite(&w,sizeof(float),1,F);
  w = num_grid;            fwrite(&w,sizeof(float),1,F);
  w = num_grid;            fwrite(&w,sizeof(float),1,F);
  ntemp = 6*sizeof(float); fwrite(&ntemp,sizeof(int),1,F);

  for(j=0; j<3; j++)
    {
      ntemp = ntot*sizeof(float); 
      fwrite(&ntemp,sizeof(int),1,F);
      v = verts;
      do 
	{
	  w = v->v[j] + 0.5;
	  fwrite(&w,sizeof(float),1,F);
	  v = v->next;
	} 
      while(v != verts);
      fwrite(&ntemp,sizeof(int),1,F);
    }

  fclose(F);
}
コード例 #12
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 * Write the TIN to a Stanford Polygon File Format (PLY),
 * http://en.wikipedia.org/wiki/PLY_(file_format)
 */
bool vtTin::WritePLY(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	int i, count = 0;
	int verts = NumVerts();
	int tris = NumTris();
	int total = verts + tris;

	fprintf(fp, "ply\n");
	fprintf(fp, "format ascii 1.0\n");
	fprintf(fp, "comment VTBuilder generated\n");
	fprintf(fp, "element vertex %d\n", verts);
	fprintf(fp, "property float x\n");
	fprintf(fp, "property float y\n");
	fprintf(fp, "property float z\n");
	fprintf(fp, "element face %d\n", tris);
	fprintf(fp, "property list uchar int vertex_indices\n");
	fprintf(fp, "end_header\n");

	// write verts
	for (i = 0; i < verts; i++)
	{
		fprintf(fp, "%lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	// write tris
	for (i = 0; i < tris; i++)
	{
		// Here is  triangle definition (zero based)  A B C ...
		fprintf(fp, "3 %d %d %d\n", m_tri[i*3+0], m_tri[i*3+1], m_tri[i*3+2]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	fclose(fp);
	return true;
}
コード例 #13
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
bool vtTin::ConvertProjection(const vtProjection &proj_new)
{
	// Create conversion object
	ScopedOCTransform trans(CreateCoordTransform(&m_proj, &proj_new));
	if (!trans)
		return false;		// inconvertible projections

	int size = NumVerts();
	for (int i = 0; i < size; i++)
	{
		DPoint2 &p = m_vert[i];
		trans->Transform(1, &p.x, &p.y);
	}

	// adopt new projection
	m_proj = proj_new;

	return true;
}
コード例 #14
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 * Write the TIN to the GMS format.  Historically GMS stood for 'Groundwater
 * Modeling System' from the EMS-I company, now called Aquaveo.
 */
bool vtTin::WriteGMS(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	// first line is file identifier
	fprintf(fp, "TIN\n");
	fprintf(fp, "BEGT\n");
	fprintf(fp, "ID 1\n");			// Indices start at 1
	//fprintf(fp, "TNAM tin\n");	// "name" of the TIN; optional
	//fprintf(fp, "MAT 1\n");		// "TIN material ID"; optional

	int count = 0;
	const int verts = NumVerts();
	const int tris = NumTris();
	const int total = verts + tris;

	// write verts
	fprintf(fp, "VERT %d\n", verts);
	for (int i = 0; i < verts; i++)
	{
		fprintf(fp, "%lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	// write tris
	fprintf(fp, "TRI %d\n", tris);
	for (int i = 0; i < tris; i++)
	{
		// the indices in the file are 1-based, so add 1
		fprintf(fp, "%d %d %d\n", m_tri[i*3+0]+1, m_tri[i*3+1]+1, m_tri[i*3+2]+1);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	fprintf(fp, "ENDT\n");
	fclose(fp);
	return true;
}
コード例 #15
0
ファイル: EditPoly.cpp プロジェクト: Joincheng/lithtech
//determines if this polygon is concave or not
bool CEditPoly::IsConcave()
{
	uint32 nNumPts = NumVerts();

	if(nNumPts <= 3)
	{
		return false;
	}

	//get the normal for this polygon
	LTVector vNormal = Normal();

	//now go through every edge
	uint32 nPrevPt = nNumPts - 1;
	for(uint32 nCurrPt = 0; nCurrPt < nNumPts; nPrevPt = nCurrPt, nCurrPt++)
	{
		//build the edge normal
		LTVector vEdge = m_pBrush->m_Points[Index(nCurrPt)] - m_pBrush->m_Points[Index(nPrevPt)];

		//find the normal
		LTVector vEdgeNorm = vNormal.Cross(vEdge);
		vEdgeNorm.Norm();

		//now run through all the other points
		for(uint32 nTestPt = 0; nTestPt < nNumPts; nTestPt++)
		{
			//ignore the points on the edge
			if((nTestPt == nCurrPt) || (nTestPt == nPrevPt))
				continue;

			//see if it is on the correct side
			if(vEdgeNorm.Dot(m_pBrush->m_Points[Index(nTestPt)] - m_pBrush->m_Points[Index(nCurrPt)]) > 0.001f)
			{
				return true;
			}
		}
	}

	return false;

}
コード例 #16
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
bool vtTin::ComputeExtents()
{
	const int size = NumVerts();
	if (size == 0)
		return false;

	m_EarthExtents.SetInsideOut();
	m_fMinHeight = 1E9;
	m_fMaxHeight = -1E9;

	for (int j = 0; j < size; j++)
	{
		m_EarthExtents.GrowToContainPoint(m_vert[j]);

		float z = m_z[j];
		if (z > m_fMaxHeight)
			m_fMaxHeight = z;
		if (z < m_fMinHeight)
			m_fMinHeight = z;
	}
	return true;
}
コード例 #17
0
ファイル: BasePoly.cpp プロジェクト: Joincheng/lithtech
bool CBasePoly::IsConvex()
{
	CVector			v1, v2, v3;
	CVector			vec1, vec2;
	uint32			i;
	CDReal			dot, sign=0.0f;

	
	
	for( i=0; i < NumVerts(); i++ )
	{
		v1 = Pt(i);
		v2 = NextPt(i);
		v3 = NextPt(m_Indices.NextI(i) );
	
		vec1 = v2 - v1;
		vec2 = v3 - v2;

		vec1.Norm();
		vec2.Norm();

		dot = Normal().Dot( vec1.Cross(vec2) );
		if( (sign == 0.0f) && (dot != 0.0f) )
		{
			sign = dot;
		}
		else
		{
			if( sign < 0.0f && dot > 0.0f )
				return false;
			else if( sign > 0.0f && dot < 0.0f )
				return false;
		}
	}

	return true;
}
コード例 #18
0
ファイル: EditPoly.cpp プロジェクト: Joincheng/lithtech
BOOL CEditPoly::IntersectRay( CEditRay &ray, CReal &t, BOOL bBackface )
{
	ASSERT(NumVerts() > 1);

	CReal dot1, dot2, div;
	LTVector testPt;

	// Trivial reject.
	if( (Normal().Dot(ray.m_Pos) - Dist()) >= 0.0f )
	{
		// It's pointing away from (or is perpendicular to) the polygon.
		if( Normal().Dot(ray.m_Dir) >= -0.001f )
			return FALSE;
	}
	else
	{
		// Backfacing.
		if( !bBackface )
		{
			return FALSE;
		}
		else
		{
			// It's pointing away from (or is perpendicular to) the polygon.
			if( Normal().Dot(ray.m_Dir) <= 0.001f )
				return FALSE;
		}
	}

	dot1 = Normal().Dot( ray.m_Pos ) - Dist();
	dot2 = Normal().Dot( ray.m_Pos + ray.m_Dir ) - Dist();

	div = dot2 - dot1;
	if(fabs(div) < 0.00001f)
		t = 0.0f;
	else
		t = -dot1 / div;
	
	ASSERT( t >= 0 );

	testPt = ray.m_Pos + (ray.m_Dir * t);
	
	// See if the intersection point lies inside the poly.
	uint32 nFanPt  = NumVerts() - 1;
	uint32 nPrevPt = 0;
	uint32 nCurrPt = 1;

	//the count of the number of triangles it is in
	uint32 nInCount = 0;

	for(; nCurrPt < NumVerts(); nPrevPt = nCurrPt, nCurrPt++)
	{
		//see if it the point is within the triangle defined by 
		//the edges fanpt->prev, fanpt->curr
		if( (g_TriArea2( Normal(), Pt(nFanPt),  Pt(nPrevPt), testPt ) > 0) ||
			(g_TriArea2( Normal(), Pt(nPrevPt), Pt(nCurrPt), testPt ) > 0) ||
			(g_TriArea2( Normal(), Pt(nCurrPt), Pt(nFanPt),  testPt ) > 0))
			continue;

		//we are in this tri
		nInCount++;
	}

	return (nInCount % 2) ? TRUE : FALSE;
}
コード例 #19
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 * Write the TIN to a AutoCAD DXF file using 3DFACE entities.
 */
bool vtTin::WriteDXF(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	// Header
	fprintf(fp, "  0\nSECTION\n");
	fprintf(fp, "  2\nHEADER\n  9\n$ACADVER\n  1\nAC1006\n");
	fprintf(fp, "  9\n$EXTMIN\n");
	fprintf(fp, " 10\n%lf\n", m_EarthExtents.left);
	fprintf(fp, " 20\n%lf\n", m_EarthExtents.bottom);
	fprintf(fp, "  9\n$EXTMAX\n");
	fprintf(fp, " 10\n%lf\n", m_EarthExtents.right);
	fprintf(fp, " 20\n%lf\n", m_EarthExtents.top);
	fprintf(fp, "  0\nENDSEC\n");

	// Tables section
	fprintf(fp, "  0\nSECTION\n");
	fprintf(fp, "  2\nTABLES\n");

	// ------------------------------------
	// Table of Layers
	fprintf(fp, "  0\nTABLE\n");
	fprintf(fp, "  2\nLAYER\n");
	fprintf(fp, " 70\n1\n");	// max number of layers which follow

	// A layer
	fprintf(fp, "  0\nLAYER\n");
	fprintf(fp, "  2\nPEN1\n");	// layer name
	fprintf(fp, " 70\n0\n");	// layer flags
	fprintf(fp, " 62\n3\n");	// color number 3 = green
	fprintf(fp, "  6\nCONTINUOUS\n");	// linetype name

	// end tables layer
	fprintf(fp, "  0\nENDTAB\n");

	// ------------------------------------
	// end tables section
	fprintf(fp, "  0\nENDSEC\n");

	// Entities
	fprintf(fp, "  0\nSECTION\n");
	fprintf(fp, "  2\nENTITIES\n");

	// write tris
	int i, count = 0;
	int verts = NumVerts();
	int tris = NumTris();
	int total = verts + tris;
	const char *layer = "PEN1";
	for (i = 0; i < tris; i++)
	{
		const int v0 = m_tri[i*3+0];
		const int v1 = m_tri[i*3+1];
		const int v2 = m_tri[i*3+2];

		fprintf(fp, "  0\n3DFACE\n");
		fprintf(fp, "  8\n%s\n", layer);
		fprintf(fp, " 62\n     3\n");	// color number
		fprintf(fp, " 10\n%lf\n", m_vert[v0].x);
		fprintf(fp, " 20\n%lf\n", m_vert[v0].y);
		fprintf(fp, " 30\n%f\n", m_z[v0]);
		fprintf(fp, " 11\n%lf\n", m_vert[v1].x);
		fprintf(fp, " 21\n%lf\n", m_vert[v1].y);
		fprintf(fp, " 31\n%f\n", m_z[v1]);
		fprintf(fp, " 12\n%lf\n", m_vert[v2].x);
		fprintf(fp, " 22\n%lf\n", m_vert[v2].y);
		fprintf(fp, " 32\n%f\n", m_z[v2]);
		// DXF wants the last point duplicated to make 4 points.
		fprintf(fp, " 13\n%lf\n", m_vert[v2].x);
		fprintf(fp, " 23\n%lf\n", m_vert[v2].y);
		fprintf(fp, " 33\n%f\n", m_z[v2]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	fprintf(fp, "  0\nENDSEC\n");
	fprintf(fp, "  0\nEOF\n");
	fclose(fp);
	return true;
}
コード例 #20
0
ファイル: chull.c プロジェクト: sleitner/cart
void chMakeHull(float tolnum, float tolvol, int numits, int loud)
{
  int i, j, n, it;
  tVertex fverts, v, v0, vmin;
  tEdge fedges;
  tFace ffaces;
  int *pts, npts, nout;
  float w, w0, wmin;

  if(tolnum<0.0 || tolnum>=1.0)
    {
      cart_error("<tolnum> parameter in chMakeSubHull must be non-negative and strictly less than 1.");
    }

  if(tolvol<=0.0 || tolvol>=1.0)
    {
      cart_error("<tolvol> parameter in chMakeSubHull must be positive and strictly less than 1.");
    }

  if(numits < 1)
    {
      cart_error("<numits> parameter in chMakeSubHull must be positive.");
    }

  /*
  //  Number of points we are allowed to miss.
  */
  npts = NumVerts(vertices);
  nout = tolnum*npts;
  if(nout < 1)
    {
      /*
      //  Tolerance is too small
      */
      chMakeFullHull();
      return;
    }

  if(loud > 1) DumpVerts2IFrIT("tmp1.bin",vertices);

  /*
  //  Save the original points.
  */
  pts = (int *)malloc(npts*sizeof(int)*3);
  if(pts == NULL)
    {
      cart_error("Unable to allocate %d bytes of memory in chMakeSubHull.",npts*sizeof(int)*3);
    }

  i = 0;
  v = vertices;
  do 
    {
      for(j=0; j<3; j++) pts[3*i+j] = v->v[j];
      i++;
      v = v->next;
    } 
  while(v != vertices);

  /*
  //  Make the full hull and save it.
  */
  if(loud) cart_debug("Creating the full hull...");

  chMakeFullHull();
  fverts = vertices;
  fedges = edges;
  ffaces = faces;

  if(loud > 1) DumpVerts2IFrIT("tmp2.bin",vertices);

  /*
  //  Loop while the stopping criterion is not met.
  */
  for(it=0; it<numits; it++)
    {
      /*
      //  For each vertex of the full hull remove it, redo the hull, and 
      //  check its volume; keep the hull that reduces the volume most.
      */
      w0 = chHullVolume();
      if(loud) cart_debug("Hull volume: %g %d",w0,NumVerts(vertices));

      wmin = w0;
      vmin = NULL;
      v0 = fverts;
      do 
	{

	  MakeOneSubHull(v0,fverts,fedges,ffaces);
	  w = chHullVolume();

	  if(w < wmin)
	    {
	      if(loud) cart_debug("Found sub-hull with volume: %g",w);
	      wmin = w;
	      vmin = v0;
	    }

	  /*
	  //  Remove that hull.
	  */
	  chReset();

	  v0 = v0->next;
	} 
      while(v0 != fverts);

      if(0)
	{
	  /*
	  //  Redo the best hull
	  */
	  MakeOneSubHull(vmin,fverts,fedges,ffaces);
	  n = 0;
	}
      else
	{
	  /*
	  //  Redo the full hull, but without one point
	  */
	  for(i=0; i<npts; i++)
	    {
	      if(pts[3*i+0]==vmin->v[0] && pts[3*i+1]==vmin->v[1] && pts[3*i+2]==vmin->v[2]) break;
	    }
	  for(; i<npts-1; i++)
	    {
	      for(j=0; j<3; j++) pts[3*i+j] = pts[3*(i+1)+j];
	    }
	  npts--;

	  chAddPoints(npts,pts);
  
	  chMakeFullHull();
	  wmin = chHullVolume();
	  n = 1;
	}

      if(loud) cart_debug("New hull volume: %g %d",wmin,NumVerts(vertices));

      /*
      //  Count the points outside.
      */
      for(i=0; i<npts; i++) 
	{
	  if(chIsPointInside(pts+3*i) == 0) n++;
	}

      if(loud) cart_debug("Missing points: %d (allowed %d), volume reduction %f",n,nout,wmin/w0);  

      /*
      //  Is reduction worth the effort?
      //  Do we miss too many points?
      */
      if(wmin>(1-tolvol)*w0 || n>nout) break;

      if(loud) cart_debug("chMakeSubHull: squeezing the hull...");

      while(fverts != NULL) DELETE(fverts,fverts);
      while(fedges != NULL) DELETE(fedges,fedges);
      while(ffaces != NULL) DELETE(ffaces,ffaces);

      fverts = vertices;
      fedges = edges;
      ffaces = faces;

      nout -= n;
    }

  /*
  //  Restore data structures
  */
  vertices = fverts;
  edges = fedges;
  faces = ffaces;

  free(pts);

  if(loud > 1) DumpVerts2IFrIT("tmp3.bin",vertices);
}
コード例 #21
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 * Combine all vertices which are at the same location.  By removing these
 * redundant vertices, the mesh will consume less space in memory and on disk.
 */
void vtTin::MergeSharedVerts(bool progress_callback(int))
{
	uint verts = NumVerts();

	uint i, j;
	int bin;

	DRECT rect = m_EarthExtents;
	double width = rect.Width();

	// make it slightly larger avoid edge condition
	rect.left -= 0.000001;
	width += 0.000002;

	m_bReplace = new int[verts];
	m_vertbin = new Bin[BINS];
	m_tribin = new Bin[BINS];

	// sort the vertices into bins
	for (i = 0; i < verts; i++)
	{
		// flag all vertices initially not to remove
		m_bReplace[i] = -1;

		// find the correct bin, and add the index of this vertex to it
		bin = (int) (BINS * (m_vert[i].x - rect.left) / width);
		m_vertbin[bin].push_back(i);
	}
	uint trisize = m_tri.size();
	for (i = 0; i < trisize; i++)
	{
		// find the correct bin, and add the index of this index to it
		bin = (int) (BINS * (m_vert[m_tri[i]].x - rect.left) / width);
		m_tribin[bin].push_back(i);
	}

	// compare within each bin, and between each adjacent bin,
	// looking for matching vertices to flag for removal
	for (bin = 0; bin < BINS; bin++)
	{
		if (progress_callback != NULL)
			progress_callback(bin * 100 / BINS);

		_CompareBins(bin, bin);
		if (bin < BINS-1)
			_CompareBins(bin, bin+1);
	}
	// now update each triangle index to point to the merge result
	for (bin = 0; bin < BINS; bin++)
	{
		if (progress_callback != NULL)
			progress_callback(bin * 100 / BINS);

		_UpdateIndicesInInBin(bin);
	}

	// now compact the vertex bins into a single array

	// make a copy to copy from
	DLine2 *vertcopy = new DLine2(m_vert);
	float *zcopy = new float[m_z.size()];
	for (i = 0; i < m_z.size(); i++)
		zcopy[i] = m_z[i];

	int inew = 0;	// index into brand new array (actually re-using old)

	for (bin = 0; bin < BINS; bin++)
	{
		if (progress_callback != NULL)
			progress_callback(bin * 100 / BINS);

		uint binverts = m_vertbin[bin].size();
		for (i = 0; i < binverts; i++)
		{
			int v_old = m_vertbin[bin].at(i);
			if (m_bReplace[v_old] != -1)
				continue;

			int v_new = inew;

			// copy old to new
			m_vert[v_new] = vertcopy->GetAt(v_old);
			m_z[v_new] = zcopy[v_old];

			uint bintris = m_tribin[bin].size();
			for (j = 0; j < bintris; j++)
			{
				int trindx = m_tribin[bin].at(j);
				if (m_tri[trindx] == v_old)
					m_tri[trindx] = v_new;
			}
			inew++;
		}
	}

	// our original array containers now hold the compacted result
	int newsize = inew;
	m_vert.SetSize(newsize);
	m_z.resize(newsize);

	// free up all the stuff we allocated
	delete [] m_bReplace;
	delete [] m_vertbin;
	delete [] m_tribin;
	delete vertcopy;
	delete [] zcopy;
}
コード例 #22
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 * Write the TIN to a VRML (.wrl) file as an IndexedFaceSet.  Note that we
 * write X and Y as geographic coordinates, but VRML only supports
 * single-precision floating point values, so it may lose some precision.
 */
bool vtTin::WriteWRL(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	fprintf(fp, "#VRML V2.0 utf8\n");
	fprintf(fp, "\n");
	fprintf(fp, "WorldInfo\n");
	fprintf(fp, "  {\n");
	fprintf(fp, "  info\n");
	fprintf(fp, "    [\n");
	fprintf(fp, "    \"Generated by VTBuilder\"\n");
	fprintf(fp, "    ]\n");
	fprintf(fp, "  title \"TIN VRML Model\"\n");
	fprintf(fp, "  }\n");
	fprintf(fp, "\n");
	fprintf(fp, "# TIN---------\n");
	fprintf(fp, "Transform\n");
	fprintf(fp, "  {\n");
	fprintf(fp, "  children\n");
	fprintf(fp, "    [\n");
	fprintf(fp, "    Shape\n");
	fprintf(fp, "      {\n");
	fprintf(fp, "      appearance Appearance\n");
	fprintf(fp, "	{\n");
	fprintf(fp, "	material Material\n");
	fprintf(fp, "	  {\n");
	fprintf(fp, "	  }\n");
	fprintf(fp, "	texture ImageTexture\n");
	fprintf(fp, "	  {\n");
	fprintf(fp, "	  url\n");
	fprintf(fp, "	    [\n");
	fprintf(fp, "	    \"OrtoImage.jpg\"\n");
	fprintf(fp, "	    ]\n");
	fprintf(fp, "	  }\n");
	fprintf(fp, "	}\n");
	fprintf(fp, "      geometry      IndexedFaceSet {\n");
	fprintf(fp, "              ccw FALSE\n");
	fprintf(fp, "              solid FALSE\n");
	fprintf(fp, "              creaseAngle 1.396263\n");
	fprintf(fp, "coord DEF Kxzy Coordinate {\n");
	fprintf(fp, "                                     point [\n");

	int i, count = 0;
	const int verts = NumVerts();
	const int tris = NumTris();
	const int total = verts + tris;

	// write verts
	//	fprintf(fp, "VERT %d\n", verts);
	for (i = 0; i < verts; i++)
	{
		fprintf(fp, "%lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	fprintf(fp, "	    ]\n");
	fprintf(fp, "	  }\n");
	fprintf(fp, "      	coordIndex \n");
	fprintf(fp, "                  [\n");

	// write tris
	for (i = 0; i < tris; i++)
	{
		// Here is  triangle definition (zero based)  A B C -1...
		// the indices in the file are 1-based, so add 1
		fprintf(fp, "%d %d %d -1\n", m_tri[i*3+0], m_tri[i*3+1], m_tri[i*3+2]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	fprintf(fp, "				  ]\n");
	fprintf(fp, "				}\n");
	fprintf(fp, "			      }\n");
	fprintf(fp, "			    ]\n");
	fprintf(fp, "			  }\n");
	fclose(fp);
	return true;
}
コード例 #23
0
ファイル: vtTin.cpp プロジェクト: kamalsirsa/vtp
/**
 * Write the TIN to a Collada (.dae) file.  Note that we write X and Y as
 * geographic coordinates, but DAE only supports single-precision floating
 * point values, so it may lose some precision.
 */
bool vtTin::WriteDAE(const char *fname, bool progress_callback(int)) const
{
	FILE *fp = vtFileOpen(fname, "wb");
	if (!fp)
		return false;

	// first line is file identifier
	fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n");
	fprintf(fp, "<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">\n");
	fprintf(fp, "  <asset>\n");
	fprintf(fp, "    <contributor>\n");
	fprintf(fp, "      <authoring_tool>VTBuilder</authoring_tool>\n");
	fprintf(fp, "    </contributor>\n");
//	fprintf(fp, "    <created>2012-01-09T14:26:45Z</created>\n");
//	fprintf(fp, "    <modified>2012-01-09T14:26:45Z</modified>\n");
//	fprintf(fp, "    <unit meter=\"0.02539999969303608\" name=\"inch\" />\n");
	fprintf(fp, "    <up_axis>Z_UP</up_axis>\n");
	fprintf(fp, "  </asset>\n");
	fprintf(fp, "  <library_visual_scenes>\n");
	fprintf(fp, "    <visual_scene id=\"ID1\">\n");
	fprintf(fp, "      <node name=\"VTBuilder\">\n");
	fprintf(fp, "        <node id=\"ID2\" name=\"Earth_Terrain\">\n");
	fprintf(fp, "          <matrix>1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>\n");
	fprintf(fp, "          <instance_geometry url=\"#ID3\">\n");
	fprintf(fp, "            <bind_material>\n");
	fprintf(fp, "              <technique_common>\n");
	fprintf(fp, "                <instance_material symbol=\"Material2\" target=\"#ID4\">\n");
	fprintf(fp, "                  <bind_vertex_input semantic=\"UVSET0\" input_semantic=\"TEXCOORD\" input_set=\"0\" />\n");
	fprintf(fp, "                </instance_material>\n");
	fprintf(fp, "              </technique_common>\n");
	fprintf(fp, "            </bind_material>\n");
	fprintf(fp, "          </instance_geometry>\n");
	fprintf(fp, "        </node>\n");
	fprintf(fp, "      </node>\n");
	fprintf(fp, "    </visual_scene>\n");
	fprintf(fp, "  </library_visual_scenes>\n");
	fprintf(fp, "  <library_geometries>\n");
	fprintf(fp, "    <geometry id=\"ID3\">\n");
	fprintf(fp, "      <mesh>\n");
	fprintf(fp, "        <source id=\"ID6\">\n");

	int count = 0;
	const int verts = NumVerts();
	const int tris = NumTris();
	const int total = verts + tris;

	// Here are:   Count   and   Coordinates X Y Z...
	fprintf(fp, "          <float_array id=\"ID10\" count=\"%d\">\n",verts);

	// write verts
	for (int i = 0; i < verts; i++)
	{
		fprintf(fp, "%lf %lf %f\n", m_vert[i].x, m_vert[i].y, m_z[i]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}
	fprintf(fp, "          </float_array>\n");

	fprintf(fp, "          <technique_common>\n");
	fprintf(fp, "            <accessor count=\"222\" source=\"#ID10\" stride=\"3\">\n");
	fprintf(fp, "              <param name=\"X\" type=\"float\" />\n");
	fprintf(fp, "              <param name=\"Y\" type=\"float\" />\n");
	fprintf(fp, "              <param name=\"Z\" type=\"float\" />\n");
	fprintf(fp, "            </accessor>\n");
	fprintf(fp, "          </technique_common>\n");
	fprintf(fp, "        </source>\n");
	fprintf(fp, "\n");
	fprintf(fp, "        <source id=\"ID8\">\n");
	fprintf(fp, "          <Name_array id=\"ID12\" count=\"0\" />\n");
	fprintf(fp, "          <technique_common>\n");
	fprintf(fp, "            <accessor count=\"0\" source=\"#ID12\" stride=\"1\">\n");
	fprintf(fp, "              <param name=\"skp_material\" type=\"Name\" />\n");
	fprintf(fp, "            </accessor>\n");
	fprintf(fp, "          </technique_common>\n");
	fprintf(fp, "        </source>\n");
	fprintf(fp, "        <vertices id=\"ID9\">\n");
	fprintf(fp, "          <input semantic=\"POSITION\" source=\"#ID6\" />\n");
	fprintf(fp, "          <input semantic=\"NORMAL\" source=\"#ID7\" />\n");
	fprintf(fp, "        </vertices>\n");

	// Here is triangles Count
	fprintf(fp, "        <triangles count=\"%d\" material=\"Material2\">\n", tris);
	fprintf(fp, "          <input offset=\"0\" semantic=\"VERTEX\" source=\"#ID9\" />\n");
	fprintf(fp, "          <p>\n");

	// write tris
	//	fprintf(fp, "TRI %d\n", tris);
	for (int i = 0; i < tris; i++)
	{
		// Here is     triangle definition (zero based)  A B C ...
		// the indices in the file are 1-based, so add 1
		fprintf(fp, "%d %d %d\n", m_tri[i*3+0], m_tri[i*3+1], m_tri[i*3+2]);

		if (progress_callback && (++count % 200) == 0)
			progress_callback(count * 99 / total);
	}

	fprintf(fp, "</p>\n");

	fprintf(fp, "        </triangles>\n");
	fprintf(fp, "      </mesh>\n");
	fprintf(fp, "    </geometry>\n");
	fprintf(fp, "  </library_geometries>\n");
	fprintf(fp, "  <library_materials>\n");
	fprintf(fp, "    <material id=\"ID4\" name=\"Google_Earth_Snapshot\">\n");
	fprintf(fp, "      <instance_effect url=\"#ID5\" />\n");
	fprintf(fp, "    </material>\n");
	fprintf(fp, "  </library_materials>\n");
	fprintf(fp, "  <library_effects>\n");
	fprintf(fp, "    <effect id=\"ID5\">\n");
	fprintf(fp, "      <profile_COMMON>\n");
	fprintf(fp, "        <technique sid=\"COMMON\">\n");
	fprintf(fp, "          <lambert>\n");
	fprintf(fp, "            <diffuse>\n");

	// Here is the color definition of the surface
	fprintf(fp, "              <color>0.3411764705882353 0.392156862745098 0.3411764705882353 1</color>\n");

	fprintf(fp, "            </diffuse>\n");
	fprintf(fp, "          </lambert>\n");
	fprintf(fp, "        </technique>\n");
	fprintf(fp, "      </profile_COMMON>\n");
	fprintf(fp, "    </effect>\n");
	fprintf(fp, "  </library_effects>\n");
	fprintf(fp, "  <scene>\n");
	fprintf(fp, "    <instance_visual_scene url=\"#ID1\" />\n");
	fprintf(fp, "  </scene>\n");
	fprintf(fp, "</COLLADA>\n");

	fclose(fp);
	return true;
}