.OBJLoader, weird indices numbers - c++

I've been messing with OpenGL and c++ lately (with FreeGLUT and GLEW) and started to try and import .obj files from 3DS Max 2014. Everything is fine if i manual type the vertices and indices but, when trying to get them from a file i get strange numbers.
when getting the indices instead of 1 there was 1000 and instead of 3 there was 3965 and when there was a 12 is was 1212 (there are ones and threes etc but sometimes they are random)
Here is the code I use to import: http://pastebin.com/1ds6fgj9
or
std::vector<std::string> Object::split(std::string str, char splitter){
char charText[1000];
int number = 0;
int numberOfWords = 0;
char current[10][100];
std::vector<std::string> tokens;
strcpy(charText, str.c_str());
int size = sizeof(charText) / sizeof(*charText);
//std::cout << size << " size\n";
for (int i = 0; i < splitter; i++){
if (charText[i] == splitter){
tokens.push_back(current[numberOfWords]);
numberOfWords++;
number = 0;
}
else{
current[numberOfWords][number] = charText[i];
number++;
}
}
return tokens;
}
Object::Object(std::string fileName, Vector3f pos, Vector3f rot, float Size, Vector3f color){
Position = pos;
Rotation = rot;
size = Size;
colors = color;
std::string data;
std::ifstream file(fileName);
std::string line;
Vector3f _verts[1024];
int noVerts = 0;
unsigned int _inds[1024];
int noIndices = 0;
while (getline(file, line)) // same as: while (getline( myfile, line ).good())
{
char charText[1024];
strcpy(charText, line.c_str());
if (charText[0] == 'v' && charText[1] != 'n' && charText[1] != 't'){
std::vector<std::string> splitLine = split(line, ' ');
_verts[noVerts] = Vector3f(atoi(splitLine[1].c_str()), atoi(splitLine[2].c_str()), atoi(splitLine[3].c_str()));
//std::cout << "Vertices Number:" << noVerts << " x:" << _verts[noVerts].getX() << " y:" << _verts[noVerts].getY() << " z:" << _verts[noVerts].getZ() << "\n";
noVerts++;
}
if (charText[0] == 'f'){
std::vector<std::string> splitLine = split(line, ' ');
for (int i = 0; i < 3; i++){
std::vector<std::string> ssl = split(splitLine[i+1], '/');
//std::cout << atoi(splitLine[i].c_str()) << "\n";
std::cout << i << ": " << atoi(ssl[0].c_str()) << " " << atoi(ssl[1].c_str()) << " " << atoi(ssl[2].c_str()) << "\n";
_inds[noIndices] = atoi(ssl[0].c_str());
noIndices++;
_inds[noIndices] = atoi(ssl[1].c_str());
noIndices++;
_inds[noIndices] = atoi(ssl[2].c_str());
noIndices++;
//std::cout << "number of indices:" << noIndices<< "\n";
}
}
}
verts = _verts;
inds = _inds;
SizeV = sizeof(verts);
SizeI = sizeof(inds);
noPoints = SizeI / sizeof(*inds);
length = SizeV / sizeof(*verts);
Matrix4f posM, rotM, sizeM;
sizeM.InitScaleTransform(size, size, size);
rotM.InitRotateTransform(rot.getX(), rot.getY(), rot.getZ());
posM.InitTranslationTransform(pos.getX(), pos.getY(), pos.getZ());
M = posM * rotM * sizeM;
for (unsigned int i = 0; i < length; i++){
verts[i] = _verts[i];
}
}
I think it is an error in my code when reading the file but if not just ask to see my other code.
[EDIT]
It does this for all obj files (not tried exporting with a different program and the obj files I have tried have very few faces).

Related

"Function uses '80408' bytes of stack: exceeds analyze:stacksize '16384'. Consider moving some data to heap" C++ error

I am trying to generate data and place them into separate files
This is a part of the code which gives me a stacksize error. I have tried adjusting the compiler to change the stacksize and suppress the warning message but it did not work.
When I run the code it does not create the output files and keeps on running without giving an output.
How can I fix this PLEASE?
This is my code:
double generateWindData(double windData[4])
{
int avgWindSpeed = windData[0];
int gust = windData[1];
int simulationDuration = windData[2];
int stepSize = windData[3];
int stepCounter = simulationDuration / stepSize + 1;
ofstream windFile;
windFile.open("WindSpeedData.txt", ios::out);
if (windFile.fail())
{
cerr << "WindSpeedData.txt could not be opened." << endl;
exit(-1);
}
int upperLimit = avgWindSpeed + gust;
int lowerLimit = avgWindSpeed - gust;
int randomWindSpeeds = rand() % ((upperLimit - lowerLimit + 1) + lowerLimit);
double simulatedSpeeds[10000];
int* initialSpeeds = new int[stepCounter];
int* times = new int[stepCounter];
int time = 0;
for (int i = 0; i < stepCounter; i++)
{
initialSpeeds[i] = randomWindSpeeds;
simulatedSpeeds[i] = initialSpeeds[i];
times[i] = time;
windFile << times[i] << ' ' << initialSpeeds[i] << endl;
time += stepSize;
}
ofstream finalFile;
finalFile.open("WindSimulation.txt", ios::out);
if (finalFile.fail())
{
cerr << "WindSimulation.txt could not be opened." << endl;
exit(-1);
}
for (int i = 0; i < stepCounter; i++) {
finalFile << times[i] << ' ' << simulatedSpeeds[i] << ' ';
if (simulatedSpeeds[i] != initialSpeeds[i])
{
finalFile << '1' << endl; //this outputs 1 to WindSimulation.txt if storm takes place
}
else {
finalFile << endl;
}
}
finalFile.close();
}
I'd replace simulatedSpeeds with a dynamically allocated array, e.g. std::vector, so it would look like this: std::vector<double> simulatedSpeeds; (you can also use its reserve method) and then inside the loop the simulatedSpeeds[i] = initialSpeeds[i]; should be replaced with simulatedSpeeds.push_back(initialSpeeds[i]);

How do I convert long doubles to char arrays?

I am running a C++ program to sort strings as numbers.
I am saving strings in a char array vector but want to sort numbers as numbers so I am converting number strings into long doubles by calling "tonum()" then converting them back to strings when I am done by calling "tostring()". I am calling "numstr()" strictly for readability and debugging. I convert numbers 0 through 7 and the 6th number across for each value changes every time I run it. In my actual program, the first 5 numbers also seem to change. How do I get consistent results for a long double so that I can properly sort long doubles in char arrays?
#include<iostream>
std::string::size_type sz;
//___________________________________________________
std::string tonum(std::string str)
{
const int len = sizeof(long double);
std::string out = "0000000000000000";
union
{
long double dbl;
char array[len];
};
try
{
dbl = stold(str);
}
catch(std::exception &err)
{
dbl = 0;
}
for (int i = 0; i < len; i++)
{
std::cout << (int)array[i] << "\n";
out[len-i-1] = array[i];
}
return(out);
}
//___________________________________________________
std::string fromnum(std::string str)
{
const int len = sizeof(long double);
std::string out = "";
union
{
long double dbl;
char array[len];
};
for (int i = 0; i < len; i++)
{
array[len-i-1] = str[i];
}
out = std::to_string(dbl);
return(out);
}
//_____________________________________________________
std::string numstr(std::string str)
{
std::string out = fromnum(str) + ":";
for (int i = 0; i < str.length(); i++)
{
std::string look = std::to_string(str[i]);
int lookint = stold(look,&sz);
if (lookint < 0) lookint += 256;
std::string look2 = std::to_string(lookint);
out += look2 + " ";
}
return(out);
}
//_____________________________________________________
int main()
{
std::cout << numstr(tonum("0")) << "\n";
std::cout << numstr(tonum("1")) << "\n";
std::cout << numstr(tonum("2")) << "\n";
std::cout << numstr(tonum("3")) << "\n";
std::cout << numstr(tonum("4")) << "\n";
std::cout << numstr(tonum("5")) << "\n";
std::cout << numstr(tonum("6")) << "\n";
std::cout << numstr(tonum("7")) << "\n";
}
//_____________________________________________________

get last line of file and write new record on it

i have a c++ program to get last line data of issuance.csv file(has id , date,time) and write new record on it
but when i try to write new data(like id,time,date) on it ,save blank line without data on issuance.csv file ,what should i do??
#define DEFAULT_ID "2000"
#define ISSUE_FILE_ADDRESS "/home/pi/file/issuance.csv"
int WriteNewRecord(string NewID, string NewCustomerID, string NewIssueDate)
{
fstream FileStream;
FileStream.open(ISSUE_FILE_ADDRESS, fstream::app | fstream::out);//Just for write into file
if(!FileStream.is_open())
{
cout << "File Open Error1" << endl;
return -1;
}
FileStream << NewID << "," << NewCustomerID << "," << NewIssueDate << endl;//Just for write into file
FileStream.close();
return 0;
}
int GetLastData(string& LastID, string& LastCustomerID, string& LastDate, string& LastTime)
{
fstream FileStream;
FileStream.open(ISSUE_FILE_ADDRESS, fstream::in);
if(!FileStream.is_open())
{
cout << "File Open Error2" << endl;
return -1;
}
string Line;
int Indices[3];
getline(FileStream, Line);
if(Line.length())
{
do {
Indices[0] = Line.find(",");
Indices[1] = Line.find(",", Indices[0] + 1);
Indices[2] = Line.find(",", Indices[1] + 1);
LastID = Line.substr(0, Indices[0]);
LastCustomerID = Line.substr(Indices[0] + 1, Indices[1] - Indices[0] - 1);
LastDate = Line.substr(Indices[1] + 1, Indices[2] - Indices[1] - 1);
LastTime = Line.substr(Indices[2] + 1, Line.length() - Indices[2] - 1);
getline(FileStream, Line);
} while (Line.length());
}
else
LastID = DEFAULT_ID;
FileStream.close();
return 0;
}
int time(){
time_t currentTime;
struct tm *localTime;
time( &currentTime ); // Get the current time
localTime = localtime( &currentTime ); // Convert the current time to the local time
int Day = localTime->tm_mday;
int Month = localTime->tm_mon + 1;
int Year = localTime->tm_year + 1900;
int Hour = localTime->tm_hour;
int Min = localTime->tm_min;
int Sec = localTime->tm_sec;
cout << Day << "/" << Month << "/" << Year << ", "<< Hour << ":" << Min << ":" << Sec<<endl;
//std::cout << std::endl;
return (currentTime);
}
int main()
{
string ID,CustomerID,Date,Time;
if(!GetLastData(ID, CustomerID, Date,Time))
{
cout << ID << " " << CustomerID << " " << Date << " " << Time << endl;
//Issuance Operation...
//...
//...
// if(!WriteNewRecord("2008", "100000", "4/29/2015" , "10:55:15"))//Example for test
string NewID,NewCustomerID,NewIssueDate;
if(!WriteNewRecord(NewID, NewCustomerID, NewIssueDate))
{
unsigned int new_id = atoi(ID.c_str()) + 1;
char tmp[5];
sprintf(tmp, "%d", new_id);
NewID = string(tmp);
tmp[4] = 0;
NewCustomerID=CustomerID;
char write[4];
unsigned int new_date=time();
memcpy(write,&new_date,2);
//cout << write << endl;
sscanf ( NewIssueDate.c_str(), "%d", &new_date );
cout<< NewIssueDate<<"," << NewCustomerID<<","<< NewID <<endl;
//cout << NewIssueDate<<endl;
return 0;
}
}
}
If you look at your code, you do
string NewID,NewCustomerID,NewIssueDate, NewIssueTime;
if(!WriteNewRecord(NewID, NewCustomerID, NewIssueDate))
{
// Initialize variable but don't write them to the file
}
When you declare the std::string variables, they are initialized to be empty, so writing them to a file will write nothing. You then initialize the variables, after you write them to the file.
You could try using FileStream.seekp (std::ios::end); before writing

segfault variable creation c++

So I'm having some troubles with a segfault right now.
The problem appears to be on line 122
file_stream.read(binaryData, fileSizeInt);
The message seems to be unable to create variable object.
I'm using the debugger on CLion, if this is of any help.
I'm fairly new to C++ so please bear with me on this. I've included my source code below, since I have no idea what will and wont be relevant.
#include <fstream>
#include <iostream>
#include <math.h>
using namespace std;
//string dataLocation = "/dev/rdisk2"; // Variable for the mounting point of the SD Card.
string dataLocation = "/Volumes/Untitled/data/smith_data_backup.dat"; // Test location
int sectorSize = 512;
int bytesRead = 0;
string outDir = "/Volumes/Untitled/data/readData/";
char data_stop[10] = "Data_Stop";
char* findHeader(char* inputData) {
int i = 1;
//look for the end of the header
while(true) {
//cout << data[i] << '\n';
if (inputData[i] == '}') {
// found the end of the header
cout << "found the end of the header" << '\n';
break;
}
if (i > 200) { // don't get into an infinite loop here
cout << "something went wrong here" << '\n';
break;
}
i++;
}
// copy the header to a new char array
char* header = new char[i+1];
memcpy(header, &inputData[0], (size_t) (i +1));
return header;
}
int main() {
ifstream file_stream;
file_stream.open(dataLocation);
for( int j = 0; j < 10; j++ ) {
char data[sectorSize]; // figure out a decent size for this.....
string date = "";
string time = "";
string site = "";
string intId = "";
string totalFiles = "";
string fileNo = "";
string fileSize = "";
try {
// read the data file... this will be fun
cout << "Reading the data file" << '\n';
file_stream.read(data, sectorSize);
bytesRead += sectorSize;
if (data[0] == '{') {
char *header = findHeader(data);
cout << header << '\n';
//loop over the header to find the date, time, site ID, Instrument ID, and expected file size.
int commasFound = 0;
for(int i = 1; header[i] != '}', i++;) {
// increment the number of commas that have been found
if (header[i] == ',') {
commasFound ++;
continue;
}
//check for the end f the header
if (header[i] == '}') {
break;
}
//for some reason the first one never gets added
if (i==2) {
date += header[1];
}
// append to appropriate strings based on the number of commas that have been passed in the header
if (commasFound == 0) {
date += header[i];
}
if (commasFound == 1 && time.length() < 6) {
time += header[i];
}
if (commasFound == 2) {
fileNo += header[i];
}
if (commasFound == 6) {
site += header[i];
}
if (commasFound == 8) {
intId += header[i];
}
if (commasFound == 16) {
fileSize += header[i];
}
if (commasFound == 17) {
totalFiles += header[i];
}
//paranoia of infinite loops
if (i > 150) {
break;
}
}
string formattedDate = "20" + date.substr(4,2) + date.substr(2,2) + date.substr(0,2);
cout << formattedDate << " " << time << " " << " " << site << " " << intId << " " << fileSize << " " << totalFiles<< " " << '\n';
// Read in the data size
int fileSizeInt = atoi(fileSize.c_str()) * atoi(fileSize.c_str());
char binaryData[fileSizeInt];
file_stream.read(binaryData, fileSizeInt);
bytesRead += fileSizeInt;
string dateDir = outDir + formattedDate.substr(0,4) + "/" + date.substr(2,2) + "/" + site + "/" + date.substr(0,2) + "/";
string fileName = dateDir + formattedDate + "_" + time + "_" + site + "_" + intId + "_Full_Data.dat";
//cout << fileName << '\n';
//create the directory with the date.
string mkdirCommand = "mkdir -p " + dateDir;
system(mkdirCommand.c_str());
cout << "size " << sizeof(binaryData) << '\n';
//write data to file
try {
cout << "Write the data file " << '\n';
cout << header << " " << strlen(header) << '\n';
ofstream outFile;
outFile.open(fileName.c_str());
outFile.write(header, strlen(header));
outFile.write(binaryData, sizeof(binaryData));
outFile.write(data_stop, sizeof(data_stop));
outFile.close();
} catch (ofstream::failure e ) {
cout << "Unable to write the file " << fileName << '\n';
}
//read till the start of the next sector
int nextSector = (int) ceil(((double) bytesRead)/512.0);
int startOfNextSector = nextSector * 512;
cout << startOfNextSector << '\n';
int bytesToRead = startOfNextSector - bytesRead;
char dump[bytesToRead];
file_stream.read(dump, bytesToRead);
bytesRead += bytesToRead;
// The first block may be empty, quick check to see if the first block needs to be skipped
} else if (j == 0 && data[0] != '{') {
cout << "Skipping the first block" << '\n';
continue;
} else {
//cout << "no start here....." << bytesRead << '\n';
}
}
catch (ifstream::failure& e) {
cout << "Error" << "\n";
break;
}
}
file_stream.close();
return 0;
}

C++ char vector addition

This is a part of a program that I am writing to compute the addition of two integers as strings. (Writing my own bigInt class).
There appears to be a problem when I am adding the two integers together. Because they are both in vectors of char type, I had to add a '0' to each element of the vector before concatenating it into a string.
However, the results are still not what I am expecting:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string const Number = "1000";
string const Number2 = "1000";
vector<char> reverse;
vector<char> reverse2;
//cout << (rostrNumber[1] - '0') << endl;
cout << "Original Number: " << Number << endl;
reverse.clear();
for (int i = Number.size() - 1; i >= 0; i--)
{
reverse.push_back(Number[i]);
}
cout << "Reversed: " << endl;
cout << reverse[0] << reverse[1] << reverse[2] << reverse[3] << endl;
cout << endl << endl;
reverse2.clear();
{
for (int i = Number2.size() - 1; i >= 0; i--)
{
reverse2.push_back(Number[i]);
}
}
cout << "Adding these two integers" << endl;
vector<char> const rcvN1 = reverse;
vector<char> const rcvN2 = reverse2;
vector<char> Results;
Results.clear();
//Local copies
vector<char> vN1 = rcvN1;
vector<char> vN2 = rcvN2;
int iSize1 = vN1.size();
int iSize2 = vN2.size();
int i, iSize = iSize2;
int iC = 0, iR;
for (i = 0; i<iSize; i++)
{
iR = vN1[i] + vN2[i] + iC;
if (iR > 9)
{
iR -= 10;
iC = 1;
}
else
iC = 0;
Results.push_back(iR);
cout << Results[0] << endl;
}
if (iC > 0)
Results.push_back(iC);
string ostr;
vector<char>::const_reverse_iterator rIter = Results.rbegin();
for (; rIter != Results.rend(); rIter++)
ostr += *rIter +'0';
cout << "Results: " << ostr << endl;
system("PAUSE");
return 0;
}