Dev - C++ - Ayuda C++

 
Vista:
sin imagen de perfil

Ayuda C++

Publicado por Emma (2 intervenciones) el 16/03/2016 13:36:52
Buenos días,

Necesito ayuda con mi código para un trabajo fin de Grado. Funcionaba hasta ahora, pero con un nuevo archivo que he corrido hoy, me sale el mensaje de "Violación de segmento". Después de leer foros y buscar ayudas, he sido incapaz de arreglarlo :0

El código lee una serie de nodos y elementos de una malla 3D que sale de abaqus y los convierte en un formato que pueda leer un software de procesado de imagenes como Mimics. Funciona con todos las mallas 3D que había probado hasta ahora.

Agradezco de antemano cualquier ayuda :0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
#include <iostream>
#include <fstream>
#include <vector>
#include <stdlib.h>
#include <string.h>
 
/*convert mm to m*/
#define SCALE 1
 
/* compile with:
	g++ -o abq_to_amira abq_to_amira.cpp
options -O=0 -d for debug

(valgrind) ./abq_to_amira -f test.inp
*/
 
/*some algebra.c routines*/
void invers4gaussj(double T[4][4], double TI[4][4]);
void multve4(double a[4][4], double b[4], double c[4]);
 
using namespace std;
 
typedef struct _node
{
	int id;
	float coords[3];
} node;
 
typedef struct _elm
{
	int id;
	int nodes[4];
} element;
 
bool findtag(ifstream& fp, char *tag)
{
	/*searches through fp to find text specified by *tag.
	  returns true if found, with fp pointing to beginning
	  of line containing tag. Returns false otherwise*/
	long pos=fp.tellg();
	string line;
	string::size_type posn;
 
	getline(fp, line);
 
	while(!fp.eof())
	{
		if((posn=line.find(tag))!=string::npos)
		{ /*found our tag- reset ifstream to beginning of line and exit*/
			fp.seekg(pos);
			return true;
		}
		pos=fp.tellg();
		getline(fp, line);
	}
	if(fp.eof()) return false;
}
 
bool peakline(ifstream& fp, char *tag)
{
	long pos=fp.tellg();
	string line;
	string::size_type posn;
 
	getline(fp, line);
	fp.seekg(pos);
	if((posn=line.find(tag))!=string::npos) return true;
	else return false;
}
 
int getorder(ifstream& fp)
{ //determine element type
	long pos=fp.tellg();
	string::size_type posn;
	string line;
	string type;
	getline(fp, line);
	fp.seekg(pos);
 
	/*finding text within strings is case-sensitive. We will limit
	  checks to all upper case or all lower case*/
	if((posn=line.find("type="))!=string::npos)
	{
		if((posn=line.find("c3d", posn+5))!=string::npos)
		{
			if(line[posn+3]=='4') return 1; //first order tet
			else if(line[posn+3]=='1' && line[posn+4]=='0') return 2; //second order tet
			else return -3; //not a tet
		}
		else if((posn=line.find("C3D", posn+5))!=string::npos)
		{
			if(line[posn+3]=='4') return 1; //first order tet
			else if(line[posn+3]=='1' && line[posn+4]=='0') return 2; //second order tet
			else return -3; //not a tet
		}
		else return -2; //not solid elements
	}
	else if((posn=line.find("TYPE="))!=string::npos)
	{
		if((posn=line.find("c3d", posn+5))!=string::npos)
		{
			if(line[posn+3]=='4') return 1; //first order tet
			else if(line[posn+3]=='1' && line[posn+4]=='0') return 2; //second order tet
			else return -3; //not a tet
		}
		else if((posn=line.find("C3D", posn+5))!=string::npos)
		{
			if(line[posn+3]=='4') return 1; //first order tet
			else if(line[posn+3]=='1' && line[posn+4]=='0') return 2; //second order tet
			else return -3; //not a tet
		}
		else return -2; //not solid elements
	}
	else return -1; //element type not found
}
 
 
int main(int argc, char** argv)
{
	ifstream ifp;
	string filename;
 
	string::size_type len;
 
	double xfm[4][4];
	double xfm_inv[4][4];
 
	double b[4], c[4];
 
	int i,j,k;
 
	int transform=0;
 
	for(i=1;i<argc;i++)
	{
		if(!strncmp(argv[i], "-h", 2))
		{
			cout << "Usage:  abq_to_amira (-h -f <input file> -t)" << endl << endl;
 
			cout << "Convert and abaqus input file to amira mesh. The input file must contain" << endl;
			cout << "All nodes and element definitions to completely define the mesh. The program" << endl;
			cout << "Will not follow *INCLUDE links." << endl << endl;
			cout << "Optional parameters:" << endl;
			cout << "-h\t\tHelp" << endl;
			cout << "-f <input file>\t the name of the ABAQUS input file to read.  If the parameter" << endl;
			cout << "\t\tis omitted, femur.inp is used.  If the input file cannot be found" << endl;
			cout << "\t\tabq_to_amira exits with an error." << endl;
			cout << "-t\t\t Apply transform to nodes, e.g. femur-to-ct coordinate transform. The" << endl;
			cout << "\t\ttransform should be in the file xfm.txt, and for a transform matrix A," << endl;
			cout << "\t\tcoordinate p in the CT-coordsys and p' in the femur coordsys, p'=Ap." << endl;
			cout << "\t\tThe contents of the file are a one-dimensional array separated by spaces," << endl;
			cout << "\t\tand elements [0] [1] [2] [3] are the first *column* of matrix A (amira format)." << endl;
 
			exit (0);
		}
 
		if(!strncmp(argv[i], "-t", 2))
		{/*Apply transform to abaqus mesh before writing amira mesh*/
			transform=1;
			ifstream tmp("xfm.txt");
			for(j=0;j<4;j++)
			{
				for(k=0;k<4;k++)
				{
					tmp>>xfm[k][j]; //amira xfm matrix is transposed!
					if(tmp.fail())
					{
						cout << "Error reading transpose matrix" << endl;
						exit(1);
					}
					cout << xfm[k][j] << " ";
				}
			}
			cout << endl;
			tmp.close();
			invers4gaussj(xfm, xfm_inv);
			continue;
		}
 
		if(!strncmp(argv[i], "-f", 2))
		{/*use filename given after -f argument*/
			if(i>argc-2)
			{
				printf("Error: must give a file name with -f option\n");
				exit(1);
			}
			filename=string(argv[i+1]);
			i++;
			continue;
		}
		else
		{
			printf("Unknown option: %s\n", argv[i]);
		}
	}
 
	if((len=filename.size())<4)
	{
		filename=string("femur.inp");
	}
 
	ifp.open(filename.c_str());
 
	if(!ifp)
	{
		cout << "Input file not found" << endl;
		exit(1);
	}
 
	ofstream ofp("amira.mesh");
	if(!ofp)
	{
		cout << "Error opening output file." << endl;
		exit(1);
	}
 
	ofstream ofp2("amira.elm");
	if(!ofp2)
	{
		cout << "Error opening output file2." << endl;
		exit(1);
	}
 
	//read from file into the following
	node tnode;
	element telement;
 
	//if read from file was successful, load into vectors:
	vector<node> nodes;
	vector<int> sortnodes; /*a look-up table to help find correct node (in case gaps in node numbers)*/
	vector<element> elements;
 
	size_t numnodes;
	size_t numelements;
 
	int elmtype; //C3D4 or C3D10
 
 
	string line;
	char d; //to hold comma from unformated input
 
	if(!findtag(ifp, "*NODE"))
	{
		cout << "Couldn't find any nodes. Make sure '*Node' section exists." << endl;
		exit(1);
	}
 
	getline(ifp, line);
 
	/*we are now at beginning of node definitions*/
	/*iterate until we find the next command/comment line*/
	while(!peakline(ifp, "*"))
	{
		ifp >> tnode.id >> d >> tnode.coords[0] >> d >> tnode.coords[1] >> d >> tnode.coords[2];
//		cout << tnode.id << " " << tnode.coords[0]<< " " << tnode.coords[1] << " " << tnode.coords[2] << endl;
		if(ifp.fail())
		{
			cout << "Problem with node definitions." << endl;
			cout << "Last node: " << tnode.id << endl;
			exit(1);
		}
		ifp.ignore(256, '\n');
		nodes.push_back(tnode);
	}
 
	cout << "End of node definitions." << endl;
 
	/*now copy the nodes so that the vector index == node id. Pre-allocate the size
	  with the last node id*/
	sortnodes.reserve(nodes.back().id);
	for(i=0;i<nodes.size();i++)
	{
		sortnodes[nodes[i].id]=i+1; //node numbers start at 1, not 0 for amira mesh
	}
 
	if(!findtag(ifp, "*E"))
	{
		cout << "Couldn't find any elements. Make sure at least one '*Element' section exists." << endl;
		exit(1);
	}
 
	while(!ifp.eof())
	{
		elmtype=getorder(ifp);
		cout << "Elements: " << elmtype << endl;
		numelements=elements.size();
		if(elmtype<0)
		{
			if(numelements==0)
			{
				cout << "No valid element types, CODE " << elmtype << endl;
				exit(1);
			}
			else break;
		}
 
		getline(ifp, line);
		//now at beginning of element definitions
		while(!peakline(ifp, "*"))
		{
			ifp >> telement.id >> d >> telement.nodes[0] >> d >> telement.nodes[1] >> d >> telement.nodes[2] >> d >> telement.nodes[3];
			cout << telement.id << " " << telement.nodes[0] << " " << telement.nodes[3] << endl;
			if(ifp.fail())
			{
				if(numelements==0)
				{
					cout << "Problem with element definitions." << endl;
					exit(1);
				}
				else
				{
					cout << "File read error: possible end of file. Last element read: " << telement.id << endl;
					cout << "Continuing with current elements." << endl;
					break;
				}
			}
			ifp.ignore(256, '\n');
			//if(elmtype==2) getline(ifp, line);
			elements.push_back(telement);
		}
 
		//finished an element set. Jump ahead to see if there are any more, and continue
		if((!ifp.good()) || (!findtag(ifp, "*ELEMENT,")))
		{
			cout << "End of element definitions." << endl;
			break;
		}
	}
 
	//write element order file header
	ofp2 << "Element numbers in abaqus input file." << endl;
 
	//write amira file header
	ofp << "# AmiraMesh ASCII 1.0" << endl << endl;
	ofp << "define Nodes " << nodes.size() << endl;
	ofp << "define Tetrahedra " << elements.size() << endl << endl;
	ofp << "Nodes { float[3] Coordinates } = @1" << endl;
	ofp << "Tetrahedra { int[4] Nodes } = @2" << endl << endl;
 
	ofp << "@1" << endl;
	for(i=0; i<nodes.size(); i++)
	{
		if(transform)
		{
			b[0]=nodes[i].coords[0]/SCALE;  b[1]=nodes[i].coords[1]/SCALE;  b[2]=nodes[i].coords[2]/SCALE;  b[3]=1;
			multve4(xfm_inv, b, c);
		}
		else
		{
			c[0]=nodes[i].coords[0]/SCALE;  c[1]=nodes[i].coords[1]/SCALE;  c[2]=nodes[i].coords[2]/SCALE;  c[3]=1;
		}
		ofp << c[0] << "\t" << c[1] << "\t" << c[2] << endl;
	}
	ofp << endl;
 
	ofp << "@2" << endl;
 
	for(i=0; i<elements.size(); i++)
	{
	/*need to handle missing node numbers- i.e. get node by id, not by vector index*/
		telement=elements[i];
 
		ofp << sortnodes[telement.nodes[0]] << "\t" << sortnodes[telement.nodes[1]] << "\t" << sortnodes[telement.nodes[2]] << "\t" << sortnodes[telement.nodes[3]] << endl;
		ofp2 << elements[i].id << ", " << endl;
	}
	ofp << endl;
 
 
	ifp.close();
	ofp.close();
	ofp2.close();
}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Ayuda C++

Publicado por Juan Carlos (3 intervenciones) el 23/03/2016 10:25:23
Hola Emma, si talves pueda ayudarte si adjuntas un archivo en el que el programa funcione bien y el
archivo con el que no.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Ayuda C++

Publicado por Emma (2 intervenciones) el 04/05/2016 10:39:16
Muchas gracias por tu respuesta Juan Carlos! Tienes razón...si un ejemplo para correrlo es difícil que me podáis ayudar ;) Adjunto unos ejemplos y el código completo.

Para correrlo hay que copiar el archivo de ejemplo en la carpeta Program y escribir en la consola: ./abq_to_amira1 -f Ejemplo.inp

Muchisimas gracias de nuevo!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar