/*************************************************************************
	File:	pcld_in.c

	FormZ unstructured translator sample.  Imports and exports point cloud data.

	COPYRIGHT (C) 2001.  All Rights Reserved.
	auto*des*sys, Inc., Columbus, Ohio, USA.
*************************************************************************/

#include "pcld_prvt.h"



/*************************************************************************
	Reads a point cloud file and creates a formZ point cloud object.
*************************************************************************/
static short bspl_create_pcld_obj_from_bsplfile(fzrt_int windex, 
								 			   	char *fname, 
										       	fz_objt_ptr *new_obj,
										       	float *density)
{
	fzrt_int			err = FZRT_NOERR;
	FILE			*fp = NULL;
	fz_xyz_td		*pnts = NULL;
	fzrt_int			ii, jj, npnts = 0;
	float			tdensity = -1.0;
	char			aline[25];
	fzrt_int			slen;
	char			tmp_name[256];

	/* open the file. */
	_fzrt_file_funcs.fzrt_file_cnvt_name(fname, tmp_name, 256);
	fp = fopen(tmp_name, "r");
	if(fp != NULL)
	{
		/* Read and parse the file's contents. */
		if (fscanf(fp, "%20s", aline) != 1)
		{
			err = _fzrt_base_funcs.fzrt_error_set(ferror(fp), FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_ANSI, 0);
		}

		slen = strlen(aline);
		for (jj = 0; jj < slen-1; jj++)
		{
			if (!isdigit(aline[jj]))
			{
				err = _fzrt_base_funcs.fzrt_error_set(ferror(fp), FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_ANSI, 0);
			}
		}
		if (!isdigit(aline[slen-1]))
			aline[slen-1] = '\0';

		npnts = atoi(aline);
		
		if (fscanf(fp, "%20s", aline) != 1)
		{
			err = _fzrt_base_funcs.fzrt_error_set(ferror(fp), FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_ANSI, 0);
		}
		
		slen = strlen(aline);
		for (jj = 0; jj < slen-1; jj++)
		{
			if (!isdigit(aline[jj]) && 
				aline[jj] != '-' &&
				aline[jj] != '.' &&
				aline[jj] != 'e')
			{
				err = _fzrt_base_funcs.fzrt_error_set(PCLD_INVAL_ERR_ID, FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_PLUGIN, _pcld_plugin_runtime_id);
			}
		}
		if (!isdigit(aline[slen-1]))
		{
			aline[slen-1] = '\0';
		}

		tdensity = atof(aline);
		
		/* Allocate memory for the points */
		if (_fzrt_mem_funcs.fzrt_new_ptr(npnts * sizeof(fz_xyz_td), (fzrt_ptr*)&pnts) == FZRT_NOERR &&
			pnts != NULL)
		{
			/* Read all the points. */
			for(ii = 0; ii < npnts && err == FZRT_NOERR; ii++)
			{
				if (fscanf(fp, "%20s", aline) != 1)
				{
					err = _fzrt_base_funcs.fzrt_error_set(ferror(fp), FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_ANSI, 0);
				}

				slen = strlen(aline);
				for (jj=0; jj<slen-1; jj++)
				{
					if (!isdigit(aline[jj]) && 
						aline[jj] != '-' &&
						aline[jj] != '.' &&
						aline[jj] != 'e')
					{
						err = _fzrt_base_funcs.fzrt_error_set(PCLD_INVAL_ERR_ID, FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_PLUGIN, _pcld_plugin_runtime_id);
					}
				}
				if (!isdigit(aline[slen-1]))
				{
					aline[slen-1] = '\0';
				}

				pnts[ii].x = atof(aline);

				if (fscanf(fp, "%20s", aline) != 1)
				{
					err = _fzrt_base_funcs.fzrt_error_set(ferror(fp), FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_ANSI, 0);
				}
				
				slen = strlen(aline);
				for (jj=1; jj<slen-1; jj++)
				{
					if (!isdigit(aline[jj]) && 
						aline[jj] != '-' &&
						aline[jj] != '.' &&
						aline[jj] != 'e')
					{
						err = _fzrt_base_funcs.fzrt_error_set(PCLD_INVAL_ERR_ID, FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_PLUGIN, _pcld_plugin_runtime_id);
					}
				}
				if (!isdigit(aline[slen-1]))
				{
					aline[slen-1] = '\0';
				}
				
				pnts[ii].y = atof(aline);

				if (fscanf(fp, "%20s", aline) != 1)
				{
					err = _fzrt_base_funcs.fzrt_error_set(ferror(fp), FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_ANSI, 0);
				}
				
				slen = strlen(aline);
				for (jj=1; jj<slen-1; jj++)
				{
					if (!isdigit(aline[jj]) && 
						aline[jj] != '-' &&
						aline[jj] != '.' &&
						aline[jj] != 'e')
					{
						err = _fzrt_base_funcs.fzrt_error_set(PCLD_INVAL_ERR_ID, FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_PLUGIN, _pcld_plugin_runtime_id);
					}
				}
				if (!isdigit(aline[slen-1]))
				{
					aline[slen-1] = '\0';
				}
				
				pnts[ii].z = atof(aline);
			}
			
			if (err == FZRT_NOERR)
			{
				/* Create a point cloud object. */
				_model_funcs.fz_objt_cnstr_point_cloud(windex,
																   pnts, npnts, 
																   new_obj);
				*density = tdensity;
			}

			/* Free memory for the points */
			_fzrt_mem_funcs.fzrt_dispose_ptr((fzrt_ptr)pnts);
			pnts=NULL;
		}
		else
		{
			err = _fzrt_base_funcs.fzrt_error_set(FZRT_FILE_OPEN_ERROR, FZRT_ERROR_SEVERITY_ERROR, FZRT_ERROR_CONTEXT_FZRT, 0);
		}

		fclose(fp);
	}

	return(err);
}


/*************************************************************************
	Opens and reads a point cloud file.
	Creates one point cloud object for the whole file.
	Scales the object by the value set in the options dialog.
*************************************************************************/
fzrt_error_td pcld_read(fzrt_int windex, fzrt_floc_ptr floc)
{
	fzrt_int 							err = FZRT_NOERR;
	float							density;
	fz_objt_ptr						new_obj=NULL;
	fz_rmtl_ptr						surf;
	fz_tag_td						surf_tag;
	char							fname[256];
	fz_xyz_td						scl;

	if(err == FZRT_NOERR)
	{
		/* Get the file name. */
		_fzrt_file_funcs.fzrt_file_floc_get_name(floc, fname, 256);

		/* Read the file and create a point cloud object. */
		err = bspl_create_pcld_obj_from_bsplfile(windex, fname, &new_obj, &density);
		
		if (new_obj != NULL)
		{
			/* Scale the object. */
			density *= _import_scale;
			scl.x = scl.y = scl.z = _import_scale;
			_model_funcs.fz_objt_edit_scale_objt(windex, new_obj, &scl);
			_model_funcs.fz_objt_add_objt_to_project(windex, new_obj);

			/* Set the object's density attribute. */
			_model_attr_funcs.fz_objt_attr_set_objt_sdns(windex, new_obj, density);
		
			/* Set the object's surface style to the current surface style. */
			_rmtl_funcs.fz_rmtl_get_current(windex, &surf);
			_rmtl_funcs.fz_rmtl_ptr_to_tag(windex, surf, &surf_tag);
			_model_attr_funcs.fz_objt_attr_set_objt_rmtl(windex, new_obj, &surf_tag);
		}
	}

	return(err);
}
