[GRASS-SVN] r49828 - grass-addons/grass7/vector/v.in.ply

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Dec 19 05:32:31 EST 2011


Author: mmetz
Date: 2011-12-19 02:32:31 -0800 (Mon, 19 Dec 2011)
New Revision: 49828

Added:
   grass-addons/grass7/vector/v.in.ply/Makefile
   grass-addons/grass7/vector/v.in.ply/body.c
   grass-addons/grass7/vector/v.in.ply/globals.h
   grass-addons/grass7/vector/v.in.ply/header.c
   grass-addons/grass7/vector/v.in.ply/local_proto.h
   grass-addons/grass7/vector/v.in.ply/main.c
   grass-addons/grass7/vector/v.in.ply/v.in.ply.html
Log:
import new v.in.ply

Added: grass-addons/grass7/vector/v.in.ply/Makefile
===================================================================
--- grass-addons/grass7/vector/v.in.ply/Makefile	                        (rev 0)
+++ grass-addons/grass7/vector/v.in.ply/Makefile	2011-12-19 10:32:31 UTC (rev 49828)
@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../..
+
+PGM = v.in.ply
+
+LIBES = $(VECTORLIB) $(DBMILIB) $(GISLIB)
+DEPENDENCIES = $(VECTORDEP) $(DBMIDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd

Added: grass-addons/grass7/vector/v.in.ply/body.c
===================================================================
--- grass-addons/grass7/vector/v.in.ply/body.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.in.ply/body.c	2011-12-19 10:32:31 UTC (rev 49828)
@@ -0,0 +1,193 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+#define BUFLEN 4000
+
+int read_ascii_item(char *item, int type, int *int_val, double *dbl_val)
+{
+    if (int_val) {
+	if (type == PLY_UCHAR)
+	    *int_val = (int)(unsigned char)atoi(item);
+	else if (type == PLY_CHAR)
+	    *int_val = (int)(char)atoi(item);
+	else if (type == PLY_USHORT)
+	    *int_val = (int)(unsigned short)atoi(item);
+	else if (type == PLY_SHORT)
+	    *int_val = (int)(short)atoi(item);
+	else if (type == PLY_UINT)
+	    *int_val = (int)strtoul(item, NULL, 10);
+	else if (type == PLY_INT)
+	    *int_val = atoi(item);
+    }
+    if (dbl_val && (type == PLY_FLOAT || type == PLY_DOUBLE))
+	*dbl_val = (double)atof(item);
+
+    return 0;
+}
+
+int get_element_data_ascii(struct ply_file *ply, struct prop_data *data)
+{
+    char buf[BUFLEN], *ptr;
+    int i, type;
+    char **tokens;
+    int ntokens;
+
+    if (G_getl2(buf, BUFLEN - 1, ply->fp) == 0) {
+	/* EOF; should not happen */
+	G_fatal_error(_("Incomplete PLY file!"));
+    }
+    
+    ptr = buf;
+    /* skip leading spaces and tabs */
+    while (*ptr == ' ' || *ptr == '\t')
+	ptr++;
+
+    G_debug(3, "tokenize data");
+    tokens = G_tokenize2(ptr, " \t", "\"");
+    ntokens = G_number_of_tokens(tokens);
+    
+    if (ntokens != ply->curr_element->n_properties)
+	G_fatal_error(_("Wrong number of properties"));
+
+    G_debug(3, "convert data");
+    for (i = 0; i < ply->curr_element->n_properties; i++) {
+	
+	if (ply->curr_element->property[i]->is_list)
+	    G_fatal_error(_("Property can not be list"));
+	
+	type = ply->curr_element->property[i]->type;
+
+	data[i].int_val = 0;
+	data[i].dbl_val = 0;
+
+	read_ascii_item(tokens[i], type, &data[i].int_val, &data[i].dbl_val);
+
+	G_debug(3, "data: %d, %f", data[i].int_val, data[i].dbl_val);
+    }
+
+    G_free_tokens(tokens);
+
+    return 0;
+}
+
+int get_element_data_bigendian(struct ply_file *ply, struct prop_data *data)
+{
+    return 0;
+}
+
+int get_element_data_littleendian(struct ply_file *ply, struct prop_data *data)
+{
+    return 0;
+}
+
+int get_element_data(struct ply_file *ply, struct prop_data *data)
+{
+    if (ply->file_type == PLY_ASCII)
+	return get_element_data_ascii(ply, data);
+    else if (ply->file_type == PLY_BINARY_BE)
+	return get_element_data_bigendian(ply, data);
+    else if (ply->file_type == PLY_BINARY_LE)
+	return get_element_data_littleendian(ply, data);
+
+    return 0;
+}
+
+int get_element_list_ascii(struct ply_file *ply)
+{
+    char buf[BUFLEN], *ptr;
+    int i, type;
+    char **tokens;
+    int ntokens;
+
+    if (!ply->curr_element->property[0]->is_list)
+	G_fatal_error(_("Property must be a list"));
+
+
+    if (G_getl2(buf, BUFLEN - 1, ply->fp) == 0) {
+	/* EOF; should not happen */
+	G_fatal_error(_("Incomplete PLY file!"));
+    }
+    
+    ptr = buf;
+    /* skip leading spaces and tabs */
+    while (*ptr == ' ' || *ptr == '\t')
+	ptr++;
+
+    G_debug(3, "tokenize data");
+    tokens = G_tokenize2(ptr, " \t", "\"");
+    ntokens = G_number_of_tokens(tokens);
+
+    G_debug(3, "read list");
+
+    type = ply->curr_element->property[0]->type;
+
+    read_ascii_item(tokens[0], type, &(ply->list.n_values), NULL);
+    if (ntokens != ply->list.n_values + 1)
+	G_fatal_error(_("Broken list"));
+    if (ply->list.n_values >= ply->list.n_alloc) {
+	ply->list.n_alloc = ply->list.n_values + 10;
+	ply->list.index = (int *)G_realloc(ply->list.index, 
+				sizeof(int) * ply->list.n_alloc);
+    }
+    for (i = 0; i < ply->list.n_values; i++) {
+	read_ascii_item(tokens[i + 1], type, &(ply->list.index[i]), NULL);
+    }
+
+    G_free_tokens(tokens);
+
+    return 0;
+}
+
+int get_element_list_bigendian(struct ply_file *ply)
+{
+    return 0;
+}
+
+int get_element_list_littleendian(struct ply_file *ply)
+{
+    return 0;
+}
+
+int get_element_list(struct ply_file *ply)
+{
+    if (ply->file_type == PLY_ASCII)
+	return get_element_list_ascii(ply);
+    else if (ply->file_type == PLY_BINARY_BE)
+	return get_element_list_bigendian(ply);
+    else if (ply->file_type == PLY_BINARY_LE)
+	return get_element_list_littleendian(ply);
+
+    return 0;
+}
+
+int append_vertex(struct Map_info *Map, struct line_pnts *Points, int cat)
+{
+    int n;
+    static struct line_pnts *PPoints = NULL;
+    static struct line_cats *CCats = NULL;
+    
+    if (!PPoints)
+	PPoints = Vect_new_line_struct();
+    if (!CCats)
+	CCats = Vect_new_cats_struct();
+	
+    Vect_rewind(Map);
+    
+    while (Vect_read_next_line(Map, PPoints, CCats) >= 0) {
+	for (n = 0; n < CCats->n_cats; n++) {
+	    if (CCats->field[n] == 1 && CCats->cat[n] == cat) {
+		Vect_append_point(Points, PPoints->x[0], PPoints->y[0],
+		                  PPoints->z[0]);
+	    }
+	}
+	
+    }
+    
+    return 0;
+}

Added: grass-addons/grass7/vector/v.in.ply/globals.h
===================================================================
--- grass-addons/grass7/vector/v.in.ply/globals.h	                        (rev 0)
+++ grass-addons/grass7/vector/v.in.ply/globals.h	2011-12-19 10:32:31 UTC (rev 49828)
@@ -0,0 +1,75 @@
+#ifndef __GLOBALS_H__
+#define __GLOBALS_H__
+
+#define PLY_ASCII      1        /* ascii PLY file */
+#define PLY_BINARY_BE  2        /* binary PLY file, big endian */
+#define PLY_BINARY_LE  3        /* binary PLY file, little endian */
+
+/* known PLY elements */
+#define PLY_VERTEX     1
+#define PLY_FACE       2
+#define PLY_EDGE       3
+#define PLY_OTHER      4
+
+/* PLY data types */
+#define PLY_INVALID     0
+#define PLY_CHAR        1
+#define PLY_UCHAR       2
+#define PLY_SHORT       3
+#define PLY_USHORT      4
+#define PLY_INT         5
+#define PLY_UINT        6
+#define PLY_FLOAT       7
+#define PLY_DOUBLE      8
+
+#define PLY_IS_INT(type) ((type) >= PLY_CHAR && (type) <= PLY_UINT)
+
+extern int ply_type_size[];
+
+struct ply_list {
+    int n_values;
+    int n_alloc;
+    int *index;
+};
+
+struct prop_data {
+    int int_val;
+    double dbl_val;
+};
+
+struct ply_property {           /* description of a property */
+    char *name;                 /* property name */
+    int type;            	/* property's data type */
+
+    int is_list;                /* 0 = scalar, 1 = list */
+    int list_type;              /* list index type, must be integer */
+    int count_offset;           /* offset byte for list count */
+};
+
+struct ply_element {     	/* description of an element */
+    char *name;                 /* element name */
+    int type;			/* element type (vertex, face, edge, other) */
+    int n;                      /* number of elements in this object */
+    int size;                   /* size of element (bytes) or -1 if variable */
+    int n_properties;           /* number of properties for this element */
+    struct ply_property **property;    /* list of properties in the file */
+};
+
+struct ply_file {        	/* description of PLY file */
+    FILE *fp;                   /* file pointer */
+    int file_type;              /* ascii or binary */
+    char *version;            	/* version number, should be 1.0 */
+    int n_elements;             /* number of element types of object */
+    struct ply_element **element;        /* list of elements */
+    struct ply_element *curr_element;    /* currently processed element */
+    struct ply_list list;	/* list of vertices */
+    int n_comments;             /* number of comments */
+    char **comment;             /* list of comments */
+    int header_size;            /* header_size (offset to body) */
+    int x;			/* vertex property index for x coordinate */
+    int y;			/* vertex property index for y coordinate */
+    int z;			/* vertex property index for z coordinate */
+};
+
+
+#endif

Added: grass-addons/grass7/vector/v.in.ply/header.c
===================================================================
--- grass-addons/grass7/vector/v.in.ply/header.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.in.ply/header.c	2011-12-19 10:32:31 UTC (rev 49828)
@@ -0,0 +1,212 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+int get_ply_datatype(char *desc)
+{
+    if (strcmp(desc, "char") == 0 || strcmp(desc, "int8") == 0)
+	return PLY_CHAR;
+    else if (strcmp(desc, "uchar") == 0 || strcmp(desc, "uint8") == 0)
+	return PLY_UCHAR;
+    else if (strcmp(desc, "short") == 0 || strcmp(desc, "int16") == 0)
+	return PLY_SHORT;
+    else if (strcmp(desc, "ushort") == 0 || strcmp(desc, "uint16") == 0)
+	return PLY_USHORT;
+    else if (strcmp(desc, "int") == 0 || strcmp(desc, "int32") == 0)
+	return PLY_INT;
+    else if (strcmp(desc, "uint") == 0 || strcmp(desc, "uint32") == 0)
+	return PLY_UINT;
+    else if (strcmp(desc, "float") == 0 || strcmp(desc, "float32") == 0)
+	return PLY_FLOAT;
+    else if (strcmp(desc, "double") == 0 || strcmp(desc, "float64") == 0)
+	return PLY_DOUBLE;
+
+    return PLY_INVALID;  /* invalid type */
+}
+
+int add_element(struct ply_file *ply, char **tokens, int ntokens)
+{
+    struct ply_element *element;
+
+    if (ntokens != 3)
+	G_fatal_error(_("Invalid PLY element description"));
+
+    /* create the new element */
+    element = (struct ply_element *) G_malloc(sizeof(struct ply_element));
+    element->name = G_store(tokens[1]);
+    element->n = atoi(tokens[2]);
+    element->n_properties = 0;
+    element->property = NULL;
+    
+    if (strcmp(tokens[1], "vertex") == 0)
+	element->type = PLY_VERTEX;
+    else if (strcmp(tokens[1], "face") == 0)
+	element->type = PLY_FACE;
+    else if (strcmp(tokens[1], "edge") == 0)
+	element->type = PLY_EDGE;
+    else
+	element->type = PLY_OTHER;
+    
+    /* add new element to ply struct */
+    ply->n_elements++;
+    ply->element = (struct ply_element **) G_realloc(ply->element,
+                     sizeof(struct ply_element *) * ply->n_elements);
+    
+    ply->element[ply->n_elements - 1] = element;
+    
+    return 0;
+}
+
+int add_property(struct ply_file *ply, char **tokens, int ntokens)
+{
+    struct ply_property *property;
+    struct ply_element *element;
+    int type;
+    
+    if (ntokens < 3)
+	G_fatal_error(_("Invalid PLY property syntax"));
+    
+    /* create the new property */
+    property = (struct ply_property *) G_malloc(sizeof(struct ply_property));
+    
+    /* init property */
+    property->name = NULL;
+    property->type = 0;
+    property->is_list = 0;
+    property->list_type = 0;
+    
+    /* expected syntax:
+     * property <data-type> <property-name>
+     * property list <numerical-type> <numerical-type> <property-name> */
+     
+    if (strcmp(tokens[1], "list") == 0) {
+	if (ntokens != 5) {
+	    G_warning(_("Invalid PLY list syntax"));
+	    return 0;
+	}
+	property->is_list = 1;
+	type = get_ply_datatype(tokens[2]);
+	if (!PLY_IS_INT(type))
+	    G_fatal_error(_("List count must be integer, is %s"), 
+		tokens[1]);
+	property->type = type;
+	type = get_ply_datatype(tokens[3]);
+	if (!PLY_IS_INT(type))
+	    G_fatal_error(_("List index must be integer, is %s"), 
+		tokens[2]);
+	property->list_type = type;
+	property->name = G_store(tokens[4]);
+	
+    }
+    else if ((type = get_ply_datatype(tokens[1])) > 0) {
+	property->type = type;
+	property->name = G_store(tokens[2]);
+    }
+    else {
+	G_fatal_error(_("Invalid PLY property syntax"));
+    }
+	
+    element = ply->element[ply->n_elements - 1];
+
+    element->n_properties++;
+    element->property = (struct ply_property **) G_realloc (element->property,
+                  sizeof(struct ply_property *) * (element->n_properties + 1));
+
+    element->property[element->n_properties - 1] = property;
+
+    return 0;
+}
+
+int add_comment(struct ply_file *ply, char *buf)
+{
+    char *ptr = &buf[7];
+    
+    while (*ptr == ' ' || *ptr == '\t')
+	ptr++;
+
+    ply->comment = (char **) G_realloc (ply->comment,
+		 sizeof(char *) * (ply->n_comments + 1));
+
+    ply->comment[ply->n_comments++] = G_store(ptr);
+
+    return 0;
+}
+
+int read_ply_header(struct ply_file *ply)
+{
+    int buflen = 4000;
+    char *buf = (char *)G_malloc(buflen);
+    char *buf_raw = (char *)G_malloc(buflen);
+    char *ptr;
+    char **tokens;
+    int ntokens;
+    int magic_word = 0;
+
+
+    while (1) {
+	if (G_getl2(buf, buflen - 1, ply->fp) == 0) {
+	    /* EOF; should not happen */
+	    G_fatal_error(_("Incomplete PLY file!"));
+	}
+
+	if (buf[0] == '\0') {
+	    /* empty row, should not happen */
+	    continue;
+	}
+	/* G_tokenize() will modify the buffer, so we make a copy */
+	strcpy(buf_raw, buf);
+	
+	ptr = buf;
+	/* skip leading spaces and tabs */
+	while (*ptr == ' ' || *ptr == '\t')
+	    ptr++;
+
+	tokens = G_tokenize2(ptr, " \t", "\"");
+	ntokens = G_number_of_tokens(tokens);
+	
+	if (!magic_word) {
+	    if (ntokens == 1 && strcmp(tokens[0], "ply") == 0) {
+		magic_word = 1;
+		continue;
+	    }
+	    else
+		G_fatal_error(_("This is not a PLY file!"));
+	}
+
+	if (strcmp(tokens[0], "format") == 0) {
+	    if (ntokens != 3)
+		G_fatal_error(_("Incomplete format description!"));
+	    if (strcmp(tokens[1], "ascii") == 0)
+		ply->file_type = PLY_ASCII;
+	    else if (strcmp(tokens[1], "binary_big_endian") == 0)
+		ply->file_type = PLY_BINARY_BE;
+	    else if (strcmp(tokens[1], "binary_little_endian") == 0)
+		ply->file_type = PLY_BINARY_LE;
+	    else
+		G_fatal_error(_("Unknown PLY format <%s>!"), tokens[1]);
+	    ply->version = G_store(tokens[2]);
+	}
+	else if (strcmp(tokens[0], "element") == 0)
+	    add_element(ply, tokens, ntokens);
+	else if (strcmp(tokens[0], "property") == 0)
+	    add_property(ply, tokens, ntokens);
+	else if (strcmp(tokens[0], "comment") == 0)
+	    add_comment(ply, buf_raw);
+	else if (strcmp(tokens[0], "end_header") == 0) {
+	    ply->header_size = G_ftell(ply->fp);
+	    G_free_tokens(tokens);
+	    break;
+	}
+
+	G_free_tokens(tokens);
+    }
+
+    G_free(buf);
+    G_free(buf_raw);
+
+    return 0;
+}

Added: grass-addons/grass7/vector/v.in.ply/local_proto.h
===================================================================
--- grass-addons/grass7/vector/v.in.ply/local_proto.h	                        (rev 0)
+++ grass-addons/grass7/vector/v.in.ply/local_proto.h	2011-12-19 10:32:31 UTC (rev 49828)
@@ -0,0 +1,18 @@
+#ifndef __LOCAL_PROTO_H__
+#define __LOCAL_PROTO_H__
+
+#include <stdio.h>
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/dbmi.h>
+#include "globals.h"
+
+/* header.c */
+int read_ply_header(struct ply_file *ply);
+
+/* body */
+int get_element_data(struct ply_file *ply, struct prop_data *data);
+int get_element_list(struct ply_file *ply);
+int append_vertex(struct Map_info *Map, struct line_pnts *Points, int cat);
+
+#endif /* __LOCAL_PROTO_H__ */

Added: grass-addons/grass7/vector/v.in.ply/main.c
===================================================================
--- grass-addons/grass7/vector/v.in.ply/main.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.in.ply/main.c	2011-12-19 10:32:31 UTC (rev 49828)
@@ -0,0 +1,285 @@
+
+/****************************************************************************
+ *
+ * MODULE:       v.in.ply
+ *               
+ * AUTHOR(S):    Markus Metz
+ *
+ * PURPOSE:      Convert PLY (Polygon file format) files to GRASS vectors
+ *
+ * COPYRIGHT:    (C) 2011 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+int ply_type_size[] = { 0, 1, 1, 2, 2, 4, 4, 4, 8 };
+
+int main(int argc, char *argv[])
+{
+    struct GModule *module;
+    struct Option *old, *new, *x_opt, *y_opt, *z_opt;
+    struct Flag *table_flag, *notopo_flag, *region_flag;
+    char *table;
+    int i, j, type, max_cat;
+    int zcoor = WITHOUT_Z, make_table;
+    int xprop, yprop, zprop;
+    struct ply_file ply;
+    struct prop_data *data = NULL;
+    double x, y, z, coord;
+
+    struct Map_info Map;
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("import"));
+    module->description =
+	_("Creates a vector map from a PLY file.");
+
+    /************************** Command Parser ************************************/
+    old = G_define_standard_option(G_OPT_F_INPUT);
+    old->label = _("Name of input file to be imported");
+    old->description = ("'-' for standard input");
+    
+    new = G_define_standard_option(G_OPT_V_OUTPUT);
+
+    x_opt = G_define_option();
+    x_opt->key = "x";
+    x_opt->type = TYPE_INTEGER;
+    x_opt->required = NO;
+    x_opt->multiple = NO;
+    x_opt->answer = "1";
+    x_opt->label = ("Number of vertex property used as x coordinate");
+    x_opt->description = _("First vertex property is 1");
+
+    y_opt = G_define_option();
+    y_opt->key = "y";
+    y_opt->type = TYPE_INTEGER;
+    y_opt->required = NO;
+    y_opt->multiple = NO;
+    y_opt->answer = "2";
+    y_opt->label = _("Number of vertex property used as y coordinate");
+    y_opt->description = _("First vertex property is 1");
+
+    z_opt = G_define_option();
+    z_opt->key = "z";
+    z_opt->type = TYPE_INTEGER;
+    z_opt->required = NO;
+    z_opt->multiple = NO;
+    z_opt->answer = "3";
+    z_opt->label = _("Number of vertex property used as z coordinate");
+    z_opt->description = _("First vertex property is 1. If 0, z coordinate is not used");
+
+    table_flag = G_define_flag();
+    table_flag->key = 't';
+    table_flag->description = _("Do not create attribute table");
+
+    notopo_flag = G_define_flag();
+    notopo_flag->key = 'b';
+    notopo_flag->description = _("Do not build topology");
+
+    region_flag = G_define_flag();
+    region_flag->key = 'r';
+    region_flag->description =
+	_("Only import points falling within current region (points mode)");
+    region_flag->guisection = _("Points");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* coords */
+    xprop = atoi(x_opt->answer);
+    yprop = atoi(y_opt->answer);
+    zprop = atoi(z_opt->answer);
+
+    /* 3D */
+    zcoor = zprop > 0;
+
+    if (xprop < 1 || yprop < 1)
+	G_fatal_error(_("x and y must be positive"));
+    
+    if (xprop == yprop || xprop == zprop || yprop == zprop)
+	G_fatal_error(_("x, y, z must be three different numbers"));
+
+    /* init ply object */
+    ply.fp = NULL;
+    ply.file_type = 0;
+    ply.version = NULL;
+    ply.n_elements = 0;
+    ply.element = NULL;
+    ply.curr_element = NULL;
+    ply.n_comments = 0;
+    ply.comment = NULL;
+    ply.header_size = 0;
+    ply.list.n_alloc = 10;
+    ply.list.index = G_malloc(sizeof(int) * ply.list.n_alloc);
+    ply.x = xprop - 1;
+    ply.y = yprop - 1;
+    ply.z = zprop - 1;
+
+    /* open input file */
+    if ((ply.fp = fopen(old->answer, "r")) == NULL)
+	G_fatal_error(_("Can not open input file <%s>"), old->answer);
+
+    /* read ply header */
+    read_ply_header(&ply);
+    
+    for (i = 0; i < ply.n_elements; i++) {
+	G_debug(0, "element name: _%s_", ply.element[i]->name);
+	G_debug(0, "element type: %d", ply.element[i]->type);
+
+	for (j = 0; j < ply.element[i]->n_properties; j++) {
+	    G_debug(0, "poperty name: _%s_", ply.element[i]->property[j]->name);
+	    G_debug(0, "poperty type: %d", ply.element[i]->property[j]->type);
+	}
+    }
+    
+    
+    /* vertices present ? */
+    ply.curr_element = NULL;
+    for (i = 0; i < ply.n_elements; i++) {
+	if (ply.element[i]->type == PLY_VERTEX) {
+	    ply.curr_element = ply.element[i];
+	}
+	else if (ply.element[i]->type == PLY_FACE) {
+	    if (ply.element[i]->n_properties != 1) {
+		G_fatal_error(_("PLY faces must have only one property"));
+	    }
+	    else if (ply.element[i]->property[0]->is_list != 1) {
+		G_fatal_error(_("PLY faces need a list of vertices"));
+	    }
+	}
+    }
+    if (!ply.curr_element)
+	G_fatal_error(_("No vertices in PLY file"));
+    if (ply.curr_element->n == 0)
+	G_fatal_error(_("No vertices in PLY file"));
+    
+    Vect_open_new(&Map, new->answer, zcoor);
+    Vect_hist_command(&Map);
+    
+    /* table for vertices only
+     * otherwise we would need to put faces and edges into separate layers */
+
+    /* alloc memory for vertex data */
+    data = (struct prop_data *)G_realloc(data,
+           sizeof(struct prop_data) * ply.curr_element->n_properties);
+
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    G_message(_("%d vertices"), ply.curr_element->n);
+
+    x = y = z = 0.0;
+    max_cat = 0;
+    for (i = 0; i < ply.curr_element->n; i++) {
+	G_percent(i, ply.curr_element->n, 4);
+	get_element_data(&ply, data);
+	
+	Vect_reset_line(Points);
+	Vect_reset_cats(Cats);
+	Vect_cat_set(Cats, 1, i);
+	
+	/* x, y, z coord */
+	for (j = 0; j < ply.curr_element->n_properties; j++) {
+	    if (j == ply.x || j == ply.y || j == ply.z) {
+		type = ply.curr_element->property[j]->type;
+		coord = 0.0;
+
+		if (type == PLY_UCHAR)
+		    coord = data[j].int_val;
+		else if (type == PLY_CHAR)
+		    coord = data[j].int_val;
+		else if (type == PLY_USHORT)
+		    coord = data[j].int_val;
+		else if (type == PLY_SHORT)
+		    coord = data[j].int_val;
+		else if (type == PLY_UINT)
+		    coord = data[j].int_val;
+		else if (type == PLY_FLOAT || type == PLY_DOUBLE)
+		    coord = data[j].dbl_val;
+		    
+		if (j == ply.x)
+		    x = coord;
+		else if (j == ply.y)
+		    y = coord;
+		else if (j == ply.z)
+		    z = coord;
+		
+		
+	    }
+	}
+	Vect_append_point(Points, x, y, z);
+	Vect_write_line(&Map, GV_POINT, Points, Cats);
+
+	max_cat = i;
+    }
+    G_percent(1, 1, 1);
+    G_free(data);
+    
+    /* other elements */
+    ply.curr_element = NULL;
+    for (i = 0; i < ply.n_elements; i++) {
+	if (ply.element[i]->type == PLY_VERTEX) {
+	    continue;
+	}
+	if (ply.element[i]->n == 0) {
+	    continue;
+	}
+
+	ply.curr_element = ply.element[i];
+	
+	/* faces: get vertex list */
+	if (ply.element[i]->type == PLY_FACE) {
+	    for (j = 0; j < ply.element[i]->n; j++) {
+		int k;
+
+		get_element_list(&ply);
+		
+		/* fetch points from vector map, sequential reading
+		 * this is going to be slow */
+		Vect_reset_line(Points);
+		Vect_reset_cats(Cats);
+		Vect_cat_set(Cats, 2, j);
+		 
+		 for (k = 0; k < ply.list.n_values; k++) {
+		     append_vertex(&Map, Points, ply.list.index[k]);
+		 }
+		 if (ply.list.n_values > 2) {
+		     Vect_append_point(Points,
+		                       Points->x[Points->n_points - 1],
+		                       Points->y[Points->n_points - 1],
+		                       Points->z[Points->n_points - 1]);
+		    
+		    Vect_write_line(&Map, GV_FACE, Points, Cats);
+		 }
+	    }
+	}
+
+    }
+
+
+    if (!notopo_flag->answer)
+	Vect_build(&Map);
+
+    Vect_close(&Map);
+
+    G_done_msg(" ");
+
+    exit(EXIT_SUCCESS);
+}

Added: grass-addons/grass7/vector/v.in.ply/v.in.ply.html
===================================================================
--- grass-addons/grass7/vector/v.in.ply/v.in.ply.html	                        (rev 0)
+++ grass-addons/grass7/vector/v.in.ply/v.in.ply.html	2011-12-19 10:32:31 UTC (rev 49828)
@@ -0,0 +1,286 @@
+<h2>DESCRIPTION</h2>
+
+<em>v.in.ascii</em> converts a vector map
+in <a href="vectorascii.html">GRASS ASCII vector format</a> to a
+vector map in binary format. The module may import two formats:
+<ul>
+<li><b>standard</b> contains all data types, each coordinate on one row</li>
+<li><b>point</b> (default) reads only points, each point defined on
+  one row. Values are separated by a user-definable delimiter. If
+  the <b>columns</b> option is not defined, default names are used. It
+  is possible to specify the column order for the x,y,z coordinates
+  and category values.</li>
+</ul>
+
+<p><em><a href="v.out.ascii.html">v.out.ascii</a></em> performs the
+function of <em>v.in.ascii</em> in reverse; i.e., it converts vector
+maps in binary format to GRASS ASCII vector format. These two companion programs
+are useful both for importing and exporting vector maps between GRASS
+and other software, and for transferring data between machines.
+
+<h2>NOTES</h2>
+ 
+The input is read from the file specified by the <b>input</b> option or
+from standard input.
+
+<p>The field separator may be a character, the word '<tt>tab</tt>'
+(or '<tt>\t</tt>') for tab, '<tt>space</tt>' (or '&nbsp;') for a blank,
+or '<tt>comma</tt>' (or ',') for a comma.
+
+<p>An attribute table is only created if it is needed, i.e. when at
+least one attribute column is present in the input file besides
+geometry columns. The attribute column will be auto-scanned for type, but
+may be explicitly declared along with the geometry columns using the
+<b>columns</b> parameter.
+
+<p>Use the <b>-z</b> flag to convert ASCII data into a 3D vector map.
+
+<p>In special cases of data import, such as the import of large LIDAR
+datasets (millions of data points), it may be necessary to disable
+topology support (vector level 1) due to memory constraints.  This is
+done with the <b>-b</b> flag. As only very few vector modules support
+points data processing at vector level 1, usually topology is required
+(vector level 2). Therefore it is recommened that the user first try
+to import the data without creating a database (the <b>-t</b> flag) or
+within a subregion (the <b>-r</b> flag) before resorting the to
+disabling of topology.
+
+<p>If old version is requested, the <b>output</b> files
+from <em><a href="v.out.ascii.html">v.out.ascii</a></em> is placed in
+the <tt>$LOCATION/$MAPSET/dig_ascii/</tt>
+and <tt>$LOCATION/$MAPSET/dig_att</tt> directory.
+
+<h3>Import of files without category column</h3>
+
+If the input file does not contain a category column, there is the
+possibility to auto-generate these IDs (categories). To automatically
+add an additional column named 'cat', the <b>cat</b> parameter must be
+set to the virtual column number 0 (<tt>cat=0</tt>). This is the
+default action if the <b>cat</b> parameter is not set.
+
+<h3>Importing from a spreadsheet</h3>
+
+Data may be imported from many spreadsheet programs by saving the
+spreadsheet as a comma separated variable (.csv) text file, and then
+using the <b>fs=','</b> or <b>fs=comma</b> option
+with <em>v.in.ascii</em> in <b>points</b> mode.  If the input file
+contains any header lines, such as column headings, the
+<b>skip</b> parameter should be used. These skipped header lines will
+be written to the map's history file for later reference (read with
+<tt>v.info&nbsp;-h</tt>). The skip option only works in <b>points</b> mode.
+
+<p>Any line starting with the hash character ('<tt>#</tt>') will be treated as
+a comment and skipped completely if located in the main data file. If located
+in the header, as defined by the <b>skip</b> parameter, it will be treated as
+a header line and written to the history file.
+
+<h3>Import of sexagesimal degree (degree, minutes, seconds, DMS)</h3>
+
+The import of DMS formatted degrees is supported (in this case no sign
+but N/S, E/W characters are used to indicate the hemispheres).  While
+the positions are internally translated into decimal degrees during
+the import, the original DMS values are maintained in the attribute
+table. This requires both the latitude and the longitude columns to be
+defined as <tt>varchar()</tt>, not as numbers.  A warning will be
+issued which can be ignored. See <a href="vectorascii.html">GRASS
+ASCII vector format specification</a> for details.
+
+<h3>Importing only selected columns</h3>
+Although <em>v.in.ascii</em> doesn't have an option to specify which columns
+should be imported, you can use a shell filter to achieve the same effect,
+e.g.:
+
+<div class="code"><pre>
+# Print out the column number for each field, supposing the file has a header
+head -1 input_file | tr '&lt;the_field_separator_character&gt;' '\n' | cat -n
+# From the listing, select the columns you want and feed them to v.in.ascii
+# do not use the input= option
+cut -d&lt;the_field_separator_character&gt; -f&lt;comma-separated_list_of_columns&gt; input_file | v.in.ascii &lt;your_options&gt;
+</pre></div>
+
+
+<h2>EXAMPLES</h2>
+
+<h3>Example 1a) - standard format mode</h3>
+Sample ASCII polygon vector map for 'standard' format mode. 
+The two areas will be assigned categories 20 and 21. 
+<p><div class="code"><pre>
+echo "ORGANIZATION: GRASS Development Team
+DIGIT DATE:   1/9/2005
+DIGIT NAME:   -
+MAP NAME:     test
+MAP DATE:     2005
+MAP SCALE:    10000
+OTHER INFO:   Test polygons
+ZONE:  0
+MAP THRESH:   0.500000
+VERTI:
+B  6
+ 5958812.48844435 3400828.84221011
+ 5958957.29887089 3400877.11235229
+ 5959021.65906046 3400930.7458436
+ 5959048.47580612 3400973.65263665
+ 5959069.92920264 3401032.64947709
+ 5958812.48844435 3400828.84221011
+C  1 1
+ 5958952.42189184 3400918.23126419
+ 1 20
+B  4
+ 5959010.9323622 3401338.36037757
+ 5959096.7459483 3401370.54047235
+ 5959091.38259917 3401450.99070932
+ 5959010.9323622 3401338.36037757
+C  1 1
+ 5959063.08352122 3401386.98533277
+ 1 21" | v.in.ascii format=standard output=test_polygons
+</pre></div>
+
+<h3>Example 1b) - standard format mode</h3>
+
+Sample ASCII 3D line vector map for 'standard' format mode with simplified input
+(note the space field separator).
+Note the <b>-z</b> flag indicating 3D vector input, and the <b>-n</b> flag
+indicating no vector header should be expected from the input file.
+
+<div class="code"><pre>
+echo "L 5 1
+591336 4927369 1224
+594317 4925341 1292
+599356 4925162 1469
+602396 4926653 1235
+607524 4925431 1216
+1 321 " | v.in.ascii -zn out=line3d format=standard
+</pre></div>
+
+This can be used to create a vector line of a GPS track: the GPS points have
+to be stored into a file with a preceding 'L' and the number of points (per line).
+
+<h3>Example 2 - point format mode</h3>
+
+Generate a 2D points vector map 'coords.txt' as ASCII file:
+<div class="code"><pre>
+1664619|5103481
+1664473|5095782
+1664273|5101919
+1663427|5105234
+1663709|5102614
+</pre></div>
+
+<p>Import into GRASS:
+<div class="code"><pre>
+v.in.ascii input=coords.txt output=mymap
+</pre></div>
+As the <b>cat</b> option is set to 0 by default, an extra column 'cat'
+containing the category numbers will be auto-generated.
+
+<h3>Example 3 - point format mode</h3>
+
+Generate a 2D points vector map 'points.dat' as ASCII file:
+<div class="code"><pre>
+1|1664619|5103481|studna
+2|1664473|5095782|kadibudka
+3|1664273|5101919|hruska
+4|1663427|5105234|mysi dira
+5|1663709|5102614|mineralni pramen
+</pre></div>
+
+<p>Import into GRASS:
+<div class="code"><pre>
+cat points.dat | v.in.ascii out=mypoints x=2 y=3 cat=1 \
+    columns='cat int, x double precision, y double precision, label varchar(20)'
+</pre></div>
+
+<p>The module is reading from standard input, using the default '|' (pipe) delimiter.
+
+<h3>Example 4 - point format mode</h3>
+
+Generating a 3D points vector map from DBMS (idcol must be an integer column):<br>
+<div class="code"><pre>
+echo "select east,north,elev,idcol from mytable" | db.select -c | v.in.ascii -z out=mymap
+</pre></div>
+
+The module is reading from standard input, using the default '|' (pipe) delimiter.
+<br>
+The import works for 2D maps as well (no elev column and no '-z' flag).
+
+
+<h3>Example 5 - point format mode</h3>
+
+Generate a 3D points vector map 'points3d.dat' with attributes as ASCII file:
+<div class="code"><pre>
+593493.1|4914730.2|123.1|studna|well
+591950.2|4923000.5|222.3|kadibudka|closet
+589860.5|4922000.0|232.3|hruska|pear
+590400.5|4922820.8|143.2|mysi dira|mouse hole
+593549.3|4925500.7|442.6|mineralni pramen|mineral spring
+600375.7|4925235.6|342.2|kozi stezka|goat path
+</pre></div>
+<p>Import into GRASS:
+<div class="code"><pre>
+#As the 'cat' option is set to 0 by default, an extra column 'cat'
+#containing the IDs will be auto-generated (no need to define that):
+cat points3d.dat | v.in.ascii -z z=3 cat=0 out=mypoints3D \
+    columns='x double precision, y double precision, z double precision, \
+    label_cz varchar(20), label_en varchar(20)'
+v.info -c mypoints3D
+v.info mypoints3D
+</pre></div>
+
+
+<h3>Example 6 - point format mode</h3>
+
+Generate points file by clicking onto the map:
+<div class="code"><pre>
+#For LatLong locations:
+d.where -d -l | awk '{printf "%f|%f|point\n", $1, $2}' | v.in.ascii out=points \
+    columns='x double precision, y double precision, label varchar(20)'
+
+#For other projections:
+d.where | awk '{printf "%f|%f|point\n", $1, $2}' | v.in.ascii out=points \
+    columns='x double precision, y double precision, label varchar(20)'
+</pre></div>
+
+The 'point' string (or some similar entry) is required to generate a database table.
+When simply piping the coordinates (and optionally height) without additional column(s) 
+into <em>v.in.ascii</em>, only the vector map geometry will be generated.
+
+<h3>Example 7 - point format mode</h3>
+
+Convert ground control points into vector points:
+<div class="code"><pre>
+cat $MAPSET/group/$GROUP/POINTS | v.in.ascii out=$GROUP_gcp fs=space skip=3 \
+    col='x double precision, y double precision, x_target double precision, \
+    y_target double precision, ok int'
+</pre></div>
+
+<h2>REFERENCES</h2>
+
+<a href="sql.html">SQL command notes</a> for creating databases
+<br>
+<a href="vectorascii.html">GRASS ASCII vector format</a> specification
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="db.execute.html">db.execute</a>,
+<a href="r.in.ascii.html">r.in.ascii</a>,
+<a href="r.in.xyz.html">r.in.xyz</a>,
+<a href="v.build.html">v.build</a>,
+<a href="v.build.polylines.html">v.build.polylines</a>,
+<a href="v.centroids.html">v.centroids</a>,
+<a href="v.clean.html">v.clean</a>,
+<a href="v.db.connect.html">v.db.connect</a>,
+<a href="v.info.html">v.info</a>,
+<a href="v.out.ascii.html">v.out.ascii</a>,
+</em>
+
+<h2>AUTHORS</h2>
+
+Michael Higgins,
+U.S.Army Construction Engineering 
+Research Laboratory<br>
+James Westervelt, U.S.Army Construction Engineering 
+Research Laboratory<br>
+Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date: 2011-11-08 22:24:20 +0100 (Tue, 08 Nov 2011) $</i>



More information about the grass-commit mailing list