+ fix reading of meshes with textures when vertexes are isolated
This commit is contained in:
parent
8cfabdb579
commit
d51ea4c96b
|
@ -344,9 +344,13 @@ bool MeshInput::LoadOBJ (std::istream &rstrIn)
|
|||
|
||||
this->_rclMesh.Clear(); // remove all data before
|
||||
|
||||
MeshKernel tmp;
|
||||
tmp.Adopt(meshPoints,meshFacets);
|
||||
this->_rclMesh.Merge(tmp);
|
||||
MeshCleanup meshCleanup(meshPoints,meshFacets);
|
||||
if (_material)
|
||||
meshCleanup.SetMaterial(_material);
|
||||
meshCleanup.RemoveInvalids();
|
||||
MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets);
|
||||
meshAdj.SetFacetNeighbourhood();
|
||||
this->_rclMesh.Adopt(meshPoints,meshFacets);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -486,29 +490,14 @@ bool MeshInput::LoadOFF (std::istream &rstrIn)
|
|||
}
|
||||
|
||||
this->_rclMesh.Clear(); // remove all data before
|
||||
// Don't use Assign() because Merge() checks which points are really needed.
|
||||
// This method sets already the correct neighbourhood
|
||||
unsigned long ct = meshPoints.size();
|
||||
std::list<unsigned long> removeFaces;
|
||||
for (MeshFacetArray::_TConstIterator it = meshFacets.begin(); it != meshFacets.end(); ++it) {
|
||||
bool ok = true;
|
||||
for (int i=0;i<3;i++) {
|
||||
if (it->_aulPoints[i] >= ct) {
|
||||
Base::Console().Warning("Face index %lu out of range\n", it->_aulPoints[i]);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
removeFaces.push_front(it-meshFacets.begin());
|
||||
}
|
||||
|
||||
for (std::list<unsigned long>::iterator it = removeFaces.begin(); it != removeFaces.end(); ++it)
|
||||
meshFacets.erase(meshFacets.begin() + *it);
|
||||
|
||||
MeshKernel tmp;
|
||||
tmp.Adopt(meshPoints,meshFacets);
|
||||
this->_rclMesh.Merge(tmp);
|
||||
MeshCleanup meshCleanup(meshPoints,meshFacets);
|
||||
if (_material)
|
||||
meshCleanup.SetMaterial(_material);
|
||||
meshCleanup.RemoveInvalids();
|
||||
MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets);
|
||||
meshAdj.SetFacetNeighbourhood();
|
||||
this->_rclMesh.Adopt(meshPoints,meshFacets);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -978,16 +967,15 @@ bool MeshInput::LoadPLY (std::istream &inp)
|
|||
}
|
||||
|
||||
this->_rclMesh.Clear(); // remove all data before
|
||||
#if 1
|
||||
MeshCleanup(meshPoints,meshFacets).RemoveInvalids();
|
||||
|
||||
MeshCleanup meshCleanup(meshPoints,meshFacets);
|
||||
if (_material)
|
||||
meshCleanup.SetMaterial(_material);
|
||||
meshCleanup.RemoveInvalids();
|
||||
MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets);
|
||||
meshAdj.SetFacetNeighbourhood();
|
||||
this->_rclMesh.Adopt(meshPoints,meshFacets);
|
||||
#else
|
||||
MeshKernel tmp;
|
||||
tmp.Adopt(meshPoints,meshFacets);
|
||||
this->_rclMesh.Merge(tmp);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1036,11 +1024,12 @@ bool MeshInput::LoadMeshNode (std::istream &rstrIn)
|
|||
}
|
||||
|
||||
this->_rclMesh.Clear(); // remove all data before
|
||||
// Don't use Assign() because Merge() checks which points are really needed.
|
||||
// This method sets already the correct neighbourhood
|
||||
MeshKernel tmp;
|
||||
tmp.Adopt(meshPoints,meshFacets);
|
||||
this->_rclMesh.Merge(tmp);
|
||||
|
||||
MeshCleanup meshCleanup(meshPoints,meshFacets);
|
||||
meshCleanup.RemoveInvalids();
|
||||
MeshPointFacetAdjacency meshAdj(meshPoints.size(),meshFacets);
|
||||
meshAdj.SetFacetNeighbourhood();
|
||||
this->_rclMesh.Adopt(meshPoints,meshFacets);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1516,7 +1505,7 @@ bool MeshOutput::SaveAny(const char* FileName, MeshIO::Format format) const
|
|||
{
|
||||
// ask for write permission
|
||||
Base::FileInfo file(FileName);
|
||||
Base::FileInfo directory(file.dirPath());
|
||||
Base::FileInfo directory(file.dirPath());
|
||||
if ((file.exists() && !file.isWritable()) || !directory.exists() || !directory.isWritable())
|
||||
throw Base::FileException("No write permission for file",FileName);
|
||||
|
||||
|
@ -2519,6 +2508,7 @@ bool MeshOutput::SaveVRML (std::ostream &rstrOut) const
|
|||
MeshCleanup::MeshCleanup(MeshPointArray& p, MeshFacetArray& f)
|
||||
: pointArray(p)
|
||||
, facetArray(f)
|
||||
, materialArray(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2526,6 +2516,11 @@ MeshCleanup::~MeshCleanup()
|
|||
{
|
||||
}
|
||||
|
||||
void MeshCleanup::SetMaterial(Material* mat)
|
||||
{
|
||||
materialArray = mat;
|
||||
}
|
||||
|
||||
void MeshCleanup::RemoveInvalids()
|
||||
{
|
||||
// first mark all points as invalid
|
||||
|
@ -2562,6 +2557,21 @@ void MeshCleanup::RemoveInvalidFacets()
|
|||
std::size_t countInvalidFacets = std::count_if(facetArray.begin(), facetArray.end(),
|
||||
std::bind2nd(MeshIsFlag<MeshFacet>(), MeshFacet::INVALID));
|
||||
if (countInvalidFacets > 0) {
|
||||
|
||||
// adjust the material array if needed
|
||||
if (materialArray && materialArray->binding == MeshIO::PER_FACE &&
|
||||
materialArray->diffuseColor.size() == facetArray.size()) {
|
||||
std::vector<App::Color> colors;
|
||||
colors.reserve(facetArray.size() - countInvalidFacets);
|
||||
for (std::size_t index = 0; index < facetArray.size(); index++) {
|
||||
if (facetArray[index].IsValid()) {
|
||||
colors.push_back(materialArray->diffuseColor[index]);
|
||||
}
|
||||
}
|
||||
|
||||
materialArray->diffuseColor.swap(colors);
|
||||
}
|
||||
|
||||
MeshFacetArray copy_facets(facetArray.size() - countInvalidFacets);
|
||||
// copy all valid facets to the new array
|
||||
std::remove_copy_if(facetArray.begin(), facetArray.end(), copy_facets.begin(),
|
||||
|
@ -2598,6 +2608,21 @@ void MeshCleanup::RemoveInvalidPoints()
|
|||
|
||||
// delete point, number of valid points
|
||||
std::size_t validPoints = pointArray.size() - countInvalidPoints;
|
||||
|
||||
// adjust the material array if needed
|
||||
if (materialArray && materialArray->binding == MeshIO::PER_VERTEX &&
|
||||
materialArray->diffuseColor.size() == pointArray.size()) {
|
||||
std::vector<App::Color> colors;
|
||||
colors.reserve(validPoints);
|
||||
for (std::size_t index = 0; index < pointArray.size(); index++) {
|
||||
if (pointArray[index].IsValid()) {
|
||||
colors.push_back(materialArray->diffuseColor[index]);
|
||||
}
|
||||
}
|
||||
|
||||
materialArray->diffuseColor.swap(colors);
|
||||
}
|
||||
|
||||
MeshPointArray copy_points(validPoints);
|
||||
// copy all valid facets to the new array
|
||||
std::remove_copy_if(pointArray.begin(), pointArray.end(), copy_points.begin(),
|
||||
|
@ -2629,15 +2654,15 @@ void MeshPointFacetAdjacency::Build()
|
|||
}
|
||||
|
||||
pointFacetAdjacency.resize(numPoints);
|
||||
for (std::size_t i = 0; i < numPoints; i++)
|
||||
pointFacetAdjacency[i].reserve(numFacetAdjacency[i]);
|
||||
for (std::size_t i = 0; i < numPoints; i++)
|
||||
pointFacetAdjacency[i].reserve(numFacetAdjacency[i]);
|
||||
|
||||
std::size_t numFacets = facets.size();
|
||||
for (std::size_t i = 0; i < numFacets; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
pointFacetAdjacency[facets[i]._aulPoints[j]].push_back(i);
|
||||
}
|
||||
}
|
||||
for (std::size_t i = 0; i < numFacets; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
pointFacetAdjacency[facets[i]._aulPoints[j]].push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeshPointFacetAdjacency::SetFacetNeighbourhood()
|
||||
|
@ -2646,25 +2671,25 @@ void MeshPointFacetAdjacency::SetFacetNeighbourhood()
|
|||
for (std::size_t index = 0; index < numFacets; index++) {
|
||||
MeshFacet& facet1 = facets[index];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
std::size_t n1 = facet1._aulPoints[i];
|
||||
std::size_t n2 = facet1._aulPoints[(i+1)%3];
|
||||
|
||||
bool success = false;
|
||||
const std::vector<std::size_t>& refFacets = pointFacetAdjacency[n1];
|
||||
for (std::vector<std::size_t>::const_iterator it = refFacets.begin(); it != refFacets.end(); ++it) {
|
||||
if (*it != index) {
|
||||
MeshFacet& facet2 = facets[*it];
|
||||
if (facet2.HasPoint(n2)) {
|
||||
facet1._aulNeighbours[i] = *it;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
facet1._aulNeighbours[i] = ULONG_MAX;
|
||||
}
|
||||
std::size_t n1 = facet1._aulPoints[i];
|
||||
std::size_t n2 = facet1._aulPoints[(i+1)%3];
|
||||
|
||||
bool success = false;
|
||||
const std::vector<std::size_t>& refFacets = pointFacetAdjacency[n1];
|
||||
for (std::vector<std::size_t>::const_iterator it = refFacets.begin(); it != refFacets.end(); ++it) {
|
||||
if (*it != index) {
|
||||
MeshFacet& facet2 = facets[*it];
|
||||
if (facet2.HasPoint(n2)) {
|
||||
facet1._aulNeighbours[i] = *it;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
facet1._aulNeighbours[i] = ULONG_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,14 @@ public:
|
|||
MeshCleanup(MeshPointArray& p, MeshFacetArray& f);
|
||||
~MeshCleanup();
|
||||
|
||||
/*!
|
||||
\brief Set the material array.
|
||||
In case the material array sets the colors per vertex and
|
||||
\ref RemoveInvalids() removes points from the array the
|
||||
material array will be adjusted.
|
||||
*/
|
||||
void SetMaterial(Material* mat);
|
||||
|
||||
/*!
|
||||
\brief Remove unreferenced and invalid facets.
|
||||
*/
|
||||
|
@ -209,6 +217,7 @@ private:
|
|||
private:
|
||||
MeshPointArray& pointArray;
|
||||
MeshFacetArray& facetArray;
|
||||
Material* materialArray;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
Loading…
Reference in New Issue
Block a user