⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readwrite.c

📁 su 的源代码库
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       *//*********************** self documentation **********************//*****************************************************************************READWRITE - READ or WRITE a triangulated modelreadModel		Read a model in the form produced by writeModelwriteModel		Write a model to a file******************************************************************************Function Prototypes:Model *readModel (FILE *fp);void writeModel (Model *m, FILE *fp);******************************************************************************readModel:Input:fp		file pointer to file containing modelwriteModel:Input:m		pointer to Modelfp		file pointer******************************************************************************Author:  Jack K. Cohen, Center for Wave Phenomena, 09/21/90Modified:  Dave Hale, Center for Wave Phenomena, 11/30/90	Converted representation of model from ascii to binary for speed.	Added code to read attributes.Modified (writeModel):  Craig Artley, Center for Wave Phenomena, 04/08/94	Corrected bug;  previously the edgeuses and vertextuses of the	exterior face were not written.******************************************************************************//**************** end self doc ********************************/#include "Triangles/triP.h"/* functions defined and used internally */static void createModel (Model **mptr, Address **fheadptr, FILE *fp);static void createFace (Model *m, Address **fheadptr, Address **euheadptr,	size_t sfa, FILE *fp);static void createEdgeUse (Address **fheadptr, Address **euheadptr,	Address **vuheadptr, Address **eheadptr, size_t seua, FILE *fp);static void createVertexUse (Address **euheadptr, Address **vuheadptr,	Address **vheadptr, size_t svua, FILE *fp);static void createEdge (Address **euheadptr, Address **eheadptr, size_t sea,	FILE *fp);static void createVertex (Address **vuheadptr, Address **vheadptr, size_t sva,	FILE *fp);static Address *fillAddress (Address *head, address_t oa, address_t na);static Address *getAddress (Address *head, address_t oa, address_t *value);/* macros */#define DONODE(node, headptr, oa, type)				\{								\	int found;						\	address_t value;					\	headptr = updateAddressTree(headptr, oa, &found);	\	if (!found) {						\		node = (type *) malloc(sizeof(type));		\		headptr = fillAddress(headptr, oa, node);	\	} else {						\		headptr = getAddress(headptr, oa, &value);	\		node = (type *) value;				\	}							\}#define DOFIELD(node, field, headptr, oa, type)			\{								\	int found;						\	address_t value;					\	type *field;						\	headptr = updateAddressTree(headptr, oa, &found);	\	if (!found) {						\		field = (type *) malloc(sizeof(type));		\		headptr = fillAddress(headptr, oa, field);	\		node->field = field;				\	} else {						\		headptr = getAddress(headptr, oa, &value);	\		node->field = (type *) value;			\	}							\}Model *readModel (FILE *fp)/*****************************************************************************readModel - Read a model in the form produced by writeModel******************************************************************************Input:fp		file pointer to file containing model******************************************************************************Author:  Jack K. Cohen, Center for Wave Phenomena, 09/21/90Modified:  Dave Hale, Center for Wave Phenomena, 11/30/90	Converted representation of model from ascii to binary for speed.	Added code to read attributes.******************************************************************************/{	Model *m;		/* pointer to model to be returned */	Address *fhead  = NULL;	/* pointers to binary trees	*/	Address *euhead = NULL;	Address *vuhead = NULL;	Address *ehead  = NULL;	Address *vhead  = NULL;	int type;		while(fread(&type,sizeof(int),1,fp)) {		if (type==MODELTYPE) {			createModel(&m,&fhead,fp);		} else if (type==FACETYPE) {			createFace(m,&fhead,&euhead,m->sfa,fp);		} else if (type==EDGEUSETYPE) {			createEdgeUse(&fhead,&euhead,&vuhead,&ehead,				m->seua,fp);		} else if (type==VERTEXUSETYPE) {			createVertexUse(&euhead,&vuhead,&vhead,m->svua,fp);		} else if (type==EDGETYPE) {			createEdge(&euhead,&ehead,m->sea,fp);		} else if (type==VERTEXTYPE) {			createVertex(&vuhead,&vhead,m->sva,fp);		} else {			fprintf(stderr,"invalid type in model\n");			exit(EXIT_FAILURE);		}	}	return m;}static void createModel(Model **mptr, Address **fheadptr, FILE *fp){	Model *m;	Face *f;	int found;	*mptr = m = (Model*)malloc(sizeof(Model));	fread(m,sizeof(address_t),1,fp);	if (fread(m,sizeof(Model),1,fp)!=1) {		fprintf(stderr,"error reading Model\n");		exit(EXIT_FAILURE);	}	*fheadptr = updateAddressTree(*fheadptr,m->f,&found);	if (!found) {		f = (Face*)malloc(sizeof(Face));		*fheadptr = fillAddress(*fheadptr,m->f,f);		m->f = f;	} else {		fprintf(stderr,"Model's first face already exists\n");		exit(EXIT_FAILURE);	}	m->vAdd = NULL;	m->vDel = NULL;	m->tAdd = NULL;	m->tDel = NULL;	if (m->ma!=NULL && m->sma!=0) {		m->ma = malloc(m->sma);		if (fread(m->ma,m->sma,1,fp)!=1) {			fprintf(stderr,"error reading model attributes\n");			exit(EXIT_FAILURE);		}	} else {		m->ma = NULL;	}}static void createFace (Model *m, Address **fheadptr, Address **euheadptr,	size_t sfa, FILE *fp){	Face *of,*f;	fread(&of,sizeof(Face*),1,fp);	DONODE(f,*fheadptr,of,Face);	if (fread(f,sizeof(Face),1,fp)!=1) {		fprintf(stderr,"error reading Face\n");		exit(EXIT_FAILURE);	}	f->m = m;	DOFIELD(f,fPrev,*fheadptr,f->fPrev,Face);	DOFIELD(f,fNext,*fheadptr,f->fNext,Face);	DOFIELD(f,eu,*euheadptr,f->eu,EdgeUse);	if (f->fa!=NULL && sfa!=0) {		f->fa = malloc(sfa);		if (fread(f->fa,sfa,1,fp)!=1) {			fprintf(stderr,"error reading FaceAttributes\n");			exit(EXIT_FAILURE);		}	} else {		f->fa = NULL;	}}static void createEdgeUse (Address **fheadptr, Address **euheadptr,	Address **vuheadptr, Address **eheadptr, size_t seua, FILE *fp){	EdgeUse *oeu,*eu;		fread(&oeu,sizeof(EdgeUse*),1,fp);	DONODE(eu,*euheadptr,oeu,EdgeUse);	if (fread(eu,sizeof(EdgeUse),1,fp)!=1) {		fprintf(stderr,"error reading EdgeUse\n");		exit(EXIT_FAILURE);	}	if (eu->f==NULL) eu->f = NULL;	else DOFIELD(eu,f,*fheadptr,eu->f,Face);	DOFIELD(eu,vu,*vuheadptr,eu->vu,VertexUse);	DOFIELD(eu,euMate,*euheadptr,eu->euMate,EdgeUse);	DOFIELD(eu,euCW,*euheadptr,eu->euCW,EdgeUse);	DOFIELD(eu,euCCW,*euheadptr,eu->euCCW,EdgeUse);	DOFIELD(eu,e,*eheadptr,eu->e,Edge);	if (eu->eua!=NULL && seua!=0) {		eu->eua = malloc(seua);		if (fread(eu->eua,seua,1,fp)!=1) {			fprintf(stderr,"error reading edge-use attributes\n");			exit(EXIT_FAILURE);		}	} else {		eu->eua = NULL;	}}static void createVertexUse (Address **euheadptr, Address **vuheadptr,	Address **vheadptr, size_t svua, FILE *fp){	VertexUse *ovu,*vu;		fread(&ovu,sizeof(VertexUse*),1,fp);	DONODE(vu,*vuheadptr,ovu,VertexUse);	if (fread(vu,sizeof(VertexUse),1,fp)!=1) {		fprintf(stderr,"error reading VertexUse\n");		exit(EXIT_FAILURE);	}	DOFIELD(vu,eu,*euheadptr,vu->eu,EdgeUse);	DOFIELD(vu,vuPrev,*vuheadptr,vu->vuPrev,VertexUse);	DOFIELD(vu,vuNext,*vuheadptr,vu->vuNext,VertexUse);	DOFIELD(vu,v,*vheadptr,vu->v,Vertex);	if (vu->vua!=NULL && svua!=0) {		vu->vua = malloc(svua);		if (fread(vu->vua,svua,1,fp)!=1) {			fprintf(stderr,				"error reading vertex-use attributes\n");			exit(EXIT_FAILURE);		}	} else {		vu->vua = NULL;	}}static void createEdge (Address **euheadptr, Address **eheadptr, size_t sea,	FILE *fp){	Edge *oe,*e;		fread(&oe,sizeof(Edge*),1,fp);	DONODE(e,*eheadptr,oe,Edge);	if (fread(e,sizeof(Edge),1,fp)!=1) {		fprintf(stderr,"error reading Edge\n");		exit(EXIT_FAILURE);	}	DOFIELD(e,eu,*euheadptr,e->eu,EdgeUse);	if (e->ea!=NULL && sea!=0) {		e->ea = malloc(sea);		if (fread(e->ea,sea,1,fp)!=1) {			fprintf(stderr,"error reading edge attributes\n");			exit(EXIT_FAILURE);		}	} else {		e->ea = NULL;	}}static void createVertex (Address **vuheadptr, Address **vheadptr, size_t sva,	FILE *fp){	Vertex *ov,*v;		fread(&ov,sizeof(Vertex*),1,fp);	DONODE(v,*vheadptr,ov,Vertex);	if (fread(v,sizeof(Vertex),1,fp)!=1) {		fprintf(stderr,"error reading Vertex");		exit(EXIT_FAILURE);	}	DOFIELD(v,vu,*vuheadptr,v->vu,VertexUse);	if (v->va!=NULL && sva!=0) {		v->va = malloc(sva);		if (fread(v->va,sva,1,fp)!=1) {			fprintf(stderr,"error reading vertex attributes\n");			exit(EXIT_FAILURE);		}	} else {		v->va = NULL;	}}static Address *fillAddress(Address *p, address_t oa, address_t na)/* tree searcher to register the newly allocated address */{	int sign;	if (p == NULL) {  /* not in tree--error */		fprintf(stderr, "fillAddress called on non-existent node\n");		exit(EXIT_FAILURE);	}	else if ((sign = (int)oa - (int)(p->oaddress)) < 0)		p->aLeft = fillAddress(p->aLeft, oa, na);	else if (sign > 0)		p->aRight = fillAddress(p->aRight, oa, na);	else /* sign == 0; we've found the entry to fill */		p->naddress = na;	return p;}static Address *getAddress(Address *p, address_t oa, address_t *value)/* tree searcher to fetch a newly allocated address */{	int sign;	if (p == NULL) {  /* not in tree--error */		fprintf(stderr, "getAddress called on non-existent node\n");		exit(EXIT_FAILURE);	}	else if ((sign = (int)oa - (int)(p->oaddress)) < 0)		p->aLeft = getAddress(p->aLeft, oa, value);	else if (sign > 0)		p->aRight = getAddress(p->aRight, oa, value);	else /* sign == 0; we've found the value to return */		*value = p->naddress;	return p;}#ifdef TESTmain(){	Model *m;	m = readModel(0,0,0,0,0,0,stdin);	writeModel(m,0,0,0,0,0,0,stdout);}#endif/* functions defined and used internally */static void _writeModel (FILE *fp, Model *m, size_t sma);static void writeFace (FILE *fp, Face *f, size_t sfa);static void writeEdgeUse (FILE *fp, EdgeUse *eu, size_t seua);static void writeEdge (FILE *fp, Edge *e, size_t sea);static void writeVertexUse (FILE *fp, VertexUse *vu, size_t svua);static void writeVertex (FILE *fp, Vertex *v, size_t sva);void writeModel (Model *m, FILE *fp)/*****************************************************************************writeModel - Write a model to a file******************************************************************************Input:m		pointer to Modelfp		file pointer******************************************************************************Author:    Jack K. Cohen, Center for Wave Phenomena, 09/15/90Modified:  Dave Hale, Center for Wave Phenomena, 11/29/90	Converted representation of model from ascii to binary for speed.	Added code to write attributes.Modified:  Craig Artley, Center for Wave Phenomena, 04/08/94	Corrected bug;  previously the edgeuses and vertextuses of the	exterior face were not written.******************************************************************************/{	Face *f;	EdgeUse *eu,*euFirst;	Address *vhead=NULL,*ehead=NULL;	int repeat;	/* write the model data */	_writeModel(fp,m,m->sma);	/* loop over all faces in model */	f = m->f;	do {			writeFace(fp,f,m->sfa);		/* loop over all edgeuses in face */		eu = f->eu;		do {					/* write edgeuse, edge, vertexuse, and vertex */			writeEdgeUse(fp,eu,m->seua);			ehead = updateAddressTree(ehead,eu->e,&repeat);			if (!repeat) writeEdge(fp,eu->e,m->sea);			writeVertexUse(fp,eu->vu,m->svua);			vhead = updateAddressTree(vhead,eu->vu->v,&repeat);			if (!repeat) writeVertex(fp,eu->vu->v,m->sva);							/* next edgeuse */			eu = eu->euCW;		} while (eu!=f->eu);				/* next face */		f = f->fNext;	} while (f!=m->f);	/* loop over all faces in model, looking for the exterior */	f = m->f;	do {		/* find an edgeuse belonging to the exterior face */		if (f->eu->euMate->f==NULL) {			eu = f->eu->euMate;			break;		} else if (f->eu->euCW->euMate->f==NULL) {			eu = f->eu->euCW->euMate;			break;		} else if (f->eu->euCCW->euMate->f==NULL) {			eu = f->eu->euCCW->euMate;			break;		}		/* next face */		f = f->fNext;	} while (f!=m->f);	/* confirm the resulting edgeuse belongs to the exterior */	if (eu->f!=NULL) {		fprintf(stderr,"writeModel: can't find exterior face\n");		exit(EXIT_FAILURE);	}	/* loop over all edgeuses in exterior face */	euFirst = eu;	do {		/* write edgeuse and vertexuse (edges & vertices done above) */		writeEdgeUse(fp,eu,m->seua);		writeVertexUse(fp,eu->vu,m->svua);		/* next edgeuse */		eu = eu->euCW;	} while (eu!=euFirst);}static void _writeModel(FILE *fp, Model *m, size_t sma){	int type=MODELTYPE;	fwrite(&type,sizeof(int),1,fp);	fwrite(&m,sizeof(Model*),1,fp);	fwrite(m,sizeof(Model),1,fp);	if (m->ma!=NULL && sma!=0) fwrite(m->ma,sma,1,fp);}static void writeFace(FILE *fp, Face *f, size_t sfa){	int type=FACETYPE;	fwrite(&type,sizeof(int),1,fp);	fwrite(&f,sizeof(Face*),1,fp); 	fwrite(f,sizeof(Face),1,fp);	if (f->fa!=NULL && sfa!=0) fwrite(f->fa,sfa,1,fp);}static void writeEdgeUse(FILE *fp, EdgeUse *eu, size_t seua){	int type=EDGEUSETYPE;	fwrite(&type,sizeof(int),1,fp);	fwrite(&eu,sizeof(EdgeUse*),1,fp);	fwrite(eu,sizeof(EdgeUse),1,fp);	if (eu->eua!=NULL && seua!=0) fwrite(eu->eua,seua,1,fp);}static void writeEdge(FILE *fp, Edge *e, size_t sea){	int type=EDGETYPE;	fwrite(&type,sizeof(int),1,fp);	fwrite(&e,sizeof(Edge*),1,fp);	fwrite(e,sizeof(Edge),1,fp);	if (e->ea!=NULL && sea!=0) fwrite(e->ea,sea,1,fp);}static void writeVertexUse(FILE *fp, VertexUse *vu, size_t svua){	int type=VERTEXUSETYPE;	fwrite(&type,sizeof(int),1,fp);	fwrite(&vu,sizeof(VertexUse*),1,fp);	fwrite(vu,sizeof(VertexUse),1,fp);	if (vu->vua!=NULL && svua!=0) fwrite(vu->vua,svua,1,fp);}static void writeVertex(FILE *fp, Vertex *v, size_t sva){	int type=VERTEXTYPE;	fwrite(&type,sizeof(int),1,fp);	fwrite(&v,sizeof(Vertex*),1,fp);	fwrite(v,sizeof(Vertex),1,fp);	if (v->va!=NULL && sva!=0) fwrite(v->va,sva,1,fp);}#ifdef TESTmain(){	Model *m;	m = makeModel(1.0,2.0,5.0,6.0);	writeModel(m,stdout);}#endifAddress *updateAddressTree(Address *p, address_t oa, int *found)/* add nodes to a tree on the fly--after Kernighan and Ritchie, *//* The C Programming Language, 2nd Edition, p. 139ff. *//* Used internally in readModel() and writeModel(). */{	int sign;	if (p == NULL) {  /* not in tree */		p = (Address*) malloc(sizeof(Address));		p->oaddress = oa;		p->aLeft = p->aRight = NULL;		*found = 0;	}	else if ((sign = ((int)oa - (int)(p->oaddress))) < 0)		p->aLeft = updateAddressTree(p->aLeft, oa, found);	else if (sign > 0)		p->aRight = updateAddressTree(p->aRight, oa, found);	else /* sign == 0; we've found the entry */		*found = 1;	return p;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -