예제 #1
0
파일: stlinit.c 프로젝트: 2bright/Slic3r
/* Reads the contents of the file pointed to by stl->fp into the stl structure,
   starting at facet first_facet.  The second argument says if it's our first
   time running this for the stl and therefore we should reset our max and min stats. */
void
stl_read(stl_file *stl, int first_facet, int first) {
  stl_facet facet;
  int   i;

  if (stl->error) return;

  if(stl->stats.type == binary) {
    fseek(stl->fp, HEADER_SIZE, SEEK_SET);
  } else {
    rewind(stl->fp);
  }

  for(i = first_facet; i < stl->stats.number_of_facets; i++) {
    if(stl->stats.type == binary)
      /* Read a single facet from a binary .STL file */
    {
      /* we assume little-endian architecture! */
      if (fread(&facet.normal, sizeof(stl_normal), 1, stl->fp) \
          + fread(&facet.vertex, sizeof(stl_vertex), 3, stl->fp) \
          + fread(&facet.extra, sizeof(char), 2, stl->fp) != 6) {
        perror("Cannot read facet");
        stl->error = 1;
        return;
      }
    } else
      /* Read a single facet from an ASCII .STL file */
    {
      // skip solid/endsolid
      // (in this order, otherwise it won't work when they are paired in the middle of a file)
      fscanf(stl->fp, "endsolid\n");
      fscanf(stl->fp, "solid%*[^\n]\n");  // name might contain spaces so %*s doesn't work and it also can be empty (just "solid")
      
      if((fscanf(stl->fp, " facet normal %f %f %f\n", &facet.normal.x, &facet.normal.y, &facet.normal.z) + \
          fscanf(stl->fp, " outer loop\n") + \
          fscanf(stl->fp, " vertex %f %f %f\n", &facet.vertex[0].x, &facet.vertex[0].y,  &facet.vertex[0].z) + \
          fscanf(stl->fp, " vertex %f %f %f\n", &facet.vertex[1].x, &facet.vertex[1].y,  &facet.vertex[1].z) + \
          fscanf(stl->fp, " vertex %f %f %f\n", &facet.vertex[2].x, &facet.vertex[2].y,  &facet.vertex[2].z) + \
          fscanf(stl->fp, " endloop\n") + \
          fscanf(stl->fp, " endfacet\n")) != 12) {
        perror("Something is syntactically very wrong with this ASCII STL!");
        stl->error = 1;
        return;
      }
    }
    /* Write the facet into memory. */
    stl->facet_start[i] = facet;

    stl_facet_stats(stl, facet, first);
    first = 0;
  }
  stl->stats.size.x = stl->stats.max.x - stl->stats.min.x;
  stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
  stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
  stl->stats.bounding_diameter = sqrt(
                                   stl->stats.size.x * stl->stats.size.x +
                                   stl->stats.size.y * stl->stats.size.y +
                                   stl->stats.size.z * stl->stats.size.z
                                 );
}
예제 #2
0
/* Reads the contents of the file pointed to by stl->fp into the stl structure,
   starting at facet first_facet.  The second argument says if it's our first
   time running this for the stl and therefore we should reset our max and min stats. */
void
stl_read(stl_file *stl, int first_facet, int first) {
  stl_facet facet;
  int   i;

  if (stl->error) return;

  if(stl->stats.type == binary) {
    fseek(stl->fp, HEADER_SIZE, SEEK_SET);
  } else {
    rewind(stl->fp);
    /* Skip the first line of the file */
    while(getc(stl->fp) != '\n');
  }

  for(i = first_facet; i < stl->stats.number_of_facets; i++) {
    if(stl->stats.type == binary)
      /* Read a single facet from a binary .STL file */
    {
      /* we assume little-endian architecture! */
      if (fread(&facet.normal, sizeof(stl_normal), 1, stl->fp) \
          + fread(&facet.vertex, sizeof(stl_vertex), 3, stl->fp) \
          + fread(&facet.extra, sizeof(char), 2, stl->fp) != 6) {
        perror("Cannot read facet");
        stl->error = 1;
        return;
      }
    } else
      /* Read a single facet from an ASCII .STL file */
    {
      if((fscanf(stl->fp, "%*s %*s %f %f %f\n", &facet.normal.x, &facet.normal.y, &facet.normal.z) + \
          fscanf(stl->fp, "%*s %*s") + \
          fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[0].x, &facet.vertex[0].y,  &facet.vertex[0].z) + \
          fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[1].x, &facet.vertex[1].y,  &facet.vertex[1].z) + \
          fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[2].x, &facet.vertex[2].y,  &facet.vertex[2].z) + \
          fscanf(stl->fp, "%*s") + \
          fscanf(stl->fp, "%*s")) != 12) {
        perror("Something is syntactically very wrong with this ASCII STL!");
        stl->error = 1;
        return;
      }
    }
    /* Write the facet into memory. */
    stl->facet_start[i] = facet;

    stl_facet_stats(stl, facet, first);
    first = 0;
  }
  stl->stats.size.x = stl->stats.max.x - stl->stats.min.x;
  stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
  stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
  stl->stats.bounding_diameter = sqrt(
                                   stl->stats.size.x * stl->stats.size.x +
                                   stl->stats.size.y * stl->stats.size.y +
                                   stl->stats.size.z * stl->stats.size.z
                                 );
}
예제 #3
0
static void
stl_read(stl_file *stl, int first_facet, int first)
{
  stl_facet facet;
  int   i;

  if(stl->stats.type == binary)
    {
      fseek(stl->fp, HEADER_SIZE, SEEK_SET);
    }
  else
    {
      rewind(stl->fp);
      /* Skip the first line of the file */
      while(getc(stl->fp) != '\n');
    }

  for(i = first_facet; i < stl->stats.number_of_facets; i++)
    {
      if(stl->stats.type == binary)
	/* Read a single facet from a binary .STL file */
	{
	  facet.normal.x = stl_get_little_float(stl->fp);
	  facet.normal.y = stl_get_little_float(stl->fp);
	  facet.normal.z = stl_get_little_float(stl->fp);
	  facet.vertex[0].x = stl_get_little_float(stl->fp);
	  facet.vertex[0].y = stl_get_little_float(stl->fp);
	  facet.vertex[0].z = stl_get_little_float(stl->fp);
	  facet.vertex[1].x = stl_get_little_float(stl->fp);
	  facet.vertex[1].y = stl_get_little_float(stl->fp);
	  facet.vertex[1].z = stl_get_little_float(stl->fp);
	  facet.vertex[2].x = stl_get_little_float(stl->fp);
	  facet.vertex[2].y = stl_get_little_float(stl->fp);
	  facet.vertex[2].z = stl_get_little_float(stl->fp);
	  facet.extra[0] = fgetc(stl->fp);
	  facet.extra[1] = fgetc(stl->fp);
	}
      else
	/* Read a single facet from an ASCII .STL file */
	{
      	  fscanf(stl->fp, "%*s %*s %f %f %f\n", &facet.normal.x,
		 &facet.normal.y, &facet.normal.z);
	  fscanf(stl->fp, "%*s %*s");
	  fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[0].x,
		 &facet.vertex[0].y,  &facet.vertex[0].z);
	  fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[1].x,
		 &facet.vertex[1].y,  &facet.vertex[1].z);
	  fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[2].x,
		 &facet.vertex[2].y,  &facet.vertex[2].z);
	  fscanf(stl->fp, "%*s");
	  fscanf(stl->fp, "%*s");
	}
      /* Write the facet into memory. */
      stl->facet_start[i] = facet;
      
      stl_facet_stats(stl, facet, first);
      first = 0;
    }
    stl->stats.size.x = stl->stats.max.x - stl->stats.min.x;
    stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
    stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
    stl->stats.bounding_diameter = sqrt(
        stl->stats.size.x * stl->stats.size.x +
        stl->stats.size.y * stl->stats.size.y +
        stl->stats.size.z * stl->stats.size.z
        );
}
예제 #4
0
파일: stlinit.c 프로젝트: gringer/Slic3r
/* Reads the contents of the file pointed to by stl->fp into the stl structure,
   starting at facet first_facet.  The second argument says if it's our first
   time running this for the stl and therefore we should reset our max and min stats. */
void
stl_read(stl_file *stl, int first_facet, int first) {
  stl_facet facet;
  int   i;

  if (stl->error) return;

  if(stl->stats.type == binary) {
    fseek(stl->fp, HEADER_SIZE, SEEK_SET);
  } else {
    rewind(stl->fp);
  }

  for(i = first_facet; i < stl->stats.number_of_facets; i++) {
    if(stl->stats.type == binary)
      /* Read a single facet from a binary .STL file */
    {
      /* we assume little-endian architecture! */
      if (fread(&facet, 1, SIZEOF_STL_FACET, stl->fp) != SIZEOF_STL_FACET) {
        stl->error = 1;
        return;
      }
    } else
      /* Read a single facet from an ASCII .STL file */
    {
      // skip solid/endsolid
      // (in this order, otherwise it won't work when they are paired in the middle of a file)
      fscanf(stl->fp, "endsolid\n");
      fscanf(stl->fp, "solid%*[^\n]\n");  // name might contain spaces so %*s doesn't work and it also can be empty (just "solid")
      
      if((fscanf(stl->fp, " facet normal %f %f %f\n", &facet.normal.x, &facet.normal.y, &facet.normal.z) + \
          fscanf(stl->fp, " outer loop\n") + \
          fscanf(stl->fp, " vertex %f %f %f\n", &facet.vertex[0].x, &facet.vertex[0].y,  &facet.vertex[0].z) + \
          fscanf(stl->fp, " vertex %f %f %f\n", &facet.vertex[1].x, &facet.vertex[1].y,  &facet.vertex[1].z) + \
          fscanf(stl->fp, " vertex %f %f %f\n", &facet.vertex[2].x, &facet.vertex[2].y,  &facet.vertex[2].z) + \
          fscanf(stl->fp, " endloop\n") + \
          fscanf(stl->fp, " endfacet\n")) != 12) {
        perror("Something is syntactically very wrong with this ASCII STL!");
        stl->error = 1;
        return;
      }
    }

#if 0
      // Report close to zero vertex coordinates. Due to the nature of the floating point numbers,
      // close to zero values may be represented with singificantly higher precision than the rest of the vertices.
      // It may be worth to round these numbers to zero during loading to reduce the number of errors reported
      // during the STL import.
      for (size_t j = 0; j < 3; ++ j) {
        if (facet.vertex[j].x > -1e-12f && facet.vertex[j].x < 1e-12f)
            printf("stl_read: facet %d.x = %e\r\n", j, facet.vertex[j].x);
        if (facet.vertex[j].y > -1e-12f && facet.vertex[j].y < 1e-12f)
            printf("stl_read: facet %d.y = %e\r\n", j, facet.vertex[j].y);
        if (facet.vertex[j].z > -1e-12f && facet.vertex[j].z < 1e-12f)
            printf("stl_read: facet %d.z = %e\r\n", j, facet.vertex[j].z);
      }
#endif

#if 1
    {
      // Positive and negative zeros are possible in the floats, which are considered equal by the FP unit.
      // When using a memcmp on raw floats, those numbers report to be different.
      // Unify all +0 and -0 to +0 to make the floats equal under memcmp.
      uint32_t *f = (uint32_t*)&facet;
      for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats
        if (*f == 0x80000000)
          // Negative zero, switch to positive zero.
          *f = 0;
    }
#else
    {
      // Due to the nature of the floating point numbers, close to zero values may be represented with singificantly higher precision 
      // than the rest of the vertices. Round them to zero.
      float *f = (float*)&facet;
      for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats
        if (*f > -1e-12f && *f < 1e-12f)
          // Negative zero, switch to positive zero.
          *f = 0;
    }
#endif
    /* Write the facet into memory. */
    memcpy(stl->facet_start+i, &facet, SIZEOF_STL_FACET);
    stl_facet_stats(stl, facet, first);
    first = 0;
  }
  stl->stats.size.x = stl->stats.max.x - stl->stats.min.x;
  stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
  stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
  stl->stats.bounding_diameter = sqrt(
                                   stl->stats.size.x * stl->stats.size.x +
                                   stl->stats.size.y * stl->stats.size.y +
                                   stl->stats.size.z * stl->stats.size.z
                                 );
}