|
-
Sep 30th, 2002, 02:14 PM
#1
Thread Starter
Addicted Member
Struct and vectors...need some dynamic stuff...
Hi,
I can do this okay.
Code:
typedef struct TRIANGLE{
VERTEX a,b,c;
};
vector<TRIANGLE> t;
//or even this
typedef struct QUAD{
VERTEX a,b,c,d;
};
vector<QUAD> q;
I want to create a struct FACE that stores 3, 4, 5....n number of vertices. This would allow me to parse a string from an .OBJ file that may contain anywhere from 3 or more vertices to define one polygon or face.
There are work arounds. For example: I could decide that all faces are only 3, 4 or 5 vertices...I could create three respective vectors. As I read each line from the file, I could parse to determine if the line is 3, 4 or 5 and then load into appropriate vectors. I am looking for something a little more flexible.
Any clues? Suggestions?
Regards,
ChuckB
-
Sep 30th, 2002, 02:40 PM
#2
Fanatic Member
use C++ style:
PHP Code:
struct POINT
{
POINT(VERTEX x, VERTEX y) : a(x), b(y) {}
VERTEX a,b;
};
struct TRIANGLE : public POINT
{
TRIANGLE(VERTEX x, VERTEX y, VERTEX z) : POINT(x,y), c(z) {}
VERTEX c;
};
struct QUAD : public POINT
{
QUAD(VERTEX w, VERTEX x, VERTEX y, VERTEX z) :
POINT(w,x), c(y), d(z) {}
VERTEX c,d;
};
// ...
vector<POINT*> vec;
// ...
vec.push(new TRIANGLE({2,3},{5,6}));
//...
-
Sep 30th, 2002, 03:14 PM
#3
Frenzied Member
C++ =):
Code:
template<int n>
class FACE
{
VERTEX _v[n];
};
...
vector<FACE<10> > v; // vector of faces with 10 vertices each.
Only works if you have n faces in all of your faces... otherwise, vectors:
Code:
struct FACE
{
vector<VERTEX> _v;
};
Z.
-
Sep 30th, 2002, 03:27 PM
#4
Fanatic Member
Oooh, Nice but i dont see how it would be dynamic cuz the template is always compile time and you wont know how many faces untill run-time, faces will always be 1+... maybe a container class should better suit the situation?
-
Sep 30th, 2002, 10:11 PM
#5
Thread Starter
Addicted Member
MoMad,
I have looked at your sample...and it is my understanding that this is a C++ example as opposed to what I offered which I take is a C example. Am I right about that?
I need to get jump started since this code format is new to me.
Code:
struct POINT
{
POINT(VERTEX x, VERTEX y) : a(x), b(y) {}
VERTEX a,b;
};
If you have got the time, could you do some explaining on this for me?
The POINT structure contains two vertices a and b. Right?
Why doesn't the point contain only one vertex?
Each vertex a and b has 3 values (say x,y,z). Right?
You are using VERTEX because you would have defined it earlier like...
typedef struct VERTEX{
float x,y,z;
}
Right? Or a C++ version?
What does the ':a(x),b(y){}' mean?
Z, I am comfortable using the .reserve property for a vector. I intend to read the number of 'faces' during program load and use this for now. There is a possibility to reserve a 10 pointed face in a vector....in which I have an element indicating how many of the 10 points are used. This seems wasteful of space though...which is probably a real premium loading 3D models.
Regards,
ChuckB
-
Sep 30th, 2002, 10:31 PM
#6
Frenzied Member
Just throwing that template thing out there =). They really are the most useful thing since sliced bread =).
Best bet would be to use the vector method.
Dunno what MoMad was doing with that POINT class... doesnt make sense =). the a(x), b(y) {} is a constructor initiialization list. Essentially, its the same as doing this:
Code:
POINT(VERTEX x, VERTEX y)
{
a = x;
b = y;
};
Except that using the initializer list calls the class's copy constructor (you can get into trouble with that =).
And, if you are using a vector, you cant be using C =). I think the point was the inheritance. The only problem there is that you dont know how many VERTEX structures are in each pointer, so it is useless without using RTTI, which nearly defeats the purpose of inheritance (to be able to refer to an object of one type with a pointer to a parent type, without needing to know the actual type).
Z.
-
Sep 30th, 2002, 10:54 PM
#7
Fanatic Member
Well what im trying to get at eventually is this:
C++ will give you the following for free:
a. Copy constructor
b. = operator
c. destructor
So you can use these without needed to explicitly define them yourself.
I dont know what vertex is but now that I know, I can give you a better sample:
PHP Code:
struct VERTEX {
VERTEX (float a, float b, float c) : x(a), y(b), z(c) {}
float x, y, z;
}
struct FACE {
FACE(VERTEX a) : x(a) {}
VERTEX x;
}
struct PLANE : public FACE {
PLANE (VERTEX a, VERTEX b) : FACE(a), y(b) {}
VERTEX y;
}
struct TRIANGLE : public FACE {
TRIANGLE (VERTEX a, VERTEX b, VERTEX c) : FACE(a), y(b), z(c) {}
VERTEX y,z;
}
struct QUAD : public FACE {
QUAD (VERTEX a, VERTEX b, VERTEX c, VERTEX d) : FACE(a), y(b), z(c), w(d) {}
VERTEX y,z,w;
}
// ... and so on
But notice that in C++ a struct acts like a class but with all members "public". We created a base class of FACE and derived everything else from it. The reason i did this is because I want all of these classes to have something in common! Just like DD or D3D, you can tell the different versions of FACE apart by finding out the size of the object 
Anyways, starting at the plane, the plane has 1 extra vertex than the face, but its constructor takes 2 arguments, they are being assigned the two different vertexes... all the way down the list...
Bottom line is, the way i am creating an inheritance table will help you make your faces pretty much anything because they will essentially all be a "derived" copy of the "base" class which is FACE.
Like Z said, the a(x), b(y) {} are just another way of saying a = x and b = y; but since you arent using dynamic data in the class-per se, remember that C++ will give you a copy constructor for free. Well if you have dynamic data, this copy constructor must be overwritten. It also gives you a = operator which is essentially the same thing.
Anyways, with the way i set up the classes above you can continue and add more vertexes to each level, you probably need a max of 4 (QUAD) but hey u can go 5 or 6 or 7.... etc or x.
So in your vector you do this:
PHP Code:
vector<FACE*> vec;
// ...
// somewhere in the input loop
// suppose you read in 4 vertexes and wanna add it to the list
vec.push(new QUAD(a,b,c,d));
// or how about 2
vec.push(new PLANE(a,b));
// or etc...
vec.push(new FACE(a));
Ofcourse, this sollution will still have an associated if/else/switch statement, but it makes for a nice clean getaway.
-
Oct 1st, 2002, 06:38 AM
#8
Thread Starter
Addicted Member
MoMad and Z,
Thanks for working with me on this. I just wrote this small sample using MoMad's format above.
I left out face, plane and quad to keep it simple. I want to start with a VERTEX, a 3D point in space (I use x,y,z). I want TRIANGLE to inherit three vertices....I'll call these 3D points s,t,u.
Code:
#include <stdio.h>
#include <cstdlib>
struct VERTEX {
VERTEX (float a, float b, float c) : x(a), y(b), z(c) {}
float x, y, z;
};
struct TRIANGLE : public VERTEX {
TRIANGLE (VERTEX a, VERTEX b, VERTEX c) : s(a), t(b), u(c) {}
VERTEX s, t, u;
};
int main(int argc, char *argv[])
{
VERTEX a,b,c;
vector<VERTEX*> v;
a.x=12.0;
a.y=15.5;
a.z=14.5;
b.x=16.0;
b.y=13.5;
b.z=14.5;
c.x=18.0;
c.y=10.5;
c.z=14.5;
v.push(new TRIANGLE(a,b,c));
system("pause");
return 0;
}
I am getting compiler errors regarding the second struct above...something about 'no matching function call for VERTEX::VERTEX'. Now, I suspect I am missing some important concepts here that I didn't glean from your earlier postings. Any more light on the subject would be helpful.
Regards,
ChuckB
-
Oct 1st, 2002, 12:58 PM
#9
Frenzied Member
Be careful with those copy constructors:
Code:
class x()
{
public:
x(){p=new char[10];}
~x(){if(p) delete p; p = NULL;}
private:
char * p;
};
...
x* y = new x;
x* z = new x(y);
delete y;
delete z;
Chuck, try just adding a trivial VERTEX constructor:
Code:
struct VERTEX{
VERTEX(){}
...
};
Chuck, why are you inheriting TRIANGLE from VERTEX? This doesnt make sense, as you end up with a class that essentially looks like this:
Code:
struct TRIANGLE
{
VERTEX s, t, u;
float x, y, z;
};
Z.
-
Oct 1st, 2002, 01:22 PM
#10
Fanatic Member
Z, I said that as long as you dont have dynamic data (new/delete created data), you are fine using the copy constructor provided. But it looks like MSVC doesnt support the "free" stuff you get with C++ classes.
do it like this then:
PHP Code:
struct VERTEX {
VERTEX (const VERTEX& v) : x(v.x), y(v.y), z(v.z) {}
VERTEX (float a=0.0, float b=0.0, float c=0.0) : x(a), y(b), z(c) {}
float x, y, z;
}
struct FACE {
FACE(VERTEX a) : x(a) {}
VERTEX x;
}
// needs FACE and VERTEX
struct PLANE : public FACE {
PLANE (VERTEX a, VERTEX b) : FACE(a), y(b) {}
VERTEX y;
}
// needs FACE and VERTEX
struct TRIANGLE : public FACE {
TRIANGLE (VERTEX a, VERTEX b, VERTEX c) : FACE(a), y(b), z(c) {}
VERTEX y,z;
}
// needs FACE and VERTEX
struct QUAD : public FACE {
QUAD (VERTEX a, VERTEX b, VERTEX c, VERTEX d) : FACE(a), y(b), z(c), w(d) {}
VERTEX y,z,w;
}
If you just wanna use TRIANGLE you will need FACE and VERTEX at least. Now this code should work wether VC gives you your rights or not!
BTW: Learn the initialization list, alot of times, when you write polymorphism code (inheritance and deriving, etc) you will be REQUIRED to backward pass base member initializations only thru the initilizer list. (eh, *** did i just say?) English: You will be required to use the initilizer list when you derive a class (if you want to initialize the base members).
E.G
PHP Code:
class Base {
public:
Base (int a = 0) : x(a) {}
protected:
bool done;
private:
int x;
}; // <-------------- dont forget semi-colon
class DerivedFromBase : public Base {
public:
DerivedFromBase (int a, bool d) : Base(a), done(d) {}
// you see how you have direct access to done but not to a?
// private says only the class that owns it and friend classes
// can see it or access it. protected says, self, friends, and
// derived child classes can see it and access it. The only way
// you can initialize private data is by calling a function that
// does this, like the constructor (a special function).
};
[edit]
BTW: I changed the vertex constructor to default the vertex to {0.0, 0.0, 0.0} if nothing gets passed. Thus default and trivial constructor.
Last edited by MoMad; Oct 1st, 2002 at 01:26 PM.
-
Oct 1st, 2002, 02:04 PM
#11
Frenzied Member
Dont initialize anything in your default VERTEX constructor. Doing so can be pointless in many situations(ie, you are going to fill it anyway, what is the point of 3 float copys?). Also, you dont HAVE to use initializer lists(i dont). To call a constructor of a Base class, simply call it in the derived constructor (ie, "Base(a)"). Nothing wrong there...
I would have to say, though, that this is a bad use of inheritance. Read my thoughts on RTTI a few posts up =).
Z.
-
Oct 1st, 2002, 02:43 PM
#12
Thread Starter
Addicted Member
Hi,
Here is my fundamental problem to following this thread. I know how to create structures and classes. However, MoMad's format for a class differs from what I have seen. I understand inheritance and I have a program that does just that...but not this style.
Is this a class or not...
Code:
// needs FACE and VERTEX
struct PLANE : public FACE {
PLANE (VERTEX a, VERTEX b) : FACE(a), y(b) {}
VERTEX y;
}
If it is not, is it a C++ way to do structures?
If it is a class...I am used to seeing it written as
Code:
class PLANE: public FACE(
VERTEX s, t;
public:
PLANE (VERTEX a, VERTEX b){ //constructor
s=a;
t=b;
}
~PLANE(){} //destructor
}
Z, I understood in concept what I was doing was wrong...just couldn't see clearly what was being explained.
MoMad, I have to figure out what this format is you are using because it is new to me...and I hope somehow it explains my need for dynamic stuff. :-)
I'll look for some web resources I can download and review that explains more clearly what you guys have been writing about.
Feeling a bit fustrated right now...need to do some more reading. :-)
Regards,
ChuckB
-
Oct 1st, 2002, 02:58 PM
#13
Fanatic Member
so sorry.
in C++ a struct is just a class with all methods and members "public" as opposed to class having all members and variables "private" by default.
So you can just write that as a class instead of struct, but be sure to put public: where appropriate or you would not be able to say obj.x (will not be able to access members and variables)..
FACE(a) just says "initialize the face with this parameter"
-
Oct 1st, 2002, 03:00 PM
#14
Fanatic Member
Originally posted by Zaei
Dont initialize anything in your default VERTEX constructor. Doing so can be pointless in many situations(ie, you are going to fill it anyway, what is the point of 3 float copys?). Also, you dont HAVE to use initializer lists(i dont). To call a constructor of a Base class, simply call it in the derived constructor (ie, "Base(a)"). Nothing wrong there...
I would have to say, though, that this is a bad use of inheritance. Read my thoughts on RTTI a few posts up =).
Z.
Alright how about this then:
PHP Code:
class VERTEX {
public:
VERTEX () {}
VERTEX (const VERTEX& v) : x(v.x), y(v.y), z(v.z) {}
VERTEX (float a, float b, float c) : x(a), y(b), z(c) {}
float x, y, z;
}
-
Oct 1st, 2002, 03:20 PM
#15
Fanatic Member
Ok, I think i might've went too fast explaining my logic on this:
PHP Code:
// you want to have a dynamic way of adding vertexes right?
// Here is the vertex class
class VERTEX {
public:
VERTEX () {}
VERTEX (const VERTEX& v) : x(v.x), y(v.y), z(v.z) {}
VERTEX (float a, float b, float c) : x(a), y(b), z(c) {}
float x, y, z;
};
// Now here is a class that will give you however many number of vertexes u want
class FACES {
private:
int vertCount;
VERTEX * pVertexes;
public:
FACES () : vertexes(0), vertCount(0) {}
// i wont make a cc but theres no need for it really
// initialize with space for how many vertecies
bool Init (int count) {
Release ();
vertCount = count;
if (vertCount > 0) {
vertexes = new VERTEX [ vertCount ];
return true;
}
return false;
}
// add to the list
bool AddVert (VERTEX * vert, int index) {
if (index < 0 || index >= vertCount) {
return false;
}
vertexes[index]->x = vert->x;
vertexes[index]->y = vert->y;
vertexes[index]->z = vert->z;
return true;
}
// Resize the list (if you change ur mind)
bool Resize (int newsize) {
if (newsize <= vertCount) {
return false;
}
VERTEX * pVert = new VERTEX[newsize];
if (pVert) {
for (int i = 0; i < vertCount; i++) {
pVert[i].x = vertexes[i].x;
pVert[i].y = vertexes[i].y;
pVert[i].z = vertexes[i].z;
}
Release ();
vertexes = pVert;
vertCount = newsize;
return true;
}
return false;
}
// Release all associated memory
void Release () {
if (vertexes) delete [] vertexes;
vertCount = 0;
vertexes = 0;
}
// Get method (returns an array)
VERTEX * GetVertexes () { return pVertexes; }
int GetCount () const { return vertCount; }
};
// also you can overload the iostream operators << and >>
I dont really have much time to put the actual code right now, but i hope this idea is more understandable than my previous one.
[edit] Aaah what the hell, i added the code (look again)[/edit]
Last edited by MoMad; Oct 1st, 2002 at 03:42 PM.
-
Oct 1st, 2002, 03:34 PM
#16
Frenzied Member
That works, MoMad, but using a vector would be safer, and only add (I believe) one pointer's worth of storage usage.
And there IS a need for a copy constructor in your code. See the code I posted above =).
Chuck: When using C++, the only difference between a struct and a class is that a struct defaults to having public members, while a class defaults to private. That is the ONLY difference.
So yes, it IS a class, only instead of using a usual looking function for a constructor, it uses the initializer list. You can do a bit of reading on that.
As to my posts about the usage of inheritance in this instance... let me demonstrate:
Code:
struct p
{
float x, y, z;
};
struct tri : public p
{
p a, b, c;
};
struct face : public p
{
p a, b, c, d;
};
...
p* stuff = new tri[10];
stuff[0].a.x = 0; // cant do this, a doesnt exist
You see? Since p only contains 3 floats, You dont actually know how many vertices are hiding in a p*.
Z.
-
Oct 1st, 2002, 03:45 PM
#17
Fanatic Member
I guess if you use a vector, it defeats the purpose of this class that i posted, and it will be much safer to use a vector but you need to do the inheritance stuff if you're gonna do a vector because ther all wont be the same size (or perhaps a vector of vectors).
-
Oct 1st, 2002, 03:48 PM
#18
Fanatic Member
Originally posted by Zaei
...
p* stuff = new tri[10];
stuff[0].a.x = 0; // cant do this, a doesnt exist
[/code]
typecast it to tri! ((tri *) stuff[0]).a.x works. But when you are dealing with having a base class thats the same as the child class, then it really starts looking weird.
-
Oct 1st, 2002, 04:13 PM
#19
Frenzied Member
How do you guarentee that it IS a tri?
Code:
vector<p*> v;
v.push_back(new p);
v.push_back(new tri);
v.push_back(new p);
v.push_back(new face);
Z.
-
Oct 1st, 2002, 04:47 PM
#20
Fanatic Member
duh, i kno, but if you wrote the code wouldnt you know?
-
Oct 1st, 2002, 05:23 PM
#21
Frenzied Member
Not necessarily...
Code:
void LoadFromFile(..., vector<p*>& v)
{
...
if(prim_type == string("face"))
{
v.push_back(new face(face_data));
}
if(prim_type == string("tri"))
{
v.push_back(new tri(face_data));
}
...
}
Z.
-
Oct 1st, 2002, 10:12 PM
#22
Thread Starter
Addicted Member
WOW!
I really appreciate this discussion. MoMad...that's a lot of coding...thanks!
Z, I am going to look at the code you wrote...
v.push_back(new tri);
the idea of pushing an object 'tri' is new to me inside the ( ).
I read chapters 4 & 5 tonight from ANSI/ISO C++ Professional Programmer's Handbook by Danny Kale (Online Version). It helped me to understand that a struct is a shorthand for class...except everything is public in a struct...and a class is by default private.
I even understand the constructor style used above and the related initialization.
I will study the code here and try to get a variation working in my test program....and I will utilize vectors...as I finally understand them enough to use them. :-)
To put all of this together I intend on writing a program that will read a basic .OBJ 3D file that includes vertices for a 3D model and various face sizes: triangle, quads, etc. Reading the file, parsing each individual line, loading into the appropriate sized vector and error handling are my goal. All in C++ of course... :-)
Thanks!
Regards,
ChuckB
-
Oct 1st, 2002, 10:33 PM
#23
Frenzied Member
Just be sure that you can get the pointer back , or you end up with a memory leak =).
Z.
-
Oct 2nd, 2002, 03:06 AM
#24
Fanatic Member
Doesnt pop_back give it back to you?
PHP Code:
p * ptr;
do {
ptr = v.pop_back();
if (ptr)
delete ptr;
} while (ptr);
... maybe not, im not too familiar with vector, but i know its basic functions and i think i kno but with a push, there should be a pop right? lol.
-
Oct 2nd, 2002, 06:49 AM
#25
Frenzied Member
No, it was just a general warning.. ie, dont do this:
Code:
strcpy(new char[128], "Hello, World!");
pop_back removes the last element, you would probably be better off using an iterator...
Z.
-
Oct 2nd, 2002, 07:05 AM
#26
Thread Starter
Addicted Member
Hi,
Can you explain something about "for_each"? I figured this was related to this thread since it includes a class.
Code:
//this came from The Standard C++ Library
class PrintIn{
public:
void operator()(int elem) const {
cout << elem << ' ';
}
};
int main()
{
. . . .
for_each(coll.begin(), coll.end(), PrintIn());
. . . .
}
I understand that PrintIn is the class name. I know there are no constructors here so a default constructor is used. I know also that what is happening is operator overloading. Forcing the '( )' to receive an int from the calling function. This PrintIn() becomes the third argument in the for_each above.
How could I eliminate the class PrintIn and simply type an expression for the 3rd argument that does the same thing?
Something like 'cout << int elem'. This doesn't work of course, but this would help me to understand more thoroughly.
Regards,
ChuckB
-
Oct 2nd, 2002, 07:54 AM
#27
transcendental analytic
for_each is an STL algortim that performs a function on all elements on a range specified by two iterators, so in other words it does something for each element within the range, the last parameter is the unary function to which for_each passes each element, in this case PrintIn, which is a functor (function object), a class that acts as a function. The compilers tends to inline functors better than regular functions and functors can have a private state as well (which i personally dislike, as much as i dislike OOP in general)
no you can't type the expression inline, maybe if you tweak with macros, but C++ is an old language, they didn't know of the problems with the complexity before they came..
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Oct 2nd, 2002, 08:42 AM
#28
Function pointers cannot be inlined, a member function of an object can be, and the object itself is 0 bytes large if it doesn't contain data or virtual functions. It is therefore more efficient than a function pointer (which you could pass, nothing wrong with it).
MoMad: if you think about it you class hierarchy is a very bad example of OOP. It revolts against any definition of inheritance I've heard or read. Especially the "is a" connection. "A quad IS A triangle"? Doesn't fit. I'd say go with Zs templated version. Derive it from a common base class FACE:
Code:
class BASE_FACE {
public:
// This is to find out the number of vertices
virtual unsigned int GetVertexCount() = 0;
};
template<unsigned int nVertices>
class FACE : public BASE_FACE {
public: // for easier use
VERTEX arV[nVertices];
virtual unsigned int GetVertexCount() {
return nVertices;
};
};
vector<FACE_BASE*> v;
v.push_back(new FACE<3>);
v.push_back(new FACE<10>);
Just be extremly careful with this. The vector doesn't delete objects for you. Before you remove an item from the vector you must ALWAYS first call delete on it (or get a copy of the pointer and call delete later). This include a vector that goes out of scope.
An even better solution is this: only use triangles as faces. No current 3D car accepts other faces anyway as they are not guaranteed to be plane, so why bother having them in the first place?
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Oct 2nd, 2002, 10:32 AM
#29
Thread Starter
Addicted Member
Kedaman, Thanks for clarifying the function object 'functor'.
CornedBee, I didn't know 3D cards support only triangles. I was experimenting with anim8or 3D software and noticed that when I exported an .OBJ file, it had faces with 3 or 4 points...I read the spec later for .OBJ files, and it implied that a face could consist of many points...which is what started me on this thread in the beginning.
I suppose I could only deal with triangles and ignore other polygons OR have my program convert polygons to triangles...so as not to lose any mesh data. Let me kick that idea around.
Regards,
ChuckB
-
Oct 2nd, 2002, 10:47 AM
#30
I think the X loader converts all higher faces to sets of triangles.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Oct 2nd, 2002, 03:18 PM
#31
Fanatic Member
Originally posted by Zaei
No, it was just a general warning.. ie, dont do this:
Code:
strcpy(new char[128], "Hello, World!");
pop_back removes the last element, you would probably be better off using an iterator...
Z.
But strcpy returns that new char[128] anyways... so you can say:
char * strptr = strcpy(new char[128], "Hello, World!");
Originally posted by CornedBee
Especially the "is a" connection. "A quad IS A triangle"?
Thats why I didnt use TRIANGLE as the base class, but I see what you mean though. The template works better in this case, but you can typedef the different templates anyways.. so that you will have a set amount of vertexes in any case so make use of this.
Use what CornedBee wrote, with a little bit of adition:
PHP Code:
// the typedefs should look like
typedef FACE<3> TRI_FACE;
typedef FACE<4> QUAD_FACE;
// etc
// when u are adding, you can just say new TRI_FACE or whatever
// this is just an alias for FACE<3>. Also you can pass in stuff to
// the constructor
//...
// this could be in a clear function (it just clears the memory used)
FACE_BASE * ptr;
while (ptr = v.back()) { // get the last element
if (ptr) { // if it exists, delete it
delete ptr;
ptr = 0;
v.pop_back (); // and erase it from the vector
}
// now the pointer to the last element is decremented.
}
hope that helps
-
Oct 2nd, 2002, 03:30 PM
#32
Frenzied Member
I know, MoMad, but the way I typed it, you lose the pointer =). You might see a REAL newbie do that occasionally =).
Chuck, the reason 3d Cards support only triangles is that A) you can make any polygon with a set of triangles, and B) triangles cannot be concave (for instance, a quad shaped so that it forms a v shape is concave), which allows for certain optimizations for rendering.
Z.
-
Oct 2nd, 2002, 04:10 PM
#33
Oh, and I forgot:
Copy constructors are defined implicitly. They are also called implicitly. But if you want to call a copy constructor explicitly you need to define it explicitly. And you may not call the copy constructor in the copy constructor itself (think about it a little, it would be an endless recursion).
Here's another case where you must use a constructor list:
Code:
class A {
public:
const int m_cnSomething;
};
How do you initialize this? Global constants can be initialized like this:
const int c_Constant = 4;
Static member constants the same way:
Code:
class B {
public:
static const int sc_Whee;
};
const int B::sc_Whee = 5;
(Side note: Sun thought this syntax to be confusing and changed it in Java)
Does this work with member constants too?
Code:
class A {
public:
const int m_cnSomething;
};
// No, compiler error!
const int A::m_cnSomething = 0;
class A {
public:
// No, compiler error!
const int m_cnSomething = 1;
};
Since the constant is defined per instance we need a place to initialize it per instance: the constructor!
Code:
class A {
public:
const int m_cnSomething;
// Sorry, assignment to const illegal!
A(int i) { m_cnSomething = i; };
};
There is only one way to correctly initialize constants: the constructor list.
Code:
class A {
public:
const int m_cnSomething;
// Sorry, assignment to const illegal!
A(int i) : m_cnSomething(i) {};
};
Of course there was absolutly no point in writing such a long post for something that nobody cares for, but I don't care either.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Oct 2nd, 2002, 04:21 PM
#34
Fanatic Member
Wow, I didnt know you can assign a variable to a constant... isnt there some rules about that?
its like saying:
const int num = i;
-
Oct 3rd, 2002, 12:05 AM
#35
transcendental analytic
const means not mutable, but when you first initiate a constant its not assigning, the constant has to have a value, const only means that it can't be changed after that (although i think thats what CB tried to explain..)
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Oct 3rd, 2002, 12:16 AM
#36
Fanatic Member
I see... So I never thought of it this way, maybe thats why I never successfully made a const variable inside a class: (i always used enums )
enum {
MAX_VARS = 10;
}
on another note, how is squirrel coming? I havent seen any download links or anywhere to get a piece of it on the site... Are you hosting it somewhere else? Is it open source? Can I beta test it or take a look at it (sneak peek or whatever the deal is?)
-
Oct 3rd, 2002, 02:52 AM
#37
transcendental analytic
I've just updated my site, check the link in my sig. The compiler is going to be out soon for beta testing, right now i'm revising the most crucial change in the language so far, which has to extends the complexity of contructs beyond the scope limits of lamda calculus. If the latest change turns out to be successful then the compiler should be out quite soon, otherways I will have to come up with something new..
My site is totally renewed, the latest changes in syntax are updated and the summary is corrected, also there's some example code on squirrel just to show how the abstraction works, when the language definitions are out you wont be working with such lowlevel matters though, so its not going to look that scary, if you don't like math or logic then its easy to hide..
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Oct 6th, 2002, 08:27 PM
#38
Thread Starter
Addicted Member
Hi,
I have chosen to use the .OBJ file format for 3D objects. With freeware 'Anim8or' (www.anim8or.com) I can import 3DS files, edit or create and then export in .OBJ file format.
The .OBJ format is easy.
g Fuselage
# No. points 2328:
v -96.6345 9.10905 42.9418
. . .
# No. faces 4632:
f 1//4633 1166//5894 584//5282
. . .
'v' means vertex and 'f' means face. All faces are triangles. I have two structures VERTEX and FACE (triangle). I read No. of points and create a VERTEX vector with 2328 elements...4632 with the the FACE vector. Works great!! Even loads into OpenGL program.
Here is the problem. The 'g' stands for group. There can be several groups in a .OBJ file. I.e. fuselage, cockpit, landinggear, etc.
?????????????????????????????
How do I generate several different VERTEX vectors and FACE vectors for the file?? I will not know how many groups to create until the file is read. Any suggestions?
Incidently, I am not using the 'texture' or 'normal' values at present...just vertices and faces.
I am including the function that parses each string read from a file. I would appreciate any ideas on making the function smaller and/or more efficient. There is not error checking.
Code:
//process string read from file and places into appropriate vectors
void ProcessData(string s)
{
VERTEX vtemp ={0.0f,0.0f,0.0f};
FACE ftemp={0,0,0};
//Parses string = "# No. points 2328:"
if(s.substr(0,12)=="# No. points"){
mbGetVertex=true;
mbGetFace=false;
int g=s.find(":");
s= s.substr(13,g-12);
mnVertices=atoi(s.c_str());
cout << mnVertices << endl;
v.reserve(mnVertices +1);
}
//Parses string = "v 104.17 2.36533 -13.3778"
if((s.substr(0,2)=="v ")&&(mbGetVertex==true)){
mnVertexPos++;
int g=0;
int h=0;
for (int m=2;m< s.size();m++){
if((s.substr(m,1)==" ") &&(g!=0))
h=m;
if((s.substr(m,1)==" ")&&(g==0)){
g=m; //stores second space
}
}
string t=s.substr(2,g-2);
vtemp.x=atof(t.c_str());
t=s.substr(g+1,h-g);
vtemp.y=atof(t.c_str());
t=s.substr(h+1);
vtemp.z=atof(t.c_str());
v.push_back(vtemp); }
//Parse string = "# No. faces 4632:"
if(s.substr(0,11)=="# No. faces"){
mbGetFace=true;
mbGetVertex=false;
int g=s.find(":");
s= s.substr(12,g-11);
mnFaces=atoi(s.c_str());
cout << mnFaces << endl;
f.reserve(mnFaces);
}
//Parse string = "f 35//4667 746//5444 1559//6291"
if((s.substr(0,2)=="f ")&&(mbGetFace==true)){
mnFacePos++;
int g=0;
int h=0;
for (int m=2;m< s.size();m++){
if((s.substr(m,1)==" ") &&(g!=0))
h=m;
if((s.substr(m,1)==" ")&&(g==0)){
g=m; //stores second space
}
}
int fs;
string t=s.substr(2,g-2);
fs = t.find("/");
t=t.substr(0,fs);
ftemp.a = atoi(t.c_str());
t=s.substr(g+1,h-g);
fs = t.find("/");
t=t.substr(0,fs);
ftemp.b = atoi(t.c_str());
t=s.substr(h+1);
fs = t.find("/");
t=t.substr(0,fs);
ftemp.c = atoi(t.c_str());
f.push_back(ftemp);
}
}
Regards,
ChuckB
-
Oct 6th, 2002, 08:53 PM
#39
Frenzied Member
Need a GROUP struct =).
GROUP holds the number of faces and vertices in the group. Just read each group individually, and then add each to a vector of groups.
Z.
-
Oct 6th, 2002, 09:22 PM
#40
Thread Starter
Addicted Member
Let me see if I follow what you are saying...
typedef struct GROUP {
VERTEX v;
FACE f;
};
vector<GROUP> g;
g.reserve(1); //I like using 1 as first location...skip 0 pos.
//read 1st group...
vector<VERTEX> g[1].v;
vector<FACE> g[1].f;
g[1].v.reserve(number of vertices of 1st group);
g[1].f.reserve(number of faces of 1st group);
Is this what you are saying? How about my formatting above..does that look correct?
Regards,
ChuckB
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|