I have made a few classes in c++. They somehow cooperate doing some 3d stuff.
Basically it is a moving camera acting as a flight, i have placed a lot of objects around the scene together with a b-spline surfcae.
The problem class is the polygon class. this class read 3d files generates faces, edges and so on.
here are two of the building blocks(structs)
Expand|Select|Wrap|Line Numbers
- struct FACE{
- int num; // index
- int index[3]; // index to 3 vertices
- vector3 normal; //normal vector to face
- };
- struct EDGE{
- int s_node; //start vertex
- int e_node; //end vertex
- FACE* adjface1; //adjacent face1;
- FACE* adjface2; //adjacent face2;
- };
- struct VERTEX{
- double x,y,z; // Vertices coordinates
- vector3 normal; //vertex normal
- };
I save these struct in their own vector, but it seems like something goes terrible wrong with this edge struct. When i later on call a method from outside this class that uses this vector of EDGE struct the program crashes after listing a 120 of 1600 edge structs from the vector. At this point i am doing this listing cout<<edges[c].adjface1->normal.x and so on only to debug.
edges is here the vector containing all the EDGE structs.
I have checked this print right after constructing the EDGE structs and everythig
is right. In fact i am using this struct to compute the vertex normals so i know it work when i call it from within the class.
The method i call from outside the class crash with a test 3d object after printing 120 of 1500 edges(the debug window in visual c++ opens) but if i call this method from within the class ,right after making the edges it list correctly all 1500 edges.
This is bad news because i have to call this method everytime something moves in the scene to get the contour edges of the objects.
Does anyone have any idees what is going on ? Could it be anything with the pointers to faces ? Should i make them as indicies instead ?
The vertex vector stores all the vertices and face struct adresses them with indicies to the vertex vector instead of pointers to structs.
The method calcSilEdges() is the one i mean. Calling this from outside dont work well only a few prints appear before debug window opens.
The Poly class object are saved in a vector outside this class so i can call each objects draw method.
Here is the poly class (stripped a lot)but i must say it is very hard to read.
Expand|Select|Wrap|Line Numbers
- #include "Poly.h"
- Poly::Poly(string s){
- LoadFile(s);
- }
- void Poly:: LoadFile(string s){
- normalizeVertices();
- calculateFaceNormals();
- }
- void Poly::makeVertexFacesArray(){
- }
- void Poly::calculateFaceNormals(){
- makeEdges();
- for(int i=0; i<numberOfFaces; i++){
- //vector 1 of face
- vec1=vec1.set((vertices[faces[i].index[1]].x-vertices[faces[i].index[0]].x),(vertices[faces[i].index[1]].y-vertices[faces[i].index[0]].y),(vertices[faces[i].index[1]].z-vertices[faces[i].index[0]].z));
- //vector 2 of face
- vec2=vec2.set(vertices[faces[i].index[2]].x-vertices[faces[i].index[0]].x,vertices[faces[i].index[2]].y-vertices[faces[i].index[0]].y,vertices[faces[i].index[2]].z-vertices[faces[i].index[0]].z);
- vec3=vec3.cross(vec1,vec2);
- //normalize
- vec3=vec3.normalize(vec3);
- // save in struct
- faces[i].normal=vec3;
- }
- glVertex3f(vertices[faces[i].index[j]].x,vertices[faces[i].index[j]].y,vertices[faces[i].index[j]].z);
- vector<int> face;
- vector<int>::iterator it;
- cout<<"number vert "<<numberOfFaces<<endl;
- cout<<"number edges "<<edges.size()<<endl;
- for(int c=0;c<numberOfVertices;c++){
- cout<<".";
- normalvector.x=0;
- normalvector.y=0;
- normalvector.z=0;
- float number=0;
- for(unsigned int cc=0;cc<edges.size();cc++){
- if(c==edges[cc].s_node || c==edges[cc].e_node){
- int e1=edges[cc].adjface1->num;
- it=find(face.begin(),face.end(),e1);
- if(it==face.end()){
- face.push_back(e1);
- tempvector = edges[cc].adjface1->normal;
- normalvector=normalvector.add(tempvector,normalvector);
- number=number+1;
- }
- else{
- }
- if(edges[cc].adjface2!=NULL){
- int e2=edges[cc].adjface2->num;
- it=find(face.begin(),face.end(),e2);
- if(it==face.end()){
- //cout<<"face "<<e2<<" var ikke i listen"<<endl;
- face.push_back(e2);
- tempvector = edges[cc].adjface2->normal;
- normalvector=normalvector.add(tempvector,normalvector);
- number=number+1;
- }
- else{
- }
- }
- }
- }
- normalvector=normalvector.mulSkalar(normalvector,(1/number));
- vertices[c].normal=normalvector;
- face.clear();
- }
- //calcSilEdges(lpos); // this works
- }
- void Poly::Draw(){
- glColor3f(c.r,c.g,c.b);
- for(int i=0; i<numberOfFaces; i++){
- glBegin(GL_TRIANGLES);
- for(int j=0; j<3; j++){
- glNormal3f(vertices[faces[i].index[j]].normal.x,vertices[faces[i].index[j]].normal.y,vertices[faces[i].index[j]].normal.z); glVertex3f(vertices[faces[i].index[j]].x,vertices[faces[i].index[j]].y,vertices[faces[i].index[j]].z);
- }
- glEnd();
- }
- }
- void Poly::normalizeVertices(){
- for (unsigned int c=0;c<vertices.size();c++)
- {
- vertices[c].x=(vertices[c].x)/maxvalue;
- vertices[c].y=(vertices[c].y)/maxvalue;
- vertices[c].z=(vertices[c].z)/maxvalue;
- }
- }
- void Poly::setPoints(float x1, float y1, float z1){
- v.x=x1;
- v.y=y1;
- v.z=z1;
- vertices.push_back(v);
- }
- // method to triangulate surface
- void Poly::makeFaces(int row, int col, float detail){
- int i=0;
- int mod = (int)ceil((1/detail));
- TEMPARRAY temp;
- TEMPARRAY temp2;
- vector<TEMPARRAY> arrays; //vector to keep row number arrays
- vector<TEMPARRAY> arrays2;
- //init vertices idices
- int counter2=0;
- cout<<"mod "<<mod<<endl;
- cout<<"col "<<col<<endl;
- for(int c=0;c<(row-3);c++){
- for(int counter=0;counter<(mod*mod*(col-3));counter++){
- temp.tempA.push_back(counter2);
- counter2++;
- }
- arrays.push_back(temp);
- temp.tempA.clear();
- }
- for(int c=0;c<(row-3);c++){
- for(int counter=0;counter<(mod*mod*(col-3))-(mod+1);counter++){
- if((counter+1)%mod==0){
- if (counter<vertices.size()-(mod+1)){
- counter=counter+1;
- }
- }
- f.index[0]=arrays[c].tempA[counter];
- f.index[1]=arrays[c].tempA[counter+1];
- f.index[2]=arrays[c].tempA[counter+mod];
- f.num=numberOfFaces;
- faces.push_back(f);
- numberOfFaces=numberOfFaces+1;
- f.index[0]=arrays[c].tempA[counter+1];
- f.index[1]=arrays[c].tempA[counter+mod+1];
- f.index[2]=arrays[c].tempA[counter+mod];
- f.num=numberOfFaces;
- faces.push_back(f);
- numberOfFaces=numberOfFaces+1;
- }
- }
- int flag=0;
- for(int c=0;c<(row-3);c++){
- for(int counter=0;counter<(mod*mod*(col-3));counter++){
- if(c==0){
- if((counter+1)%mod==0){
- temp.tempA.push_back(arrays[c].tempA[counter]);
- }
- }
- if(c==(row-4)){
- if((counter)%mod==0){
- temp2.tempA.push_back(arrays[c].tempA[counter]);
- flag=2;
- }
- }
- if ((c!=0) & (c!=(row-4))){
- if((counter+1)%mod==0){
- temp.tempA.push_back(arrays[c].tempA[counter]);
- flag=1;
- }
- if((counter)%mod==0){
- temp2.tempA.push_back(arrays[c].tempA[counter]);
- flag=1;
- }
- }
- }
- if(flag==0){
- arrays2.push_back(temp);
- }
- if(flag==1){
- arrays2.push_back(temp2);
- arrays2.push_back(temp);
- }
- if(flag==2){
- arrays2.push_back(temp2);
- }
- temp.tempA.clear();
- temp2.tempA.clear();
- }
- for(int c=0;c<(arrays2.size()-1);c++){
- for(int counter=0;counter<((mod*(col-3))-1);counter++){
- f.index[0]=arrays2[c].tempA[counter];
- f.index[1]=arrays2[c+1].tempA[counter];
- f.index[2]=arrays2[c].tempA[counter+1];
- f.num=numberOfFaces;
- faces.push_back(f);
- numberOfFaces=numberOfFaces+1;
- f.index[0]=arrays2[c+1].tempA[counter];
- f.index[1]=arrays2[c+1].tempA[counter+1];
- f.index[2]=arrays2[c].tempA[counter+1];
- f.num=numberOfFaces;
- faces.push_back(f);
- numberOfFaces=numberOfFaces+1;
- }
- }
- }
- }
- void Poly::makeEdges(){
- for(int c=0;c<faces.size();c++){
- e.s_node = faces[c].index[0];
- e.e_node = faces[c].index[1];
- e.adjface1 = &faces[c];
- e.adjface2 = NULL;
- edges.push_back(e);
- e.s_node = faces[c].index[1];
- e.e_node = faces[c].index[2];
- e.adjface1 = &faces[c];
- e.adjface2 = NULL;
- edges.push_back(e);
- e.s_node = faces[c].index[2];
- e.e_node = faces[c].index[0];
- e.adjface1 = &faces[c];
- e.adjface2 = NULL;
- edges.push_back(e);
- }
- for(int c=0;c<edges.size();c++){
- int start=edges[c].s_node;
- int end=edges[c].e_node;
- for(int cc=0;cc<edges.size();cc++){
- if(start==edges[cc].s_node || start==edges[cc].e_node){
- if(end==edges[cc].s_node || end==edges[cc].e_node){
- if((start!=edges[cc].s_node) & (end!=edges[cc].e_node)){
- edges[c].adjface2=edges[cc].adjface1;
- edges.erase(edges.begin()+cc);
- //cout<<"edges size "<<edges.size()<<endl;
- }
- }
- }
- }
- }
- }
- }
- void Poly::calcSilEdges(float pos[]){
- lpos[0]=pos[0];
- lpos[1]=pos[1];
- lpos[2]=pos[2];
- for(unsigned int c=0;c<edges.size();c++){
- cout<<edges[c].adjface1->normal.x<<endl;
- }
- }