/*! This method checks if [this] AP and the given AP are functionally equivalent. In contrast to is isExactMatch this function will return true if the attrs and props are same even if they are in different order; it is computationally much more involved than isExactMatch(). On that note, it may be worth looking into putting some more explicit collision guarantees into the checksum computation algorithm, such to take advantage of those checksums here. IOW, make it such to be trusted that if checksums match, APs are equivalent (but not necessarily exact matches). \retval TRUE if equivalent to given AP (regardless of order), FALSE otherwise. */ bool PP_AttrProp::isEquivalent(const PP_AttrProp * pAP2) const { if(!pAP2) return false; if( getAttributeCount() != pAP2->getAttributeCount() || getPropertyCount() != pAP2->getPropertyCount()) return false; UT_uint32 i; const gchar * pName, * pValue, * pValue2; for(i = 0; i < getAttributeCount(); ++i) { UT_return_val_if_fail(getNthAttribute(i,pName,pValue),false); if(!pAP2->getAttribute(pName,pValue2)) return false; // ignore property attribute if(0 == strcmp(pValue, PT_PROPS_ATTRIBUTE_NAME)) continue; // handle revision attribute correctly if(0 == strcmp(pValue, PT_REVISION_ATTRIBUTE_NAME)) { // requires special treatment PP_RevisionAttr r1(pValue); PP_RevisionAttr r2 (pValue2); if(!(r1 == r2)) { return false; } } else if(0 != strcmp(pValue,pValue2)) return false; } for(i = 0; i < getPropertyCount(); ++i) { UT_return_val_if_fail(getNthProperty(i,pName,pValue),false); if(!pAP2->getProperty(pName,pValue2)) return false; if(0 != strcmp(pValue,pValue2)) return false; } return true; }
gl::GeometryPtr Mesh::getGeometry(GLenum elementType) const { validate(); int flags = getFlags(); size_t attributeCount = getAttributeCount(); std::vector<glm::vec4> vertices = buildVertices(); // TODO add triangle stripping algorithm? int elements; int verticesPerElement; switch (elementType) { case GL_LINES: elements = (unsigned int)indices.size() / 2; verticesPerElement = 2; break; case GL_TRIANGLES: elements = (unsigned int)indices.size() / 3; verticesPerElement = 3; break; case GL_POINTS: elements = (unsigned int)indices.size(); verticesPerElement = 1; break; default: throw std::runtime_error("unsupported geometry type"); } return gl::GeometryPtr(new gl::Geometry(vertices, indices, elements, flags, elementType, verticesPerElement)); }
//----------------------------------------------------------------------------- void PDCFileWriter::writePDCHeader(ofstream &outfile) { //create temporary versions of the variables to byte-swap int temp_formatVersion = getFormatVersion(); int temp_byteOrder = getByteOrder(); int temp_extra1 = getExtra1(); int temp_extra2 = getExtra2(); int temp_numParticles = getParticleCount(); int temp_numAttributes = getAttributeCount(); //do swap of byte order swapInt((char*) &temp_formatVersion); swapInt((char*) &temp_byteOrder); swapInt((char*) &temp_extra1); swapInt((char*) &temp_extra2); swapInt((char*) &temp_numParticles); swapInt((char*) &temp_numAttributes); //write out to file for(int i=0;i<4;i++) { outfile.put( m_format[i]); } outfile.write((char*) &temp_formatVersion, sizeof(int)); outfile.write((char*) &temp_byteOrder, sizeof(int)); outfile.write((char*) &temp_extra1, sizeof(int)); outfile.write((char*) &temp_extra2, sizeof(int)); outfile.write((char*) &temp_numParticles, sizeof(int)); outfile.write((char*) &temp_numAttributes, sizeof(int)); }
uint MeshData::compareAttributes(MeshData* other) { uint attr; if (other->getAttributeCount() != getAttributeCount()) { #ifndef PLG_RELEASE dprintf(2, "warning: MeshData objects have different number of attributes: %u vs. %u\n", other->getAttributeCount(), getAttributeCount()); #endif return 1; } for (attr = 0; attr < getAttributeCount(); attr++) { if (!other->hasAttribute(getAttributeName(attr))) { #ifndef PLG_RELEASE dprintf(2, "warning: MeshData objects have different attributes: %s\n", getAttributeName(attr)); #endif return 1; } } return 0; }
bool PP_Revision::operator == (const PP_Revision &op2) const { // this is quite involved, but we will start with the simple // non-equality cases if(getId() != op2.getId()) return false; if(getType() != op2.getType()) return false; // OK, so we have the same type and id, do we have the same props ??? UT_uint32 iPCount1 = getPropertyCount(); UT_uint32 iPCount2 = op2.getPropertyCount(); UT_uint32 iACount1 = getAttributeCount(); UT_uint32 iACount2 = op2.getAttributeCount(); if((iPCount1 != iPCount2) || (iACount1 != iACount2)) return false; // now the lengthy comparison UT_uint32 i; const gchar * n; const gchar * v1, * v2; for(i = 0; i < iPCount1; i++) { getNthProperty(i,n,v1); op2.getProperty(n,v2); if(strcmp(v1,v2)) return false; } for(i = 0; i < iACount1; i++) { getNthAttribute(i,n,v1); op2.getAttribute(n,v2); if(strcmp(v1,v2)) return false; } return true; }
void PP_Revision::_refreshString() const { m_sXMLProps.clear(); m_sXMLAttrs.clear(); UT_uint32 i; UT_uint32 iCount = getPropertyCount(); const gchar * n, *v; for(i = 0; i < iCount; i++) { if(!getNthProperty(i,n,v)) { // UT_ASSERT_HARMLESS( UT_SHOULD_NOT_HAPPEN ); continue; } if(!v || !*v) v = "-/-"; m_sXMLProps += n; m_sXMLProps += ":"; m_sXMLProps += v; if(i < iCount - 1) m_sXMLProps += ";"; } iCount = getAttributeCount(); for(i = 0; i < iCount; i++) { if(!getNthAttribute(i,n,v)) { // UT_ASSERT_HARMLESS( UT_SHOULD_NOT_HAPPEN ); continue; } if(!v || !*v) v = "-/-"; m_sXMLAttrs += n; m_sXMLAttrs += ":"; m_sXMLAttrs += v; if(i < iCount - 1) m_sXMLAttrs += ";"; } m_bDirty = false; }
std::vector<glm::vec4> Mesh::buildVertices() const { int flags = getFlags(); size_t attributeCount = getAttributeCount(); size_t vertexCount = positions.size(); std::vector<glm::vec4> vertices; vertices.reserve(vertexCount * attributeCount); for (size_t i = 0; i < vertexCount; ++i) { vertices.push_back(positions[i]); if (flags & gl::Geometry::Flag::HAS_NORMAL) { vertices.push_back(normals[i]); } if (flags & gl::Geometry::Flag::HAS_COLOR) { vertices.push_back(glm::vec4(colors[i], 1)); } if (flags & gl::Geometry::Flag::HAS_TEXTURE) { vertices.push_back(glm::vec4(texCoords[i], 1, 1)); } } return vertices; }
/*! This method does the same as PP_AttrProp::isEquivalent(const PP_AttrProp *) except that instead of being passed another AP to be compared to, it is passed sets of attributes and properties which only virtually comprise another AP. \retval TRUE if equivalent (regardless of order) to given Attrs and Props, FALSE otherwise. */ bool PP_AttrProp::isEquivalent(const gchar ** attrs, const gchar ** props) const { UT_uint32 iAttrsCount = 0; UT_uint32 iPropsCount = 0; const gchar ** p = attrs; while(p && *p) { iAttrsCount++; p += 2; } p = props; while(p && *p) { iPropsCount++; p += 2; } if( getAttributeCount() != iAttrsCount || getPropertyCount() != iPropsCount) return false; UT_uint32 i; const gchar * pName, * pValue, * pValue2; for(i = 0; i < getAttributeCount(); ++i) { pName = attrs[2*i]; pValue = attrs[2*i + 1]; if(!getAttribute(pName,pValue2)) return false; // ignore property attribute if(0 == strcmp(pValue, PT_PROPS_ATTRIBUTE_NAME)) continue; // handle revision attribute correctly if(0 == strcmp(pValue, PT_REVISION_ATTRIBUTE_NAME)) { // requires special treatment PP_RevisionAttr r1(pValue); PP_RevisionAttr r2 (pValue2); if(!(r1 == r2)) { return false; } } else if(0 != strcmp(pValue,pValue2)) return false; } for(i = 0; i < getPropertyCount(); ++i) { pName = props[2*i]; pValue = props[2*i + 1]; if(!getProperty(pName,pValue2)) return false; if(0 != strcmp(pValue,pValue2)) return false; } return true; }