示例#1
0
void
read_file(FILE *inFile)
{
  int i,j,k;
  PlyFile *ply;
  int nprops;
  int num_elems;
  PlyProperty **plist;
  char *elem_name;
  float version;
  int get_nx,get_ny,get_nz;

  /*** Read in the original PLY object ***/


  ply  = ply_read (inFile, &nelems, &elist);
  ply_get_info (ply, &version, &file_type);

  for (i = 0; i < nelems; i++) {

    /* get the description of the first element */
    elem_name = elist[i];
    plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);

    if (equal_strings ("vertex", elem_name)) {

      /* see if vertex holds any normal information */
      get_nx = get_ny = get_nz = 0;
      for (j = 0; j < nprops; j++) {
        if (equal_strings ("nx", plist[j]->name)) get_nx = 1;
        if (equal_strings ("ny", plist[j]->name)) get_ny = 1;
        if (equal_strings ("nz", plist[j]->name)) get_nz = 1;
      }

      /* create a vertex list to hold all the vertices */
      vlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems);
      nverts = num_elems;

      /* set up for getting vertex elements */

      ply_get_property (ply, elem_name, &vert_props[0]);
      ply_get_property (ply, elem_name, &vert_props[1]);
      ply_get_property (ply, elem_name, &vert_props[2]);
      if (get_nx) ply_get_property (ply, elem_name, &vert_props[3]);
      if (get_ny) ply_get_property (ply, elem_name, &vert_props[4]);
      if (get_nz) ply_get_property (ply, elem_name, &vert_props[5]);
      vert_other = ply_get_other_properties (ply, elem_name,
                     offsetof(Vertex,other_props));

      /* grab all the vertex elements */
      for (j = 0; j < num_elems; j++) {
        vlist[j] = (Vertex *) malloc (sizeof (Vertex));
        ply_get_element (ply, (void *) vlist[j]);
      }
    }
    else if (equal_strings ("face", elem_name)) {

      /* create a list to hold all the face elements */
      flist = (Face **) malloc (sizeof (Face *) * num_elems);
      nfaces = num_elems;

      /* set up for getting face elements */

      ply_get_property (ply, elem_name, &face_props[0]);
      face_other = ply_get_other_properties (ply, elem_name,
                     offsetof(Face,other_props));

      /* grab all the face elements */
      for (j = 0; j < num_elems; j++) {
        flist[j] = (Face *) malloc (sizeof (Face));
        ply_get_element (ply, (void *) flist[j]);
      }
    }
    else
      other_elements = ply_get_other_element (ply, elem_name, num_elems);
  }

  comments = ply_get_comments (ply, &num_comments);
  obj_info = ply_get_obj_info (ply, &num_obj_info);

  ply_close (ply);
}
示例#2
0
void PlyReader::parseFile()
{
	SURGSIM_ASSERT(isValid()) << "'" << m_filename << "' is an invalid .ply file";

	if (m_startParseFileCallback != nullptr)
	{
		m_startParseFileCallback();
	}

	char* currentElementName;
	for (int elementIndex = 0; elementIndex < m_data->elementCount; ++elementIndex)
	{
		currentElementName = m_data->elementNames[elementIndex];

		int numberOfElements;
		int propertyCount;

		// Free this after we are done with it
		PlyProperty** properties =
			ply_get_element_description(m_data->plyFile, currentElementName, &numberOfElements, &propertyCount);

		std::vector<int> listOffsets;
		// Check if the user wanted this element, if yes process
		if (m_requestedElements.find(currentElementName) != m_requestedElements.end())
		{
			ElementInfo& elementInfo = m_requestedElements[currentElementName];

			// Build the propertyinfo structure
			for (size_t propertyIndex = 0; propertyIndex < elementInfo.requestedProperties.size(); ++propertyIndex)
			{
				PropertyInfo& propertyInfo = elementInfo.requestedProperties[propertyIndex];
				PlyProperty requestedProperty = {nullptr, 0, 0, 0, 0, 0, 0, 0};

				// Create temp char*
				std::vector<char> writable(propertyInfo.propertyName.size() + 1);
				std::copy(propertyInfo.propertyName.begin(), propertyInfo.propertyName.end(), writable.begin());
				requestedProperty.name = &writable[0];
				requestedProperty.internal_type = propertyInfo.dataType;
				requestedProperty.offset = propertyInfo.dataOffset;
				requestedProperty.count_internal = propertyInfo.countType;
				requestedProperty.count_offset = propertyInfo.countOffset;
				requestedProperty.is_list = (propertyInfo.countType != 0) ? PLY_LIST : PLY_SCALAR;

				if (requestedProperty.is_list == PLY_LIST)
				{
					listOffsets.push_back(propertyInfo.dataOffset);
				}

				// Tell ply that we want this property to be read and put into the readbuffer
				ply_get_property(m_data->plyFile, currentElementName, &requestedProperty);
			}

			void* readBuffer = elementInfo.startElementCallback(currentElementName, numberOfElements);

			for (int element = 0; element < numberOfElements; ++element)
			{
				ply_get_element(m_data->plyFile, readBuffer);
				if (elementInfo.processElementCallback != nullptr)
				{
					try
					{
						elementInfo.processElementCallback(currentElementName);
					}
					catch (const std::exception&)
					{
						for (size_t i = 0; i<listOffsets.size(); ++i)
						{
							void** item = (void **)((char *)readBuffer + listOffsets[i]); // NOLINT
							free(item[0]);
						}
						for (int i = 0; i < propertyCount; ++i)
						{
							free(properties[i]->name);
							free(properties[i]);
						}
						free(properties);
						throw;
					}
				}

				// Free the lists that where allocated by plyreader
				// This gains access to the buffer, where ply.c put the address of
				// the memory that was allocated to carry the information for the list property
				// it does that for all properties that where marked as lists
				for (size_t i = 0; i<listOffsets.size(); ++i)
				{
					void** item = (void **)((char *)readBuffer + listOffsets[i]); // NOLINT
					free(item[0]);
				}

			}

			if (elementInfo.endElementCallback != nullptr)
			{
				elementInfo.endElementCallback(currentElementName);
			}
		}
		else
		{
			// Inefficient way to skip an element, but there does not seem to be an
			// easy way to ignore an element
			// The data for other is stored internally in the plyFile data structure
			// and should not be freed
			ply_get_other_element(m_data->plyFile, currentElementName, numberOfElements);

		}

		// Free the data allocated in the ply_get_element_description call
		for (int i = 0; i < propertyCount; ++i)
		{
			free(properties[i]->name);
			free(properties[i]);
		}
		free(properties);
	}

	if (m_endParseFileCallback != nullptr)
	{
		m_endParseFileCallback();
	}
}