Пример #1
0
/**
 * Remove all the triangles of this TIN which intersect a given line segment.
 *
 * \param ep1, ep2 The endpoints of the line segment.
 * \return The number of triangles removed.
 */
int vtTin::RemoveTrianglesBySegment(const DPoint2 &ep1, const DPoint2 &ep2)
{
	int count = 0;

	uint tris = NumTris();
	for (uint i = 0; i < tris; i++)
	{
		// get 2D points
		const int v0 = m_tri[i*3];
		const int v1 = m_tri[i*3+1];
		const int v2 = m_tri[i*3+2];
		const DPoint2 &p1 = m_vert[v0];
		const DPoint2 &p2 = m_vert[v1];
		const DPoint2 &p3 = m_vert[v2];

		if (LineSegmentsIntersect(ep1, ep2, p1, p2) ||
			LineSegmentsIntersect(ep1, ep2, p2, p3) ||
			LineSegmentsIntersect(ep1, ep2, p3, p1))
		{
			m_tri.erase(m_tri.begin() + i*3, m_tri.begin() + i*3 + 3);
			i--;
			tris--;
			count++;
		}
	}
	if (count > 0)
	{
		RemoveUnusedVertices();
		ComputeExtents();
	}
	return count;
}
Пример #2
0
/**
 * 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;
}
Пример #3
0
/**
 * 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;
}
Пример #4
0
double vtTin::GetArea2D()
{
	double area = 0.0;
	uint tris = NumTris();
	for (uint i = 0; i < tris; i++)
	{
		const DPoint2 &p1 = m_vert[m_tri[i*3]];
		const DPoint2 &p2 = m_vert[m_tri[i*3+1]];
		const DPoint2 &p3 = m_vert[m_tri[i*3+2]];
		area += AreaOfTriangle(p1, p2, p3);
	}
	return area;
}
Пример #5
0
/**
 * 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;
}
Пример #6
0
bool BEZIER::Collide(VERTEX origin, VERTEX direction, VERTEX &outtri)
{
	int i;
	
	VERTEX curtri[3];
	
	int retval = 0;
	
	float t, u, v;
	
	int x, y;
	
	for (i = 0; i < NumTris(COLLISION_DIVS) && !retval; i++)
	{	
		GetTri(COLLISION_DIVS, i, curtri);
		
		retval = INTERSECT_FUNCTION(origin.v3(), direction.v3(),
			curtri[0].v3(), curtri[1].v3(), curtri[2].v3(), 
			&t, &u, &v);
		
		if (retval)
		{
			if (i % 2 == 0)
			{
				u = 1.0 - u;
				v = 1.0 - v;
			}
			
			u = 1.0 - u;
			v = 1.0 - v;
			
			x = (i/2) % COLLISION_DIVS;
			y = (i/2) / COLLISION_DIVS;
			u += (float) x;
			v += (float) y;
			u = u / (float) COLLISION_DIVS;
			v = v / (float) COLLISION_DIVS;
			
			//u = 1.0 - u;
			//v = 1.0 - v;
			
			//cout << u << "," << v << endl;
			outtri = SurfCoord(u, v);
			return true;
		}
	}
	
	outtri = origin;
	return false;
}
Пример #7
0
Triangle OgreMeshAsset::Tri(int submeshIndex, int triangleIndex)
{
    if (subMeshTriangleCounts.size() == 0)
        CreateKdTree();

    if (triangleIndex < 0 || NumTris(submeshIndex) < triangleIndex)
    {
        LogError("Invalid triangle index to call to OgreMeshAsset::Tri(submeshIndex=" + QString::number(submeshIndex) + ", triangleIndex=" + QString::number(triangleIndex) + "), the specified submesh has only " + NumTris(submeshIndex) + " triangles!");
        return Triangle();
    }
    // Shift to index in proper location of the submesh triangles array.
    for(int i = 0; i < submeshIndex; ++i)
        triangleIndex += subMeshTriangleCounts[i];
    return meshData.Object(triangleIndex);
}
Пример #8
0
/**
 * If you are going to do a large number of height-testing of this TIN
 * (with FindAltitudeOnEarth), call this method once first to set up a
 * series of indexing bins which greatly speed up testing.
 *
 * \param bins Number of bins per dimension, e.g. a value of 50 produces
 *		50*50=2500 bins.  More bins produces faster height-testing with
 *		the only tradeoff being a small amount of RAM per bin.
 * \param progress_callback If supplied, this function will be called back
 *		with a value of 0 to 100 as the operation progresses.
 */
void vtTin::SetupTriangleBins(int bins, bool progress_callback(int))
{
	DRECT rect = m_EarthExtents;
	m_BinSize.x = rect.Width() / bins;
	m_BinSize.y = rect.Height() / bins;

	delete m_trianglebins;
	m_trianglebins = new BinArray(bins, bins);

	uint tris = NumTris();
	for (uint i = 0; i < tris; i++)
	{
		if ((i%100)==0 && progress_callback)
			progress_callback(i * 100 / tris);

		// get 2D points
		const DPoint2 &p1 = m_vert[m_tri[i*3]];
		const DPoint2 &p2 = m_vert[m_tri[i*3+1]];
		const DPoint2 &p3 = m_vert[m_tri[i*3+2]];

		// find the correct range of bins, and add the index of this index to it
		DPoint2 fminrange, fmaxrange;

		fminrange.x = std::min(std::min(p1.x, p2.x), p3.x);
		fmaxrange.x = std::max(std::max(p1.x, p2.x), p3.x);

		fminrange.y = std::min(std::min(p1.y, p2.y), p3.y);
		fmaxrange.y = std::max(std::max(p1.y, p2.y), p3.y);

		IPoint2 bin_start, bin_end;

		bin_start.x = (uint) ((fminrange.x-rect.left) / m_BinSize.x);
		bin_end.x = (uint)	 ((fmaxrange.x-rect.left) / m_BinSize.x);

		bin_start.y = (uint) ((fminrange.y-rect.bottom) / m_BinSize.y);
		bin_end.y = (uint)	 ((fmaxrange.y-rect.bottom) / m_BinSize.y);

		for (int j = bin_start.x; j <= bin_end.x; j++)
		{
			for (int k = bin_start.y; k <= bin_end.y; k++)
			{
				Bin *bin = m_trianglebins->GetBin(j, k);
				if (bin)
					bin->push_back(i);
			}
		}
	}
}
Пример #9
0
/**
 * 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;
}
Пример #10
0
/**
 * 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;
}
Пример #11
0
double vtTin::GetArea3D()
{
	double area = 0.0;
	uint tris = NumTris();

	for (uint i = 0; i < tris; i++)
	{
		const int v0 = m_tri[i*3];
		const int v1 = m_tri[i*3+1];
		const int v2 = m_tri[i*3+2];
		const DPoint2 &p1 = m_vert[v0];
		const DPoint2 &p2 = m_vert[v1];
		const DPoint2 &p3 = m_vert[v2];
		DPoint3 dp1(p1.x, p1.y, m_z[v0]);
		DPoint3 dp2(p2.x, p2.y, m_z[v1]);
		DPoint3 dp3(p3.x, p3.y, m_z[v2]);

		area += AreaOfTriangle(dp1, dp2, dp3);
	}

	return area;
}
Пример #12
0
/**
 * Return the length of the longest edge of a specific triangle.
 */
double vtTin::GetTriMaxEdgeLength(int iTri) const
{
	const int tris = NumTris();
	if (iTri < 0 || iTri >= tris)
		return 0.0;

	// get points
	const int v0 = m_tri[iTri*3];
	const int v1 = m_tri[iTri*3+1];
	const int v2 = m_tri[iTri*3+2];
	const DPoint2 &p1 = m_vert[v0];
	const DPoint2 &p2 = m_vert[v1];
	const DPoint2 &p3 = m_vert[v2];

	// check lengths
	double len1 = (p2 - p1).Length();
	double len2 = (p3 - p2).Length();
	double len3 = (p1 - p3).Length();
	return len1 > len2 ?
		(len1 > len3 ? len1 : len3) :
	(len2 > len3 ? len2 : len3);
}
Пример #13
0
/**
 * Test each triangle for clockwisdom, fix if needed.  The result should
 *  be a TIN with consistent vertex ordering, such that all face normals
 *  point up rather than down, that is, counter-clockwise.
 */
void vtTin::CleanupClockwisdom()
{
	int v0, v1, v2;
	uint tris = NumTris();
	for (uint i = 0; i < tris; i++)
	{
		v0 = m_tri[i*3];
		v1 = m_tri[i*3+1];
		v2 = m_tri[i*3+2];
		// get 2D points
		const DPoint2 &p1 = m_vert[v0];
		const DPoint2 &p2 = m_vert[v1];
		const DPoint2 &p3 = m_vert[v2];

		// The so-called 2D cross product
		double cross2d = (p2-p1).Cross(p3-p1);
		if (cross2d < 0)
		{
			// flip
			m_tri[i*3+1] = v2;
			m_tri[i*3+2] = v1;
		}
	}
}
Пример #14
0
bool vtTin::FindTriangleOnEarth(const DPoint2 &p, float &fAltitude, int &iTriangle,
	bool bTrue) const
{
	uint tris = NumTris();

	// If we have some triangle bins, they can be used for a much faster test
	if (m_trianglebins != NULL)
	{
		int col = (int) ((p.x - m_EarthExtents.left) / m_BinSize.x);
		int row = (int) ((p.y - m_EarthExtents.bottom) / m_BinSize.y);
		Bin *bin = m_trianglebins->GetBin(col, row);
		if (!bin)
			return false;

		for (uint i = 0; i < bin->size(); i++)
		{
			if (TestTriangle(bin->at(i), p, fAltitude))
			{
				iTriangle = bin->at(i);
				return true;
			}
		}
		// If it was not in any of these bins, then it did not hit anything
		return false;
	}
	// If no bins, we do a naive slow search.
	for (uint i = 0; i < tris; i++)
	{
		if (TestTriangle(i, p, fAltitude))
		{
			iTriangle = i;
			return true;
		}
	}
	return false;
}
Пример #15
0
/**
 * 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;
}
Пример #16
0
/**
 * 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;
}
Пример #17
0
/**
 * 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;
}