3
* ***** BEGIN GPL LICENSE BLOCK *****
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20
* All rights reserved.
25
* Added dxf_read_arc, dxf_read_ellipse and dxf_read_lwpolyline
26
* Copyright (C) 2004 by Etheract Software Labs
28
* - Blender Foundation
30
* ***** END GPL LICENSE BLOCK *****/
32
#include "BLI_storage.h"
34
#include <ctype.h> /* isdigit, isspace */
52
#include "MEM_guardedalloc.h"
54
#include "DNA_object_types.h"
55
#include "DNA_mesh_types.h"
56
#include "DNA_meshdata_types.h"
57
#include "DNA_material_types.h"
58
#include "DNA_curve_types.h"
59
#include "DNA_camera_types.h"
60
#include "DNA_scene_types.h"
62
#include "BKE_utildefines.h"
63
#include "BLI_blenlib.h"
66
#include "BKE_blender.h"
67
#include "BKE_global.h"
70
#include "BKE_library.h"
71
#include "BKE_object.h"
72
#include "BKE_material.h"
73
#include "BKE_report.h"
75
#include "BKE_displist.h"
76
#include "BKE_DerivedMesh.h"
77
#include "BKE_curve.h"
79
#ifndef DISABLE_PYTHON
80
#include "BPY_extern.h"
85
static int is_dxf(char *str);
86
static void dxf_read(Scene *scene, char *filename);
87
static int is_stl(char *str);
89
static int is_stl_ascii(char *str)
95
fpSTL = fopen(str, "rb");
96
if ( (numread = fread( (void *) buffer, sizeof(char), 1000, fpSTL)) <= 0 )
97
{ fclose(fpSTL); return 0; }
99
for (i=0; i < numread; ++i) {
100
/* if bit 8 is set we assume binary */
101
if (buffer[i] & 0x80)
102
{ fclose(fpSTL); return 0; }
106
if ( !(strstr(buffer, "solid")) && !(strstr(buffer, "SOLID")) )
107
{ fclose(fpSTL); return 0; }
114
static int is_stl(char *str)
118
if ( (str[i] !='s') && (str[i] !='S'))
121
if ( (str[i] !='t') && (str[i] !='T'))
124
if ( (str[i] !='l') && (str[i] !='L'))
130
#define READSTLVERT { \
131
if (fread(mvert->co, sizeof(float), 3, fpSTL) != 3) { \
132
char error_msg[255]; \
133
MEM_freeN(vertdata); \
134
MEM_freeN(facedata); \
136
sprintf(error_msg, "Problems reading face %d!", i); \
140
if (ENDIAN_ORDER==B_ENDIAN) { \
141
SWITCH_INT(mvert->co[0]); \
142
SWITCH_INT(mvert->co[1]); \
143
SWITCH_INT(mvert->co[2]); \
148
static void simple_vertex_normal_blend(short *no, short *ble)
150
if(no[0]==0 && no[1]==0 && no[2]==0) {
154
no[0]= (2*no[0] + ble[0])/3;
155
no[1]= (2*no[1] + ble[1])/3;
156
no[2]= (2*no[2] + ble[2])/3;
160
static void mesh_add_normals_flags(Mesh *me)
162
MVert *v1, *v2, *v3, *v4;
169
for(a=0; a<me->totface; a++, mface++) {
170
v1= me->mvert+mface->v1;
171
v2= me->mvert+mface->v2;
172
v3= me->mvert+mface->v3;
173
v4= me->mvert+mface->v4;
175
normal_tri_v3( nor,v1->co, v2->co, v3->co);
176
sno[0]= 32767.0*nor[0];
177
sno[1]= 32767.0*nor[1];
178
sno[2]= 32767.0*nor[2];
180
simple_vertex_normal_blend(v1->no, sno);
181
simple_vertex_normal_blend(v2->no, sno);
182
simple_vertex_normal_blend(v3->no, sno);
184
simple_vertex_normal_blend(v4->no, sno);
186
mface->edcode= ME_V1V2|ME_V2V3;
190
static void read_stl_mesh_binary(Scene *scene, char *str)
195
MVert *mvert, *vertdata;
196
MFace *mface, *facedata;
197
unsigned int numfacets = 0, i, j, vertnum;
198
unsigned int maxmeshsize, nummesh, lastmeshsize;
199
unsigned int totvert, totface;
200
ReportList *reports= NULL; /* XXX */
202
fpSTL= fopen(str, "rb");
204
BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno));
208
if(fseek(fpSTL, 80, SEEK_SET) != 0) {
209
BKE_reportf(reports, RPT_ERROR, "Failed reading file: %s.", strerror(errno));
214
if(fread(&numfacets, 4*sizeof(char), 1, fpSTL) != 1) {
216
BKE_reportf(reports, RPT_ERROR, "Failed reading file: premature end of file.");
218
BKE_reportf(reports, RPT_ERROR, "Failed reading file: %s.", strerror(errno));
222
if (ENDIAN_ORDER==B_ENDIAN) {
223
SWITCH_INT(numfacets);
226
maxmeshsize = MESH_MAX_VERTS/3;
228
nummesh = (numfacets / maxmeshsize) + 1;
229
lastmeshsize = numfacets % maxmeshsize;
232
for (j=0; j < nummesh; ++j) {
234
if (j == nummesh-1) {
235
totface = lastmeshsize;
238
totface = maxmeshsize;
240
totvert = 3 * totface;
242
vertdata = MEM_callocN(totvert*sizeof(MVert), "mverts");
243
facedata = MEM_callocN(totface*sizeof(MFace), "mface");
248
for (i=0; i < totface; i++) {
249
fseek(fpSTL, 12, SEEK_CUR); /* skip the face normal */
257
mface->v1 = vertnum++;
258
mface->v2 = vertnum++;
259
mface->v3 = vertnum++;
262
fseek(fpSTL, 2, SEEK_CUR);
265
ob= add_object(scene, OB_MESH);
267
me->totvert = totvert;
268
me->totface = totface;
269
me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN,
271
me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN,
274
mesh_add_normals_flags(me);
284
#define STLALLOCERROR { \
285
char error_msg[255]; \
287
sprintf(error_msg, "Can't allocate storage for %d faces!", \
288
numtenthousand * 10000); \
292
#define STLBAILOUT(message) { \
293
char error_msg[255]; \
296
sprintf(error_msg, "Line %d: %s", linenum, message); \
300
#define STLREADLINE { \
301
if (!fgets(buffer, 2048, fpSTL)) STLBAILOUT("Can't read line!"); \
305
#define STLREADVERT { \
307
if ( !(cp = strstr(buffer, "vertex")) && \
308
!(cp = strstr(buffer, "VERTEX")) ) STLBAILOUT("Bad vertex!"); \
309
vp = vertdata + 3 * totvert; \
310
if (sscanf(cp + 6, "%f %f %f", vp, vp+1, vp+2) != 3) \
311
STLBAILOUT("Bad vertex!"); \
314
static void read_stl_mesh_ascii(Scene *scene, char *str)
317
char buffer[2048], *cp;
322
float *vertdata, *vp;
323
unsigned int numtenthousand, linenum;
324
unsigned int i, vertnum;
325
unsigned int totvert, totface;
326
ReportList *reports= NULL; /* XXX */
328
/* ASCII stl sucks ... we don't really know how many faces there
329
are until the file is done, so lets allocate faces 10000 at a time */
331
fpSTL= fopen(str, "r");
333
BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno));
337
/* we'll use the standard malloc/realloc for now ...
338
* lets allocate enough storage to hold 10000 triangles,
339
* i.e. 30000 verts, i.e., 90000 floats.
342
vertdata = malloc(numtenthousand*3*30000*sizeof(float)); // uses realloc!
343
if (!vertdata) { STLALLOCERROR; }
346
/* Get rid of the first line */
352
/* Read in the next line */
355
/* lets check if this is the end of the file */
356
if ( strstr(buffer, "endsolid") || strstr(buffer, "ENDSOLID") )
359
/* Well, guess that wasn't the end, so lets make
360
* sure we have enough storage for some more faces
362
if ( (totface) && ( (totface % 10000) == 0 ) ) {
364
vertdata = realloc(vertdata,
365
numtenthousand*3*30000*sizeof(float));
366
if (!vertdata) { STLALLOCERROR; }
369
/* Don't read normal, but check line for proper syntax anyway
371
if ( !(cp = strstr(buffer, "facet")) &&
372
!(cp = strstr(buffer, "FACET")) ) STLBAILOUT("Bad normal line!");
373
if ( !(strstr(cp+5, "normal")) &&
374
!(strstr(cp+5, "NORMAL")) ) STLBAILOUT("Bad normal line!");
376
/* Read in what should be the outer loop line
379
if ( !(cp = strstr(buffer, "outer")) &&
380
!(cp = strstr(buffer, "OUTER")) ) STLBAILOUT("Bad outer loop!");
381
if ( !(strstr(cp+5, "loop")) &&
382
!(strstr(cp+5, "LOOP")) ) STLBAILOUT("Bad outer loop!");
384
/* Read in the face */
389
/* Read in what should be the endloop line
392
if ( !strstr(buffer, "endloop") && !strstr(buffer, "ENDLOOP") )
393
STLBAILOUT("Bad endloop!");
395
/* Read in what should be the endfacet line
398
if ( !strstr(buffer, "endfacet") && !strstr(buffer, "ENDFACET") )
399
STLBAILOUT("Bad endfacet!");
401
/* Made it this far? Increment face count */
406
/* OK, lets create our mesh */
407
ob = add_object(scene, OB_MESH);
410
me->totface = totface;
411
me->totvert = totvert;
412
me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
414
me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
417
/* Copy vert coords and create topology */
421
for (i=0; i < totface; ++i) {
422
memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
427
memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
432
memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
441
mesh_add_normals_flags(me);
452
/* ***************** INVENTOR ******************* */
455
#define IV_MAXSTACK 3000000
456
#define IV_MAXFIELD 10
459
static float *iv_data_stack;
460
static float ivcolors[IV_MAXCOL][3];
461
static Object *ivsurf;
462
static ListBase ivbase;
465
struct IvNode *next, *prev;
467
char *fieldname[IV_MAXFIELD];
468
int datalen[IV_MAXFIELD];
469
float *data[IV_MAXFIELD];
472
static int iv_curcol=0;
474
static int iv_colornumber(struct IvNode *iv)
476
float *fp, fr = 0.0, fg = 0.0, fb = 0.0;
480
/* search back to last material */
482
if( strcmp(iv->nodename, "Material")==0) {
484
if(fp==0) fp= iv->data[1];
492
else if( strcmp(iv->nodename, "BaseColor")==0) {
499
else if( strcmp(iv->nodename, "PackedColor")==0) {
500
cp= (char *)iv->data[0];
510
if(iv->datalen[0]<3) return 0;
512
for(a=0; a<iv_curcol; a++) {
514
if(ivcolors[a][0]== fr)
515
if(ivcolors[a][1]== fg)
516
if(ivcolors[a][2]== fb) return a+1
520
if(a>=IV_MAXCOL) a= IV_MAXCOL-1;
529
static int iv_finddata(struct IvNode *iv, char *field, int fieldnr)
531
/* search for "field", count data size and make datablock. return skipdata */
533
int len, stackcount, skipdata=0;
534
char *cpa, terminator, str[64];
540
while( *cpa != '}' ) {
542
if( *cpa == *field ) {
543
if( strncmp(cpa, field, len)==0 ) {
544
iv->fieldname[fieldnr]= cpa;
546
/* read until first character */
553
while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) cpa++;
564
while( *cpa!=terminator && *cpa != '}' ) {
566
/* in fact, isdigit should include the dot and minus */
567
if( (isdigit(*cpa) || *cpa=='.' || *cpa=='-') && (isspace(cpa[-1]) || cpa[-1]==0 || cpa[-1]==',') ) {
569
memcpy(str, cpa, 16);
572
sscanf(str, "%x", (int *)fp);
575
/* atof doesn't stop after the first float
576
* in a long string at Windows... so we copy
577
* the float to a new string then atof... */
578
char *cpa_temp = strpbrk(cpa, ", \n");
586
*fp= (float) atof(str);
591
if(stackcount>=IV_MAXSTACK) {
592
printf("stackoverflow in IV read\n");
601
iv->datalen[fieldnr]= stackcount;
603
iv->data[fieldnr]= MEM_mallocN(sizeof(float)*stackcount, "iv_finddata");
604
memcpy(iv->data[fieldnr], iv_data_stack, sizeof(float)*stackcount);
606
else iv->data[fieldnr]= 0;
618
static void read_iv_index(float *data, float *baseadr, float *index, int nr, int coordtype)
620
/* write in data: baseadr with offset index (and number nr) */
626
fp= baseadr+coordtype*ofs;
635
static void read_inventor(Scene *scene, char *str, struct ListBase *listb)
637
struct IvNode *iv, *ivp, *ivn;
638
char *maindata, *md, *cpa;
639
float *index, *data, *fp;
640
int file, filelen, count, lll, face, nr = 0;
641
int skipdata, ok, a, b, tot, first, colnr, coordtype, polytype, *idata;
643
ReportList *reports= NULL; /* XXX */
645
ivbase.first= ivbase.last= 0;
649
file= open(str, O_BINARY|O_RDONLY);
651
BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno));
655
filelen= BLI_filesize(file);
661
maindata= MEM_mallocN(filelen, "leesInventor");
662
if(read(file, maindata, filelen) < filelen) {
663
BKE_reportf(reports, RPT_ERROR, "Failed reading file: premature end of file.");
669
iv_data_stack= MEM_mallocN(sizeof(float)*IV_MAXSTACK, "ivstack");
671
/* preprocess: remove comments */
674
while(count<filelen) {
675
if( *md=='#' ) { /* comment */
676
while( *md!=13 && *md!=10) { /* enters */
680
if(count>=filelen) break;
688
/* now time to collect: which are the nodes and fields? */
691
while(count<filelen) {
692
if( *md=='{' ) { /* read back */
695
while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) { /* remove spaces/enters/tab */
700
while( *cpa>32 && *cpa<128) cpa--;
706
iv= MEM_callocN(sizeof(struct IvNode), "leesInventor");
709
if(strcmp(cpa, "Coordinate3")==0 || strcmp(cpa, "Coordinate4")==0) {
710
skipdata= iv_finddata(iv, "point", 0);
713
else if(strcmp(cpa, "VertexProperty")==0) {
714
skipdata= iv_finddata(iv, "vertex", 0);
717
else if(strcmp(cpa, "IndexedLineSet")==0) {
718
skipdata= iv_finddata(iv, "coordIndex", 0);
721
else if(strcmp(cpa, "IndexedTriangleMesh")==0) {
722
skipdata= iv_finddata(iv, "coordIndex", 0);
725
else if(strcmp(cpa, "IndexedFaceSet")==0) {
726
skipdata= iv_finddata(iv, "coordIndex", 0);
729
else if(strcmp(cpa, "FaceSet")==0) {
730
skipdata= iv_finddata(iv, "numVertices", 0);
733
else if(strcmp(cpa, "Material")==0) {
734
iv_finddata(iv, "diffuseColor", 0);
735
iv_finddata(iv, "ambientColor", 1);
738
else if(strcmp(cpa, "BaseColor")==0) {
739
iv_finddata(iv, "rgb", 0);
742
else if(strcmp(cpa, "PackedColor")==0) {
743
iv_finddata(iv, "rgba", 0);
746
else if(strcmp(cpa, "QuadMesh")==0) {
747
iv_finddata(iv, "verticesPerColumn", 0);
748
iv_finddata(iv, "verticesPerRow", 1);
752
else if(strcmp(cpa, "IndexedTriangleStripSet")==0) {
753
skipdata= iv_finddata(iv, "coordIndex", 0);
756
else if(strcmp(cpa, "TriangleStripSet")==0) {
757
skipdata= iv_finddata(iv, "numVertices", 0);
760
else if(strcmp(cpa, "IndexedNurbsSurface")==0 || strcmp(cpa, "NurbsSurface")==0) {
761
iv_finddata(iv, "numUControlPoints", 0);
762
iv_finddata(iv, "numVControlPoints", 1);
763
iv_finddata(iv, "uKnotVector", 2);
764
iv_finddata(iv, "vKnotVector", 3);
772
if(count<filelen) break;
778
BLI_addtail(&ivbase, iv);
795
if( strncmp(iv->nodename, "Indexed", 7)==0) {
796
/* seek back: same name? */
800
if(strcmp(iv->nodename, ivp->nodename)==0) break;
802
if(strcmp(ivp->nodename, "Coordinate3")==0 ||
803
strcmp(ivp->nodename, "Coordinate4")==0 ||
804
strcmp(ivp->nodename, "VertexProperty")==0) {
814
tot= iv->datalen[0] + ivp->datalen[0];
816
data= MEM_mallocN(tot*sizeof(float), "samenvoeg iv");
817
memcpy(data, ivp->data[0], sizeof(float)*ivp->datalen[0]);
818
memcpy(data+ivp->datalen[0], iv->data[0], sizeof(float)*iv->datalen[0]);
820
ivp->datalen[0]+= iv->datalen[0];
821
MEM_freeN(ivp->data[0]);
824
BLI_remlink(&ivbase, iv);
825
MEM_freeN(iv->data[0]);
835
/* convert Nodes to DispLists */
839
/* printf(" Node: %s\n", iv->nodename); */
840
/* if(iv->fieldname[0]) printf(" Field: %s len %d\n", iv->fieldname[0], iv->datalen[0]); */
843
if( strcmp(iv->nodename, "IndexedLineSet")==0 ) {
845
colnr= iv_colornumber(iv);
847
/* seek back to data */
851
if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
855
if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
862
/* count the nr of lines */
865
lll = iv->datalen[0]-1;
866
for(a=0; a<lll; a++) {
867
if(index[0]!= -1 && index[1]!= -1) tot++;
871
tot*= 2; /* nr of vertices */
872
dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor1");
873
BLI_addtail(listb, dl);
878
data= (float *)(dl+1);
881
for(a=0; a<lll; a++) {
882
if(index[0]!= -1 && index[1]!= -1) {
883
read_iv_index(data, ivp->data[0], index, 2, coordtype);
890
else if( strcmp(iv->nodename, "FaceSet")==0 ) {
892
colnr= iv_colornumber(iv);
894
/* seek back to data */
898
if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
902
if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
909
/* count triangles */
913
polytype= (int) index[0];
915
for(a=0; a<iv->datalen[0]; a++) {
916
if(index[0]== polytype) tot++; /* one kind? */
921
tot*= polytype; /* nr of vertices */
922
dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor4");
923
BLI_addtail(listb, dl);
926
dl->parts= tot/polytype;
928
data= (float *)(dl+1);
932
for(a=0; a<iv->datalen[0]; a++) {
934
VECCOPY(data, index);
938
VECCOPY(data, index);
942
VECCOPY(data, index);
947
VECCOPY(data, index);
954
else if( strcmp(iv->nodename, "TriangleStripSet")==0 ) {
956
colnr= iv_colornumber(iv);
958
/* seek back to data */
962
if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
966
if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
973
/* count triangles */
977
index= iv->data[0]; /* strip size */
979
for(a=0; a<iv->datalen[0]; a++) {
980
tot+= (int) index[0];
981
face+= ((int) index[0]) - 2;
985
dl= MEM_callocN(sizeof(struct DispList), "leesInventor4");
986
dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
987
dl->index= MEM_callocN( face*3*sizeof(int), "dl index");
993
BLI_addtail(listb, dl);
996
index= iv->data[0]; /* strip size */
997
fp= ivp->data[0]; /* vertices */
1002
for(a=0; a<iv->datalen[0]; a++) {
1005
for(b=0; b<index[0]; b++) {
1013
for(b=0; b<lll; b++) {
1026
else if( strcmp(iv->nodename, "IndexedFaceSet")==0 ) {
1028
colnr= iv_colornumber(iv);
1030
/* seek back to data */
1034
if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1038
if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1045
/* count triangles */
1048
lll = iv->datalen[0]-2;
1049
for(a=0; a<lll; a++) {
1050
if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
1054
/*number of vertices */
1055
tot= ivp->datalen[0]/coordtype;
1058
dl= MEM_callocN(sizeof(struct DispList), "leesInventor5");
1059
BLI_addtail(listb, dl);
1060
dl->type= DL_INDEX3;
1065
dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1066
dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
1071
for(b=tot; b>0; b--) {
1081
lll=iv->datalen[0]-2;
1082
for(a=0; a<lll; a++) {
1084
if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
1086
/* this trick is to fill poly's with more than 3 vertices correctly */
1092
idata[1]= (int) index[1];
1093
idata[2]= (int) index[2];
1103
else if( strcmp(iv->nodename, "IndexedTriangleMesh")==0 ||
1104
strcmp(iv->nodename, "IndexedTriangleStripSet")==0 ) {
1106
colnr= iv_colornumber(iv);
1108
/* seek back to data */
1112
if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1116
if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1123
/* count triangles */
1126
lll=iv->datalen[0]-2;
1127
for(a=0; a<lll; a++) {
1128
if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
1132
/* nr of vertices */
1133
tot= ivp->datalen[0]/coordtype;
1135
dl= MEM_callocN(sizeof(struct DispList), "leesInventor6");
1136
BLI_addtail(listb, dl);
1137
dl->type= DL_INDEX3;
1142
dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
1143
dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
1148
for(b=tot; b>0; b--) {
1158
lll=iv->datalen[0]-2;
1159
for(a=lll; a>0; a--) {
1161
if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
1162
idata[0]= (int) index[0];
1163
idata[1]= (int) index[1];
1164
idata[2]= (int) index[2];
1171
else if( strcmp(iv->nodename, "QuadMesh")==0 ) {
1173
colnr= iv_colornumber(iv);
1175
/* seek back to data */
1179
if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1183
if( strcmp(ivp->nodename, "VertexProperty")==0 ) {
1187
if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1194
tot= (int) (floor(*(iv->data[0])+0.5) * floor(*(iv->data[1])+0.5));
1197
dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor8");
1198
BLI_addtail(listb, dl);
1200
dl->parts= (int) floor(*(iv->data[0])+0.5);
1201
dl->nr= (int) floor(*(iv->data[1])+0.5);
1203
data= (float *)(dl+1);
1204
memcpy(data, ivp->data[0], tot*3*sizeof(float));
1208
else if(strcmp(iv->nodename, "IndexedNurbsSurface")==0 || strcmp(iv->nodename, "NurbsSurface")==0) {
1210
colnr= iv_colornumber(iv);
1212
/* sek back to data */
1216
if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
1220
if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
1226
a= (int) *(iv->data[0]);
1227
b= (int) *(iv->data[1]);
1231
if( (a>=4 || b>=4) && tot>6) {
1238
ob= add_object(scene, OB_SURF);
1243
nu = (Nurb*) MEM_callocN(sizeof(Nurb),"addNurbprim") ;
1244
BLI_addtail(&cu->nurb, nu);
1256
(BPoint*)MEM_callocN(tot * sizeof(BPoint), "addNurbprim3");
1260
VECCOPY(bp->vec, data);
1262
bp->vec[3]= data[3];
1263
mul_v3_fl(bp->vec, 1.0f/data[3]);
1265
else bp->vec[3]= 1.0;
1270
/* iv->datalen[2] / [3] is number of knots */
1271
nu->orderu= iv->datalen[2] - nu->pntsu;
1272
nu->orderv= iv->datalen[3] - nu->pntsv;
1274
nu->knotsu= MEM_mallocN( sizeof(float)*(iv->datalen[2]), "knots");
1275
memcpy(nu->knotsu, iv->data[2], sizeof(float)*(iv->datalen[2]));
1276
nu->knotsv= MEM_mallocN( sizeof(float)*(iv->datalen[3]), "knots");
1277
memcpy(nu->knotsv, iv->data[3], sizeof(float)*(iv->datalen[3]));
1279
switchdirectionNurb(nu);
1283
dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor3");
1284
BLI_addtail(listb, dl);
1286
dl->nr= (int) *(iv->data[0]);
1287
dl->parts= (int) *(iv->data[1]);
1289
data= (float *)(dl+1);
1307
for(a=0; a<IV_MAXFIELD; a++) {
1308
if(iv->data[a]) MEM_freeN(iv->data[a]);
1313
BLI_freelistN(&ivbase);
1314
MEM_freeN(maindata);
1315
MEM_freeN(iv_data_stack);
1319
/* ************************************************************ */
1321
static void displist_to_mesh(Scene *scene, DispList *dlfirst)
1329
float *data, vec[3], min[3], max[3];
1330
int a, b, startve, *idata, totedge=0, tottria=0, totquad=0, totvert=0, totface, totcol=0, colnr;
1332
unsigned int maxvertidx;
1335
INIT_MINMAX(min, max);
1340
/* PATCH 1 (polyfill) can't be done, there's no listbase here. do that first! */
1342
if(dl->type==DL_SEGM && dl->nr>2) {
1343
data= (float *)(dl+1);
1344
if(data[0]==data[3*(dl->nr-1)]) {
1345
if(data[1]==data[3*(dl->nr-1)+1]) {
1346
if(data[2]==data[3*(dl->nr-1)+2]) {
1355
if(dl->col > totcol) totcol= dl->col;
1357
/* size and count */
1358
if(dl->type==DL_SURF) {
1361
if(dl->flag & DL_CYCL_U) a++;
1362
if(dl->flag & DL_CYCL_V) b++;
1366
totvert+= dl->nr*dl->parts;
1368
data= (float *)(dl+1);
1369
for(a= dl->nr*dl->parts; a>0; a--) {
1370
DO_MINMAX(data, min, max);
1374
else if(dl->type==DL_POLY) {
1375
if(dl->nr==3 || dl->nr==4) {
1376
if(dl->nr==3) tottria+= dl->parts;
1377
else totquad+= dl->parts;
1379
totvert+= dl->nr*dl->parts;
1381
data= (float *)(dl+1);
1382
for(a= dl->nr*dl->parts; a>0; a--) {
1383
DO_MINMAX(data, min, max);
1389
tottria+= dl->nr*dl->parts;
1390
totvert+= dl->nr*dl->parts;
1392
data= (float *)(dl+1);
1393
for(a= dl->nr*dl->parts; a>0; a--) {
1394
DO_MINMAX(data, min, max);
1400
else if(dl->type==DL_INDEX3) {
1401
tottria+= dl->parts;
1405
for(a= dl->nr; a>0; a--) {
1406
DO_MINMAX(data, min, max);
1410
else if(dl->type==DL_SEGM) {
1412
tottria+= (dl->nr-1)*dl->parts;
1413
totvert+= dl->nr*dl->parts;
1415
data= (float *)(dl+1);
1416
for(a= dl->nr*dl->parts; a>0; a--) {
1417
DO_MINMAX(data, min, max);
1429
vec[0]= (min[0]+max[0])/2;
1430
vec[1]= (min[1]+max[1])/2;
1431
vec[2]= (min[2]+max[2])/2;
1433
ob= add_object(scene, OB_MESH);
1434
VECCOPY(ob->loc, vec);
1435
where_is_object(scene, ob);
1441
ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
1442
ob->matbits= MEM_callocN(sizeof(char)*totcol, "ob->matbits");
1443
me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
1445
ob->totcol= (unsigned char) me->totcol;
1450
for(a=0; a<totcol; a++) {
1451
ma= G.main->mat.first;
1453
if(ma->mtex[0]==0) {
1454
if(ivcolors[a][0]==ma->r && ivcolors[a][1]==ma->g && ivcolors[a][2]==ma->b) {
1463
ma= add_material("ext");
1465
ma->r= ivcolors[a][0];
1466
ma->g= ivcolors[a][1];
1467
ma->b= ivcolors[a][2];
1472
totface= totquad+tottria+totedge;
1474
printf("Import: %d vertices %d faces\n", totvert, totface);
1476
me->totvert= totvert;
1477
me->totface= totface;
1478
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
1480
me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
1482
maxvertidx= totvert-1;
1495
if(dl->type==DL_SURF) {
1496
data= (float *)(dl+1);
1498
for(a=dl->parts*dl->nr; a>0; a--) {
1499
mvert->co[0]= data[0] -vec[0];
1500
mvert->co[1]= data[1] -vec[1];
1501
mvert->co[2]= data[2] -vec[2];
1507
for(a=0; a<dl->parts; a++) {
1509
if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
1517
for(; b<dl->nr; b++) {
1524
mface->mat_nr= colnr;
1525
test_index_face(mface, NULL, 0, 4);
1536
startve += dl->parts*dl->nr;
1539
else if(dl->type==DL_POLY) {
1541
if(dl->nr==3 || dl->nr==4) {
1542
data= (float *)(dl+1);
1544
for(a=dl->parts*dl->nr; a>0; a--) {
1545
mvert->co[0]= data[0] -vec[0];
1546
mvert->co[1]= data[1] -vec[1];
1547
mvert->co[2]= data[2] -vec[2];
1552
for(a=0; a<dl->parts; a++) {
1554
mface->v1= startve+a*dl->nr;
1555
mface->v2= startve+a*dl->nr+1;
1556
mface->v3= startve+a*dl->nr+2;
1557
mface->mat_nr= colnr;
1558
test_index_face(mface, NULL, 0, 3);
1562
mface->v1= startve+a*dl->nr;
1563
mface->v2= startve+a*dl->nr+1;
1564
mface->v3= startve+a*dl->nr+2;
1565
mface->v4= startve+a*dl->nr+3;
1566
mface->mat_nr= colnr;
1567
test_index_face(mface, NULL, 0, 4);
1571
startve += dl->parts*dl->nr;
1574
data= (float *)(dl+1);
1576
for(a=dl->parts*dl->nr; a>0; a--) {
1577
mvert->co[0]= data[0] -vec[0];
1578
mvert->co[1]= data[1] -vec[1];
1579
mvert->co[2]= data[2] -vec[2];
1585
for(b=0; b<dl->parts; b++) {
1586
for(a=0; a<dl->nr; a++) {
1587
mface->v1= startve+a;
1589
if(a==dl->nr-1) mface->v2= startve;
1590
else mface->v2= startve+a+1;
1592
mface->mat_nr= colnr;
1600
else if(dl->type==DL_INDEX3) {
1603
for(a=dl->nr; a>0; a--) {
1604
mvert->co[0]= data[0] -vec[0];
1605
mvert->co[1]= data[1] -vec[1];
1606
mvert->co[2]= data[2] -vec[2];
1612
for(b=dl->parts; b>0; b--) {
1613
mface->v1= startve+idata[0];
1614
mface->v2= startve+idata[1];
1615
mface->v3= startve+idata[2];
1616
mface->mat_nr= colnr;
1618
if (mface->v1>maxvertidx) mface->v1= maxvertidx;
1619
if (mface->v2>maxvertidx) mface->v2= maxvertidx;
1620
if (mface->v3>maxvertidx) mface->v3= maxvertidx;
1622
test_index_face(mface, NULL, 0, 3);
1628
else if(dl->type==DL_SEGM) {
1629
data= (float *)(dl+1);
1631
for(a=dl->parts*dl->nr; a>0; a--) {
1632
mvert->co[0]= data[0] -vec[0];
1633
mvert->co[1]= data[1] -vec[1];
1634
mvert->co[2]= data[2] -vec[2];
1639
for(b=0; b<dl->parts; b++) {
1640
for(a=0; a<dl->nr-1; a++) {
1641
mface->v1= startve+a;
1642
mface->v2= startve+a+1;
1643
mface->mat_nr= colnr;
1652
mesh_add_normals_flags(me);
1656
static void displist_to_objects(Scene *scene, ListBase *lbase)
1658
DispList *dl, *first, *prev, *next;
1660
int maxaantal, curcol, totvert=0, vert;
1662
/* irst this: is still active */
1664
where_is_object(scene, ivsurf);
1665
// XXX docenter_new();
1672
/* PATCH 1: polyfill */
1673
if(dl->type==DL_POLY && dl->nr>4) {
1674
/* solution: put them together in separate listbase */
1677
/* PATCH 2: poly's of 2 points */
1678
if(dl->type==DL_POLY && dl->nr==2) dl->type= DL_SEGM;
1683
/* count vertices */
1688
if(dl->type==DL_SURF) totvert+= dl->nr*dl->parts;
1689
else if(dl->type==DL_POLY) {
1690
if(dl->nr==3 || dl->nr==4) totvert+= dl->nr*dl->parts;
1691
else if(dl->nr>4) totvert+= dl->nr*dl->parts;
1693
else if(dl->type==DL_INDEX3) totvert+= dl->nr;
1694
else if(dl->type==DL_SEGM) totvert+= dl->nr*dl->parts;
1701
if(ivsurf==0) {}; //XXX error("Found no data");
1702
if(lbase->first) BLI_freelistN(lbase);
1709
if(totvert>maxaantal) {
1711
/* try to put colors together */
1713
tempbase.first= tempbase.last= 0;
1715
while(lbase->first) {
1719
if(dl->col==curcol) {
1720
BLI_remlink(lbase, dl);
1721
BLI_addtail(&tempbase, dl);
1728
/* in tempbase are all 'curcol' */
1730
dl= first= tempbase.first;
1734
if(dl->type==DL_SURF) vert= dl->nr*dl->parts;
1735
else if(dl->type==DL_POLY) {
1736
if(dl->nr==3 || dl->nr==4) vert= dl->nr*dl->parts;
1737
else if(dl->nr>4) vert= dl->nr*dl->parts;
1739
else if(dl->type==DL_INDEX3) totvert+= dl->nr;
1740
else if(dl->type==DL_SEGM) vert= dl->nr*dl->parts;
1743
if(totvert > maxaantal || dl->next==0) {
1745
displist_to_mesh(scene, first);
1750
displist_to_mesh(scene, first);
1760
freedisplist(&tempbase);
1765
else displist_to_mesh(scene, lbase->first);
1767
freedisplist(lbase);
1771
int BKE_read_exotic(Scene *scene, char *name)
1773
ListBase lbase={0, 0};
1777
int *s0 = (int*) str;
1780
// make sure we're not trying to read a directory....
1783
if (name[len-1] !='/' && name[len-1] != '\\') {
1784
gzfile = gzopen(name,"rb");
1786
if (NULL == gzfile ) {
1787
//XXX error("Can't open file: %s", name);
1790
gzread(gzfile, str, 31);
1793
if ((*s0 != FORM) && (strncmp(str, "BLEN", 4) != 0) && !BLI_testextensie(name,".blend.gz")) {
1795
//XXX waitcursor(1);
1796
if(strncmp(str, "#Inventor V1.0", 14)==0) {
1797
if( strncmp(str+15, "ascii", 5)==0) {
1798
read_inventor(scene, name, &lbase);
1799
displist_to_objects(scene, &lbase);
1802
//XXX error("Can only read Inventor 1.0 ascii");
1805
else if((strncmp(str, "#VRML V1.0 asc", 14)==0)) {
1806
read_inventor(scene, name, &lbase);
1807
displist_to_objects(scene, &lbase);
1810
else if(is_dxf(name)) {
1811
dxf_read(scene, name);
1814
else if(is_stl(name)) {
1815
if (is_stl_ascii(name))
1816
read_stl_mesh_ascii(scene, name);
1818
read_stl_mesh_binary(scene, name);
1821
#ifndef DISABLE_PYTHON
1822
// TODO: this should not be in the kernel...
1823
else { // unknown format, call Python importloader
1824
if (BPY_call_importloader(name)) {
1827
//XXX error("Unknown file type or error, check console");
1831
#endif /* DISABLE_PYTHON */
1832
//XXX waitcursor(0);
1841
/* ************************ WRITE ************************** */
1844
char temp_dir[160]= {0, 0};
1846
static void write_vert_stl(Object *ob, MVert *verts, int index, FILE *fpSTL)
1850
VECCOPY(vert, verts[(index)].co);
1851
mul_m4_v3(ob->obmat, vert);
1853
if (ENDIAN_ORDER==B_ENDIAN) {
1854
SWITCH_INT(vert[0]);
1855
SWITCH_INT(vert[1]);
1856
SWITCH_INT(vert[2]);
1859
fwrite(vert, sizeof(float), 3, fpSTL);
1862
static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm)
1864
MVert *mvert = dm->getVertArray(dm);
1865
MFace *mface = dm->getFaceArray(dm);
1866
int i, numfacets = 0, totface = dm->getNumFaces(dm);
1867
float zero[3] = {0.0f, 0.0f, 0.0f};
1869
for (i=0; i<totface; i++, mface++) {
1870
fwrite(zero, sizeof(float), 3, fpSTL);
1871
write_vert_stl(ob, mvert, mface->v1, fpSTL);
1872
write_vert_stl(ob, mvert, mface->v2, fpSTL);
1873
write_vert_stl(ob, mvert, mface->v3, fpSTL);
1874
fprintf(fpSTL, " ");
1877
if(mface->v4) { /* quad = 2 tri's */
1878
fwrite(zero, sizeof(float), 3, fpSTL);
1879
write_vert_stl(ob, mvert, mface->v1, fpSTL);
1880
write_vert_stl(ob, mvert, mface->v3, fpSTL);
1881
write_vert_stl(ob, mvert, mface->v4, fpSTL);
1882
fprintf(fpSTL, " ");
1890
static int write_object_stl(FILE *fpSTL, Scene *scene, Object *ob, Mesh *me)
1893
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
1895
numfacets += write_derivedmesh_stl(fpSTL, ob, dm);
1902
void write_stl(Scene *scene, char *str)
1909
ReportList *reports= NULL; /* XXX */
1911
if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
1912
if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
1913
if(BLI_testextensie(str,".stl")==0) strcat(str, ".stl");
1915
if (BLI_exists(str)) {
1916
; //XXX if(saveover(str)==0)
1920
fpSTL= fopen(str, "wb");
1923
BKE_reportf(reports, RPT_ERROR, "Can't open file: %s.", strerror(errno));
1926
strcpy(temp_dir, str);
1928
//XXX waitcursor(1);
1930
/* The header part of the STL */
1931
/* First 80 characters are a title or whatever you want.
1932
Lets make the first 32 of those spam and the rest the filename.
1933
Those first 80 characters will be followed by 4 bytes
1934
which will be overwritten later with an integer holding
1935
how many facets are written (we set them to ' ' for now).
1937
fprintf(fpSTL, "Binary STL output from Blender: %-48.48s ", str);
1939
/* Write all selected mesh objects */
1940
base= scene->base.first;
1942
if (base->flag & SELECT) {
1944
if (ob->type == OB_MESH) {
1947
numfacets += write_object_stl(fpSTL, scene, ob, me);
1953
/* time to write the number of facets in the 4 bytes
1956
fseek(fpSTL, 80, SEEK_SET);
1958
if (ENDIAN_ORDER==B_ENDIAN) {
1959
SWITCH_INT(numfacets);
1961
fwrite(&numfacets, 4*sizeof(char), 1, fpSTL);
1965
//XXX waitcursor(0);
1968
/* ******************************* WRITE VRML ***************************** */
1970
static void replace_chars(char *str1, char *str2)
1972
int a= strlen(str2);
1976
if(str2[a]=='.' || str2[a]==' ') str1[a]= '_';
1977
else str1[a]= str2[a];
1982
static void write_material_vrml(FILE *fp, Material *ma)
1986
replace_chars(str, ma->id.name+2);
1988
fprintf(fp, "\tDEF %s\n", str);
1989
fprintf(fp, "\tMaterial {\n");
1991
fprintf(fp, "\t\tdiffuseColor %f %f %f\n", ma->r, ma->g, ma->b);
1992
fprintf(fp, "\t\tspecularColor %f %f %f\n", ma->specr, ma->specg, ma->specb);
1993
fprintf(fp, "\t\tshininess %f \n", ((float)ma->har)/100.0);
1994
fprintf(fp, "\t\ttransparency %f \n", 1.0-ma->alpha);
1996
fprintf(fp, "\t}\n");
2000
unsigned int *mcol_to_vcol(Mesh *me)
2003
unsigned int *mcol, *mcoln, *mcolmain;
2006
if(me->totface==0 || me->mcol==0) return 0;
2008
mcoln= mcolmain= MEM_mallocN(sizeof(int)*me->totvert, "mcoln");
2009
mcol = (unsigned int *)me->mcol;
2012
for(a=me->totface; a>0; a--, mface++) {
2013
mcoln[mface->v1]= mcol[0];
2014
mcoln[mface->v2]= mcol[1];
2015
mcoln[mface->v3]= mcol[2];
2016
if(mface->v4) mcoln[mface->v4]= mcol[3];
2024
void mcol_to_rgba(unsigned int col, float *r, float *g, float *b, float *a)
2043
static void write_mesh_vrml(FILE *fp, Mesh *me)
2050
int a, b, totcol, texind;
2053
replace_chars(str, me->id.name+2);
2055
fprintf(fp, "\tDEF %s\n", str);
2056
fprintf(fp, "\tSeparator {\n");
2059
ima= ((MTFace *)me->mtface)->tpage;
2061
fprintf(fp, "\t\tTexture2 {\n");
2062
fprintf(fp, "\t\t\tfilename %s\n", ima->name);
2063
fprintf(fp, "\t\t\twrapS REPEAT \n");
2064
fprintf(fp, "\t\t\twrapT REPEAT \n");
2065
fprintf(fp, "\t\t}\n");
2070
unsigned int *mcol, *mcolmain;
2071
float r, g, b, cola;
2073
fprintf(fp, "\t\tMaterial {\n");
2074
fprintf(fp, "\t\t\tdiffuseColor [\n");
2077
mcol= mcolmain= mcol_to_vcol(me);
2080
mcol_to_rgba(*mcol, &r, &g, &b, &cola);
2081
fprintf(fp, "\t\t\t\t %f %f %f,\n", r, g, b);
2084
MEM_freeN(mcolmain);
2086
fprintf(fp, "\t\t\t]\n");
2087
fprintf(fp, "\t\t}\n");
2089
fprintf(fp, "\t\tMaterialBinding { value PER_VERTEX_INDEXED }\n");
2093
fprintf(fp, "\t\tCoordinate3 {\n");
2094
fprintf(fp, "\t\t\tpoint [\n");
2099
fprintf(fp, "\t\t\t\t %f %f %f,\n", mvert->co[0], mvert->co[1], mvert->co[2]);
2102
fprintf(fp, "\t\t\t]\n");
2103
fprintf(fp, "\t\t}\n");
2107
if(totcol==0) totcol= 1;
2108
texind= 0; // index for uv coords
2110
for(b=0; b<totcol; b++) {
2116
replace_chars(str, ma->id.name+2);
2118
fprintf(fp, "\t\tUSE %s\n\n", str);
2124
fprintf(fp, "\t\tTextureCoordinate2 {\n");
2125
fprintf(fp, "\t\t\tpoint [\n");
2131
if(mface->mat_nr==b) {
2132
fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[0][0], tface->uv[0][1]);
2133
fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[1][0], tface->uv[1][1]);
2134
fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[2][0], tface->uv[2][1]);
2135
if(mface->v4) fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[3][0], tface->uv[3][1]);
2140
fprintf(fp, "\t\t\t]\n");
2141
fprintf(fp, "\t\t}\n");
2144
fprintf(fp, "\t\tIndexedFaceSet {\n");
2145
fprintf(fp, "\t\t\tcoordIndex [\n");
2150
if(mface->mat_nr==b) {
2151
if(mface->v4) fprintf(fp, "\t\t\t\t %d, %d, %d, %d, -1,\n", mface->v1, mface->v2, mface->v3, mface->v4);
2152
else fprintf(fp, "\t\t\t\t %d, %d, %d, -1,\n", mface->v1, mface->v2, mface->v3);
2156
fprintf(fp, "\t\t\t]\n");
2159
fprintf(fp, "\t\t\ttextureCoordIndex [\n");
2164
if(mface->mat_nr==b) {
2166
fprintf(fp, "\t\t\t\t %d, %d, %d, %d, -1,\n", texind, texind+1, texind+2, texind+3);
2170
fprintf(fp, "\t\t\t\t %d, %d, %d, -1,\n", texind, texind+1, texind+2);
2176
fprintf(fp, "\t\t\t]\n");
2178
fprintf(fp, "\t\t}\n");
2181
fprintf(fp, "\t}\n");
2184
static void write_camera_vrml(FILE *fp, Object *ob)
2189
invert_m4_m4(ob->imat, ob->obmat);
2191
fprintf(fp, "\tMatrixTransform {\n");
2193
fprintf(fp, "\tmatrix \n");
2195
fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[0][0], ob->imat[0][1], ob->imat[0][2], ob->imat[0][3]);
2196
fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[1][0], ob->imat[1][1], ob->imat[1][2], ob->imat[1][3]);
2197
fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[2][0], ob->imat[2][1], ob->imat[2][2], ob->imat[2][3]);
2198
fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[3][0], ob->imat[3][1], ob->imat[3][2], ob->imat[3][3]);
2200
fprintf(fp, "\t}\n");
2204
fprintf(fp, "\tPerspectiveCamera {\n");
2205
fprintf(fp, "\t\tfocalDistance %f\n", cam->lens/10.0);
2207
fprintf(fp, "\t}\n");
2211
static void write_object_vrml(FILE *fp, Object *ob)
2216
fprintf(fp, "\tSeparator {\n");
2217
fprintf(fp, "\t\tMatrixTransform {\n");
2219
fprintf(fp, "\t\tmatrix \n");
2221
fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[0][0], ob->obmat[0][1], ob->obmat[0][2], ob->obmat[0][3]);
2222
fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[1][0], ob->obmat[1][1], ob->obmat[1][2], ob->obmat[1][3]);
2223
fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[2][0], ob->obmat[2][1], ob->obmat[2][2], ob->obmat[2][3]);
2224
fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[3][0], ob->obmat[3][1], ob->obmat[3][2], ob->obmat[3][3]);
2226
fprintf(fp, "\t\t}\n");
2230
replace_chars(str, id->name+2);
2232
fprintf(fp, "\t\tUSE %s\n", str);
2233
fprintf(fp, "\t}\n");
2237
void write_vrml(Scene *scene, char *str)
2244
if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2245
if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2246
if(BLI_testextensie(str,".wrl")==0) strcat(str, ".wrl");
2247
//XXX saveover() if(saveover(str)==0) return;
2249
fp= fopen(str, "w");
2252
//XXX error("Can't write file");
2255
strcpy(temp_dir, str);
2257
//XXX waitcursor(1);
2259
/* FIRST: write all the datablocks */
2261
fprintf(fp, "#VRML V1.0 ascii\n\n# Blender V%d\n\n# 'Switch' is used as a hack, to ensure it is not part of the drawing\n\n", BLENDER_VERSION);
2262
fprintf(fp, "Separator {\n");
2263
fprintf(fp, "Switch {\n");
2265
ma= G.main->mat.first;
2268
write_material_vrml(fp, ma);
2273
/* only write meshes we're using in this scene */
2274
flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
2276
for(base= scene->base.first; base; base= base->next)
2277
if(base->object->type== OB_MESH)
2278
((ID *)base->object->data)->flag |= LIB_DOIT;
2280
me= G.main->mesh.first;
2282
if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
2283
write_mesh_vrml(fp, me);
2288
/* THEN:Hidden Objects */
2289
fprintf(fp, "\n\t# Hidden Objects, in invisible layers\n\n");
2290
base= scene->base.first;
2292
if(base->object->type== OB_MESH) {
2293
if( (base->lay & scene->lay)==0 ) {
2294
write_object_vrml(fp, base->object);
2301
fprintf(fp, "\n# Visible Objects\n\n");
2302
fprintf(fp, "Separator {\n");
2306
write_camera_vrml(fp, scene->camera);
2308
/* THEN:The Objects */
2310
base= scene->base.first;
2312
if(base->object->type== OB_MESH) {
2313
if(base->lay & scene->lay) {
2314
write_object_vrml(fp, base->object);
2325
//XXX waitcursor(0);
2329
/* ******************************* WRITE DXF ***************************** */
2331
#define write_group(id,data) fprintf(fp, "%d\n%s\n", id, data)
2333
/* A completely wacky function to try and make good
2334
indexed (AutoCAD index) values out of straight rgb
2337
static int rgb_to_dxf_col (float rf, float gf, float bf)
2339
int r= (int) (rf*255.0f);
2340
int g= (int) (gf*255.0f);
2341
int b= (int) (bf*255.0f);
2345
/* Grayscale value */
2346
if (((int)r/10)==((int)g/10) && ((int)g/10)==((int)b/10)) ret= 250+((int)r/51);
2347
/* A nice chroma value */
2349
rgb_to_hsv (rf,gf,bf,&h,&s,&v);
2351
ret= (int) (10.0f + (h*239.0f));
2354
/* If its whitish make the index odd */
2355
if (s<.5 || v>.5) if(ret%2) ret++;
2361
/* And its completely wacky complement */
2363
static void dxf_col_to_rgb (int cid, float *rf, float *gf, float *bf)
2367
/* Grayscale values */
2368
if (cid>=250 && cid <= 255) {
2369
*rf= *gf= *bf= (float) ((cid-250)*51)/255;
2370
CLAMP(*rf, 0.0, 1.0);
2371
CLAMP(*gf, 0.0, 1.0);
2372
CLAMP(*bf, 0.0, 1.0);
2375
} else if (cid<10) {
2413
/* Get chroma values */
2415
h= (float) (cid-10)/239;
2418
/* If its odd make it a bit whitish */
2419
if (cid%2) { s=.75; v= 0.25;
2420
} else { s= 0.25; v= 0.75;}
2422
hsv_to_rgb (h, s, v, rf, gf, bf);
2426
static void write_mesh_dxf(FILE *fp, Mesh *me)
2434
replace_chars(str, me->id.name+2);
2436
write_group(0, "BLOCK");
2438
write_group(2, str); /* The name */
2440
write_group(8, "Meshes"); /* DXF Layer */
2441
write_group(70, "64"); /* DXF block flags */
2443
write_group(10, "0.0"); /* X of base */
2444
write_group(20, "0.0"); /* Y of base */
2445
write_group(30, "0.0"); /* Z of base */
2447
write_group(3, str); /* The name (again) */
2449
write_group(0, "POLYLINE"); /* Start the mesh */
2450
write_group(66, "1"); /* Vertices follow flag */
2451
write_group(8,"Meshes"); /* DXF Layer */
2456
sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
2457
write_group(62, str); /* Color index */
2461
write_group(70, "64"); /* Polymesh mesh flag */
2463
fprintf(fp, "71\n%d\n", me->totvert); /* Total vertices */
2464
fprintf(fp, "72\n%d\n", me->totface); /* Total faces */
2466
/* Write the vertices */
2470
write_group(0, "VERTEX"); /* Start a new vertex */
2471
write_group(8, "Meshes"); /* DXF Layer */
2472
fprintf (fp, "10\n%f\n", mvert->co[0]); /* X cord */
2473
fprintf (fp, "20\n%f\n", mvert->co[1]); /* Y cord */
2474
fprintf (fp, "30\n%f\n", mvert->co[2]); /* Z cord */
2475
write_group(70, "192"); /* Polymesh vertex flag */
2480
/* Write the face entries */
2484
write_group(0, "VERTEX"); /* Start a new face */
2485
write_group(8, "Meshes");
2487
/* Write a face color */
2489
ma= me->mat[(int)mface->mat_nr];
2491
sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
2492
write_group(62, str); /* Color index */
2495
else write_group(62, "254"); /* Color Index */
2497
/* Not sure what this really corresponds too */
2498
write_group(10, "0.0"); /* X of base */
2499
write_group(20, "0.0"); /* Y of base */
2500
write_group(30, "0.0"); /* Z of base */
2502
write_group(70, "128"); /* Polymesh face flag */
2505
fprintf (fp, "71\n%d\n", mface->v1+1);
2506
fprintf (fp, "72\n%d\n", mface->v2+1);
2507
fprintf (fp, "73\n%d\n", mface->v3+1);
2508
fprintf (fp, "74\n%d\n", mface->v4+1);
2510
fprintf (fp, "71\n%d\n", mface->v1+1);
2511
fprintf (fp, "72\n%d\n", mface->v2+1);
2512
fprintf (fp, "73\n%d\n", mface->v3+1);
2517
write_group(0, "SEQEND");
2519
write_group(0, "ENDBLK");
2522
static void write_object_dxf(FILE *fp, Object *ob, int layer)
2529
write_group(0, "INSERT"); /* Start an insert group */
2531
sprintf(str, "%d", layer);
2532
write_group(8, str);
2534
replace_chars(str, id->name+2);
2535
write_group(2, str);
2537
fprintf (fp, "10\n%f\n", ob->loc[0]); /* X of base */
2538
fprintf (fp, "20\n%f\n", ob->loc[1]); /* Y of base */
2539
fprintf (fp, "30\n%f\n", ob->loc[2]); /* Z of base */
2541
fprintf (fp, "41\n%f\n", ob->size[0]); /* X scale */
2542
fprintf (fp, "42\n%f\n", ob->size[1]); /* Y scale */
2543
fprintf (fp, "43\n%f\n", ob->size[2]); /* Z scale */
2545
fprintf (fp, "50\n%f\n", (float) ob->rot[2]*180/M_PI); /* Can only write the Z rot */
2548
void write_dxf(struct Scene *scene, char *str)
2554
if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
2555
if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
2556
if(BLI_testextensie(str,".dxf")==0) strcat(str, ".dxf");
2559
if (BLI_exists(str)) {
2560
; //XXX if(saveover(str)==0)
2564
fp= fopen(str, "w");
2567
//XXX error("Can't write file");
2570
strcpy(temp_dir, str);
2572
//XXX waitcursor(1);
2574
/* The header part of the DXF */
2576
write_group(0, "SECTION");
2577
write_group(2, "HEADER");
2578
write_group(0, "ENDSEC");
2580
/* The blocks part of the DXF */
2582
write_group(0, "SECTION");
2583
write_group(2, "BLOCKS");
2586
/* only write meshes we're using in this scene */
2587
flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
2589
for(base= scene->base.first; base; base= base->next)
2590
if(base->object->type== OB_MESH)
2591
((ID *)base->object->data)->flag |= LIB_DOIT;
2593
/* Write all the meshes */
2594
me= G.main->mesh.first;
2596
if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
2597
write_mesh_dxf(fp, me);
2602
write_group(0, "ENDSEC");
2604
/* The entities part of the DXF */
2606
write_group(0, "SECTION");
2607
write_group(2, "ENTITIES");
2609
/* Write all the mesh objects */
2610
base= scene->base.first;
2612
if(base->object->type== OB_MESH) {
2613
write_object_dxf(fp, base->object, base->lay);
2618
write_group(0, "ENDSEC");
2622
write_group(0, "EOF");
2625
//XXX waitcursor(0);
2629
static int dxf_line= 0;
2630
static FILE *dxf_fp= NULL;
2632
/* exotic.c(2863) : note C6311: c:/Program Files/Microsoft Visual
2633
* Studio/VC98/include\ctype.h(268) : see previous definition of
2635
#define ton_iswspace(c) (c==' '||c=='\n'||c=='\t')
2637
static void clean_wspace (char *str)
2649
if(!ton_iswspace(*from)) to++;
2655
static int all_wspace(char *str)
2658
if (!ton_iswspace(*str)) return 0;
2665
static int all_digits(char *str)
2668
if (!isdigit(*str)) return 0;
2675
static int dxf_get_layer_col(char *layer)
2680
static int dxf_get_layer_num(Scene *scene, char *layer)
2684
if (all_digits(layer) && atoi(layer)<(1<<20)) ret= atoi(layer);
2685
if (ret == 0) ret = scene->lay;
2690
static void dos_clean(char *str)
2702
static void myfgets(char *str, int len, FILE *fp)
2706
while(len>0 && (c=getc(dxf_fp)) ) {
2710
/* three types of enters, \n \r and \r\n */
2711
if(c == '\n') break;
2713
c= getc(dxf_fp); // read the linefeed from stream
2714
if(c != 10) ungetc(c, dxf_fp); // put back, if it's not one...
2720
static int read_groupf(char *str)
2728
while ((c=getc(dxf_fp)) && ton_iswspace(c));
2730
if (c==EOF) return -1;
2732
myfgets(tmp, 255, dxf_fp);
2736
if(sscanf(tmp, "%d\n", &ret)!=1) return -2;
2738
myfgets(tmp, 255, dxf_fp);
2742
if (!all_wspace(tmp)) {
2743
if (sscanf(tmp, "%s\n", str)!=1) return -2;
2752
//XXX error() is now printf until we have a callback error
2753
#define id_test(id) if(id<0) {char errmsg[128];fclose(dxf_fp); if(id==-1) sprintf(errmsg, "Error inputting dxf, near line %d", dxf_line); else if(id==-2) sprintf(errmsg, "Error reading dxf, near line %d", dxf_line);printf("%s", errmsg); return;}
2755
#define read_group(id,str) {id= read_groupf(str); id_test(id);}
2757
#define group_is(idtst,str) (id==idtst&&strcmp(val,str)==0)
2758
#define group_isnt(idtst,str) (id!=idtst||strcmp(val,str)!=0)
2759
#define id_check(idtst,str) if(group_isnt(idtst,str)) { fclose(dxf_fp); printf("Error parsing dxf, near line %d", dxf_line); return;}
2762
static char val[256];
2764
static short error_exit=0;
2765
static short hasbumped=0;
2767
static int is_dxf(char *str)
2771
dxf_fp= fopen(str, "r");
2772
if (dxf_fp==NULL) return 0;
2774
id= read_groupf(val);
2775
if ((id==0 && strcmp(val, "SECTION")==0)||id==999) return 1;
2782
/* NOTES ON THE READER */
2785
It turns out that most DXF writers like (LOVE) to
2786
write meshes as a long string of 3DFACE entities.
2787
This means the natural way to read a DXF file
2788
(every entity corresponds to an object) is completely
2789
unusable, reading in 10,000 faces each as an
2790
object just doesn't cut it. Thus the 3DFACE
2791
entry reader holds state, and only finalizes to
2792
an object when a) the layer name changes, b) the
2793
entry type changes, c) we are done reading.
2795
PS... I decided to do the same thing with LINES,
2796
apparently the same thing happens sometimes as
2799
PPS... I decided to do the same thing with everything.
2800
Now it is all really nasty and should be rewritten.
2803
Added circular and elliptical arcs and lwpolylines.
2804
These are all self-contained and have the size known
2805
in advance, and so I haven't used the held state. -- martin
2808
static void dxf_add_mat (Object *ob, Mesh *me, float color[3], char *layer)
2815
ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
2816
ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits");
2821
me->mat= MEM_callocN(sizeof(void *)*1, "me->mat");
2824
if (strlen(layer)) dxf_col_to_rgb(dxf_get_layer_col(layer), &color[0], &color[1], &color[2]);
2825
color[0]= color[1]= color[2]= 0.8f;
2828
ma= G.main->mat.first;
2830
if(ma->mtex[0]==0) {
2831
if(color[0]==ma->r && color[1]==ma->g && color[2]==ma->b) {
2840
ma= add_material("ext");
2849
/* General DXF vars */
2850
static float cent[3]={0.0, 0.0, 0.0};
2851
static char layname[32]="";
2852
static char entname[32]="";
2853
static float color[3]={-1.0, -1.0, -1.0};
2854
static float *vcenter;
2855
static float zerovec[3]= {0.0, 0.0, 0.0};
2857
#define reset_vars cent[0]= cent[1]= cent[2]=0.0; strcpy(layname, ""); color[0]= color[1]= color[2]= -1.0
2860
static void dxf_get_mesh(Scene *scene, Mesh** m, Object** o, int noob)
2866
*o = add_object(scene, OB_MESH);
2869
if (strlen(entname)) new_id(&G.main->object, (ID *)ob, entname);
2870
else if (strlen(layname)) new_id(&G.main->object, (ID *)ob, layname);
2872
if (strlen(layname)) ob->lay= dxf_get_layer_num(scene, layname);
2873
else ob->lay= scene->lay;
2874
// not nice i know... but add_object() sets active base, which needs layer setting too (ton)
2875
scene->basact->lay= ob->lay;
2884
*m = add_mesh("Mesh");
2891
if (strlen(entname)) new_id(&G.main->mesh, (ID *)me, entname);
2892
else if (strlen(layname)) new_id(&G.main->mesh, (ID *)me, layname);
2898
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, 0);
2899
me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
2902
static void dxf_read_point(Scene *scene, int noob) {
2910
read_group(id, val);
2913
BLI_strncpy(layname, val, sizeof(layname));
2914
} else if (id==10) {
2915
cent[0]= (float) atof(val);
2916
} else if (id==20) {
2917
cent[1]= (float) atof(val);
2918
} else if (id==30) {
2919
cent[2]= (float) atof(val);
2920
} else if (id==60) {
2921
/* short invisible= atoi(val); */
2922
} else if (id==62) {
2923
int colorid= atoi(val);
2925
CLAMP(colorid, 1, 255);
2926
dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
2928
read_group(id, val);
2931
dxf_get_mesh(scene, &me, &ob, noob);
2933
me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
2934
CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
2936
dxf_add_mat (ob, me, color, layname);
2939
mvert->co[0]= mvert->co[1]= mvert->co[2]= 0;
2941
if (ob) VECCOPY(ob->loc, cent);
2946
/* Line state vars */
2947
static Object *linehold=NULL;
2948
static Mesh *linemhold=NULL;
2950
static char oldllay[32];
2951
static short lwasline=0; /* last was face 3d? */
2953
static void dxf_close_line(void)
2956
if (linehold==NULL) return;
2961
static void dxf_read_line(Scene *scene, int noob) {
2962
/* Entity specific vars */
2963
float epoint[3]={0.0, 0.0, 0.0};
2964
short vspace=0; /* Whether or not coords are relative */
2969
MVert *mvert, *vtmp;
2970
MFace *mface, *ftmp;
2974
read_group(id, val);
2977
BLI_strncpy(layname, val, sizeof(layname));
2978
} else if (id==10) {
2979
cent[0]= (float) atof(val);
2980
} else if (id==20) {
2981
cent[1]= (float) atof(val);
2982
} else if (id==30) {
2983
cent[2]= (float) atof(val);
2984
} else if (id==11) {
2985
epoint[0]= (float) atof(val);
2986
} else if (id==21) {
2987
epoint[1]= (float) atof(val);
2988
} else if (id==31) {
2989
epoint[2]= (float) atof(val);
2990
} else if (id==60) {
2991
/* short invisible= atoi(val); */
2992
} else if (id==62) {
2993
int colorid= atoi(val);
2995
CLAMP(colorid, 1, 255);
2996
dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
2997
} else if (id==67) {
3000
read_group(id, val);
3003
/* Check to see if we need to make a new object */
3005
if(!lwasline || strcmp(layname, oldllay)!=0)
3007
if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS)
3010
if (linemhold==NULL) {
3011
dxf_get_mesh(scene, &me, &ob, noob);
3013
if(ob) VECCOPY(ob->loc, cent);
3015
dxf_add_mat (ob, me, color, layname);
3027
vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
3028
ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface");
3031
memcpy(vtmp, me->mvert, (me->totvert-2)*sizeof(MVert));
3032
MEM_freeN(me->mvert);
3034
me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
3038
memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
3039
MEM_freeN(me->mface);
3041
me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
3044
mvert= &me->mvert[(me->totvert-2)];
3046
sub_v3_v3v3(mvert->co, cent, vcenter);
3048
if (vspace) { VECCOPY(mvert->co, epoint);
3049
} else sub_v3_v3v3(mvert->co, epoint, vcenter);
3051
mface= &(((MFace*)me->mface)[me->totface-1]);
3052
mface->v1= me->totvert-2;
3053
mface->v2= me->totvert-1;
3059
/* 2D Polyline state vars */
3060
static Object *p2dhold=NULL;
3061
static Mesh *p2dmhold=NULL;
3062
static char oldplay[32];
3063
static short lwasp2d=0;
3065
static void dxf_close_2dpoly(void)
3068
if (p2dhold==NULL) return;
3073
static void dxf_read_ellipse(Scene *scene, int noob)
3077
* The Parameter option of the ELLIPSE command uses the following equation to define an elliptical arc.
3079
* p(u)=c+a*cos(u)+b*sin(u)
3081
* The variables a, b, c are determined when you select the endpoints for the
3082
* first axis and the distance for the second axis. a is the negative of 1/2
3083
* of the major axis length, b is the negative of 1/2 the minor axis length,
3084
* and c is the center point (2-D) of the ellipse.
3086
* Because this is actually a vector equation and the variable c is actually
3087
* a point with X and Y values, it really should be written as:
3089
* p(u)=(Cx+a*cos(u))*i+(Cy+b*sin(u))*j
3093
* Cx is the X value of the point c
3094
* Cy is the Y value of the point c
3095
* a is -(1/2 of the major axis length)
3096
* b is -(1/2 of the minor axis length)
3097
* i and j represent unit vectors in the X and Y directions
3099
* http://astronomy.swin.edu.au/~pbourke/geomformats/dxf2000/ellipse_command39s_parameter_option_dxf_06.htm
3100
* (reproduced with permission)
3102
* NOTE: The start and end angles ('parameters') are in radians, whereas those for the circular arc are
3103
* in degrees. The 'sense' of u appears to be determined by the extrusion direction (see more detailed comment
3106
* TODO: The code is specific to ellipses in the x-y plane right now.
3110
/* Entity specific vars */
3111
float epoint[3]={0.0, 0.0, 0.0};
3112
float center[3]={0.0, 0.0, 0.0};
3113
float extrusion[3]={0.0, 0.0, 1.0};
3114
float axis_endpoint[3] = {0.0, 0.0, 0.0}; /* major axis endpoint */
3115
short vspace=0; /* Whether or not coords are relative */
3116
float a, b, x, y, z;
3117
float phid = 0.0f, phi = 0.0f, theta = 0.0f;
3118
float start_angle = 0.0f;
3119
float end_angle = 2*M_PI;
3120
float axis_ratio = 1.0f;
3131
read_group(id, val);
3134
BLI_strncpy(layname, val, sizeof(layname));
3135
} else if (id==10) {
3136
center[0]= (float) atof(val);
3137
} else if (id==20) {
3138
center[1]= (float) atof(val);
3139
} else if (id==30) {
3140
center[2]= (float) atof(val);
3141
} else if (id==11) {
3142
axis_endpoint[0]= (float) atof(val);
3143
} else if (id==21) {
3144
axis_endpoint[1]= (float) atof(val);
3145
} else if (id==31) {
3146
axis_endpoint[2]= (float) atof(val);
3147
} else if (id==40) {
3148
axis_ratio = (float) atof(val);
3149
} else if (id==41) {
3150
printf("dxf: start = %f", atof(val) * 180/M_PI);
3151
start_angle = -atof(val) + M_PI_2;
3152
} else if (id==42) {
3153
printf("dxf: end = %f", atof(val) * 180/M_PI);
3154
end_angle = -atof(val) + M_PI_2;
3155
} else if (id==62) {
3156
int colorid= atoi(val);
3157
CLAMP(colorid, 1, 255);
3158
dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
3159
} else if (id==67) {
3161
} else if (id==100) {
3163
} else if (id==210) {
3164
extrusion[0] = atof(val);
3165
} else if (id==220) {
3166
extrusion[1] = atof(val);
3167
} else if (id==230) {
3168
extrusion[2] = atof(val);
3170
read_group(id, val);
3173
if(!lwasline || strcmp(layname, oldllay)!=0) dxf_close_line();
3174
if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS)
3177
/* The 'extrusion direction' seems akin to a face normal,
3178
* insofar as it determines the direction of increasing phi.
3179
* This is again x-y plane specific; it should be fixed at
3182
if (extrusion[2] < 0) {
3184
start_angle = M_PI - end_angle;
3185
end_angle = M_PI - temp;
3188
if(end_angle > start_angle)
3189
end_angle -= 2 * M_PI;
3193
x = axis_endpoint[0];
3194
y = axis_endpoint[1];
3195
z = axis_endpoint[2];
3196
a = sqrt(x*x + y*y + z*z);
3199
theta = atan2(y, x);
3204
#ifndef DEBUG_CENTER
3205
epoint[0] = center[0] + x*cos(theta) - y*sin(theta);
3206
epoint[1] = center[1] + x*sin(theta) + y*cos(theta);
3207
epoint[2] = center[2];
3219
dxf_get_mesh(scene, &me, &ob, noob);
3220
strcpy(oldllay, layname);
3221
if(ob) VECCOPY(ob->loc, cent);
3222
dxf_add_mat (ob, me, color, layname);
3224
tot = 32; /* # of line segments to divide the arc into */
3226
phid = (end_angle - start_angle)/tot;
3228
me->totvert += tot+1;
3229
me->totface += tot+1;
3231
me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
3232
me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
3234
CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
3235
CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
3237
printf("vertex and face buffers allocated\n");
3239
for(v = 0; v <= tot; v++) {
3243
epoint[0] = center[0] + x*cos(theta) - y*sin(theta);
3244
epoint[1] = center[1] + x*sin(theta) + y*cos(theta);
3245
epoint[2] = center[2];
3247
mvert= &me->mvert[v];
3250
VECCOPY(mvert->co, epoint);
3252
sub_v3_v3v3(mvert->co, epoint, vcenter);
3256
mface= &(((MFace*)me->mface)[v-1]);
3264
VECCOPY(cent, epoint);
3269
static void dxf_read_arc(Scene *scene, int noob)
3271
/* Entity specific vars */
3272
float epoint[3]={0.0, 0.0, 0.0};
3273
float center[3]={0.0, 0.0, 0.0};
3274
float extrusion[3]={0.0, 0.0, 1.0};
3275
short vspace=0; /* Whether or not coords are relative */
3277
float phid = 0.0f, phi = 0.0f;
3278
float start_angle = 0.0f;
3279
float end_angle = 2*M_PI;
3290
read_group(id, val);
3293
BLI_strncpy(layname, val, sizeof(layname));
3294
} else if (id==10) {
3295
center[0]= (float) atof(val);
3296
} else if (id==20) {
3297
center[1]= (float) atof(val);
3298
} else if (id==30) {
3299
center[2]= (float) atof(val);
3300
} else if (id==40) {
3301
dia = (float) atof(val);
3302
} else if (id==62) {
3303
int colorid= atoi(val);
3305
CLAMP(colorid, 1, 255);
3306
dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
3307
} else if (id==67) {
3309
} else if (id==100) {
3311
} else if (id==50) {
3312
start_angle = (90 - atoi(val)) * M_PI/180.0;
3313
} else if (id==51) {
3314
end_angle = (90 - atoi(val)) * M_PI/180.0;
3315
} else if (id==210) {
3316
extrusion[0] = atof(val);
3317
} else if (id==220) {
3318
extrusion[1] = atof(val);
3319
} else if (id==230) {
3320
extrusion[2] = atof(val);
3322
read_group(id, val);
3325
if(!lwasline || strcmp(layname, oldllay)!=0) dxf_close_line();
3326
if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS)
3329
/* Same xy-plane-specific extrusion direction code as in read_ellipse
3330
* (read_arc and read_ellipse should ideally be rewritten to share code)
3333
if (extrusion[2] < 0) {
3335
start_angle = M_PI - end_angle;
3336
end_angle = M_PI - temp;
3340
if(end_angle > start_angle)
3341
end_angle -= 2 * M_PI;
3343
cent[0]= center[0]+dia*sin(phi);
3344
cent[1]= center[1]+dia*cos(phi);
3347
dxf_get_mesh(scene, &me, &ob, noob);
3348
strcpy(oldllay, layname);
3349
if(ob) VECCOPY(ob->loc, cent);
3350
dxf_add_mat (ob, me, color, layname);
3352
tot = 32; /* # of line segments to divide the arc into */
3353
phid = (end_angle - start_angle)/tot; /* fix so that arcs have the same 'resolution' as circles? */
3355
me->totvert += tot+1;
3356
me->totface += tot+1;
3358
me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
3359
me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
3361
CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
3362
CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
3364
for(v = 0; v <= tot; v++) {
3366
epoint[0]= center[0]+dia*sin(phi);
3367
epoint[1]= center[1]+dia*cos(phi);
3368
epoint[2]= center[2];
3370
mvert= &me->mvert[v];
3373
VECCOPY(mvert->co, epoint);
3375
sub_v3_v3v3(mvert->co, epoint, vcenter);
3379
mface= &(((MFace*)me->mface)[v-1]);
3387
VECCOPY(cent, epoint);
3392
static void dxf_read_polyline(Scene *scene, int noob) {
3393
/* Entity specific vars */
3394
short vspace=0; /* Whether or not coords are relative */
3403
float vert[3] = {0};
3405
MVert *mvert, *vtmp;
3406
MFace *mface, *ftmp;
3410
read_group(id, val);
3413
BLI_strncpy(layname, val, sizeof(layname));
3414
} else if (id==10) {
3415
cent[0]= (float) atof(val);
3416
} else if (id==20) {
3417
cent[1]= (float) atof(val);
3418
} else if (id==30) {
3419
cent[2]= (float) atof(val);
3420
} else if (id==60) {
3421
/* short invisible= atoi(val); */
3422
} else if (id==62) {
3423
int colorid= atoi(val);
3425
CLAMP(colorid, 1, 255);
3426
dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
3427
} else if (id==67) {
3429
} else if (id==70) {
3432
read_group(id, val);
3435
if (flag & 9) { // 1= closed curve, 8= 3d curve
3436
if(!lwasp2d || strcmp(layname, oldplay)!=0) dxf_close_2dpoly();
3437
if(p2dmhold != NULL && p2dmhold->totvert>MESH_MAX_VERTS)
3440
if (p2dmhold==NULL) {
3441
dxf_get_mesh(scene, &me, &ob, noob);
3443
strcpy(oldplay, layname);
3445
if(ob) VECCOPY(ob->loc, cent);
3447
dxf_add_mat (ob, me, color, layname);
3458
while (group_is(0, "VERTEX")) {
3459
read_group(id, val);
3462
vert[0]= (float) atof(val);
3463
} else if (id==20) {
3464
vert[1]= (float) atof(val);
3465
} else if (id==30) {
3466
vert[2]= (float) atof(val);
3468
read_group(id, val);
3473
vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
3476
memcpy (vtmp, me->mvert, (me->totvert-1)*sizeof(MVert));
3477
MEM_freeN(me->mvert);
3479
me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
3482
mvert= &me->mvert[me->totvert-1];
3484
if (vspace) { VECCOPY(mvert->co, vert);
3485
} else sub_v3_v3v3(mvert->co, vert, vcenter);
3492
oldtotface= me->totface;
3493
me->totface+= nverts-1;
3495
ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface");
3498
memcpy(ftmp, me->mface, oldtotface*sizeof(MFace));
3499
MEM_freeN(me->mface);
3501
me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
3507
for(a=1; a<nverts; a++, mface++) {
3508
mface->v1= (me->totvert-nverts)+a-1;
3509
mface->v2= (me->totvert-nverts)+a;
3517
dxf_get_mesh(scene, &me, &ob, noob);
3519
if(ob) VECCOPY(ob->loc, cent);
3521
dxf_add_mat (ob, me, color, layname);
3523
while (group_is(0, "VERTEX")) {
3525
vids[0]= vids[1]= vids[2]= vids[3]= 0;
3528
read_group(id, val);
3531
; /* Layer def, skip */
3532
} else if (id==10) {
3533
vert[0]= (float) atof(val);
3534
} else if (id==20) {
3535
vert[1]= (float) atof(val);
3536
} else if (id==30) {
3537
vert[2]= (float) atof(val);
3538
} else if (id==70) {
3540
} else if (id==71) {
3541
vids[0]= abs(atoi(val));
3542
} else if (id==72) {
3543
vids[1]= abs(atoi(val));
3544
} else if (id==73) {
3545
vids[2]= abs(atoi(val));
3546
} else if (id==74) {
3547
vids[3]= abs(atoi(val));
3549
read_group(id, val);
3552
if (vflags & 128 && vflags & 64) {
3555
/* If we are nearing the limit scan to the next entry */
3556
if(me->totvert > MESH_MAX_VERTS)
3557
while(group_isnt(0, "SEQEND")) read_group(id, val);
3559
vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
3562
memcpy(vtmp, me->mvert, (me->totvert-1)*sizeof(MVert));
3563
MEM_freeN(me->mvert);
3565
me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
3568
mvert= &me->mvert[(me->totvert-1)];
3570
if (vspace) { VECCOPY(mvert->co, vert);
3571
} else sub_v3_v3v3(mvert->co, vert, vcenter);
3573
} else if (vflags & 128) {
3575
//XXX error("(PL) Error parsing dxf, not enough vertices near line %d", dxf_line);
3584
ftmp= MEM_callocN(me->totface*sizeof(MFace), "mfaces");
3587
memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
3588
MEM_freeN(me->mface);
3590
me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
3593
mface= &(((MFace*)me->mface)[me->totface-1]);
3594
mface->v1= vids[0]-1;
3595
mface->v2= vids[1]-1;
3596
mface->v3= vids[2]-1;
3598
if(vids[3] && vids[3]!=vids[0]) {
3599
mface->v4= vids[3]-1;
3600
test_index_face(mface, NULL, 0, 4);
3602
else test_index_face(mface, NULL, 0, 3);
3607
//XXX error("Error parsing dxf, unknown polyline information near %d", dxf_line);
3618
static void dxf_read_lwpolyline(Scene *scene, int noob) {
3619
/* Entity specific vars */
3620
short vspace=0; /* Whether or not coords are relative */
3628
float vert[3] = {0};
3637
/* block structure is
3641
* nverts.times { 10 => x, 20 => y }
3644
read_group(id, val);
3646
BLI_strncpy(layname, val, sizeof(layname));
3647
} else if (id==38) {
3648
vert[2]= (float) atof(val);
3649
} else if (id==60) {
3650
/* short invisible= atoi(val); */
3651
} else if (id==62) {
3652
int colorid= atoi(val);
3654
CLAMP(colorid, 1, 255);
3655
dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
3656
} else if (id==67) {
3658
} else if (id==70) {
3660
} else if (id==90) {
3664
printf("nverts %d\n", nverts);
3668
dxf_get_mesh(scene, &me, &ob, noob);
3669
strcpy(oldllay, layname);
3670
if(ob) VECCOPY(ob->loc, cent);
3671
dxf_add_mat (ob, me, color, layname);
3673
me->totvert += nverts;
3674
me->totface += nverts;
3676
me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
3677
me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
3679
CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
3680
CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
3682
for (v = 0; v < nverts; v++) {
3685
vert[0]= (float) atof(val);
3687
//XXX error("Error parsing dxf, expected (10, <x>) at line %d", dxf_line);
3692
vert[1]= (float) atof(val);
3694
//XXX error("Error parsing dxf, expected (20, <y>) at line %d", dxf_line);
3697
mvert = &me->mvert[v];
3700
VECCOPY(mvert->co, vert);
3702
sub_v3_v3v3(mvert->co, vert, vcenter);
3706
mface= &(((MFace*)me->mface)[v-1]);
3713
/* flag & 1 -> closed polyline
3714
* TODO: give the polyline actual 2D faces if it is closed */
3718
mface= &(((MFace*)me->mface)[nverts - 1]);
3719
mface->v1 = nverts-1;
3727
/* 3D Face state vars */
3728
static Object *f3dhold=NULL;
3729
static Mesh *f3dmhold=NULL;
3730
static char oldflay[32];
3731
static short lwasf3d=0; /* last was face 3d? */
3733
/* how can this function do anything useful (ton)? */
3734
static void dxf_close_3dface(void)
3737
if (f3dhold==NULL) return;
3742
static void dxf_read_3dface(Scene *scene, int noob)
3744
/* Entity specific vars */
3745
float vert2[3]={0.0, 0.0, 0.0};
3746
float vert3[3]={0.0, 0.0, 0.0};
3747
float vert4[3]={0.0, 0.0, 0.0};
3755
MVert *mvert, *vtmp;
3756
MFace *mface, *ftmp;
3760
read_group(id, val);
3763
BLI_strncpy(layname, val, sizeof(layname));
3765
/* First vert/origin */
3766
} else if (id==10) {
3767
cent[0]= (float) atof(val);
3768
if (nverts<1)nverts++;
3769
} else if (id==20) {
3770
cent[1]= (float) atof(val);
3771
if (nverts<1)nverts++;
3772
} else if (id==30) {
3773
cent[2]= (float) atof(val);
3774
if (nverts<1)nverts++;
3777
} else if (id==11) {
3778
vert2[0]= (float) atof(val);
3779
if (nverts<2)nverts++;
3780
} else if (id==21) {
3781
vert2[1]= (float) atof(val);
3782
if (nverts<2)nverts++;
3783
} else if (id==31) {
3784
vert2[2]= (float) atof(val);
3785
if (nverts<2)nverts++;
3788
} else if (id==12) {
3789
vert3[0]= (float) atof(val);
3790
if (nverts<3)nverts++;
3791
} else if (id==22) {
3792
vert3[1]= (float) atof(val);
3793
if (nverts<3)nverts++;
3794
} else if (id==32) {
3795
vert3[2]= (float) atof(val);
3796
if (nverts<3)nverts++;
3799
} else if (id==13) {
3800
vert4[0]= (float) atof(val);
3801
if (nverts<4)nverts++;
3802
} else if (id==23) {
3803
vert4[1]= (float) atof(val);
3804
if (nverts<4)nverts++;
3805
} else if (id==33) {
3806
vert4[2]= (float) atof(val);
3807
if (nverts<4)nverts++;
3810
} else if (id==60) {
3811
/* short invisible= atoi(val); */
3812
} else if (id==62) {
3813
int colorid= atoi(val);
3815
CLAMP(colorid, 1, 255);
3816
dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
3817
} else if (id==67) {
3820
read_group(id, val);
3823
/* Check to see if we need to make a new object */
3825
if(!lwasf3d || strcmp(layname, oldflay)!=0) dxf_close_3dface();
3826
if(f3dmhold != NULL && f3dmhold->totvert>MESH_MAX_VERTS)
3830
//XXX error("(3DF) Error parsing dxf, not enough vertices near line %d", dxf_line);
3837
if (f3dmhold==NULL) {
3838
dxf_get_mesh(scene, &me, &ob, noob);
3840
strcpy(oldflay, layname);
3842
if(ob) VECCOPY(ob->loc, cent);
3844
dxf_add_mat (ob, me, color, layname);
3853
me->totvert+= nverts;
3856
vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
3857
ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface");
3860
memcpy(vtmp, me->mvert, (me->totvert-nverts)*sizeof(MVert));
3861
MEM_freeN(me->mvert);
3863
me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
3867
memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
3868
MEM_freeN(me->mface);
3870
me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
3873
mvert= &me->mvert[(me->totvert-nverts)];
3874
sub_v3_v3v3(mvert->co, cent, vcenter);
3877
if (vspace) { VECCOPY(mvert->co, vert2);
3878
} else sub_v3_v3v3(mvert->co, vert2, vcenter);
3881
if (vspace) { VECCOPY(mvert->co, vert3);
3882
} else sub_v3_v3v3(mvert->co, vert3, vcenter);
3886
if (vspace) { VECCOPY(mvert->co, vert4);
3887
} else sub_v3_v3v3(mvert->co, vert4, vcenter);
3890
mface= &(((MFace*)me->mface)[me->totface-1]);
3891
mface->v1= (me->totvert-nverts)+0;
3892
mface->v2= (me->totvert-nverts)+1;
3893
mface->v3= (me->totvert-nverts)+2;
3896
mface->v4= (me->totvert-nverts)+3;
3900
test_index_face(mface, NULL, 0, nverts);
3905
static void dxf_read(Scene *scene, char *filename)
3907
Mesh *lastMe = G.main->mesh.last;
3909
/* clear ugly global variables, that can hang because on error the code
3910
below returns... tsk (ton) */
3916
dxf_fp= fopen(filename, "r");
3917
if (dxf_fp==NULL) return;
3920
read_group(id, val);
3921
if (group_is(0, "EOF")) break;
3923
if (id==999) continue;
3924
id_check(0, "SECTION");
3926
read_group(id, val);
3927
if (group_is(2, "HEADER")) {
3928
} else if (group_is(2, "TABLES")) {
3929
} else if (group_is(2, "OBJECTS")) {
3930
} else if (group_is(2, "CLASSES")) {
3931
} else if (group_is(2, "BLOCKS")) {
3933
read_group(id, val);
3934
if (group_is(0, "BLOCK")) {
3935
while(group_isnt(0, "ENDBLK")) {
3936
read_group(id, val);
3939
BLI_strncpy(entname, val, sizeof(entname));
3941
/* Now the object def should follow */
3942
if(strlen(entname)==0) {
3943
//XXX error("Error parsing dxf, no mesh name near %d", dxf_line);
3948
/* Now the object def should follow */
3949
while(group_isnt(0, "ENDBLK")) {
3950
read_group(id, val);
3952
if(group_is(0, "POLYLINE")) {
3953
dxf_read_polyline(scene, 1);
3954
if(error_exit) return;
3958
while(group_isnt(0, "SEQEND")) read_group(id, val);
3960
} else if(group_is(0, "LWPOLYLINE")) {
3961
dxf_read_lwpolyline(scene, 1);
3962
if(error_exit) return;
3966
while(group_isnt(0, "SEQEND")) read_group(id, val);
3967
} else if(group_is(0, "ATTRIB")) {
3968
while(group_isnt(0, "SEQEND")) read_group(id, val);
3972
} else if(group_is(0, "POINT")) {
3973
dxf_read_point(scene, 1);
3974
if(error_exit) return;
3978
} else if(group_is(0, "LINE")) {
3979
dxf_read_line(scene, 1);
3980
if(error_exit) return;
3984
} else if(group_is(0, "3DFACE")) {
3985
dxf_read_3dface(scene, 1);
3986
if(error_exit) return;
3990
} else if (group_is(0, "CIRCLE")) {
3991
dxf_read_arc(scene, 1);
3992
} else if (group_is(0, "ELLIPSE")) {
3993
dxf_read_ellipse(scene, 1);
3994
} else if (group_is(0, "ENDBLK")) {
3998
} else if (group_is(0, "ENDBLK")) {
4002
while(id!=0) read_group(id, val);
4004
} else if(group_is(0, "ENDSEC")) {
4008
} else if (group_is(2, "ENTITIES")) {
4009
while(group_isnt(0, "ENDSEC")) {
4011
char layname[32]="";
4012
float cent[3]={0.0, 0.0, 0.0};
4013
float obsize[3]={1.0, 1.0, 1.0};
4014
float obrot[3]={0.0, 0.0, 0.0};
4016
if(!hasbumped) read_group(id, val);
4018
if (group_is(0, "INSERT")) {
4023
read_group(id, val);
4027
BLI_strncpy(obname, val, sizeof(obname));
4029
BLI_strncpy(layname, val, sizeof(layname));
4030
} else if (id==10) {
4031
cent[0]= (float) atof(val);
4032
} else if (id==20) {
4033
cent[1]= (float) atof(val);
4034
} else if (id==30) {
4035
cent[2]= (float) atof(val);
4036
} else if (id==41) {
4037
obsize[0]= (float) atof(val);
4038
} else if (id==42) {
4039
obsize[1]= (float) atof(val);
4040
} else if (id==43) {
4041
obsize[2]= (float) atof(val);
4042
} else if (id==50) {
4043
obrot[2]= (float) (atof(val)*M_PI/180.0);
4044
} else if (id==60) {
4045
/* short invisible= atoi(val); */
4048
read_group(id, val);
4052
if(strlen(obname)==0) {
4053
//XXX error("Error parsing dxf, no object name near %d", dxf_line);
4058
obdata= find_id("ME", obname);
4061
ob= alloc_libblock(&G.main->object, ID_OB, obname);
4067
ob->trackflag= OB_POSY;
4068
ob->upflag= OB_POSZ;
4070
ob->ipoflag = OB_OFFS_OB+OB_OFFS_PARENT;
4072
ob->dupon= 1; ob->dupoff= 0;
4073
ob->dupsta= 1; ob->dupend= 100;
4074
ob->recalc= OB_RECALC_ALL; /* needed because of weird way of adding libdata directly */
4077
((ID*)ob->data)->us++;
4079
VECCOPY(ob->loc, cent);
4080
VECCOPY(ob->size, obsize);
4081
VECCOPY(ob->rot, obrot);
4083
ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
4084
ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits");
4085
ob->totcol= (unsigned char) ((Mesh*)ob->data)->totcol;
4088
/* note: materials are either linked to mesh or object, if both then
4089
you have to increase user counts. below line is not needed.
4090
I leave it commented out here as warning (ton) */
4091
//for (i=0; i<ob->totcol; i++) ob->mat[i]= ((Mesh*)ob->data)->mat[i];
4093
if (strlen(layname)) ob->lay= dxf_get_layer_num(scene, layname);
4094
else ob->lay= scene->lay;
4097
base= MEM_callocN( sizeof(Base), "add_base");
4098
BLI_addhead(&scene->base, base);
4110
} else if(group_is(0, "POLYLINE")) {
4111
dxf_read_polyline(scene, 0);
4112
if(error_exit) return;
4116
while(group_isnt(0, "SEQEND")) read_group(id, val);
4118
} else if(group_is(0, "LWPOLYLINE")) {
4119
dxf_read_lwpolyline(scene, 0);
4120
if(error_exit) return;
4123
//while(group_isnt(0, "SEQEND")) read_group(id, val);
4125
} else if(group_is(0, "ATTRIB")) {
4126
while(group_isnt(0, "SEQEND")) read_group(id, val);
4130
} else if(group_is(0, "POINT")) {
4131
dxf_read_point(scene, 0);
4132
if(error_exit) return;
4136
} else if(group_is(0, "LINE")) {
4137
dxf_read_line(scene, 0);
4138
if(error_exit) return;
4142
} else if(group_is(0, "3DFACE")) {
4143
dxf_read_3dface(scene, 0);
4144
if(error_exit) return;
4148
} else if (group_is(0, "CIRCLE") || group_is(0, "ARC")) {
4149
dxf_read_arc(scene, 0);
4150
} else if (group_is(0, "ELLIPSE")) {
4151
dxf_read_ellipse(scene, 0);
4152
} else if(group_is(0, "ENDSEC")) {
4158
while(group_isnt(0, "ENDSEC")) read_group(id, val);
4164
/* Close any remaining state held stuff */
4170
lastMe = lastMe->id.next;
4172
lastMe = G.main->mesh.first;
4174
for (; lastMe; lastMe=lastMe->id.next) {
4175
mesh_add_normals_flags(lastMe);
4176
make_edges(lastMe, 0);