use "ARCH=arch_name make" restructured project folder, implementations and headers together under sources/
204 lines
7.5 KiB
C++
Executable File
204 lines
7.5 KiB
C++
Executable File
#include "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;
|
|
}
|
|
|