Skip to content

Instantly share code, notes, and snippets.

@FaZeRs
Created July 5, 2019 08:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FaZeRs/1a2e32a34b3825ac1353db5c61d5b26b to your computer and use it in GitHub Desktop.
Save FaZeRs/1a2e32a34b3825ac1353db5c61d5b26b to your computer and use it in GitHub Desktop.
void PuzzleWindow::paint()
{
QFont font;
QPen pen;
QDir dir = QDir(home->projectDir.filePath("planojums/"));
QJsonObject puzzle = {};
if (dir.exists()) {
QFile dataFile(dir.filePath("data.json"));
if (dataFile.open(QIODevice::ReadOnly)) {
QByteArray saveData = dataFile.readAll();
QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
puzzle = loadDoc.object();
}
dataFile.close();
}
// Only for version lower than 3.16.4
const size_t roomsCnt = home->vRooms.size();
int cols = 5;
if (4 >= roomsCnt) cols = 2;
else if (9 >= roomsCnt) cols = 3;
else if (16 >= roomsCnt) cols = 4;
if (!puzzle.value("scene-width").isNull() && !puzzle.value("scene-height").isNull() && !puzzle.value("scene-x").isNull() && !puzzle.value("scene-y").isNull()) {
scene->setSceneRect(puzzle.value("scene-x").toDouble(), puzzle.value("scene-y").toDouble(), puzzle.value("scene-width").toDouble(), puzzle.value("scene-height").toDouble());
}
for (QJsonValue puzzleFloor : puzzle.value("floors").toArray()) {
QJsonObject floorObject = puzzleFloor.toObject();
getFloor(floorObject.value("number").toInt());
}
for (size_t i = 0; i < home->vRooms.size(); i++) {
Room *room = &home->vRooms.at(i);
if (!room->isClosedArea) continue;
// Only for version lower than 3.16.4
int col = (static_cast<int>(i + 1) % cols) - 1;
if (-1 == col) col = cols - 1;
const int row = (static_cast<int>(i + 1) / cols) + (static_cast<int>(i + 1) % cols > 0) - 1;
const double scale = room->distToCeiling_mm * MAGIC_CONSTANT;
const cv::Rect boundry = Utils::getBoundry(*room);
qreal dx = boundry.x;
qreal dy = boundry.y;
// Fallback to old position calculation
QFile roomXmlFile(home->projectDir.filePath("scene_data/" + room->panoramaLayoutImg.left(23) + ".xml"));
if (!roomXmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning("Couldn't open save file.");
}
QDomDocument document;
if (!document.setContent(&roomXmlFile)) {
qWarning("failed to parse file");
}
roomXmlFile.close();
QDomElement docEle = document.documentElement();
QDomNode data = docEle.firstChildElement("data");
if (!data.toElement().isNull()) {
QString version = data.firstChildElement("info").attribute("app_version");
if (version.split(".").at(1).toInt() == 16 && version.split(".").at(2).toInt() == 3) {
qDebug() << "Version 3.16.3";
dx = col - boundry.x;
dy = row - boundry.y;
}
else if (version.split(".").at(1).toInt() < 17 && !puzzle.value("width").isNull() && !puzzle.value("height").isNull()) {
qDebug() << "Version lower than 3.17.0";
qreal oldSceneWidth = puzzle.value("width").toDouble();
qreal oldSceneHeight = puzzle.value("height").toDouble();
dx = oldSceneWidth * col - boundry.x;
dy = oldSceneHeight * row - boundry.y;
}
}
RoomGroup *roomGroup = new RoomGroup;
roomGroup->room = room;
scene->addItem(roomGroup);
drawNumber(room, roomGroup, scale, dx, dy);
if (room->vDoors.size() > 0) {
drawDoors(room, roomGroup, scale, dx, dy);
}
if (room->vWindows.size() > 0) {
drawWindows(room, roomGroup, scale, dx, dy);
}
drawName(roomGroup, scale, dx, dy);
drawMeasurements(room, roomGroup, scale, dx, dy);
drawPin(roomGroup, scale, dx, dy);
drawWall(room, roomGroup, scale, dx, dy);
drawArea(room, roomGroup, scale, dx, dy);
if (room->vSubRooms.size() > 0) {
drawSubRooms(room, roomGroup, scale, dx, dy);
}
if (room->vPillars.size() > 0) {
drawPillars(room, roomGroup, scale, dx, dy);
}
groups.append(roomGroup);
Building* building = getBuilding(1);
addRoomToBuilding(building, roomGroup);
Floor* floor = getFloor(1);
addBuildingToFloor(floor, building);
}
//ui->graphicsView->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);
// todo : rewrite
for (QJsonValue puzzleFloor : puzzle.value("floors").toArray()) {
QJsonObject floorObject = puzzleFloor.toObject();
Floor* floor = getFloor(floorObject.value("number").toInt());
for (QJsonValue puzzleRoom : floorObject.value("rooms").toArray()) {
QJsonObject roomObject = puzzleRoom.toObject();
if (!roomObject.value("room").isUndefined()) {
RoomGroup* roomGroup = nullptr;
for (auto room : groups) {
if (room->room && room->room->nr == roomObject.value("room").toString()) {
roomGroup = room;
}
}
if (roomGroup) {
// Move room to position
//roomGroup->moveBy(roomObject.value("x").toDouble(), roomObject.value("y").toDouble());
QPointF position = roomGroup->mapFromScene(roomObject.value("x").toDouble(), roomObject.value("y").toDouble());
roomGroup->setPos(position);
roomGroup->setRotation(roomObject.value("rotation").toInt());
// Remove corners from room
for (auto deletedCorner : roomObject.value("deleted_corners").toArray()) {
QJsonObject deletedCornerObject = deletedCorner.toObject();
QPointF topLeft(deletedCornerObject.value("top_left_x").toDouble(), deletedCornerObject.value("top_left_y").toDouble());
QPointF bottomRight(deletedCornerObject.value("bottom_right_x").toDouble(), deletedCornerObject.value("bottom_right_y").toDouble());
QRectF rectangle(topLeft, bottomRight);
RoomMerge* rect = new RoomMerge(rectangle);
scene->addItem(rect);
if (rect->collidingItems().size() > 0) {
for (auto item : rect->collidingItems()) {
QGraphicsPolygonItem* polygon_child = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
if (polygon_child) {
QPolygonF polygon = polygon_child->polygon();
for (auto point : polygon.toList()) {
if (rectangle.contains(point)) {
polygon.removeOne(point);
polygon_child->setPolygon(polygon);
}
}
RoomGroup* roomGroup = qgraphicsitem_cast<RoomGroup*>(polygon_child->group());
if (roomGroup) {
roomGroup->addMerge(rect);
}
}
}
}
else {
scene->removeItem(rect);
}
}
if (roomGroup->name) {
roomGroup->name->setPlainText(roomObject.value("name").toString());
}
if (!roomObject.value("area").isNull() && roomGroup->area_m2) {
roomGroup->area_m2->setPlainText(QString::number(roomObject.value("area").toDouble()));
roomGroup->area_m2->setChanged(roomObject.value("area_changed").toBool());
}
// Set rooms sub-rooms positions
if (roomGroup->room && roomGroup->room->vSubRooms.size() > 0) {
for (auto subRoom : roomObject.value("sub_rooms").toArray()) {
QJsonObject subRoomObject = subRoom.toObject();
for (auto subRoomPuzzle : roomGroup->subRooms) {
if (subRoomPuzzle->subRoom->id == subRoomObject.value("id").toString()) {
QTransform transfrom;
transfrom.translate(subRoomObject.value("x").toDouble(), subRoomObject.value("y").toDouble());
transfrom.rotate(subRoomObject.value("rotation").toInt());
subRoomPuzzle->setPos(transfrom.map(subRoomPuzzle->pos()));
subRoomPuzzle->setRotation(subRoomPuzzle->rotation() + subRoomObject.value("rotation").toInt());
subRoomPuzzle->name->setPlainText(subRoomObject.value("name").toString());
if (subRoomObject.value("area").toBool()) {
subRoomPuzzle->area_m2->setPlainText(subRoomObject.value("area").toString());
}
}
}
}
}
if (!roomObject.value("building").isNull() && roomObject.value("building").toInt() > 0) {
int buildingNumber = roomObject.value("building").toInt();
Building* building = getBuilding(buildingNumber);
addRoomToBuilding(building, roomGroup);
addBuildingToFloor(floor, building);
}
}
}
}
}
for(QJsonValue puzzleFloor : puzzle.value("floors").toArray()) {
QJsonObject floorObject = puzzleFloor.toObject();
Floor *floor = getFloor(floorObject.value("number").toInt());
for(QJsonValue puzzleRoom : floorObject.value("rooms").toArray()) {
QJsonObject roomObject = puzzleRoom.toObject();
if(roomObject.value("union_room").toBool()) {
QPolygonF mergedRoomPolygon;
QList<RoomGroup*> mergedRooms;
int buildingNumber = 1;
if (!roomObject.value("building").isNull() && roomObject.value("building").toInt() > 0) {
buildingNumber = roomObject.value("building").toInt();
}
RoomGroup *mergedRoomGroup = new RoomGroup;
for(auto mergedRoom : roomObject.value("merged_rooms").toArray()) {
for(auto group : groups) {
if(bool(group->room) && group->room->nr == mergedRoom.toString()) {
mergedRoomPolygon = mergedRoomPolygon.united(group->wall->mapToScene(group->wall->polygon()));
group->setMerged(true);
QPen pen;
pen.setColor(Qt::lightGray);
pen.setStyle(Qt::DashLine);
pen.setWidth(1);
group->wall->setPen(pen);
group->setFlag(QGraphicsItem::ItemIsMovable, false);
group->setFlag(QGraphicsItem::ItemIsSelectable, false);
group->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
group->setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
mergedRooms.append(group);
group->setGroup(mergedRoomGroup);
}
}
}
RoomWall* roomMergedWall = new RoomWall(mergedRoomPolygon);
scene->addItem(roomMergedWall);
mergedRoomGroup->addWall(roomMergedWall);
mergedRoomGroup->setUnionRoom(true);
mergedRoomGroup->mergedRooms = mergedRooms;
scene->addItem(mergedRoomGroup);
groups.append(mergedRoomGroup);
Building* building = getBuilding(buildingNumber);
addRoomToBuilding(building, mergedRoomGroup);
addBuildingToFloor(floor, building);
for(auto deletedCorner : roomObject.value("deleted_corners").toArray()) {
QJsonObject deletedCornerObject = deletedCorner.toObject();
QPointF topLeft(deletedCornerObject.value("top_left_x").toDouble(), deletedCornerObject.value("top_left_y").toDouble());
QPointF bottomRight(deletedCornerObject.value("bottom_right_x").toDouble(), deletedCornerObject.value("bottom_right_y").toDouble());
QRectF rectangle(topLeft, bottomRight);
RoomMerge* rect = new RoomMerge(rectangle);
scene->addItem(rect);
if(rect->collidingItems().size() > 0) {
for(auto item : rect->collidingItems()) {
QGraphicsPolygonItem *polygon_child = qgraphicsitem_cast<QGraphicsPolygonItem *>(item);
if (polygon_child) {
QPolygonF polygon = polygon_child->polygon();
for(auto point : polygon.toList()) {
if(rectangle.contains(point)) {
polygon.removeOne(point);
polygon_child->setPolygon(polygon);
}
}
}
RoomGroup *roomGroup = qgraphicsitem_cast<RoomGroup*>(item);
if(roomGroup) {
roomGroup->addMerge(rect);
}
}
} else {
scene->removeItem(rect);
}
}
}
}
}
}
void PuzzleWindow::saveDataFile()
{
QDir dir = QDir(home->projectDir.filePath("planojums/"));
if (!dir.exists()) dir.mkpath(".");
QString filePath = dir.filePath("data.json");
QFile dataFile(filePath);
QString backupFilePath = dir.filePath("data.json.bak");
QFile backupDataFile(backupFilePath);
if(dataFile.exists()) {
if(backupDataFile.exists()) {
backupDataFile.remove();
}
dataFile.copy(backupFilePath);
}
try {
if (!dataFile.open(QIODevice::WriteOnly)) {
qWarning("Couldn't open data file.");
dataFile.close();
throw;
}
QJsonObject sceneObject;
sceneObject.insert("width", sceneWidth);
sceneObject.insert("height", sceneHeight);
sceneObject.insert("scene-width", scene->width());
sceneObject.insert("scene-height", scene->height());
sceneObject.insert("scene-x", scene->sceneRect().x());
sceneObject.insert("scene-y", scene->sceneRect().y());
std::sort(floors.begin(), floors.end(), [](const Floor* f1, const Floor* f2) -> bool { return f1->number() < f2->number(); });
QJsonArray jsonFloors;
for (Floor* floor : floors) {
if (floor->buildings.size() == 0) continue;
std::sort(floor->buildings.begin(), floor->buildings.end(), [](const Building* b1, const Building* b2) -> bool { return b1->number() < b2->number(); });
QJsonObject floorObject;
floorObject.insert("number", floor->number());
QJsonArray jsonRooms;
for (auto building : floor->buildings) {
if (building->rooms.size() == 0) continue;
for (auto roomGroup : building->rooms) {
QJsonObject roomObject;
if (roomGroup->room) {
roomObject.insert("room", roomGroup->room->nr);
if (roomGroup->name) {
roomObject.insert("name", roomGroup->name->toPlainText());
}
if (roomGroup->area_m2) {
roomObject.insert("area", roomGroup->area_m2->toPlainText().toDouble());
roomObject.insert("area_changed", roomGroup->area_m2->isChanged());
}
}
roomObject.insert("x", roomGroup->x());
roomObject.insert("y", roomGroup->y());
if (roomGroup->isMerged() && roomGroup->group()) {
roomObject.insert("rotation", roomGroup->rotation() + roomGroup->group()->rotation());
}
else {
roomObject.insert("rotation", roomGroup->rotation());
}
roomObject.insert("is_merged", roomGroup->isMerged());
roomObject.insert("union_room", roomGroup->isUnionRoom());
roomObject.insert("building", roomGroup->buildingNumber);
QJsonArray mergedRooms;
for (auto mergedRoom : roomGroup->mergedRooms) {
if (bool(mergedRoom->room)) {
mergedRooms.append(mergedRoom->room->nr);
}
}
roomObject.insert("merged_rooms", mergedRooms);
if(roomGroup->isUnionRoom()) {
QJsonArray deletedCorners;
for (auto deletedCorner : roomGroup->merges) {
QJsonObject deletedCornerObject;
deletedCornerObject.insert("top_left_x", deletedCorner->rect().topLeft().x());
deletedCornerObject.insert("top_left_y", deletedCorner->rect().topLeft().y());
deletedCornerObject.insert("bottom_right_x", deletedCorner->rect().bottomRight().x());
deletedCornerObject.insert("bottom_right_y", deletedCorner->rect().bottomRight().y());
deletedCorners.append(deletedCornerObject);
}
roomObject.insert("deleted_corners", deletedCorners);
}
QJsonArray subRooms;
for (auto subRoom : roomGroup->subRooms) {
if (subRoom->subRoom && subRoom->subRoom->isClosedArea) {
QJsonObject subRoomObject;
subRoomObject.insert("id", subRoom->subRoom->id);
subRoomObject.insert("name", subRoom->name->toPlainText());
subRoomObject.insert("area", subRoom->area_m2->toPlainText().toDouble());
subRoomObject.insert("x", subRoom->x());
subRoomObject.insert("y", subRoom->y());
subRoomObject.insert("rotation", subRoom->rotation());
subRooms.append(subRoomObject);
}
}
roomObject.insert("sub_rooms", subRooms);
jsonRooms.append(roomObject);
}
}
if(!jsonRooms.empty()) {
floorObject.insert("rooms", jsonRooms);
jsonFloors.append(floorObject);
}
}
sceneObject.insert("floors", jsonFloors);
QJsonDocument dataDoc(sceneObject);
dataFile.write(dataDoc.toJson());
dataFile.close();
} catch(...) {
if (backupDataFile.exists() && backupDataFile.size() > 0) {
if (dataFile.exists()) {
dataFile.remove();
}
backupDataFile.rename(filePath);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment