0

I'm trying to make an algorithm to find the neighbor faces of a selected face.

This is what I have so far that is not working:

vector<Face *> Face::DeterminarFacesVizinhas(vector<Face *> Faces){
    vector<Face *> Lista = {};
    bool flag = false;
    //cout << "\n" << endl;
    for (size_t x = 0; x < ReturnVertices().size(); x++)
        for (size_t i = 0; i < Faces.size(); i++)
            for (size_t j = 0; j < Faces[i]->ReturnVertices().size(); j++){
                if (Utils::CompararVertice(Faces[i]->ReturnVertices()[j], ReturnVertices()[x])) {
                    for (size_t v = 0; v < Lista.size(); v++)
                        if(Lista[v]->FaceID==Faces[i]->FaceID)
                            flag=true;
                    if(!flag)
                        Lista.push_back(Faces[i]);
                }

            }

    return Lista;
}

The output for a cube (quadrilateral faces instead of triangles) should me 4 in each face, but for some reason I get this (for loop):

vector<Face *> ListaFacesVizinhas = ModeloSG->ReturnFaces()[i]->DeterminarFacesVizinhas(ModeloSG->ReturnFaces());

sizeof(ListaFacesVizinhas) = 3
sizeof(ListaFacesVizinhas) = 3
sizeof(ListaFacesVizinhas) = 4
sizeof(ListaFacesVizinhas) = 4
sizeof(ListaFacesVizinhas) = 4
sizeof(ListaFacesVizinhas) = 4

I must compare the faces by vertices (each face has 4 vertices, each vertex is used by 2 other faces). If the face is already on the list it shall not be duplicated.

The work is using wavefront .obj files.

This is the code as it is (it's not finished yet): https://github.com/Karbust/Processing-Models-Generated-on-Blender/

Can someone point me in the right direction? I don't know what else to do...

Minimal Reproducible Example:

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <list>

using namespace std;


class Vertice {
private:
    float VerticeX, VerticeY, VerticeZ;
public:
    Vertice(float VertexX, float VertexY, float VertexZ) {
        VerticeX = VertexX;
        VerticeY = VertexY;
        VerticeZ = VertexZ;
    }
    float ReturnVX() { return VerticeX; };
    float ReturnVY() { return VerticeY; };
    float ReturnVZ() { return VerticeZ; };
    float ProdInterno(Vertice *V) const { return (VerticeX * V->ReturnVX()) + (VerticeY * V->ReturnVY()) + (VerticeZ * V->ReturnVZ()); }
};

class Utils {
public:
    bool CompararVertice(Vertice * V1, Vertice * V2) {
        return V1->ReturnVX() == V2->ReturnVX() && V1->ReturnVY() == V2->ReturnVY() && V1->ReturnVZ() == V2->ReturnVZ();
    }
};

class Face {
private:
    int FaceID{};
    vector<int> VerticeID;
    vector<Vertice *> Vertices;
public:
    vector<Face *> DeterminarFacesVizinhas(const vector<Face *>& Faces){
        vector<Face *> Lista = {};
        bool flag = false;
        Utils *U;
        for (size_t x = 0; x < ReturnVertices().size(); x++)
            for (size_t i = 0; i < Faces.size(); i++)
                for (size_t j = 0; j < Faces[i]->ReturnVertices().size(); j++){
                    if (U->CompararVertice(Faces[i]->ReturnVertices()[j], ReturnVertices()[x])) {
                        for (size_t v = 0; v < Lista.size(); v++)
                            if(Lista[v]->FaceID==Faces[i]->FaceID)
                                flag=true;
                        if(!flag)
                            Lista.push_back(Faces[i]);
                    }

                }

        return Lista;
    }
    void Add(int fID, int vID, Vertice *V){
        FaceID = fID;
        VerticeID.push_back(vID);
        Vertices.push_back(V);
    }
    int ReturnfID() { return FaceID; };
    vector<int> ReturnvID() { return VerticeID; };
    vector<Vertice *> ReturnVertices() { return Vertices; };
};

class Modelo {
private:
    string Nome;
    vector<Vertice *> Vertices;
    vector<Face *> Faces;
    Face *FaceMaiorCurvatura;

    void AddValueVertices(float VertexX, float VertexY, float VertexZ) {
        Vertices.push_back(new Vertice(VertexX, VertexY, VertexZ));
    }
public:
    Modelo(const string &fich){
        ifstream objeto (fich);

        if(objeto.fail())
            throw exception();

        string line, temp, v;
        int i = 0, w = 1;
        float VertexX = 0.0f, VertexY = 0.0f, VertexZ = 0.0f;

        while(!objeto.eof()){
            getline (objeto,line);
            if (line[0] == 'v'){
                istringstream iss(line);
                iss >> v >> VertexX >> VertexY >> VertexZ;
                AddValueVertices(VertexX, VertexY, VertexZ);
            }
            else if(line[0] == 'f'){
                istringstream iss(line);
                Face *novaFace = new Face();
                i = 0;
                while(iss >> temp){
                    if(i != 0)
                        novaFace->Add(w, stoi(temp), Vertices[stoi(temp)-1]);
                    i++;
                }

                temp.clear();            

                Faces.push_back(novaFace);

                w++;
            }
        }

        Nome = fich;
    }
    string ReturnNome() { return Nome; };    
    vector<Vertice *> ReturnVertices() { return Vertices; };
    vector<Face *> ReturnFaces() { return Faces; };    
    Face *ReturnFaceMaiorCurvatura() { return FaceMaiorCurvatura; };
};

class SGestao {
private:
    Modelo *ModeloSG;
public:
    Face *FaceMaiorCurvatura() {

        for(size_t i = 0; i < ModeloSG->ReturnFaces().size(); i++){
            vector<Face *> ListaFacesVizinhas = ModeloSG->ReturnFaces()[i]->DeterminarFacesVizinhas(ModeloSG->ReturnFaces());
            cout << "ListaFacesVizinhas = " << ListaFacesVizinhas.size() << endl;
        }

        Face *temp = ModeloSG->ReturnFaceMaiorCurvatura();

        return ModeloSG->ReturnFaces()[1];
    }

    void Load(const string &fich){
        auto *newModelo = new Modelo(fich);
        ModeloSG = newModelo;
    }
};


int main()
{
    auto *SG = new SGestao();
    SG->Load("cubo.obj");

    SG->FaceMaiorCurvatura();
}

cubo.obj:

# Blender v2.66 (sub 1) OBJ File: ''
# www.blender.org
mtllib cubo.mtl
o Cube.001
v -2.798875 4.114415 -0.012605
v -2.798875 4.114417 -8.241435
v 5.429955 4.114417 -8.241435
v 5.429954 4.114415 -0.012604
v -2.798877 -4.114415 -0.012609
v 5.429955 -4.114415 -0.012607
v 5.429956 -4.114414 -8.241436
v -2.798873 -4.114414 -8.241440
usemtl Material.001
s off
f 1 2 3 4
f 5 6 7 8
f 1 5 8 2
f 2 8 7 3
f 3 7 6 4
f 5 1 4 6

Thank you

Karbust
  • 67
  • 2
  • 10
  • 1
    Please upgrade to a [mre]. – Yunnosch Jan 16 '20 at 20:12
  • `vector` should probably be a `std::set`, and you might use for range for clarity. – Jarod42 Jan 16 '20 at 20:12
  • Pass `std::vector` by const ref instead of by value. – Jarod42 Jan 16 '20 at 20:15
  • @Yunnosch I can't create a minimal reproducible example since this piece of code depends on the main functions and other functions, that's why I added the GitHub Repository where I have the full project and every file. – Karbust Jan 16 '20 at 20:24
  • @Jarod42 same result using const, and I didn't understand your first comment – Karbust Jan 16 '20 at 20:24
  • The idea of a mre is to minimise dependencies to the point where you CAN show everything needed here. Get rid of anything not needed for demonstration of exactly the small specific thing you are asking about. – Yunnosch Jan 16 '20 at 20:26
  • I meant something like [that](https://godbolt.org/z/rAskH3) is more readable (even if it should fail similarly as behavior didn't change). – Jarod42 Jan 16 '20 at 20:39
  • @Yunnosch I edited the question and added the MRE – Karbust Jan 16 '20 at 21:14
  • @Jarod42 your example gives 5, I believe it is also adding the face I selected to get is neighbors – Karbust Jan 16 '20 at 21:24
  • Quotes from [mre]: "Copy the actual text from your code editor, paste it into the question"; *"in the question itself"*. I think that is quite clear, especially after I asked you to create a MRE when links to full code were already here. Please provide a MRE directly here, not linked. – Yunnosch Jan 16 '20 at 23:10
  • @Yunnosch added – Karbust Jan 16 '20 at 23:24

0 Answers0