inline void WriteBounds(const T* in, unsigned int size, FILE* out) { T minc,maxc; ArrayBounds(in,size,minc,maxc); ::fwrite(&minc,sizeof(T),1,out); ::fwrite(&maxc,sizeof(T),1,out); }
// ------------------------------------------------------------------------------- float ComputePositionEpsilon(const aiMesh* pMesh) { const float epsilon = 1e-4f; // calculate the position bounds so we have a reliable epsilon to check position differences against aiVector3D minVec, maxVec; ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,minVec,maxVec); return (maxVec - minVec).Length() * epsilon; }
// ------------------------------------------------------------------------------- float ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num) { const float epsilon = 1e-4f; // calculate the position bounds so we have a reliable epsilon to check position differences against aiVector3D minVec, maxVec, mi, ma; MinMaxChooser<aiVector3D>()(minVec,maxVec); for (size_t a = 0; a < num; ++a) { const aiMesh* pMesh = pMeshes[a]; ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,mi,ma); minVec = std::min(minVec,mi); maxVec = std::max(maxVec,ma); } return (maxVec - minVec).Length() * epsilon; }
// ------------------------------------------------------------------------------------------------ void TempMesh::RemoveAdjacentDuplicates() { bool drop = false; std::vector<IfcVector3>::iterator base = verts.begin(); BOOST_FOREACH(unsigned int& cnt, vertcnt) { if (cnt < 2){ base += cnt; continue; } IfcVector3 vmin,vmax; ArrayBounds(&*base, cnt ,vmin,vmax); const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast<IfcFloat>(1e9); //const IfcFloat dotepsilon = 1e-9; //// look for vertices that lie directly on the line between their predecessor and their //// successor and replace them with either of them. //for(size_t i = 0; i < cnt; ++i) { // IfcVector3& v1 = *(base+i), &v0 = *(base+(i?i-1:cnt-1)), &v2 = *(base+(i+1)%cnt); // const IfcVector3& d0 = (v1-v0), &d1 = (v2-v1); // const IfcFloat l0 = d0.SquareLength(), l1 = d1.SquareLength(); // if (!l0 || !l1) { // continue; // } // const IfcFloat d = (d0/std::sqrt(l0))*(d1/std::sqrt(l1)); // if ( d >= 1.f-dotepsilon ) { // v1 = v0; // } // else if ( d < -1.f+dotepsilon ) { // v2 = v1; // continue; // } //} // drop any identical, adjacent vertices. this pass will collect the dropouts // of the previous pass as a side-effect. FuzzyVectorCompare fz(epsilon); std::vector<IfcVector3>::iterator end = base+cnt, e = std::unique( base, end, fz ); if (e != end) { cnt -= static_cast<unsigned int>(std::distance(e, end)); verts.erase(e,end); drop = true; } // check front and back vertices for this polygon if (cnt > 1 && fz(*base,*(base+cnt-1))) { verts.erase(base+ --cnt); drop = true; } // removing adjacent duplicates shouldn't erase everything :-) ai_assert(cnt>0); base += cnt; } if(drop) { IFCImporter::LogDebug("removing duplicate vertices"); } }
// ------------------------------------------------------------------------------- void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max) { ArrayBounds(mesh->mVertices,mesh->mNumVertices, min,max); out = min + (max-min)*0.5f; }