libDXF 0.0.1
A library with DXF related functions written in C.
|
00001 00038 #include "trace.h" 00039 00040 00055 DxfTrace * 00056 dxf_trace_new () 00057 { 00058 #if DEBUG 00059 DXF_DEBUG_BEGIN 00060 #endif 00061 DxfTrace *trace = NULL; 00062 size_t size; 00063 00064 size = sizeof (DxfTrace); 00065 /* avoid malloc of 0 bytes */ 00066 if (size == 0) size = 1; 00067 if ((trace = malloc (size)) == NULL) 00068 { 00069 fprintf (stderr, 00070 (_("Error in %s () could not allocate memory for a DxfTrace struct.\n")), 00071 __FUNCTION__); 00072 trace = NULL; 00073 } 00074 else 00075 { 00076 memset (trace, 0, size); 00077 } 00078 #if DEBUG 00079 DXF_DEBUG_END 00080 #endif 00081 return (trace); 00082 } 00083 00084 00098 DxfTrace * 00099 dxf_trace_init 00100 ( 00101 DxfTrace *trace 00103 ) 00104 { 00105 #if DEBUG 00106 DXF_DEBUG_BEGIN 00107 #endif 00108 /* Do some basic checks. */ 00109 if (trace == NULL) 00110 { 00111 fprintf (stderr, 00112 (_("Warning in %s () a NULL pointer was passed.\n")), 00113 __FUNCTION__); 00114 trace = dxf_trace_new (); 00115 } 00116 if (trace == NULL) 00117 { 00118 fprintf (stderr, 00119 (_("Error in %s () could not allocate memory for a DxfTrace struct.\n")), 00120 __FUNCTION__); 00121 return (NULL); 00122 } 00123 trace->id_code = 0; 00124 trace->linetype = strdup (DXF_DEFAULT_LINETYPE); 00125 trace->layer = strdup (DXF_DEFAULT_LAYER); 00126 trace->x0 = 0.0; 00127 trace->y0 = 0.0; 00128 trace->z0 = 0.0; 00129 trace->x1 = 0.0; 00130 trace->y1 = 0.0; 00131 trace->z1 = 0.0; 00132 trace->x2 = 0.0; 00133 trace->y2 = 0.0; 00134 trace->z2 = 0.0; 00135 trace->x3 = 0.0; 00136 trace->y3 = 0.0; 00137 trace->z3 = 0.0; 00138 trace->elevation = 0.0; 00139 trace->thickness = 0.0; 00140 trace->linetype_scale = DXF_DEFAULT_LINETYPE_SCALE; 00141 trace->visibility = DXF_DEFAULT_VISIBILITY; 00142 trace->color = DXF_COLOR_BYLAYER; 00143 trace->paperspace = DXF_MODELSPACE; 00144 trace->extr_x0 = 0.0; 00145 trace->extr_y0 = 0.0; 00146 trace->extr_z0 = 0.0; 00147 trace->dictionary_owner_soft = strdup (""); 00148 trace->dictionary_owner_hard = strdup (""); 00149 trace->next = NULL; 00150 #if DEBUG 00151 DXF_DEBUG_END 00152 #endif 00153 return (trace); 00154 } 00155 00156 00172 DxfTrace * 00173 dxf_trace_read 00174 ( 00175 DxfFile *fp, 00177 DxfTrace *trace 00179 ) 00180 { 00181 #if DEBUG 00182 DXF_DEBUG_BEGIN 00183 #endif 00184 char *temp_string = NULL; 00185 00186 /* Do some basic checks. */ 00187 if (fp == NULL) 00188 { 00189 fprintf (stderr, 00190 (_("Error in %s () a NULL file pointer was passed.\n")), 00191 __FUNCTION__); 00192 /* Clean up. */ 00193 free (temp_string); 00194 return (NULL); 00195 } 00196 if (trace == NULL) 00197 { 00198 fprintf (stderr, 00199 (_("Warning in %s () a NULL pointer was passed.\n")), 00200 __FUNCTION__); 00201 trace = dxf_trace_new (); 00202 trace = dxf_trace_init (trace); 00203 } 00204 (fp->line_number)++; 00205 fscanf (fp->fp, "%[^\n]", temp_string); 00206 while (strcmp (temp_string, "0") != 0) 00207 { 00208 if (ferror (fp->fp)) 00209 { 00210 fprintf (stderr, 00211 (_("Error in %s () while reading from: %s in line: %d.\n")), 00212 __FUNCTION__, fp->filename, fp->line_number); 00213 fclose (fp->fp); 00214 /* Clean up. */ 00215 free (temp_string); 00216 return (NULL); 00217 } 00218 if (strcmp (temp_string, "5") == 0) 00219 { 00220 /* Now follows a string containing a sequential 00221 * id number. */ 00222 (fp->line_number)++; 00223 fscanf (fp->fp, "%x\n", &trace->id_code); 00224 } 00225 else if (strcmp (temp_string, "6") == 0) 00226 { 00227 /* Now follows a string containing a linetype 00228 * name. */ 00229 (fp->line_number)++; 00230 fscanf (fp->fp, "%s\n", trace->linetype); 00231 } 00232 else if (strcmp (temp_string, "8") == 0) 00233 { 00234 /* Now follows a string containing a layer name. */ 00235 (fp->line_number)++; 00236 fscanf (fp->fp, "%s\n", trace->layer); 00237 } 00238 else if (strcmp (temp_string, "10") == 0) 00239 { 00240 /* Now follows a string containing the 00241 * X-coordinate of the base point. */ 00242 (fp->line_number)++; 00243 fscanf (fp->fp, "%lf\n", &trace->x0); 00244 } 00245 else if (strcmp (temp_string, "11") == 0) 00246 { 00247 /* Now follows a string containing the 00248 * X-coordinate of the alignment point. */ 00249 (fp->line_number)++; 00250 fscanf (fp->fp, "%lf\n", &trace->x1); 00251 } 00252 else if (strcmp (temp_string, "12") == 0) 00253 { 00254 /* Now follows a string containing the 00255 * X-coordinate of the alignment point. */ 00256 (fp->line_number)++; 00257 fscanf (fp->fp, "%lf\n", &trace->x2); 00258 } 00259 else if (strcmp (temp_string, "13") == 0) 00260 { 00261 /* Now follows a string containing the 00262 * X-coordinate of the alignment point. */ 00263 (fp->line_number)++; 00264 fscanf (fp->fp, "%lf\n", &trace->x3); 00265 } 00266 else if (strcmp (temp_string, "20") == 0) 00267 { 00268 /* Now follows a string containing the 00269 * Y-coordinate of the base point. */ 00270 (fp->line_number)++; 00271 fscanf (fp->fp, "%lf\n", &trace->y0); 00272 } 00273 else if (strcmp (temp_string, "21") == 0) 00274 { 00275 /* Now follows a string containing the 00276 * Y-coordinate of the alignment point. */ 00277 (fp->line_number)++; 00278 fscanf (fp->fp, "%lf\n", &trace->y1); 00279 } 00280 else if (strcmp (temp_string, "22") == 0) 00281 { 00282 /* Now follows a string containing the 00283 * Y-coordinate of the alignment point. */ 00284 (fp->line_number)++; 00285 fscanf (fp->fp, "%lf\n", &trace->y2); 00286 } 00287 else if (strcmp (temp_string, "23") == 0) 00288 { 00289 /* Now follows a string containing the 00290 * Y-coordinate of the alignment point. */ 00291 (fp->line_number)++; 00292 fscanf (fp->fp, "%lf\n", &trace->y3); 00293 } 00294 else if (strcmp (temp_string, "30") == 0) 00295 { 00296 /* Now follows a string containing the 00297 * Z-coordinate of the base point. */ 00298 (fp->line_number)++; 00299 fscanf (fp->fp, "%lf\n", &trace->z0); 00300 } 00301 else if (strcmp (temp_string, "31") == 0) 00302 { 00303 /* Now follows a string containing the 00304 * Z-coordinate of the alignment point. */ 00305 (fp->line_number)++; 00306 fscanf (fp->fp, "%lf\n", &trace->z1); 00307 } 00308 else if (strcmp (temp_string, "32") == 0) 00309 { 00310 /* Now follows a string containing the 00311 * Z-coordinate of the alignment point. */ 00312 (fp->line_number)++; 00313 fscanf (fp->fp, "%lf\n", &trace->z2); 00314 } 00315 else if (strcmp (temp_string, "33") == 0) 00316 { 00317 /* Now follows a string containing the 00318 * Z-coordinate of the alignment point. */ 00319 (fp->line_number)++; 00320 fscanf (fp->fp, "%lf\n", &trace->z3); 00321 } 00322 else if ((fp->acad_version_number <= AutoCAD_11) 00323 && (strcmp (temp_string, "38") == 0) 00324 && (trace->elevation != 0.0)) 00325 { 00326 /* Now follows a string containing the 00327 * elevation. */ 00328 (fp->line_number)++; 00329 fscanf (fp->fp, "%lf\n", &trace->elevation); 00330 } 00331 else if (strcmp (temp_string, "39") == 0) 00332 { 00333 /* Now follows a string containing the 00334 * thickness. */ 00335 (fp->line_number)++; 00336 fscanf (fp->fp, "%lf\n", &trace->thickness); 00337 } 00338 else if (strcmp (temp_string, "48") == 0) 00339 { 00340 /* Now follows a string containing the linetype 00341 * scale. */ 00342 (fp->line_number)++; 00343 fscanf (fp->fp, "%lf\n", &trace->linetype_scale); 00344 } 00345 else if (strcmp (temp_string, "60") == 0) 00346 { 00347 /* Now follows a string containing the 00348 * visibility value. */ 00349 (fp->line_number)++; 00350 fscanf (fp->fp, "%hd\n", &trace->visibility); 00351 } 00352 else if (strcmp (temp_string, "62") == 0) 00353 { 00354 /* Now follows a string containing the 00355 * color value. */ 00356 (fp->line_number)++; 00357 fscanf (fp->fp, "%d\n", &trace->color); 00358 } 00359 else if (strcmp (temp_string, "67") == 0) 00360 { 00361 /* Now follows a string containing the 00362 * paperspace value. */ 00363 (fp->line_number)++; 00364 fscanf (fp->fp, "%d\n", &trace->paperspace); 00365 } 00366 else if ((fp->acad_version_number >= AutoCAD_13) 00367 && (strcmp (temp_string, "100") == 0)) 00368 { 00369 /* Now follows a string containing the 00370 * subclass marker value. */ 00371 (fp->line_number)++; 00372 fscanf (fp->fp, "%s\n", temp_string); 00373 if ((strcmp (temp_string, "AcDbEntity") != 0) 00374 && ((strcmp (temp_string, "AcDbTrace") != 0))) 00375 { 00376 fprintf (stderr, 00377 (_("Warning in %s () found a bad subclass marker in: %s in line: %d.\n")), 00378 __FUNCTION__, fp->filename, fp->line_number); 00379 } 00380 } 00381 else if (strcmp (temp_string, "210") == 0) 00382 { 00383 /* Now follows a string containing the 00384 * X-value of the extrusion vector. */ 00385 (fp->line_number)++; 00386 fscanf (fp->fp, "%lf\n", &trace->extr_x0); 00387 } 00388 else if (strcmp (temp_string, "220") == 0) 00389 { 00390 /* Now follows a string containing the 00391 * Y-value of the extrusion vector. */ 00392 (fp->line_number)++; 00393 fscanf (fp->fp, "%lf\n", &trace->extr_y0); 00394 } 00395 else if (strcmp (temp_string, "230") == 0) 00396 { 00397 /* Now follows a string containing the 00398 * Z-value of the extrusion vector. */ 00399 (fp->line_number)++; 00400 fscanf (fp->fp, "%lf\n", &trace->extr_z0); 00401 } 00402 else if (strcmp (temp_string, "330") == 0) 00403 { 00404 /* Now follows a string containing Soft-pointer 00405 * ID/handle to owner dictionary. */ 00406 (fp->line_number)++; 00407 fscanf (fp->fp, "%s\n", trace->dictionary_owner_soft); 00408 } 00409 else if (strcmp (temp_string, "360") == 0) 00410 { 00411 /* Now follows a string containing Hard owner 00412 * ID/handle to owner dictionary. */ 00413 (fp->line_number)++; 00414 fscanf (fp->fp, "%s\n", trace->dictionary_owner_hard); 00415 } 00416 else if (strcmp (temp_string, "999") == 0) 00417 { 00418 /* Now follows a string containing a comment. */ 00419 (fp->line_number)++; 00420 fscanf (fp->fp, "%s\n", temp_string); 00421 fprintf (stdout, "DXF comment: %s\n", temp_string); 00422 } 00423 else 00424 { 00425 fprintf (stderr, 00426 (_("Warning in %s () unknown string tag found while reading from: %s in line: %d.\n")), 00427 __FUNCTION__, fp->filename, fp->line_number); 00428 } 00429 } 00430 /* Handle omitted members and/or illegal values. */ 00431 if (strcmp (trace->linetype, "") == 0) 00432 { 00433 trace->linetype = strdup (DXF_DEFAULT_LINETYPE); 00434 } 00435 if (strcmp (trace->layer, "") == 0) 00436 { 00437 trace->layer = strdup (DXF_DEFAULT_LAYER); 00438 } 00439 /* Clean up. */ 00440 free (temp_string); 00441 #if DEBUG 00442 DXF_DEBUG_END 00443 #endif 00444 return (trace); 00445 } 00446 00447 00460 int 00461 dxf_trace_write 00462 ( 00463 DxfFile *fp, 00465 DxfTrace *trace 00467 ) 00468 { 00469 #if DEBUG 00470 DXF_DEBUG_BEGIN 00471 #endif 00472 char *dxf_entity_name = strdup ("TRACE"); 00473 00474 /* Do some basic checks. */ 00475 if (fp == NULL) 00476 { 00477 fprintf (stderr, 00478 (_("Error in %s () a NULL file pointer was passed.\n")), 00479 __FUNCTION__); 00480 /* Clean up. */ 00481 free (dxf_entity_name); 00482 return (EXIT_FAILURE); 00483 } 00484 if (trace == NULL) 00485 { 00486 fprintf (stderr, 00487 (_("Error in %s () a NULL pointer was passed.\n")), 00488 __FUNCTION__); 00489 /* Clean up. */ 00490 free (dxf_entity_name); 00491 return (EXIT_FAILURE); 00492 } 00493 if (strcmp (trace->linetype, "") == 0) 00494 { 00495 fprintf (stderr, 00496 (_("Warning in %s () empty linetype string for the %s entity with id-code: %x\n")), 00497 __FUNCTION__, dxf_entity_name, trace->id_code); 00498 fprintf (stderr, 00499 (_("\t%s entity is reset to default linetype")), 00500 dxf_entity_name); 00501 trace->linetype = strdup (DXF_DEFAULT_LINETYPE); 00502 } 00503 if (strcmp (trace->layer, "") == 0) 00504 { 00505 fprintf (stderr, 00506 (_("Warning in %s () empty layer string for the %s entity with id-code: %x\n")), 00507 __FUNCTION__, dxf_entity_name, trace->id_code); 00508 fprintf (stderr, 00509 (_("\t%s entity is relocated to layer 0")), 00510 dxf_entity_name); 00511 trace->layer = strdup (DXF_DEFAULT_LAYER); 00512 } 00513 /* Start writing output. */ 00514 fprintf (fp->fp, " 0\n%s\n", dxf_entity_name); 00515 if (trace->id_code != -1) 00516 { 00517 fprintf (fp->fp, " 5\n%x\n", trace->id_code); 00518 } 00529 if ((strcmp (trace->dictionary_owner_soft, "") != 0) 00530 && (fp->acad_version_number >= AutoCAD_14)) 00531 { 00532 fprintf (fp->fp, "102\n{ACAD_REACTORS\n"); 00533 fprintf (fp->fp, "330\n%s\n", trace->dictionary_owner_soft); 00534 fprintf (fp->fp, "102\n}\n"); 00535 } 00536 if ((strcmp (trace->dictionary_owner_hard, "") != 0) 00537 && (fp->acad_version_number >= AutoCAD_14)) 00538 { 00539 fprintf (fp->fp, "102\n{ACAD_XDICTIONARY\n"); 00540 fprintf (fp->fp, "360\n%s\n", trace->dictionary_owner_hard); 00541 fprintf (fp->fp, "102\n}\n"); 00542 } 00543 if (fp->acad_version_number >= AutoCAD_13) 00544 { 00545 fprintf (fp->fp, "100\nAcDbEntity\n"); 00546 } 00547 if (trace->paperspace == DXF_PAPERSPACE) 00548 { 00549 fprintf (fp->fp, " 67\n%d\n", DXF_PAPERSPACE); 00550 } 00551 fprintf (fp->fp, " 8\n%s\n", trace->layer); 00552 if (strcmp (trace->linetype, DXF_DEFAULT_LINETYPE) != 0) 00553 { 00554 fprintf (fp->fp, " 6\n%s\n", trace->linetype); 00555 } 00556 if ((fp->acad_version_number <= AutoCAD_11) 00557 && DXF_FLATLAND 00558 && (trace->elevation != 0.0)) 00559 { 00560 fprintf (fp->fp, " 38\n%f\n", trace->elevation); 00561 } 00562 if (trace->color != DXF_COLOR_BYLAYER) 00563 { 00564 fprintf (fp->fp, " 62\n%d\n", trace->color); 00565 } 00566 if (trace->linetype_scale != 1.0) 00567 { 00568 fprintf (fp->fp, " 48\n%f\n", trace->linetype_scale); 00569 } 00570 if (trace->visibility != 0) 00571 { 00572 fprintf (fp->fp, " 60\n%d\n", trace->visibility); 00573 } 00574 if (fp->acad_version_number >= AutoCAD_13) 00575 { 00576 fprintf (fp->fp, "100\nAcDbTrace\n"); 00577 } 00578 fprintf (fp->fp, " 10\n%f\n", trace->x0); 00579 fprintf (fp->fp, " 20\n%f\n", trace->y0); 00580 fprintf (fp->fp, " 30\n%f\n", trace->z0); 00581 fprintf (fp->fp, " 11\n%f\n", trace->x1); 00582 fprintf (fp->fp, " 21\n%f\n", trace->y1); 00583 fprintf (fp->fp, " 31\n%f\n", trace->z1); 00584 fprintf (fp->fp, " 12\n%f\n", trace->x2); 00585 fprintf (fp->fp, " 22\n%f\n", trace->y2); 00586 fprintf (fp->fp, " 32\n%f\n", trace->z2); 00587 fprintf (fp->fp, " 13\n%f\n", trace->x3); 00588 fprintf (fp->fp, " 23\n%f\n", trace->y3); 00589 fprintf (fp->fp, " 33\n%f\n", trace->z3); 00590 if (trace->thickness != 0.0) 00591 { 00592 fprintf (fp->fp, " 39\n%f\n", trace->thickness); 00593 } 00594 if ((fp->acad_version_number >= AutoCAD_12) 00595 && (trace->extr_x0 != 0.0) 00596 && (trace->extr_y0 != 0.0) 00597 && (trace->extr_z0 != 1.0)) 00598 { 00599 fprintf (fp->fp, "210\n%f\n", trace->extr_x0); 00600 fprintf (fp->fp, "220\n%f\n", trace->extr_y0); 00601 fprintf (fp->fp, "230\n%f\n", trace->extr_z0); 00602 } 00603 /* Clean up. */ 00604 free (dxf_entity_name); 00605 #if DEBUG 00606 DXF_DEBUG_END 00607 #endif 00608 return (EXIT_SUCCESS); 00609 } 00610 00611 00625 int 00626 dxf_trace_free 00627 ( 00628 DxfTrace *trace 00631 ) 00632 { 00633 #if DEBUG 00634 DXF_DEBUG_BEGIN 00635 #endif 00636 /* Do some basic checks. */ 00637 if (trace == NULL) 00638 { 00639 fprintf (stderr, 00640 (_("Error in %s () a NULL pointer was passed.\n")), 00641 __FUNCTION__); 00642 return (EXIT_FAILURE); 00643 } 00644 if (trace->next != NULL) 00645 { 00646 fprintf (stderr, 00647 (_("Error in %s () pointer to next was not NULL.\n")), 00648 __FUNCTION__); 00649 return (EXIT_FAILURE); 00650 } 00651 free (trace->linetype); 00652 free (trace->layer); 00653 free (trace->dictionary_owner_soft); 00654 free (trace->dictionary_owner_hard); 00655 free (trace); 00656 trace = NULL; 00657 #if DEBUG 00658 DXF_DEBUG_END 00659 #endif 00660 return (EXIT_SUCCESS); 00661 } 00662 00663 00674 void 00675 dxf_trace_free_chain 00676 ( 00677 DxfTrace *traces 00679 ) 00680 { 00681 #ifdef DEBUG 00682 DXF_DEBUG_BEGIN 00683 #endif 00684 if (traces == NULL) 00685 { 00686 fprintf (stderr, 00687 (_("Warning in %s () a NULL pointer was passed.\n")), 00688 __FUNCTION__); 00689 } 00690 while (traces != NULL) 00691 { 00692 struct DxfTrace *iter = traces->next; 00693 dxf_trace_free (traces); 00694 traces = (DxfTrace *) iter; 00695 } 00696 #if DEBUG 00697 DXF_DEBUG_END 00698 #endif 00699 } 00700 00701 00702 /* EOF */