Created
July 5, 2019 08:23
-
-
Save FaZeRs/1a2e32a34b3825ac1353db5c61d5b26b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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