Files
rez_demo/GL_STUFF/SOURCES/CURVES/CurvesLoader.cpp

204 lines
7.5 KiB
C++
Raw Normal View History

#include "../../HEADERS/CURVES/CurvesLoader.hpp"
string CurvesLoader::currentCurveType;
vector<glm::vec3>* CurvesLoader::pointsBuffer;
vector<NURBS*> CurvesLoader::NURBSes;
vector<Bezier3Segments*> CurvesLoader::beziers;
unsigned int CurvesLoader::NURBSOrder;
NURBSType CurvesLoader::NURBS_TYPE;
vector<float>* CurvesLoader::NURBSWeights;
char CurvesLoader::lineHeader[128];
char* CurvesLoader::res;
FILE* CurvesLoader::file;
std::smatch CurvesLoader::pieces;
void CurvesLoader::beginCurve(string str, std::smatch pieces, std::regex regex) {
pointsBuffer = new vector<glm::vec3>();
NURBSWeights = new vector<float>();
NURBS_TYPE = NURBSType::BASIC;
//si inizia una patch di BEZIER
if (pieces[1].str() == "BEZIER") {
//std::cout << "next is BEZIER" << std::endl;
currentCurveType = "BEZIER";
}
//si inizia una NURBS
else if (pieces[1].str() == "NURBS") {
//std::cout << "next is NURBS" << std::endl;
currentCurveType = "NURBS";
res = fgets(lineHeader, 128, file); // read curve multiplicity
str = lineHeader;
std::regex regex("\\s*order (\\d)\\s*(clamped|cyclic)?\\s*(\\n)?");
if (res == NULL || !std::regex_match(str, pieces, regex)) {
throw "expected NURBS order";
}
else {
NURBSOrder = stoi(pieces[1]);
if (pieces.length() > 2) {
if (pieces[2].str() == "clamped") {
NURBS_TYPE = NURBSType::CLAMPED;
}
else if (pieces[2].str() == "cyclic") {
NURBS_TYPE = NURBSType::CYCLIC;
}
}
else {
NURBS_TYPE = NURBSType::BASIC;
}
std::cout << res << std::endl;
}
//std::cout << "parsed order : " << NURBSOrder << std::endl;
}
}
NURBS* CurvesLoader::BasicNURBS() {
unsigned int nFunctions = pointsBuffer->size();
unsigned int totalElements = NURBSOrder + nFunctions;
vector<float>* intervals = new vector<float>();
for (int i = 0; i <= totalElements; i++)
intervals->push_back((float) i / totalElements);
vector<unsigned int>* multiplicities = new vector<unsigned int>;
for (int i = 0; i < pointsBuffer->size(); i++)
multiplicities->push_back(1);
return new NURBS(NURBSOrder, pointsBuffer, NURBSWeights, intervals, multiplicities);
}
NURBS* CurvesLoader::ClampedNURBS() {
unsigned int nFunctions = pointsBuffer->size();
vector<float>* intervals = new vector<float>();
for (int i = 0; i <= NURBSOrder; i++)
intervals->push_back(0);
for (int i = 1; i <= nFunctions - NURBSOrder; i++)
intervals->push_back((float)i / (nFunctions - NURBSOrder));
for (int i = 0; i < NURBSOrder; i++)
intervals->push_back(1);
vector<unsigned int>* multiplicities = new vector<unsigned int>;
for (int i = 0; i < pointsBuffer->size(); i++)
multiplicities->push_back(1);
return new NURBS(NURBSOrder, pointsBuffer, NURBSWeights, intervals, multiplicities);
}
NURBS* CurvesLoader::CyclicNURBS() {
for (int i = 0; i < NURBSOrder; i++) {
pointsBuffer->push_back(pointsBuffer->at(i));
NURBSWeights->push_back(NURBSWeights->at(i));
}
unsigned int nFunctions = pointsBuffer->size();
unsigned int totalElements = NURBSOrder + nFunctions;
vector<float>* intervals = new vector<float>();
for (int i = 0; i <= totalElements; i++)
intervals->push_back((float) i/ totalElements);
vector<unsigned int>* multiplicities = new vector<unsigned int>;
for (int i = 0; i < pointsBuffer->size(); i++)
multiplicities->push_back(1);
return new NURBS(NURBSOrder, pointsBuffer, NURBSWeights, intervals, multiplicities);
}
void CurvesLoader::closeNURBS(){
try {
switch (NURBS_TYPE) {
case NURBSType::BASIC :
std::cout << "NURBS was BASIC" << std::endl;
NURBSes.push_back(BasicNURBS());
break;
case NURBSType::CLAMPED :
std::cout << "NURBS was CLAMPED" << std::endl;
NURBSes.push_back(ClampedNURBS());
break;
case NURBSType::CYCLIC :
std::cout << "NURBS was CYCLIC" << std::endl;
NURBSes.push_back(CyclicNURBS());
break;
}
}
catch (std::invalid_argument e) {
std::cout << e.what() << std::endl;
}
}
void CurvesLoader::closeBezier() {
vector<float>* intervals = new vector<float>();
int nIntervals = pointsBuffer->size() / 4;
intervals->push_back(0);
for (int i = 1; i <= nIntervals; i++)
intervals->push_back((float)i / nIntervals);
beziers.push_back(new Bezier3Segments(pointsBuffer, intervals));
}
void CurvesLoader::closePendingCurve() {
if (currentCurveType == "BEZIER") {
closeBezier();
}
else if (currentCurveType == "NURBS") {
closeNURBS();
}
}
void CurvesLoader::parseVertexData(string str) {
vector<float> vecComponents = vector<float>();
std::regex regex("-?\\d+.\\d+");
while (std::regex_search(str, pieces, regex)) {
float entry = stof(pieces[0], NULL); //potevi evitare la regex
vecComponents.push_back(entry);
str = pieces.suffix().str();
}
glm::vec3 vec(vecComponents[0], vecComponents[1], vecComponents[2]);
pointsBuffer->push_back(vec);
if (currentCurveType == "NURBS") {
NURBSWeights->push_back(vecComponents[3]);
}
}
bool CurvesLoader::loadCurves(std::string path, vector<Curve*>& curves) {
currentCurveType = "NONE";
pointsBuffer = new vector<glm::vec3>();
NURBSWeights = new vector<float>();
file = fopen(&path[0], "r");
if (file == NULL) {
printf("Impossible to open the curve file ! Are you in the right path ?\n");
getchar();
return false;
}
while (1) {
res = fgets(lineHeader, 128, file); // read the first word of the line
// EOF = End Of File. Store pending curve and quit the loop.
if (res == NULL) {
closePendingCurve(); //what if there was no pending curve? (aka return false)
break;
}
string str = lineHeader;
std::regex regex("\\s*curve \\d+ : (BEZIER|NURBS)\\n");
//inizia una curva (la prima o una nuova)
if (std::regex_match(str, pieces, regex)) {
closePendingCurve();
beginCurve(str, pieces, regex);
}
//deve essere materiale inerente la curva in costruzione
else {
std::regex regex("\\s*(-?\\d+.\\d+)(( , -?\\d+.\\d+)+)\\s*(\\n)?");
//sono dati di un vertice
if (std::regex_match(str, pieces, regex)){
parseVertexData(str);
}
else {
std::cout << "unrecognized line : " << str << std::endl;
}
}
}
std::cout << "trovate " << beziers.size() << " curve di bezier" << std::endl << "e " << NURBSes.size() << " NURBS" << std::endl;
for (Bezier3Segments* el : beziers)
curves.push_back(el);
for (NURBS* el : NURBSes)
curves.push_back(el);
/* !!! only the file existence gets checked */
return true;
}