Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Putting a Vec3-like vector into a json object #1035

Closed
PopThis opened this issue Apr 3, 2018 · 11 comments
Closed

Putting a Vec3-like vector into a json object #1035

PopThis opened this issue Apr 3, 2018 · 11 comments
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@PopThis
Copy link

PopThis commented Apr 3, 2018

I have a struct like this

struct Vertexes
{
public:
	// Construction
	float x_;
	float y_;
	float z_;

	Vertexes(float x, float y, float z) : x_(x), y_(y), z_(z) {}

	// Getters
	float getX() const { return x_; }
	float getY() const { return y_; }
	float getZ() const { return z_; }

	// Setters
	void setX(float val) { x_ = val; }
	void setY(float val) { y_ = val; }
	void setZ(float val) { z_ = val; }

	std::string getString() {
		return std::to_string(x_) + ", " + std::to_string(z_) + ", " + std::to_string(y_);
	}

	Vertexes flip() const { return Vertexes{ x_ , z_ , y_ }; }
	Vertexes smaller() const { return Vertexes{ x_ / 100, y_ / 100, z_ / 100 }; }
	Vertexes smallerflip() const { return Vertexes{ x_ / 100, z_ / 100, y_ / 100 }; }

};

Sure, I could even flatten this down to just a

struct Vec3
{
   float x, y, z;
}

But

std::vector<Vertexes> SavedPoints = { {10, 1, 5}, {7,2,2} };
json v(SavedPoints);
std::ofstream o("file.json");
o << std::setw(4) << v << std::endl;

Would not work with to_json template (line 312 at to_json.hpp)

Is there a way to store this vector of vertexes as a json output? such as
v["list"] = SavedPoints and results in

{"0":[
     [10, 1, 5]
     ],
 "1":[[7,2 ,2]
     ]
 }

Thank you very much!

@PopThis
Copy link
Author

PopThis commented Apr 3, 2018

I might've messed up the last json example. But you get the gist. Thank you again.

@nlohmann
Copy link
Owner

nlohmann commented Apr 3, 2018

Did you have a look at https://github.com/nlohmann/json/blob/develop/README.md#arbitrary-types-conversions ? This section describes how you can convert arbitrary types to/from JSON.

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Apr 3, 2018
@PopThis
Copy link
Author

PopThis commented Apr 3, 2018

The Solution I am looking into can work if it is a Vec3, but having a std::vector of Vec3 is causing the issue since you would need to create a loop to read/write indexes individually. Such as key 0, 1, 2, 3 all having their own xyz. Thank you.

@PopThis
Copy link
Author

PopThis commented Apr 3, 2018

namespace ns {
	void to_json(json& j, std::vector<Vertexes>& p) {

		for (std::vector<Vertexes>::iterator it = p.begin(); it != p.end(); ++it) {
			j = json{ {*it, { "x", it->x_ },{ "z", it->z_ },{ "y", it->y_ } } };
		}
	}
}

And then using it by

std::vector<Vertexes> SavedPoints = { { 10, 1, 5 },{ 7,2,2 } };
json jx;
ns::to_json(jx, SavedPoints);

or

std::vector<Vertexes> SavedPoints = { { 10, 1, 5 },{ 7,2,2 } };
json jx = SavedPoints;

still giving me issue at could not find to_json() method in T's Namespace

@nlohmann
Copy link
Owner

nlohmann commented Apr 3, 2018

You need to put the to_json function exactly into the namespace of Vertexes. ns is just a namespace from the example.

@PopThis
Copy link
Author

PopThis commented Apr 3, 2018

I've gotten it to work and it looks good. Thank you. The only issue left is I am sure I am doing this the wrong way.

		for (std::vector<Vertexes>::iterator it = p.begin(); it != p.end(); ++it) {
			j = json{ { unsigned int(it - p.begin()),{ "x", it->x_ },{ "z", it->z_ },{ "y", it->y_ } } };
		}

resulted in only the last index when it is printed out.

instead of the expected

[[0,["x",1.0],["z",2.0],["y",3.0],
[1,["x",7.0],["z",2.0],["y",2.0]]

it only prints out

[[1,["x",7.0],["z",2.0],["y",2.0]]]

I know this is a whole different issue on my part and I appreciate your time.

@PopThis
Copy link
Author

PopThis commented Apr 3, 2018

I've solved the issue. I forgot that I am setting j = the new json instead of push_back on it. Thank you.

namespace ns {
	void to_json(json& j, std::vector<Vertexes>& p) {

		for (std::vector<Vertexes>::iterator it = p.begin(); it != p.end(); ++it) {
			j.push_back(json{ { unsigned int(it - p.begin()),{ "x", it->x_ },{ "z", it->z_ },{ "y", it->y_ } } });
		}
	}

for example

@PopThis
Copy link
Author

PopThis commented Apr 3, 2018

One last note. Due to the push_back already taking care of the keys for us, we don't need to manually create our own key with the loop. This result in so much better solution. Thank you. Closed now.

namespace ns {
	void to_json(json& j, std::vector<Vertexes>& p) {

		for (std::vector<Vertexes>::iterator it = p.begin(); it != p.end(); ++it) {
			j.push_back(json{ { "x", it->x_ },{ "z", it->z_ },{ "y", it->y_ } } );
		}
	}
} 

@PopThis
Copy link
Author

PopThis commented Apr 3, 2018

Actually, LAST one. The other one kept increasing the size if you keep calling the function so we set it like this instead and it is all good.

	void to_json(json& j, std::vector<Vertexes>& p) {
		for (std::vector<Vertexes>::iterator it = p.begin(); it != p.end(); ++it) {
			j[it-p.begin()] = (json{ { "x", it->x_ },{ "z", it->z_ },{ "y", it->y_ } } );
		}
	}

@gregmarr
Copy link
Contributor

gregmarr commented Apr 3, 2018

You should do void to_json(json& j, Vertexes const &v) instead, then std::vector is handled automatically.

@nlohmann
Copy link
Owner

nlohmann commented Apr 4, 2018

@PopThis Can I close this issue?

@nlohmann nlohmann closed this as completed Apr 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

3 participants