コード例 #1
0
ファイル: uhfsolve.cpp プロジェクト: audunsh/FYS4411
void uhfsolve::setupF(){
    //set up the Fock matrix
    double Di = 0;
    double Ex = 0;
    double DiMinusEx = 0;
    for(int p=0;p<nStates;p++){
        for(int q=0;q<nStates;q++){
            //F(p,q) = Bs.h(p,q);
            Fu(p,q) = Bs.h(p,q);
            Fd(p,q) = Bs.h(p,q);
            for(int r=0;r<nStates;r++){
                for(int s=0;s<nStates;s++){
                    //Di = Bs.v(p,r)(q,s);
                    //Ex = Bs.v(p,r)(s,q);

                    Di = Bs.v(p,q)(r,s);
                    Ex = Bs.v(p,s)(r,q);
                    DiMinusEx = Di-Ex;
                    //F(p,q) += 0.5*coupledMatrixTilde(p,q,r,s)*P(r,s);  //Alt. 2 27/5 2014
                    Fu(p,q) += Pu(s,r)*(Di-Ex) + Pd(s,r)*Di;
                    Fd(p,q) += Pd(s,r)*(Di-Ex) + Pu(s,r)*Di;
                }
            }
        }
    }
}
コード例 #2
0
ファイル: movement.cpp プロジェクト: FerryT/OGO-2.3
void Controller::moveY(double speed)
{
	speed *= MoveSpeed;
	speed *= FRATE;

    Point<double> posrollback = Point<double>(player->origin);
	Point<double> tarrollback = Point<double>(target);
	Vector<double> vec = (-player->rotation * Vector<double>(0,1,0));
	vec.z = 0;
	vec = ~vec;
	double yaw = atan2(vec.x, vec.y);
	player->origin = player->origin + vec*speed;
	target = player->origin + Pd(.75 * sin(yaw - .25*Pi), .75 * cos(yaw-.25*Pi), 2);
	
	if(!walkAble(posrollback, player->origin)){
		player->origin = posrollback;
    	target = tarrollback;
		blocked = true;
    	return;
	}
	vec = ~(camAngle * Vector<double>(0,1,0));
	if (firstPerson)
	{
		camera.origin = player->origin + Pd(0,0,2.5) + vec;
		camera.lookAt(camera.origin + (vec * 5.0));
	}
	else
	{
		camera.origin = target - (vec * zoom);
		camera.lookAt(target);
	}
	blocked = false;
}
コード例 #3
0
float Ship::Wm(){
	float c1, c2;
	c1 = c2 = 0.;

	float PdV = Pd(v.Vk)/Vol();
	float c3 = pow(v.Year, 0.4) - 19;
	if (PdV > 40)
		c1 = 0.14 * c3;
	else if (PdV > 26)
		c1 = 0.13 * c3;
	else if (PdV > 21)
		c1 = 0.21 * c3;
	else if (PdV > 10)
		c1 = 0.22 * c3;
	else c1 = 1.;

	if (Vol() > 5000)
        c1 = 1.;

	if (v.Year < 1915)
		c2 = 1.9;
	else if(v.Year < 1933)
		c2 = 1.6;
	else c2 = 0.92;

	return find(et, e.Eng).K1 * pow(Pd(v.Vk), find(et, e.Eng).K2)* (pow((pow(v.Year, 0.45) - 29.3), 2.) + 0.45) * c1 * c2 * find(st, e.Gear).Wgear;
}
コード例 #4
0
ファイル: world.cpp プロジェクト: FerryT/OGO-2.3
Droppable::Droppable(Pd _origin, Resource _worth, long _dropped, long _ttl)
	: BoundedObject(_origin, Qd(), BoundingBox(Pd(-0.105, -0.5, 0.0), Pd(0.105, 0.5, 1.0)))
{
	model.coin = ModelObjectContainer();
	model.coin->children.insert(Assets::Model::CoinObj);
	children.insert(model.coin);
	model.coin->material = Assets::Model::CoinTex;

	worth = _worth;
	dropped = _dropped;
	ttl = _ttl;
	done = false;
	long pid = (Game::game.player ? Game::game.player->id : 0);
	id = topId++ | (pid << 16);
}
コード例 #5
0
ファイル: movement.cpp プロジェクト: FerryT/OGO-2.3
void Controller::lookZ(double speed)
{
	speed *= LookSpeed;
	speed *= FRATE;

    Qd buffer = camAngle;//Used to rollback if out of bounds

	Vector<double> mystery = ~(camAngle * Vector<double>(0,1,0));
	double mysteryYaw = atan2(mystery.x, mystery.y);

	camAngle = Qd(Rd(speed, Vd(cos(mysteryYaw),-sin(mysteryYaw),0))) * camAngle;
       if((camAngle*Vector<double>(0,1,0)).z > 0.99 || (camAngle*Vector<double>(0,1,0)).z < -0.99){
           camAngle = buffer;
           return;
       }
	Vector<double> vec = ~(camAngle * Vector<double>(0,1,0));

	if (firstPerson == true)
	{
		camera.origin = player->origin + Pd(0,0,2.5) + vec;
		camera.lookAt(camera.origin + (vec * 5.0));
	}
	else
	{
		camera.origin = target - (vec * zoom);
		camera.lookAt(target);
	}
}
コード例 #6
0
ファイル: traceLinePts.cpp プロジェクト: jacobxk/mirt
void P_nested(vector<double> &P, const vector<double> &par,
    const NumericMatrix &Theta, const int &N, const int &nfact, const int &ncat,
    const int &correct)
{
    NumericVector dummy(1);
	const int par_size = par.size();
    vector<double> dpar(nfact+3), npar(par_size - nfact - 3, 1.0);
    for(int i = 0; i < nfact+3; ++i)
        dpar[i] = par[i];
    for(int i = nfact+3; i < par_size; ++i)
        npar[i - (nfact+3) + nfact] = par[i];
    vector<double> Pd(N*2), Pn(N*(ncat-1));
    P_dich(Pd, dpar, Theta, dummy, N, nfact);
    P_nominal(Pn, npar, Theta, dummy, N, nfact, ncat-1, 0, 0);
    NumericMatrix PD = vec2mat(Pd, N, 2);
    NumericMatrix PN = vec2mat(Pn, N, ncat-1);

    int k = 0, which = 0;
    for(int i = 0; i < ncat; ++i){
        if((i+1) == correct){
            for(int j = 0; j < N; ++j){
                P[which] = PD(j,1);
                ++which;
            }
            --k;
        } else {
            for(int j = 0; j < N; ++j){
                P[which] = PD(j,0) * PN(j,k);
                ++which;
            }
        }
        ++k;
    }
}
コード例 #7
0
ファイル: game.cpp プロジェクト: timvdalen/OGO-2.3
Point<double> getSpawn(const char team){
	switch(team){
	case 'b':{
			//Pd spawn1 = game.world->terrain->ToPointD(GridPoint(5, 24));
			Pd spawn2 = game.world->terrain->ToPointD(GridPoint(5, 25));
			int randval = rand() % 2;
			if(randval == 0){
				return spawn2;
			}else{
				return spawn2;
			}
		 }
		 break;
	case 'a':{
			//Pd spawn1 = game.world->terrain->ToPointD(GridPoint(45,25));
		    Pd spawn2 = game.world->terrain->ToPointD(GridPoint(45,26));
			int randval = rand() % 2;
			if(randval == 0){
				return spawn2;
			}else{
				return spawn2;
			}
	
		 }
		 break;
	default:{
			return Pd();
		}
	}
}
コード例 #8
0
ファイル: world.cpp プロジェクト: FerryT/OGO-2.3
void Sky::frame(){
	if(stars.size() < 300){
		int res = rand()%100;
		if(res == 0){
			int x = rand()%width - (int)width/2;
			int y = rand()%height - (int)height/2;
			int min = HIGH - (int)(HIGH/10);
			int z = rand()%(HIGH-min) + min;
			stars.push_back(Star(Pd(x, y, z)));
		}
	}
	if(stars.size() > 150){
		int res = rand()%200;
		if(res == 0){
			stars.erase(stars.begin() + (rand()%stars.size()));
		}
	}
	if(stars.size() > 100){
		int res = rand()%60;
		if(res == 0){
			vector<Star>::iterator it;
			it = stars.begin() + (rand()%stars.size());
			it->big = !it->big;
		}
	}
}
コード例 #9
0
ファイル: movement.cpp プロジェクト: FerryT/OGO-2.3
void Controller::lookY(double speed)
{
	speed *= ZoomSpeed;
	speed *= FRATE;

	Vector<double> vec = ~(camAngle * Vector<double>(0,1,0));

	zoom -= speed;

	if (zoom > 25.0)
	{
		zoom = 25.0;
	}
	else if (zoom <= 5.0)
	{
		firstPerson = true;
		zoom = 5.0;
	}
	else
	{
		firstPerson = false;
	}

	if (firstPerson == true)
	{
		camera.origin = player->origin + Pd(0,0,2.5) + vec;
		camera.lookAt(camera.origin + (vec * 5.0));
	}
	else
	{
		camera.origin = target - (vec * zoom);
		camera.lookAt(target);
	}
}
コード例 #10
0
float Ship::Bunker(){
	float b1 = v.Range / (1. + 0.4 * v.Coalpct);
	float b2 = 0.;
	float b3 = 1.8/Pd(v.Vc) * v.Range * v.Vc * 0.1;

	if (v.Year < 1898 || e.Eng == QuadExp || e.Eng == TripExp)
		b2 = 1. - (1910 - v.Year)/70.;
	else if (v.Year < 1920)
		b2 = 1. + (v.Year - 1910)/20.;
	else if( v.Year < 1950)
		b2 = 1.5 + (v.Year - 1920)/60.;
	else
		b2 = 2 + (v.Year - 1950)/60.;

	float c1 = (Pd(v.Vk)/Vol() > 15 && Pd(v.Vk)/Vol() < 18) ? 0.3 : 1;
	return (b1 / (b2 * b3) + 0.005 * Vol()) * c1 * find(et, e.Eng).FcE * find(st, e.Gear).FcT;
}
コード例 #11
0
ファイル: game.cpp プロジェクト: timvdalen/OGO-2.3
void Test(string str)
{
	if(str == "a"){
		game.world->children.insert(Droppable(Pd(0.0, 0.0, 0.0), 30));
	}else if(str == "b"){
		game.world->temporary.push_back(Droppable(Pd(0.0, 0.0, 0.0), 30));
	}else{
		Player::Id pid2 = game.topId++;
		ObjectHandle player2 = Player(pid2, 'a', "Carl");
		game.root->children.insert(player2);
		game.players[pid2] = player2;

		if(game.teams.count('a'))
			game.teams['a'].resources = 1000;

		game.world->terrain->placeStructure(GridPoint(22,24), DefenseTower(pid2));
	}

}
コード例 #12
0
ファイル: world.cpp プロジェクト: FerryT/OGO-2.3
World::World(double _width, double _height)
	: BoundedObject(Pd(), Qd(),
	  BoundingBox(Pd(-_width/2, -_height/2, 0), Pd(_width,0,0), Pd(0,_height,0), Pd(_width,_height,0), Pd(), Pd(), Pd(), Pd(_width/2, _height/2, HIGH)),
	  Assets::WorldMaterial)
{

	ObjectHandle tHandle;
	tHandle = Terrain(_width, _height);
	terrain = TO(Terrain, tHandle);
	children.insert(tHandle);

	ObjectHandle hudHandle;
	hudHandle = HUD(640, 480);
	hud = TO(HUD, hudHandle);
	children.insert(hudHandle);

	children.insert(Sky((int) _width, (int) _height));

	width = _width;
	height = _height;
}
コード例 #13
0
ファイル: movement.cpp プロジェクト: FerryT/OGO-2.3
void Controller::frame()
{
	if (move[dirY] != 0.0) moveY(move[dirY]);
	if (move[dirZ] != 0.0) moveZ(move[dirZ]);
	
	if (look[dirX] != 0.0) lookX(look[dirX]);
	if (look[dirY] != 0.0) lookY(look[dirY]);
	if (look[dirZ] != 0.0) lookZ(look[dirZ]);
	
	if (move[dirY] != 0.0)
	{
		if ((move[dirX] < 0.0 && move[dirY] > 0.0)
		||  (move[dirX] > 0.0 && move[dirY] < 0.0))
			player->rotation = player->rotation * Rd(-0.05,Vd(0,0,1));
		else if ((move[dirX] > 0.0 && move[dirY] > 0.0)
		     ||  (move[dirX] < 0.0 && move[dirY] < 0.0))
			player->rotation = player->rotation * Rd(0.05,Vd(0,0,1));
		else
		{
            Vd camv = camAngle*Vd(0,1,0);
            Vd plav = player->rotation*Vd(0,1,0);
            camv.z = 0; camv = ~camv;
            plav.z = 0; plav = ~plav;
            double angle = atan2(camv.y - plav.y, camv.x - plav.x);
            double angle2 = (angle < 0? -angle : angle);
            double axis = angle2 >  0.5*Pi ^ angle > 0? 1 : -1;
            angle2 = angle2 > 0.5*Pi ? Pi - angle2 : angle2;
            angle2 = angle2 < 0.05? angle2 : 0.05;
			if (axis != 0)
                player->rotation = player->rotation * Rd(-angle2,Vd(0,0,axis));
		}
	}
	Vector<double> vec = (-player->rotation * Vector<double>(0,1,0));
	vec.z = 0;
	vec = ~vec;
	double yaw = atan2(vec.x, vec.y);
	target = player->origin + Pd(.75 * sin(yaw - .25*Pi), .75 * cos(yaw-.25*Pi), 2);
	vec = ~(camAngle * Vector<double>(0,1,0));
	if (firstPerson)
	{
		camera.lookAt(camera.origin + (vec * 5.0));
	}
	else
	{
		camera.lookAt(target);
	}
	Objects::Player * p = TO(Objects::Player,player);
	p->velocity = Vd(0,MoveSpeed,0);
}
コード例 #14
0
ファイル: movement.cpp プロジェクト: FerryT/OGO-2.3
Controller::Controller(Camera &C, ObjectHandle P) : camera(C), player(P)
{
	firstPerson = false;
	lastView = false;
	target = player->origin + Pd(-.5,-.5,2);

	Vector<double> vec = camAngle * Vector<double>(0,1,0);

	zoom = 10.0;
	camera.origin = target - (~vec * zoom);
	camera.lookAt(target);

	camAngle = Qd();
	blocked = false;
}
コード例 #15
0
ファイル: movement.cpp プロジェクト: FerryT/OGO-2.3
void Controller::lookX(double speed)
{
	speed *= -LookSpeed;
	speed *= FRATE;

	camAngle = Qd(Rd(speed, Vd(0,0,1))) * camAngle;

	Vector<double> vec = ~(camAngle * Vector<double>(0,1,0));

	if (firstPerson == true)
	{
		camera.origin = player->origin + Pd(0,0,2.5) + vec;
		camera.lookAt(camera.origin + (vec * 5.0));
	}
	else
	{
		camera.origin = target - (vec * zoom);
		camera.lookAt(target);
	}
}
コード例 #16
0
float Ship::Lcmi(){
	return (0.002 * Pd(v.Vk) + 5.5) / M2FT;
}
コード例 #17
0
ファイル: game.cpp プロジェクト: timvdalen/OGO-2.3
void Initialize(int argc, char *argv[])
{
	// Process command line arguments
	for (int i = 0; i < argc - 1; ++i)
	{
		if      (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--map-width"))
			gameWidth = atof(argv[++i]);
		else if (!strcmp(argv[i], "-y") || !strcmp(argv[i], "--map-height"))
			gameHeight = atof(argv[++i]);
		else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--path"))
			path = argv[++i];
		else if (!strcmp(argv[i], "-w") || !strcmp(argv[i], "--screen-width"))
			windowWidth = atoi(argv[++i]);
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--screen-height"))
			windowHeight = atoi(argv[++i]);
	}
	
	// Process config file
	if (!file_exists(CONFIG_FILE))
	{
		ConfigFile newconfig;
		newconfig.add("playername", "Unnamed");
		newconfig.add("team", 'a');
		newconfig.save(CONFIG_FILE);
	}
	
	try { config = new ConfigFile(CONFIG_FILE); }
	catch (ConfigFile::file_not_found e)
	{
		delete config;
		config = NULL;
		puts("Unable to create config file: " CONFIG_FILE "!");
		exit(EXIT_FAILURE);
	}
	
	fullscreen = (config->read("fullscreen", '0')) == '1'? true : false;
	/* deprecated: for (int i = 0; i < argc; ++i)
	{
		if (!strcmp(argv[i], "--fullscreen"))
			fullscreen = true;
	}*/
	// Global subsystem initializations
	srand(time(NULL));
	
	// Create window and set up viewports
	game.window = new Video::Window(windowWidth, windowHeight,
	                                GAME_NAME, fullscreen);
	Video::Viewport *view = new Video::Viewport(1,1);
	game.window->viewports.push_back(view);
	
	// Show loading screen
	// Problem: we can't use the hud prior to asset loading
	
	// Load game assets
	Assets::Initialize(argc, argv);
	
	config->readInto(NetCode::MessageOfTheDay, "motd",
		string("No message of the day ;("));
	
	// Set up game world
	game.root = World(gameWidth, gameHeight);
	game.world = TO(World,game.root);
	game.topId = 1;
	
	game.teams.insert(make_pair('a', Team('a')));
	game.teams.insert(make_pair('b', Team('b')));
	
	string name;
	unsigned char team;
	config->readInto(name, "playername", string("Unnamed"));
	team = config->read("team", 'a');
	
	Player::Id pid = game.topId++;
	ObjectHandle player = Player(pid, team, name);
	game.player = TO(Player,player);
	game.player->weapon = weapLaser;
	game.player->origin = getSpawn(team);
	game.root->children.insert(player);
	game.players[pid] = player;
	
	game.world->terrain->placeStructure(GridPoint(2,2), Mine());
	game.world->terrain->placeStructure(GridPoint(2,48), Mine());
	game.world->terrain->placeStructure(GridPoint(48,2), Mine());
	game.world->terrain->placeStructure(GridPoint(48,48), Mine());
	game.world->terrain->placeStructure(GridPoint(25,25), RichMine());
	game.world->terrain->placeStructure(GridPoint(15,25), Mine());
	game.world->terrain->placeStructure(GridPoint(35,25), Mine());
	game.world->terrain->placeStructure(GridPoint(25,5), RichMine());
	game.world->terrain->placeStructure(GridPoint(25,45), RichMine());
	game.world->terrain->placeStructure(GridPoint(6,9), Mine());
	game.world->terrain->placeStructure(GridPoint(6,41), Mine());
	game.world->terrain->placeStructure(GridPoint(44,9), Mine());
	game.world->terrain->placeStructure(GridPoint(44,41), Mine());
	game.world->terrain->placeStructure(GridPoint(10,17), Mine());
	game.world->terrain->placeStructure(GridPoint(10,33), Mine());
	game.world->terrain->placeStructure(GridPoint(40,17), Mine());
	game.world->terrain->placeStructure(GridPoint(40,33), Mine());

	ObjectHandle RedBot = player;
	ObjectHandle BlueBot = player;
	
	if (team == 'b')
	{
		RedBot = Player(INT_MAX - 'a', 'a', "RedBot", Pd(-1000,-1000,-1000));
		//game.world->children.insert(RedBot);
		game.players[TO(Player, RedBot)->id] = RedBot;
	}
	else if (team == 'a')
	{
		BlueBot = Player(INT_MAX - 'b', 'b', "BlueBot", Pd(-1000,-1000,-1000));
		//game.world->children.insert(BlueBot);
		game.players[TO(Player, BlueBot)->id] = BlueBot;
	}

	game.world->terrain->placeStructure(GridPoint(3,25), HeadQuarters(TO(Player, BlueBot)->id));
	game.world->terrain->placeStructure(GridPoint(48,26), HeadQuarters(TO(Player, RedBot)->id));

	game.world->terrain->placeStructure(GridPoint(4,26), DefenseTower(TO(Player, BlueBot)->id));
	game.world->terrain->placeStructure(GridPoint(4,23), DefenseTower(TO(Player, BlueBot)->id));
	game.world->terrain->placeStructure(GridPoint(46,27), DefenseTower(TO(Player, RedBot)->id));
	game.world->terrain->placeStructure(GridPoint(46,24), DefenseTower(TO(Player, RedBot)->id));

	for(int i = 0; i <= 50; i++) {
		game.world->terrain->placeStructure(GridPoint(0,i), Wall());
		game.world->terrain->placeStructure(GridPoint(50,i), Wall());
		game.world->terrain->placeStructure(GridPoint(i,0), Wall());
		game.world->terrain->placeStructure(GridPoint(i,50), Wall());
	}

	for(int i = 8; i <= 42; i++) {
		if (i < 23 || i > 27) {
			game.world->terrain->placeStructure(GridPoint(25,i), Wall());
			game.world->terrain->placeStructure(GridPoint(i,5), Wall());
			game.world->terrain->placeStructure(GridPoint(i,45), Wall());
		}
		if (i < 22 || i > 28) {
			game.world->terrain->placeStructure(GridPoint(i,15), Wall());
			game.world->terrain->placeStructure(GridPoint(i,35), Wall());
		}
		if (i < 13 || i > 37) {
			game.world->terrain->placeStructure(GridPoint(i,25), Wall());
		}
	}

	for (int i = 5; i <=11; i++) {
		game.world->terrain->placeStructure(GridPoint(4,i), Wall());
		game.world->terrain->placeStructure(GridPoint(46,i), Wall());
		game.world->terrain->placeStructure(GridPoint(i,11), Wall());
		game.world->terrain->placeStructure(GridPoint(i,39), Wall());
	}

	for (int i = 39; i <=45; i++) {
		game.world->terrain->placeStructure(GridPoint(4,i), Wall());
		game.world->terrain->placeStructure(GridPoint(46,i), Wall());
		game.world->terrain->placeStructure(GridPoint(i,11), Wall());
		game.world->terrain->placeStructure(GridPoint(i,39), Wall());
	}

	for (int i = 15; i <= 35; i++) {
		game.world->terrain->placeStructure(GridPoint(8,i), Wall());
		game.world->terrain->placeStructure(GridPoint(42,i), Wall());
	}

	for (int i = 3; i <= 47; i++) {
		if (i < 12 || i > 38 || (i > 19 && i < 31)) {
			game.world->terrain->placeStructure(GridPoint(18,i), Wall());
			game.world->terrain->placeStructure(GridPoint(32,i), Wall());
		}
	}

	for (int i = 13; i <= 37; i++) {
		if (i < 18 || i > 32) {
			game.world->terrain->placeStructure(GridPoint(i,20), Wall());
			game.world->terrain->placeStructure(GridPoint(i,30), Wall());
		}
	}

	game.world->terrain->placeStructure(GridPoint(11,1), Wall());
	game.world->terrain->placeStructure(GridPoint(11,2), Wall());
	game.world->terrain->placeStructure(GridPoint(11,49), Wall());
	game.world->terrain->placeStructure(GridPoint(11,48), Wall());
	game.world->terrain->placeStructure(GridPoint(39,1), Wall());
	game.world->terrain->placeStructure(GridPoint(39,2), Wall());
	game.world->terrain->placeStructure(GridPoint(39,49), Wall());
	game.world->terrain->placeStructure(GridPoint(39,48), Wall());

	// Set up user interface
	view->world = game.root;
	game.controller = new Controller(view->camera, player);
	game.input = new Input(*game.window);
	game.input->onKeyUp = KeyUp;
	game.input->onKeyDown = KeyDown;
	//input->onMouseMove = MouseMove;
	
	Echo("Everything loaded!");
	Echo("Welcome to the game");
	Echo(NetCode::MessageOfTheDay);
}
コード例 #18
0
ファイル: ObjFilter.cpp プロジェクト: ORNis/CloudCompare
CC_FILE_ERROR ObjFilter::loadFile(QString filename, ccHObject& container, LoadParameters& parameters)
{
	ccLog::Print(QString("[OBJ] ") + filename);

	//open file
	QFile file(filename);
	if (!file.open(QFile::ReadOnly))
		return CC_FERR_READING;
	QTextStream stream(&file);

	//current vertex shift
	CCVector3d Pshift(0,0,0);

	//vertices
	ccPointCloud* vertices = new ccPointCloud("vertices");
	int pointsRead = 0;

	//facets
	unsigned int facesRead = 0;
	unsigned int totalFacesRead = 0;
	int maxVertexIndex = -1;

	//base mesh
	ccMesh* baseMesh = new ccMesh(vertices);
	baseMesh->setName(QFileInfo(filename).baseName());
	//we need some space already reserved!
	if (!baseMesh->reserve(128))
	{
		ccLog::Error("Not engouh memory!");
		return CC_FERR_NOT_ENOUGH_MEMORY;
	}

	//groups (starting index + name)
	std::vector<std::pair<unsigned,QString> > groups;

	//materials
	ccMaterialSet* materials = 0;
	bool hasMaterial = false;
	int currentMaterial = -1;
	bool currentMaterialDefined = false;
	bool materialsLoadFailed = true;

	//texture coordinates
	TextureCoordsContainer* texCoords = 0;
	bool hasTexCoords = false;
	int texCoordsRead = 0;
	int maxTexCoordIndex = -1;

	//normals
	NormsIndexesTableType* normals = 0;
	int normsRead = 0;
	bool normalsPerFacet = false;
	int maxTriNormIndex = -1;

	//progress dialog
	ccProgressDialog pDlg(true);
	pDlg.setMethodTitle("OBJ file");
	pDlg.setInfo("Loading in progress...");
	pDlg.setRange(0,static_cast<int>(file.size()));
	pDlg.show();
	QApplication::processEvents();

	//common warnings that can appear multiple time (we avoid to send too many messages to the console!)
	enum OBJ_WARNINGS {	INVALID_NORMALS		= 0,
						INVALID_INDEX		= 1,
						NOT_ENOUGH_MEMORY	= 2,
						INVALID_LINE		= 3,
						CANCELLED_BY_USER	= 4,
	};
	bool objWarnings[5] = { false, false, false, false, false };
	bool error = false;

	try
	{
		unsigned lineCount = 0;
		unsigned polyCount = 0;
		QString currentLine = stream.readLine();
		while (!currentLine.isNull())
		{
			if ((++lineCount % 2048) == 0)
			{
				if (pDlg.wasCanceled())
				{
					error = true;
					objWarnings[CANCELLED_BY_USER] = true;
					break;
				}
				pDlg.setValue(static_cast<int>(file.pos()));
				QApplication::processEvents();
			}

			QStringList tokens = QString(currentLine).split(QRegExp("\\s+"),QString::SkipEmptyParts);

			//skip comments & empty lines
			if( tokens.empty() || tokens.front().startsWith('/',Qt::CaseInsensitive) || tokens.front().startsWith('#',Qt::CaseInsensitive) )
			{
				currentLine = stream.readLine();
				continue;
			}

			/*** new vertex ***/
			if (tokens.front() == "v")
			{
				//reserve more memory if necessary
				if (vertices->size() == vertices->capacity())
				{
					if (!vertices->reserve(vertices->capacity()+MAX_NUMBER_OF_ELEMENTS_PER_CHUNK))
					{
						objWarnings[NOT_ENOUGH_MEMORY] = true;
						error = true;
						break;
					}
				}

				//malformed line?
				if (tokens.size() < 4)
				{
					objWarnings[INVALID_LINE] = true;
					error = true;
					break;
				}

				CCVector3d Pd( tokens[1].toDouble(), tokens[2].toDouble(), tokens[3].toDouble() );

				//first point: check for 'big' coordinates
				if (pointsRead == 0)
				{
					if (HandleGlobalShift(Pd,Pshift,parameters))
					{
						vertices->setGlobalShift(Pshift);
						ccLog::Warning("[OBJ] Cloud has been recentered! Translation: (%.2f,%.2f,%.2f)",Pshift.x,Pshift.y,Pshift.z);
					}
				}

				//shifted point
				CCVector3 P = CCVector3::fromArray((Pd + Pshift).u);
				vertices->addPoint(P);
				++pointsRead;
			}
			/*** new vertex texture coordinates ***/
			else if (tokens.front() == "vt")
			{
				//create and reserve memory for tex. coords container if necessary
				if (!texCoords)
				{
					texCoords = new TextureCoordsContainer();
					texCoords->link();
				}
				if (texCoords->currentSize() == texCoords->capacity())
				{
					if (!texCoords->reserve(texCoords->capacity() + MAX_NUMBER_OF_ELEMENTS_PER_CHUNK))
					{
						objWarnings[NOT_ENOUGH_MEMORY] = true;
						error = true;
						break;
					}
				}

				//malformed line?
				if (tokens.size() < 2)
				{
					objWarnings[INVALID_LINE] = true;
					error = true;
					break;
				}

				float T[2] = { T[0] = tokens[1].toFloat(), 0 };

				if (tokens.size() > 2) //OBJ specification allows for only one value!!!
				{
					T[1] = tokens[2].toFloat();
				}

				texCoords->addElement(T);
				++texCoordsRead;
			}
			/*** new vertex normal ***/
			else if (tokens.front() == "vn") //--> in fact it can also be a facet normal!!!
			{
				//create and reserve memory for normals container if necessary
				if (!normals)
				{
					normals = new NormsIndexesTableType;
					normals->link();
				}
				if (normals->currentSize() == normals->capacity())
				{
					if (!normals->reserve(normals->capacity() + MAX_NUMBER_OF_ELEMENTS_PER_CHUNK))
					{
						objWarnings[NOT_ENOUGH_MEMORY] = true;
						error = true;
						break;
					}
				}

				//malformed line?
				if (tokens.size() < 4)
				{
					objWarnings[INVALID_LINE] = true;
					error = true;
					break;
				}

				CCVector3 N(static_cast<PointCoordinateType>(tokens[1].toDouble()),
							static_cast<PointCoordinateType>(tokens[2].toDouble()),
							static_cast<PointCoordinateType>(tokens[3].toDouble()));

				if (fabs(N.norm2() - 1.0) > 0.005)
				{
					objWarnings[INVALID_NORMALS] = true;
					N.normalize();
				}
				CompressedNormType nIndex = ccNormalVectors::GetNormIndex(N.u);

				normals->addElement(nIndex); //we don't know yet if it's per-vertex or per-triangle normal...
				++normsRead;
			}
			/*** new group ***/
			else if (tokens.front() == "g" || tokens.front() == "o")
			{
				//update new group index
				facesRead = 0;
				//get the group name
				QString groupName = (tokens.size() > 1 && !tokens[1].isEmpty() ? tokens[1] : "default");
				for (int i=2; i<tokens.size(); ++i) //multiple parts?
					groupName.append(QString(" ")+tokens[i]);
				//push previous group descriptor (if none was pushed)
				if (groups.empty() && totalFacesRead > 0)
					groups.push_back(std::pair<unsigned,QString>(0,"default"));
				//push new group descriptor
				if (!groups.empty() && groups.back().first == totalFacesRead)
					groups.back().second = groupName; //simply replace the group name if the previous group was empty!
				else
					groups.push_back(std::pair<unsigned,QString>(totalFacesRead,groupName));
				polyCount = 0; //restart polyline count at 0!
			}
			/*** new face ***/
			else if (tokens.front().startsWith('f'))
			{
				//malformed line?
				if (tokens.size() < 4)
				{
					objWarnings[INVALID_LINE] = true;
					currentLine = stream.readLine();
					continue;
					//error = true;
					//break;
				}

				//read the face elements (singleton, pair or triplet)
				std::vector<facetElement> currentFace;
				{
					for (int i=1; i<tokens.size(); ++i)
					{
						QStringList vertexTokens = tokens[i].split('/');
						if (vertexTokens.size() == 0 || vertexTokens[0].isEmpty())
						{
							objWarnings[INVALID_LINE] = true;
							error = true;
							break;
						}
						else
						{
							//new vertex
							facetElement fe; //(0,0,0) by default
							
							fe.vIndex = vertexTokens[0].toInt();
							if (vertexTokens.size() > 1 && !vertexTokens[1].isEmpty())
								fe.tcIndex = vertexTokens[1].toInt();
							if (vertexTokens.size() > 2 && !vertexTokens[2].isEmpty())
								fe.nIndex = vertexTokens[2].toInt();
						
							currentFace.push_back(fe);
						}
					}
				}

				if (error)
					break;

				if (currentFace.size() < 3)
				{
					ccLog::Warning("[OBJ] Malformed file: polygon on line %1 has less than 3 vertices!",lineCount);
					error = true;
					break;
				}

				//first vertex
				std::vector<facetElement>::iterator A = currentFace.begin();

				//the very first vertex of the group tells us about the whole sequence
				if (facesRead == 0)
				{
					//we have a tex. coord index as second vertex element!
					if (!hasTexCoords && A->tcIndex != 0 && !materialsLoadFailed)
					{
						if (!baseMesh->reservePerTriangleTexCoordIndexes())
						{
							objWarnings[NOT_ENOUGH_MEMORY] = true;
							error = true;
							break;
						}
						for (unsigned int i=0; i<totalFacesRead; ++i)
							baseMesh->addTriangleTexCoordIndexes(-1, -1, -1);

						hasTexCoords = true;
					}

					//we have a normal index as third vertex element!
					if (!normalsPerFacet && A->nIndex != 0)
					{
						//so the normals are 'per-facet'
						if (!baseMesh->reservePerTriangleNormalIndexes())
						{
							objWarnings[NOT_ENOUGH_MEMORY] = true;
							error = true;
							break;
						}
						for (unsigned int i=0; i<totalFacesRead; ++i)
							baseMesh->addTriangleNormalIndexes(-1, -1, -1);
						normalsPerFacet = true;
					}
				}

				//we process all vertices accordingly
				for (std::vector<facetElement>::iterator it = currentFace.begin() ; it!=currentFace.end(); ++it)
				{
					facetElement& vertex = *it;

					//vertex index
					{
						if (!vertex.updatePointIndex(pointsRead))
						{
							objWarnings[INVALID_INDEX] = true;
							error = true;
							break;
						}
						if (vertex.vIndex > maxVertexIndex)
							maxVertexIndex = vertex.vIndex;
					}
					//should we have a tex. coord index as second vertex element?
					if (hasTexCoords && currentMaterialDefined)
					{
						if (!vertex.updateTexCoordIndex(texCoordsRead))
						{
							objWarnings[INVALID_INDEX] = true;
							error = true;
							break;
						}
						if (vertex.tcIndex > maxTexCoordIndex)
							maxTexCoordIndex = vertex.tcIndex;
					}

					//should we have a normal index as third vertex element?
					if (normalsPerFacet)
					{
						if (!vertex.updateNormalIndex(normsRead))
						{
							objWarnings[INVALID_INDEX] = true;
							error = true;
							break;
						}
						if (vertex.nIndex > maxTriNormIndex)
							maxTriNormIndex = vertex.nIndex;
					}
				}

				//don't forget material (common for all vertices)
				if (currentMaterialDefined && !materialsLoadFailed)
				{
					if (!hasMaterial)
					{
						if (!baseMesh->reservePerTriangleMtlIndexes())
						{
							objWarnings[NOT_ENOUGH_MEMORY] = true;
							error = true;
							break;
						}
						for (unsigned int i=0; i<totalFacesRead; ++i)
							baseMesh->addTriangleMtlIndex(-1);

						hasMaterial = true;
					}
				}

				if (error)
					break;

				//Now, let's tesselate the whole polygon
				//FIXME: yeah, we do very ulgy tesselation here!
				std::vector<facetElement>::const_iterator B = A+1;
				std::vector<facetElement>::const_iterator C = B+1;
				for ( ; C != currentFace.end(); ++B,++C)
				{
					//need more space?
					if (baseMesh->size() == baseMesh->capacity())
					{
						if (!baseMesh->reserve(baseMesh->size()+128))
						{
							objWarnings[NOT_ENOUGH_MEMORY] = true;
							error = true;
							break;
						}
					}

					//push new triangle
					baseMesh->addTriangle(A->vIndex, B->vIndex, C->vIndex);
					++facesRead;
					++totalFacesRead;

					if (hasMaterial)
						baseMesh->addTriangleMtlIndex(currentMaterial);

					if (hasTexCoords)
						baseMesh->addTriangleTexCoordIndexes(A->tcIndex, B->tcIndex, C->tcIndex);

					if (normalsPerFacet)
						baseMesh->addTriangleNormalIndexes(A->nIndex, B->nIndex, C->nIndex);
				}
			}
			/*** polyline ***/
			else if (tokens.front().startsWith('l'))
			{
				//malformed line?
				if (tokens.size() < 3)
				{
					objWarnings[INVALID_LINE] = true;
					currentLine = stream.readLine();
					continue;
				}

				//read the face elements (singleton, pair or triplet)
				ccPolyline* polyline = new ccPolyline(vertices);
				if (!polyline->reserve(static_cast<unsigned>(tokens.size()-1)))
				{
					//not enough memory
					objWarnings[NOT_ENOUGH_MEMORY] = true;
					delete polyline;
					polyline = 0;
					currentLine = stream.readLine();
					continue;
				}

				for (int i=1; i<tokens.size(); ++i)
				{
					//get next polyline's vertex index
					QStringList vertexTokens = tokens[i].split('/');
					if (vertexTokens.size() == 0 || vertexTokens[0].isEmpty())
					{
						objWarnings[INVALID_LINE] = true;
						error = true;
						break;
					}
					else
					{
						int index = vertexTokens[0].toInt(); //we ignore normal index (if any!)
						if (!UpdatePointIndex(index,pointsRead))
						{
							objWarnings[INVALID_INDEX] = true;
							error = true;
							break;
						}

						polyline->addPointIndex(index);
					}
				}

				if (error)
				{
					delete polyline;
					polyline = 0;
					break;
				}
			
				polyline->setVisible(true);
				QString name = groups.empty() ? QString("Line") : groups.back().second+QString(".line");
				polyline->setName(QString("%1 %2").arg(name).arg(++polyCount));
				vertices->addChild(polyline);

			}
			/*** material ***/
			else if (tokens.front() == "usemtl") //see 'MTL file' below
			{
				if (materials) //otherwise we have failed to load MTL file!!!
				{
					QString mtlName = currentLine.mid(7).trimmed();
					//DGM: in case there's space characters in the material name, we must read it again from the original line buffer
					//QString mtlName = (tokens.size() > 1 && !tokens[1].isEmpty() ? tokens[1] : "");
					currentMaterial = (!mtlName.isEmpty() ? materials->findMaterialByName(mtlName) : -1);
					currentMaterialDefined = true;
				}
			}
			/*** material file (MTL) ***/
			else if (tokens.front() == "mtllib")
			{
				//malformed line?
				if (tokens.size() < 2 || tokens[1].isEmpty())
				{
					objWarnings[INVALID_LINE] = true;
				}
				else
				{
					//we build the whole MTL filename + path
					//DGM: in case there's space characters in the filename, we must read it again from the original line buffer
					//QString mtlFilename = tokens[1];
					QString mtlFilename = currentLine.mid(7).trimmed();
					ccLog::Print(QString("[OBJ] Material file: ")+mtlFilename);
					QString mtlPath = QFileInfo(filename).canonicalPath();
					//we try to load it
					if (!materials)
					{
						materials = new ccMaterialSet("materials");
						materials->link();
					}

					size_t oldSize = materials->size();
					QStringList errors;
					if (ccMaterialSet::ParseMTL(mtlPath,mtlFilename,*materials,errors))
					{
						ccLog::Print("[OBJ] %i materials loaded",materials->size()-oldSize);
						materialsLoadFailed = false;
					}
					else
					{
						ccLog::Error(QString("[OBJ] Failed to load material file! (should be in '%1')").arg(mtlPath+'/'+QString(mtlFilename)));
						materialsLoadFailed = true;
					}

					if (!errors.empty())
					{
						for (int i=0; i<errors.size(); ++i)
							ccLog::Warning(QString("[OBJ::Load::MTL parser] ")+errors[i]);
					}
					if (materials->empty())
					{
						materials->release();
						materials=0;
						materialsLoadFailed = true;
					}
				}
			}
			///*** shading group ***/
			//else if (tokens.front() == "s")
			//{
			//	//ignored!
			//}

			if (error)
				break;

			currentLine = stream.readLine();
		}
	}
	catch (const std::bad_alloc&)
	{
		//not enough memory
		objWarnings[NOT_ENOUGH_MEMORY] = true;
		error = true;
	}

	file.close();

	//1st check
	if (!error && pointsRead == 0)
	{
		//of course if there's no vertex, that's the end of the story ...
		ccLog::Warning("[OBJ] Malformed file: no vertex in file!");
		error = true;
	}

	if (!error)
	{
		ccLog::Print("[OBJ] %i points, %u faces",pointsRead,totalFacesRead);
		if (texCoordsRead > 0 || normsRead > 0)
			ccLog::Print("[OBJ] %i tex. coords, %i normals",texCoordsRead,normsRead);

		//do some cleaning
		vertices->shrinkToFit();
		if (normals)
			normals->shrinkToFit();
		if (texCoords)
			texCoords->shrinkToFit();
		if (baseMesh->size() == 0)
		{
			delete baseMesh;
			baseMesh = 0;
		}
		else
		{
			baseMesh->shrinkToFit();
		}

		if (	maxVertexIndex >= pointsRead
			||	maxTexCoordIndex >= texCoordsRead
			||	maxTriNormIndex >= normsRead)
		{
			//hum, we've got a problem here
			ccLog::Warning("[OBJ] Malformed file: indexes go higher than the number of elements! (v=%i/tc=%i/n=%i)",maxVertexIndex,maxTexCoordIndex,maxTriNormIndex);
			if (maxVertexIndex >= pointsRead)
			{
				error = true;
			}
			else
			{
				objWarnings[INVALID_INDEX] = true;
				if (maxTexCoordIndex >= texCoordsRead)
				{
					texCoords->release();
					texCoords = 0;
					materials->release();
					materials = 0;
				}
				if (maxTriNormIndex >= normsRead)
				{
					normals->release();
					normals = 0;
				}
			}
		}
		
		if (!error && baseMesh)
		{
			if (normals && normalsPerFacet)
			{
				baseMesh->setTriNormsTable(normals);
				baseMesh->showTriNorms(true);
			}
			if (materials)
			{
				baseMesh->setMaterialSet(materials);
				baseMesh->showMaterials(true);
			}
			if (texCoords)
			{
				if (materials)
				{
					baseMesh->setTexCoordinatesTable(texCoords);
				}
				else
				{
					ccLog::Warning("[OBJ] Texture coordinates were defined but no material could be loaded!");
				}
			}

			//normals: if the obj file doesn't provide any, should we compute them?
			if (!normals)
			{
				//DGM: normals can be per-vertex or per-triangle so it's better to let the user do it himself later
				//Moreover it's not always good idea if the user doesn't want normals (especially in ccViewer!)
				//if (!materials && !baseMesh->hasColors()) //yes if no material is available!
				//{
				//	ccLog::Print("[OBJ] Mesh has no normal! We will compute them automatically");
				//	baseMesh->computeNormals();
				//	baseMesh->showNormals(true);
				//}
				//else
				{
					ccLog::Warning("[OBJ] Mesh has no normal! You can manually compute them (select it then call \"Edit > Normals > Compute\")");
				}
			}

			//create sub-meshes if necessary
			ccLog::Print("[OBJ] 1 mesh loaded - %i group(s)", groups.size());
			if (groups.size() > 1)
			{
				for (size_t i=0; i<groups.size(); ++i)
				{
					const QString& groupName = groups[i].second;
					unsigned startIndex = groups[i].first;
					unsigned endIndex = (i+1 == groups.size() ? baseMesh->size() : groups[i+1].first);

					if (startIndex == endIndex)
					{
						continue;
					}

					ccSubMesh* subTri = new ccSubMesh(baseMesh);
					if (subTri->reserve(endIndex-startIndex))
					{
						subTri->addTriangleIndex(startIndex,endIndex);
						subTri->setName(groupName);
						subTri->showMaterials(baseMesh->materialsShown());
						subTri->showNormals(baseMesh->normalsShown());
						subTri->showTriNorms(baseMesh->triNormsShown());
						//subTri->showColors(baseMesh->colorsShown());
						//subTri->showWired(baseMesh->isShownAsWire());
						baseMesh->addChild(subTri);
					}
					else
					{
						delete subTri;
						subTri = 0;
						objWarnings[NOT_ENOUGH_MEMORY] = true;
					}
				}
				baseMesh->setVisible(false);
				vertices->setLocked(true);
			}

			baseMesh->addChild(vertices);
			//DGM: we can't deactive the vertices if it has children! (such as polyline)
			if (vertices->getChildrenNumber() != 0)
				vertices->setVisible(false);
			else
				vertices->setEnabled(false);

			container.addChild(baseMesh);
		}

		if (!baseMesh && vertices->size() != 0)
		{
			//no (valid) mesh!
			container.addChild(vertices);
			//we hide the vertices if the entity has children (probably polylines!)
			if (vertices->getChildrenNumber() != 0)
			{
				vertices->setVisible(false);
			}
		}

		//special case: normals held by cloud!
		if (normals && !normalsPerFacet)
		{
			if (normsRead == pointsRead) //must be 'per-vertex' normals
			{
				vertices->setNormsTable(normals);
				if (baseMesh)
					baseMesh->showNormals(true);
			}
			else
			{
				ccLog::Warning("File contains normals which seem to be neither per-vertex nor per-face!!! We had to ignore them...");
			}
		}
	}

	if (error)
	{
		if (baseMesh)
			delete baseMesh;
		if (vertices)
			delete vertices;
	}

	//release shared structures
	if (normals)
	{
		normals->release();
		normals = 0;
	}
	if (texCoords)
	{
		texCoords->release();
		texCoords = 0;
	}
	if (materials)
	{
		materials->release();
		materials = 0;
	}

	pDlg.close();

	//potential warnings
	if (objWarnings[INVALID_NORMALS])
		ccLog::Warning("[OBJ] Some normals in file were invalid. You should re-compute them (select entity, then \"Edit > Normals > Compute\")");
	if (objWarnings[INVALID_INDEX])
		ccLog::Warning("[OBJ] File is malformed! Check indexes...");
	if (objWarnings[NOT_ENOUGH_MEMORY])
		ccLog::Warning("[OBJ] Not enough memory!");
	if (objWarnings[INVALID_LINE])
		ccLog::Warning("[OBJ] File is malformed! Missing data.");

	if (error)
	{
		if (objWarnings[NOT_ENOUGH_MEMORY])
			return CC_FERR_NOT_ENOUGH_MEMORY;
		else if (objWarnings[CANCELLED_BY_USER])
			return CC_FERR_CANCELED_BY_USER;
		else 
			return CC_FERR_MALFORMED_FILE;
	}
	else
	{
		return CC_FERR_NO_ERROR;
	}
}
コード例 #19
0
ファイル: VTKFilter.cpp プロジェクト: abdullah38rcc/trunk
CC_FILE_ERROR VTKFilter::loadFile(QString filename, ccHObject& container, LoadParameters& parameters)
{
	//open ASCII file for reading
	QFile file(filename);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
		return CC_FERR_READING;

	QTextStream inFile(&file);

	//read header
	QString nextline = inFile.readLine();
	if (!nextline.startsWith("# vtk"))
		return CC_FERR_MALFORMED_FILE;

	//comment
	nextline = inFile.readLine();
	ccLog::Print(QString("[VTK] ")+nextline);

	ccMesh* mesh = 0;
	ccPointCloud* vertices = 0;
	
	std::vector<int> indexes; //global so as to avoid unnecessary mem. allocations
	QString lastSfName;
	bool acceptLookupTables = true;
	unsigned lastDataSize = 0;

	QString fileType = inFile.readLine().toUpper();
	if (fileType.startsWith("BINARY"))
	{
		//binary not supported yet!
		ccLog::Error("VTK binary format not supported yet!");
		return CC_FERR_WRONG_FILE_TYPE;
	}
	else if (fileType.startsWith("ASCII"))
	{
		//allow blank lines
		QString dataType;
		if (!GetNextNonEmptyLine(inFile,dataType))
			return CC_FERR_MALFORMED_FILE;
		if (!dataType.startsWith("DATASET"))
			return CC_FERR_MALFORMED_FILE;
		dataType.remove(0,8);
		if (dataType.startsWith("POLYDATA"))
		{
			vertices = new ccPointCloud("vertices");
			mesh = new ccMesh(vertices);
		}
		else if (dataType.startsWith("UNSTRUCTURED_GRID"))
		{
			vertices = new ccPointCloud("unnamed - VTK unstructured grid");
		}
		else
		{
			ccLog::Error(QString("VTK entity '%1' is not supported!").arg(dataType));
			return CC_FERR_WRONG_FILE_TYPE;
		}
	}

	//loop on keywords/data
	CC_FILE_ERROR error = CC_FERR_NO_ERROR;
	CCVector3d Pshift(0,0,0);
	bool skipReadLine = false;
	while (error == CC_FERR_NO_ERROR)
	{
		if (!skipReadLine && !GetNextNonEmptyLine(inFile,nextline))
			break; //end of file
		skipReadLine = false;

		assert(!nextline.isEmpty());

		if (nextline.startsWith("POINTS"))
		{
			QStringList parts = nextline.split(" ",QString::SkipEmptyParts);
			if (parts.size() != 3)
			{
				error=CC_FERR_MALFORMED_FILE;
				break;
			}

			bool ok = false;
			unsigned ptsCount = parts[1].toInt(&ok);
			if (!ok)
			{
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			//QString dataFormat = parts[3].toUpper();
			//char buffer[8];
			//unsigned char datSize = 4;
			//if (dataFormat == "DOUBLE")
			//{
			//	datSize = 8;
			//}
			//else if (dataFormat != "FLOAT")
			//{
			//	ccLog::Error(QString("Non floating point data (%1) is not supported!").arg(dataFormat));
			//	error = CC_FERR_WRONG_FILE_TYPE;
			//	break;
			//}

			if (!vertices->reserve(ptsCount))
			{
				error = CC_FERR_NOT_ENOUGH_MEMORY;
				break;
			}

			//warning: multiple points can be stored on a single line!
			unsigned iPt = 0;
			CCVector3d Pd(0,0,0);
			unsigned coordIndex = 0;
			while (iPt < ptsCount)
			{
				nextline = inFile.readLine();
				parts = nextline.split(" ",QString::SkipEmptyParts);

				for (int i=0; i<parts.size(); ++i)
				{
					Pd.u[coordIndex] = parts[i].toDouble(&ok);
					if (!ok)
					{
						ccLog::Warning("[VTK] Element #%1 of POINTS data is corrupted!",iPt);
						error = CC_FERR_MALFORMED_FILE;
						iPt = ptsCount;
						break;
					}

					if (coordIndex == 2)
					{
						//first point: check for 'big' coordinates
						if (iPt == 0)
						{
							if (HandleGlobalShift(Pd,Pshift,parameters))
							{
								vertices->setGlobalShift(Pshift);
								ccLog::Warning("[VTKFilter::loadFile] Cloud has been recentered! Translation: (%.2f,%.2f,%.2f)",Pshift.x,Pshift.y,Pshift.z);
							}
						}

						CCVector3 P = CCVector3::fromArray((Pd + Pshift).u);
						vertices->addPoint(P);

						coordIndex = 0;
						++iPt;
					}
					else
					{
						++coordIndex;
					}
				}
			}
		//end POINTS
		}
		else if (nextline.startsWith("POLYGONS") || nextline.startsWith("TRIANGLE_STRIPS"))
		{
			QStringList parts = nextline.split(" ",QString::SkipEmptyParts);
			if (parts.size() != 3)
			{
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			//current type name (i.e. POLYGONS or TRIANGLE_STRIPS)
			QString typeName = parts[0];
			bool isPolygon = (typeName == "POLYGONS");

			bool ok = false;
			unsigned elemCount = parts[1].toUInt(&ok);
			if (!ok)
			{
				error = CC_FERR_MALFORMED_FILE;
				break;
			}
			
//			unsigned totalElements = parts[2].toUInt(&ok);
			if (!ok)
			{
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			assert(mesh);
			if (!mesh)
			{
				ccLog::Warning(QString("[VTK] We found %1 data while file is not composed of POLYDATA!").arg(typeName));
				mesh = new ccMesh(vertices); //however, we can still try to load it?
			}

			for (unsigned i=0; i<elemCount; ++i)
			{
				nextline = inFile.readLine();
				parts = nextline.split(" ",QString::SkipEmptyParts);
				if (parts.empty()) 
				{
					error = CC_FERR_MALFORMED_FILE;
					break;
				}

				unsigned vertCount = parts[0].toUInt(&ok);
				if (!ok || static_cast<int>(vertCount) >= parts.size())
				{
					error = CC_FERR_MALFORMED_FILE;
					break;
				}
				else if (vertCount < 3)
				{
					ccLog::Warning(QString("[VTK] Element #%1 of %2 data is corrupted! (not enough indexes)").arg(i).arg(typeName));
				}

				if (isPolygon && (vertCount != 3 && vertCount != 4)) //quads are easy to handle as well!
				{
					ccLog::Warning(QString("[VTK] POLYGON element #%1 has an unhandled size (> 4 vertices)").arg(i));
					continue;
				}

				//reserve mem to. store indexes
				if (indexes.size() < vertCount)
				{
					try
					{
						indexes.resize(vertCount);
					}
					catch (const std::bad_alloc&)
					{
						error = CC_FERR_NOT_ENOUGH_MEMORY;
						break;
					}
				}
				//decode indexes
				for (unsigned j=0; j<vertCount; ++j)
				{
					indexes[j] = parts[j+1].toUInt(&ok);
					if (!ok)
					{
						ccLog::Warning(QString("[VTK] Element #%1 of %2 data is corrupted! (invalid index value)").arg(i).arg(typeName));
						error = CC_FERR_MALFORMED_FILE;
						break;
					}
				}

				//add the triangles
				{
					assert(vertCount > 2);
					unsigned triCount = vertCount-2;
					if (mesh->size() + triCount > mesh->maxSize())
					{
						if (!mesh->reserve(mesh->size()+triCount+256)) //take some advance to avoid too many allocations
						{
							error = CC_FERR_NOT_ENOUGH_MEMORY;
							break;
						}
					}

					if (isPolygon)
					{
						//triangle or quad
						mesh->addTriangle(indexes[0],indexes[1],indexes[2]);
						if (vertCount == 4)
							mesh->addTriangle(indexes[0],indexes[2],indexes[3]);
					}
					else
					{
						//triangle strip
						for (unsigned j=0; j<triCount; ++j)
							mesh->addTriangle(indexes[j],indexes[j+1],indexes[j+2]);
					}
				}
			}
			
			if (mesh->size() != 0 && mesh->size() < mesh->maxSize())
			{
				mesh->resize(mesh->size());
			}
		//end POLYGONS or TRIANGLE_STRIPS
		}
		else if (nextline.startsWith("NORMALS"))
		{
			if (lastDataSize == 0)
				lastDataSize = vertices->size();
			if (lastDataSize == 0)
			{
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			bool loadNormals = false;
			if (lastDataSize == vertices->size())
			{
				if (!vertices->reserveTheNormsTable())
					ccLog::Warning("[VTK] Not enough memory to load normals!");
				else
					loadNormals = true;
			}

			//warning: multiple normals can be stored on a single line!
			unsigned iNorm = 0;
			CCVector3 N;
			unsigned coordIndex = 0;
			while (iNorm < lastDataSize)
			{
				nextline = inFile.readLine();
				QStringList parts = nextline.split(" ",QString::SkipEmptyParts);

				for (int i=0; i<parts.size(); ++i)
				{
					bool ok;
					N.u[coordIndex] = static_cast<PointCoordinateType>(parts[i].toDouble(&ok));
					if (!ok)
					{
						ccLog::Warning("[VTK] Element #%1 of NORMALS data is corrupted!",iNorm);
						error = CC_FERR_MALFORMED_FILE;
						iNorm = lastDataSize;
						break;
					}

					if (coordIndex == 2)
					{
						if (loadNormals)
							vertices->addNorm(N);
						coordIndex = 0;
						++iNorm;
					}
					else
					{
						++coordIndex;
					}
				}
			}
			lastDataSize = 0; //lastDataSize is consumed

		//end NORMALS
		}
		else if (nextline.startsWith("COLOR_SCALARS"))
		{
			if (lastDataSize == 0)
				lastDataSize = vertices->size();
			if (lastDataSize == 0)
			{
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			bool loadRGBColors = vertices->reserveTheRGBTable();
			if (!loadRGBColors)
				ccLog::Warning("[VTK] Not enough memory to load RGB colors!");

			//warning: multiple colors can be stored on a single line!
			unsigned iCol = 0;
			colorType rgb[3];
			unsigned coordIndex = 0;
			while (iCol < lastDataSize)
			{
				nextline = inFile.readLine();
				QStringList parts = nextline.split(" ",QString::SkipEmptyParts);

				for (int i=0; i<parts.size(); ++i)
				{
					bool ok;
					rgb[coordIndex] = static_cast<colorType>(parts[i].toDouble(&ok) * ccColor::MAX);
					if (!ok)
					{
						ccLog::Warning("[VTK] Element #%1 of COLOR_SCALARS data is corrupted!",iCol);
						error = CC_FERR_MALFORMED_FILE;
						iCol = lastDataSize;
						break;
					}

					if (coordIndex == 2)
					{
						if (loadRGBColors)
							vertices->addRGBColor(rgb);
						coordIndex = 0;
						++iCol;
					}
					else
					{
						++coordIndex;
					}
				}
			}
			lastDataSize = 0; //lastDataSize is consumed

		//end COLOR_SCALARS
		}
		else if (nextline.startsWith("SCALARS"))
		{
			QStringList parts = nextline.split(" ",QString::SkipEmptyParts);
			lastSfName = "ScalarField";
			if (parts.size() > 1)
				lastSfName = parts[1].replace("_"," ");

			//SF already exists?
			if (vertices->getScalarFieldIndexByName(qPrintable(lastSfName)) >= 0)
				lastSfName += QString(" (%1)").arg(vertices->getNumberOfScalarFields());
			//end of SCALARS
		}
		else if (nextline.startsWith("LOOKUP_TABLE") || nextline.startsWith("VECTORS"))
		{
			bool expected = (lastDataSize != 0);
			assert(!acceptLookupTables || expected); //i.e. lastDataSize shouldn't be 0 for 'accepted' lookup tables

			QStringList parts = nextline.split(" ",QString::SkipEmptyParts);
			QString itemName = parts[0];
			if (parts.size() > 2)
			{
				bool ok = false;
				int valCount = parts[2].toUInt(&ok);
				if (ok)
					lastDataSize = valCount;
			}
			else if (!expected)
			{
				ccLog::Warning(QString("[VTK] field %1 has no size?!").arg(itemName));
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			bool createSF = (vertices->size() == lastDataSize && vertices->size() != 0);
			if (acceptLookupTables && !createSF)
			{
				ccLog::Warning(QString("[VTK] field %1 has not the right number of points (will be ignored)").arg(itemName));
			}
			createSF &= (acceptLookupTables || expected);
			if (createSF && lastSfName.isNull())
			{
				ccLog::Warning(QString("[VTK] field %1 has no name (will be ignored)").arg(itemName));
				createSF = false;
			}
			else if (!expected)
			{
				ccLog::Warning(QString("[VTK] field %1 was not expected (will be ignored)").arg(itemName));
			}

			//create scalar field?
			ccScalarField* sf = 0;
			if (createSF)
			{
				sf = new ccScalarField(qPrintable(lastSfName));
				if (!sf->reserve(lastDataSize))
				{
					ccLog::Warning(QString("[VTK] Not enough memory to load scalar field' %1' (will be ignored)").arg(lastSfName));
					sf->release();
					sf = 0;
				}
			}
			
			lastSfName.clear(); //name is "consumed"

			//warning: multiple colors can be stored on a single line!
			unsigned iScal = 0;
			while (iScal < lastDataSize)
			{
				nextline = inFile.readLine();
				QStringList parts = nextline.split(" ",QString::SkipEmptyParts);

				if (expected)
				{
					for (int i=0; i<parts.size(); ++i)
					{
						bool ok;
						ScalarType d = static_cast<ScalarType>(parts[i].toDouble(&ok));
						if (!ok)
						{
							ccLog::Warning("[VTK] Element #%1 of LOOKUP_TABLE/VECTORS data is corrupted!",iScal);
							error = CC_FERR_MALFORMED_FILE;
							if (sf)
							{
								sf->release();
								sf = 0;
							}
							iScal = lastDataSize;
							break;
						}

						if (sf)
							sf->addElement(d);
						++iScal;
					}
				}
				else
				{
					//hard to guess the right format, but an unexpected field seem to always be
					//organized as 'one element per line'
					++iScal;
				}
			}
			lastDataSize = 0; //lastDataSize is "consumed"
			acceptLookupTables = false;

			if (sf)
			{
				sf->computeMinAndMax();
				int newSFIndex = vertices->addScalarField(sf);
				if (newSFIndex == 0)
					vertices->setCurrentDisplayedScalarField(newSFIndex);
				vertices->showSF(true);
			}
		//end of SCALARS
		}
		else if (nextline.startsWith("POINT_DATA"))
		{
			//check that the number of 'point_data' match the number of points
			QStringList parts = nextline.split(" ",QString::SkipEmptyParts);
			acceptLookupTables = false;
			if (parts.size() > 1) 
			{
				bool ok;
				lastDataSize = parts[1].toUInt(&ok);
				acceptLookupTables = ok && vertices;
			}
		}
		else if (nextline.startsWith("FIELD"))
		{
			QStringList parts = nextline.split(" ",QString::SkipEmptyParts);
			if (parts.size() < 2) 
			{
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			bool ok;
			unsigned elements = parts[2].toUInt(&ok);
			if (!ok)
			{
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			elements *= 2;	//we don't know how to handle those properly but at least
							//we know that for FIELD elements, there's 2 lines per element...

			for (unsigned i=0; i<elements; ++i)
			{
				inFile.readLine(); //ignore
			}
		}
		else //unhandled property (CELLS, CELL_TYPES, etc.)
		{
			QStringList parts = nextline.split(" ",QString::SkipEmptyParts);
			if (parts.size() < 2) 
			{
				ccLog::Warning(QString("[VTK] Unhandled element: %1").arg(parts[0]));
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			bool ok;
			unsigned elements = parts[1].toUInt(&ok);
			if (!ok)
			{
				error = CC_FERR_MALFORMED_FILE;
				break;
			}

			if (nextline.startsWith("CELL_DATA"))
			{
				//read next line (in case we actually know how to read it!
				if (!GetNextNonEmptyLine(inFile,nextline))
				{
					error = CC_FERR_MALFORMED_FILE;
					break;
				}
				skipReadLine = true;

				if (	nextline.startsWith("SCALARS")
					||	nextline.startsWith("NORMALS")
					||	nextline.startsWith("COLOR_SCALARS"))
				{
					lastDataSize = elements;
					acceptLookupTables = false; //this property is for triangles!
					continue;
				}
			}
			//we'll try to blindly skip the elements...
			for (unsigned i=0; i<elements; ++i)
			{
				inFile.readLine(); //ignore
			}
		//end unhandled property
		}

		if (error != CC_FERR_NO_ERROR)
			break;
	}

	file.close();

	if (vertices && vertices->size() == 0)
	{
		delete vertices;
		vertices = 0;
		if (error == CC_FERR_NO_ERROR)
			error = CC_FERR_NO_LOAD;
	}

	if (mesh && (mesh->size() == 0 || vertices == 0))
	{
		delete mesh;
		mesh = 0;
		if (error == CC_FERR_NO_ERROR)
			error = CC_FERR_NO_LOAD;
	}

	if (mesh)
	{
		container.addChild(mesh);
		mesh->setVisible(true);

		mesh->addChild(vertices);
		vertices->setEnabled(false);
		vertices->setName("Vertices");
		vertices->setLocked(true); //DGM: no need to lock it as it is only used by one mesh!

		//DGM: normals can be per-vertex or per-triangle so it's better to let the user do it himself later
		//Moreover it's not always good idea if the user doesn't want normals (especially in ccViewer!)
		if (!mesh->hasNormals())
		{
			//	mesh->computeNormals();
			ccLog::Warning("[VTK] Mesh has no normal! You can manually compute them (select it then call \"Edit > Normals > Compute\")");
		}
		mesh->showNormals(mesh->hasNormals());
		if (vertices->hasScalarFields())
		{
			vertices->setCurrentDisplayedScalarField(0);
			mesh->showSF(true);
		}
		if (vertices->hasColors())
			mesh->showColors(true);
	}
	else if (vertices)
	{
		container.addChild(vertices);
		vertices->setVisible(true);
		if (vertices->hasNormals())
			vertices->showNormals(true);
		if (vertices->hasScalarFields())
		{
			vertices->setCurrentDisplayedScalarField(0);
			vertices->showSF(true);
		}
		if (vertices->hasColors())
			vertices->showColors(true);
	}

	return error;
}
コード例 #20
0
void Ship::output(){
	ofstream file;
	file.open("Report.txt");
	file << "[table]" << endl;

	cout << fixed << setprecision(2) << "Length: \t\t\t\t" << v.Lpp << " m" << endl;
	file << fixed << setprecision(2) << "[tr][td]Length: \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[/td][td]" << v.Lpp << " m[/td][/tr]" << endl;
	cout << "Beam: \t\t\t\t\t" << v.B << " m" << endl;
	file << "[tr][td]Beam: [/td][td]" << v.B << " m[/td][/tr]" << endl;
	cout << "Draft: \t\t\t\t\t" << v.D << " m" << endl;
	file << "[tr][td]Draft: [/td][td]" << v.D << " m[/td][/tr]" << endl;
	cout << "Freeboard: \t\t\t\t" << v.fB << " m" << endl;
	file << "[tr][td]Freeboard: [/td][td]" << v.fB << " m[/td][/tr]" << endl;
	cout << setprecision(3) << "Block Coefficient: \t\t\t" << Cb() << endl;
	file << setprecision(3) << "[tr][td]Block Coefficient: [/td][td]" << Cb() << "[/td][/tr]" << endl;
	cout << setprecision(0) << "Displacement: \t\t\t\t" << Vol() << " t" << endl;
	file << setprecision(0) << "[tr][td]Displacement: [/td][td]" << Vol() << " t[/td][/tr]" << endl;
	cout << "Lightship: \t\t\t\t" << Wh() + Wwo() + Wm() + We() + Wspus() + Bunker() << " t" << endl;
	file << "[tr][td]Lightship: [/td][td]" << Lightship() << " t[/td][/tr]" << endl;

	cout << setprecision(1) << "\nMax Speed: \t\t\t\t" << v.Vk << " kn" << endl;
	file << setprecision(1) << "\n[tr][td]Max Speed: [/td][td]" << v.Vk << " kn[/td][/tr]" << endl;
	cout << "Cruise Speed: \t\t\t\t" << v.Vc << " kn / " << v.Range << " nm" << endl;
	file << "[tr][td]Cruise Speed: [/td][td]" << v.Vc << " kn / " << v.Range << " nm[/td][/tr]" << endl;

	cout << "Engine: \t\t\t\t";
	file << "[tr][td]Engine: [/td][td]";
	switch(e.Gear){
		case Direct:
            cout << "Direct ";
            file << "Direct ";
            break;
		case Geared:
		    cout << "Geared ";
		    file << "Geared ";
		    break;
		case Turbo_Electric:
		    cout << "Turbo-Electric ";
		    file << "Turbo-Electric ";
            break;
		default:
            cout << "Unknown";
            file << "Unknown";
	}
	switch(e.Eng){
		case Diesel2stk:
		    cout << "Two Stroke Diesel" << endl;
		    file << "Two Stroke Diesel";
		    break;
		case Diesel4stk:
		    cout << "Four Stroke Diesel" << endl;
		    file << "Four Stroke Diesel" << endl;
		    break;
		case QuadExp:
		    cout << "Quadruple Expansion Reciprocating Engine" << endl;
		    file << "Quadruple Expansion Reciprocating Engine";
		    break;
		case TripExp:
		    cout << "Triple Expansion Reciprocating Engine" << endl;
		    file << "Triple Expansion Reciprocating Engine";
		    break;
		case SimExp:
		    cout << "Simple Reciprocating Engine" << endl;
		    file << "Simple Reciprocating Engine";
		    break;
		case SteamTur:
		    cout << "Steam Turbine" << endl;
		    file << "Steam Turbine";
		    break;
		default:
            cout << endl;
	}
	file << "[/td][/tr]" << endl;

	cout << setprecision(0) << "Power Delivered: \t\t\t" << Pd(v.Vk) << " hp" << endl;
	file << setprecision(0) << "[tr][td]Power Delivered: [/td][td]" << Pd(v.Vk) << " hp[/td][/tr]" << endl;
	cout << setprecision(2) << "Total Efficiency: \t\t\t" << NUt()*100 << "%" << endl;
	file << setprecision(2) << "[tr][td]Total Efficiency: [/td][td]" << NUt()*100 << "%[/td][/tr]" << endl;
	cout << setprecision(3) << "Froude Number: \t\t\t\t" << Fn() << endl;
	file << setprecision(3) << "[tr][td]Froude Number: [/td][td]" << Fn()  << "[/td][/tr]" << endl;
	cout << setprecision(0) << "Bunker Size: \t\t\t\t" << Bunker() << " t" << endl;
	file << setprecision(0) << "[tr][td]Bunker Size: [/td][td]" << Bunker() << " t[/td][/tr]" << endl;
	cout << "Service Allowance: \t\t\t" << e.SA << "%" << endl;
	file << "[tr][td]Service Allowance: [/td][td]" << e.SA << "%[/td][/tr]" << endl;

	cout << setprecision(2);
	file << setprecision(2);
	cout << "Length of Superstructure: \t\t" << v.Lspus << " m" << endl;
	file << "[tr][td]Length of Superstructure: [/td][td]" << v.Lspus << " m[/td][/tr]" << endl;

	cout << "Aftbody Shape: \t\t\t\t";
	file << "[tr][td]Aftbody Shape: [/td][td]";
	switch(e.Faa){
		case V:
		    cout << "V" << endl;
		    file << "V";
		    break;
		case U:
		    cout << "U" << endl;
		    file << "U";
		    break;
		case N:
		    cout << "N" << endl;
		    file << "N";
		    break;
		default:
		    cout << "N" << endl;
		    file << "N";
	}
	file << "[/td][/tr]";

	cout << "\nLongitudinal Center of Buoyancy: \t" << lcb() << "%" << endl;
	file << "\n[tr][td]Longitudinal Center of Buoyancy: [/td][td]" << lcb() << "% / " << lcb()*v.Lpp << " m from midpoint[/td][/tr]" << endl;
	cout << "Longitudinal Center of Gravity: \t" << lcg() << "%" << endl;
	file << "[tr][td]Longitudinal Center of Gravity: [/td][td]" << lcg() << "% / " << lcg()*v.Lpp << " m from midpoint[/td][/tr]" << endl;

	cout << "Vertical Center of Gravity: \t\t" << KGh() << " m" << endl;
	file << "[tr][td]Vertical Center of Gravity: [/td][td]" << KGh() << " m[/td][/tr]" << endl;
	cout << "Metacentric Height: \t\t\t" << GM() << " m" << endl;
	file << "[tr][td]Metacentric Height: [/td][td]" << GM() << " m[/td][/tr]" << endl;
	cout << "Roll Period: \t\t\t\t" << TR() << " s" << endl;
	file << "[tr][td]Roll Period: [/td][td]" << TR() << " s[/td][/tr]" << endl;

	cout << "\nBow Entrance Angle: \t\t\t" << iE() << " deg" << endl;
	file << "\n[tr][td]Bow Entrance Angle: [/td][td]" << iE() << " deg[/td][/tr]" << endl;
	cout << "Length of Engine Room: \t\t\t" << Lcm() << " m" << endl;
	file << "[tr][td]Length of Engine Room: [/td][td]" << Lcm() << " m[/td][/tr]" << endl;

	cout << setprecision(0) << "\nMain Belt: \t\t\t\t" << arm.mb_Ttop << " / " << arm.mb_Tbot << " mm at " << arm.b_deg << " degrees, " << arm.b_L << " m long with " << arm.b_H << " m above and " << arm.b_Db << " m below water" << endl;
	file << setprecision(0) << "\n[tr][td]Main Belt: [/td][td]" << arm.mb_Ttop << " / " << arm.mb_Tbot << " mm, " << arm.b_L << " m long with " << arm.b_H << " m above and " << arm.b_Db << " m below water[/td][/tr]" << endl;

	cout << "End Belt: \t\t\t\t" << arm.eb_Ttop << " / " << arm.eb_Tbot << " mm" << endl;
	file << "[tr][td]End Belt: [/td][td]" << arm.eb_Ttop << " / " << arm.eb_Tbot << " mm[/td][/tr]" << endl;

	cout << "Upper Belt: \t\t\t\t" << arm.ub_Ttop << " / " << arm.ub_Tbot << " mm, " << arm.b_uL << " m long" << endl;
	file << "[tr][td]Upper Belt: [/td][td]" << arm.ub_Ttop << " / " << arm.ub_Tbot << " mm, " << arm.b_uL << " m long[/td][/tr]" << endl;

	cout << "Main Deck: \t\t\t\t" << arm.md_T << " mm covering " << arm.md_P << "% / " << arm.md_P * v.Lpp << " m of deck" << endl;
	file << "[tr][td]Main Deck: [/td][td]" << arm.md_T << " m covering " << arm.md_P << "% / " << arm.md_P * v.Lpp << " m of deck[/td][/tr]" << endl;
	cout << "Weather Deck: \t\t\t\t" << arm.wd_T << " mm covering " << arm.wd_P << "% / " << arm.wd_P * v.Lpp << " m of deck" << endl;
	file << "[tr][td]Weather Deck: [/td][td]" << arm.wd_T << " m covering " << arm.wd_P << "% / " << arm.wd_P * v.Lpp << " m of deck[/td][/tr]" << endl;
	cout << "Splinter Deck: \t\t\t\t" << arm.sd_T << " mm covering " << arm.sd_P << "% / " << arm.sd_P * v.Lpp << " m of deck" << endl;
	file << "[tr][td]Splinter Deck: [/td][td]" << arm.sd_T << " m covering " << arm.sd_P << "% / " << arm.sd_P * v.Lpp << " m of deck[/td][/tr]" << endl;
	cout << "Ends Deck: \t\t\t\t" << arm.ed_T << " mm" << endl;
	file << "[tr][td]Ends Deck: [/td][td]" << arm.ed_T << " mm[/td][/tr]" << endl;

	cout << "Bulkhead: \t\t\t\t" << arm.blk_T << " mm in " << arm.blk_Lct << "x" << arm.blk_D << " m layers, " << arm.blk_L << " m long, " << arm.blk_H << " m tall" << endl;
	file << "[tr][td]Bulkhead: [/td][td]" << arm.blk_T << " mm in " << arm.blk_Lct << "x" << arm.blk_D << " m layers, " << arm.blk_L << " m long, " << arm.blk_H << " m tall[/td][/tr]" << endl;

	file << "[/table]" << endl;

    file.close();
}
コード例 #21
0
ファイル: OFFFilter.cpp プロジェクト: 3660628/trunk
CC_FILE_ERROR OFFFilter::loadFile(QString filename, ccHObject& container, LoadParameters& parameters)
{
	//try to open file
	QFile fp(filename);
	if (!fp.open(QIODevice::ReadOnly | QIODevice::Text))
		return CC_FERR_READING;

	QTextStream stream(&fp);

	QString currentLine = stream.readLine();
	if (!currentLine.toUpper().startsWith("OFF"))
		return CC_FERR_MALFORMED_FILE;

	//check if the number of vertices/faces/etc. are on the first line (yes it happens :( )
	QStringList tokens = currentLine.split(QRegExp("\\s+"),QString::SkipEmptyParts);
	if (tokens.size() == 4)
	{
		tokens.removeAt(0);
	}
	else
	{
		currentLine = GetNextLine(stream);

		//end of file already?!
		if (currentLine.isNull())
			return CC_FERR_MALFORMED_FILE;

		//read the number of vertices/faces
		tokens = currentLine.split(QRegExp("\\s+"),QString::SkipEmptyParts);
		if (tokens.size() < 2/*3*/) //should be 3 but we only use the 2 firsts...
			return CC_FERR_MALFORMED_FILE;
	}

	bool ok = false;
	unsigned vertCount = tokens[0].toUInt(&ok);
	if (!ok)
		return CC_FERR_MALFORMED_FILE;
	unsigned triCount = tokens[1].toUInt(&ok);
	if (!ok)
		return CC_FERR_MALFORMED_FILE;

	//create cloud and reserve some memory
	ccPointCloud* vertices = new ccPointCloud("vertices");
	if (!vertices->reserve(vertCount))
	{
		delete vertices;
		return CC_FERR_NOT_ENOUGH_MEMORY;
	}

	//read vertices
	{
		CCVector3d Pshift(0,0,0);
		for (unsigned i=0; i<vertCount; ++i)
		{
			currentLine = GetNextLine(stream);
			tokens = currentLine.split(QRegExp("\\s+"),QString::SkipEmptyParts);
			if (tokens.size() < 3)
			{
				delete vertices;
				return CC_FERR_MALFORMED_FILE;
			}

			//read vertex
			CCVector3d Pd(0,0,0);
			{
				bool vertexIsOk = false;
				Pd.x = tokens[0].toDouble(&vertexIsOk);
				if (vertexIsOk)
				{
					Pd.y = tokens[1].toDouble(&vertexIsOk);
					if (vertexIsOk)
						Pd.z = tokens[2].toDouble(&vertexIsOk);
				}
				if (!vertexIsOk)
				{
					delete vertices;
					return CC_FERR_MALFORMED_FILE;
				}
			}

			//first point: check for 'big' coordinates
			if (i == 0)
			{
				if (HandleGlobalShift(Pd,Pshift,parameters))
				{
					vertices->setGlobalShift(Pshift);
					ccLog::Warning("[OFF] Cloud has been recentered! Translation: (%.2f,%.2f,%.2f)",Pshift.x,Pshift.y,Pshift.z);
				}
			}

			CCVector3 P = CCVector3::fromArray((Pd + Pshift).u);
			vertices->addPoint(P);
		}
	}

	ccMesh* mesh = new ccMesh(vertices);
	mesh->addChild(vertices);
	if (!mesh->reserve(triCount))
	{
		delete mesh;
		return CC_FERR_NOT_ENOUGH_MEMORY;
	}

	//load triangles
	{
		bool ignoredPolygons = false;
		for (unsigned i=0; i<triCount; ++i)
		{
			currentLine = GetNextLine(stream);
			tokens = currentLine.split(QRegExp("\\s+"),QString::SkipEmptyParts);
			if (tokens.size() < 3)
			{
				delete mesh;
				return CC_FERR_MALFORMED_FILE;
			}

			unsigned polyVertCount = tokens[0].toUInt(&ok);
			if (!ok || static_cast<int>(polyVertCount) >= tokens.size())
			{
				delete mesh;
				return CC_FERR_MALFORMED_FILE;
			}
			if (polyVertCount == 3 || polyVertCount == 4)
			{
				//decode indexes
				unsigned indexes[4];
				for (unsigned j=0; j<polyVertCount; ++j)
				{
					indexes[j] = tokens[j+1].toUInt(&ok);
					if (!ok)
					{
						delete mesh;
						return CC_FERR_MALFORMED_FILE;
					}
				}

				//reserve memory if necessary
				unsigned polyTriCount = polyVertCount-2;
				if (mesh->size() + polyTriCount > mesh->capacity())
				{
					if (!mesh->reserve(mesh->size() + polyTriCount + 256)) //use some margin to avoid too many allocations
					{
						delete mesh;
						return CC_FERR_NOT_ENOUGH_MEMORY;
					}
				}

				//triangle or quad only
				mesh->addTriangle(indexes[0],indexes[1],indexes[2]);
				if (polyVertCount == 4)
					mesh->addTriangle(indexes[0],indexes[2],indexes[3]);

			}
			else
			{
				ignoredPolygons = true;
			}
		}

		if (ignoredPolygons)
		{
			ccLog::Warning("[OFF] Some polygons with an unhandled size (i.e. > 4) were ignored!");
		}
	}

	if (mesh->size() == 0)
	{
		ccLog::Warning("[OFF] Failed to load any polygon!");
		mesh->detachChild(vertices);
		delete mesh;
		mesh = 0;

		container.addChild(vertices);
		vertices->setEnabled(true);
	}
	else
	{
		mesh->shrinkToFit();

		//DGM: normals can be per-vertex or per-triangle so it's better to let the user do it himself later
		//Moreover it's not always good idea if the user doesn't want normals (especially in ccViewer!)
		//if (mesh->computeNormals())
		//	mesh->showNormals(true);
		//else
		//	ccLog::Warning("[OFF] Failed to compute per-vertex normals...");
		ccLog::Warning("[OFF] Mesh has no normal! You can manually compute them (select it then call \"Edit > Normals > Compute\")");

		vertices->setEnabled(false);
		//vertices->setLocked(true); //DGM: no need to lock it as it is only used by one mesh!
		container.addChild(mesh);
	}

	return CC_FERR_NO_ERROR;
}
コード例 #22
0
void ccGraphicalSegmentationTool::doExportSegmentationPolyline()
{
	MainWindow* mainWindow = MainWindow::TheInstance();
	if (mainWindow && m_segmentationPoly)
	{
		bool mode2D = false;
#ifdef ALLOW_2D_OR_3D_EXPORT
		QMessageBox messageBox(0);
		messageBox.setWindowTitle("Choose export type");
		messageBox.setText("Export polyline in:\n - 2D (with coordinates relative to the screen)\n - 3D (with coordinates relative to the segmented entities)");
		QPushButton* button2D = new QPushButton("2D");
		QPushButton* button3D = new QPushButton("3D");
		messageBox.addButton(button2D,QMessageBox::AcceptRole);
		messageBox.addButton(button3D,QMessageBox::AcceptRole);
		messageBox.addButton(QMessageBox::Cancel);
		messageBox.setDefaultButton(button3D);
		messageBox.exec();
		if (messageBox.clickedButton() == messageBox.button(QMessageBox::Cancel))
		{
			//process cancelled by user
			return;
		}
		mode2D = (messageBox.clickedButton() == button2D);
#endif

		ccPolyline* poly = new ccPolyline(*m_segmentationPoly);

		//if the polyline is 2D and we export the polyline in 3D, we must project its vertices
		if (!mode2D)
		{
			//get current display parameters
			ccGLCameraParameters camera;
			m_associatedWin->getGLCameraParameters(camera);
			const double half_w = camera.viewport[2] / 2.0;
			const double half_h = camera.viewport[3] / 2.0;

			//project the 2D polyline in 3D
			CCLib::GenericIndexedCloudPersist* vertices = poly->getAssociatedCloud();
			ccPointCloud* verticesPC = dynamic_cast<ccPointCloud*>(vertices);
			if (verticesPC)
			{
				for (unsigned i=0; i<vertices->size(); ++i)
				{
					CCVector3* Pscreen = const_cast<CCVector3*>(verticesPC->getPoint(i));
					CCVector3d Pd(half_w + Pscreen->x, half_h + Pscreen->y, 0/*Pscreen->z*/);
					CCVector3d Q3D;
					camera.unproject(Pd, Q3D);
					*Pscreen = CCVector3::fromArray(Q3D.u);
				}
				verticesPC->invalidateBoundingBox();
			}
			else
			{
				assert(false);
				ccLog::Warning("[Segmentation] Failed to convert 2D polyline to 3D! (internal inconsistency)");
				mode2D = false;
			}
		}
		
		QString polyName = QString("Segmentation polyline #%1").arg(++s_polylineExportCount);
		poly->setName(polyName);
		poly->setEnabled(false); //we don't want it to appear while the segmentation mode is enabled! (anyway it's 2D only...)
		poly->set2DMode(mode2D);
		poly->setColor(ccColor::yellow); //we use a different color so as to differentiate them from the active polyline!

		//save associated viewport
		cc2DViewportObject* viewportObject = new cc2DViewportObject(polyName + QString(" viewport"));
		viewportObject->setParameters(m_associatedWin->getViewportParameters());
		viewportObject->setDisplay(m_associatedWin);
		poly->addChild(viewportObject);

		mainWindow->addToDB(poly,false,false,false);
		ccLog::Print(QString("[Segmentation] Polyline exported (%1 vertices)").arg(poly->size()));
	}
}