Skip to content

Commit

Permalink
Issue #695 Added writing of calibration entries as part of the dwg an…
Browse files Browse the repository at this point in the history
…d dgn drawing processing.
  • Loading branch information
FJThiel committed Aug 30, 2024
1 parent 309bd58 commit 2ec278f
Show file tree
Hide file tree
Showing 9 changed files with 311 additions and 12 deletions.
42 changes: 42 additions & 0 deletions bouncer/src/repo/core/model/bson/repo_bson_calibration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (C) 2024 3D Repo Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* Assets BSON
*/

#pragma once

#include "repo_bson.h"

namespace repo {
namespace core {
namespace model {

class REPO_API_EXPORT RepoCalibration : public RepoBSON
{
public:

RepoCalibration() : RepoBSON() {}

RepoCalibration(RepoBSON bson) : RepoBSON(bson) {}

~RepoCalibration() {}
};
}// end namespace model
} // end namespace core
} // end namespace repo
68 changes: 68 additions & 0 deletions bouncer/src/repo/core/model/bson/repo_bson_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,74 @@ RepoAssets RepoBSONFactory::makeRepoBundleAssets(
return RepoAssets(builder.obj());
}

RepoCalibration repo::core::model::RepoBSONFactory::makeRepoCalibration(
const repo::lib::RepoUUID& projectId,
const repo::lib::RepoUUID& drawingId,
const repo::lib::RepoUUID& revisionId,
const std::vector<repo::lib::RepoVector3D>& horizontal3d,
const std::vector<repo::lib::RepoVector2D>& horizontal2d,
const std::vector<float>& verticalRange,
const std::string& units)
{
RepoBSONBuilder bsonBuilder;
bsonBuilder.append(REPO_LABEL_ID, repo::lib::RepoUUID::createUUID());
bsonBuilder.append(REPO_LABEL_PROJECT, projectId);
bsonBuilder.append(REPO_LABEL_DRAWING, drawingId);
bsonBuilder.append(REPO_LABEL_REVISION, revisionId);
bsonBuilder.appendTimeStamp(REPO_LABEL_CREATEDAT);

RepoBSONBuilder horizontalBuilder;
if (horizontal3d.size() == 2) {
std::vector<std::vector<float>>arrays;
std::vector<float> arr1;
arr1.push_back(horizontal3d[0].x);
arr1.push_back(horizontal3d[0].y);
arr1.push_back(horizontal3d[0].z);
arrays.push_back(arr1);

std::vector<float> arr2;
arr2.push_back(horizontal3d[1].x);
arr2.push_back(horizontal3d[1].y);
arr2.push_back(horizontal3d[1].z);
arrays.push_back(arr2);

horizontalBuilder.appendArray(REPO_LABEL_MODEL, arrays);
}
else {
repoError << "Incorrect amount of horizontal 3D vectors supplied to makeRepoCalibration" << std::endl;
}

if (horizontal2d.size() == 2) {
std::vector<std::vector<float>>arrays;
std::vector<float> arr1;
arr1.push_back(horizontal2d[0].x);
arr1.push_back(horizontal2d[0].y);
arrays.push_back(arr1);

std::vector<float> arr2;
arr2.push_back(horizontal2d[1].x);
arr2.push_back(horizontal2d[1].y);
arrays.push_back(arr2);

horizontalBuilder.appendArray(REPO_LABEL_DRAWING, arrays);
}
else {
repoError << "Incorrect amount of horizontal 2D vectors supplied to makeRepoCalibration" << std::endl;
}
bsonBuilder.append(REPO_LABEL_HORIZONTAL, horizontalBuilder.obj());

if (verticalRange.size() == 2) {
bsonBuilder.appendArray(REPO_LABEL_VERTICALRANGE, verticalRange);
}
else {
repoError << "Incorrect amount of values for vertical range supplied to makeRepoCalibration" << std::endl;
}

bsonBuilder.append(REPO_LABEL_UNITS, units);

return RepoCalibration(bsonBuilder.obj());
}

ReferenceNode RepoBSONFactory::makeReferenceNode(
const std::string &database,
const std::string &project,
Expand Down
22 changes: 22 additions & 0 deletions bouncer/src/repo/core/model/bson/repo_bson_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "repo_bson_task.h"
#include "repo_bson_user.h"
#include "repo_bson_assets.h"
#include "repo_bson_calibration.h"
#include "repo_node.h"
#include "repo_node_camera.h"
#include "repo_node_metadata.h"
Expand Down Expand Up @@ -162,6 +163,27 @@ namespace repo {
const std::vector<std::string>& repoJsonFiles,
const std::vector<RepoSupermeshMetadata> metadata);

/**
* Create a Drawing Calibration BSON
* @param projectId uuid of the project
* @param drawingId uuid of the drawing
* @param revisionId uuid of the revision
* @param horizontal3d two reference points in the 3d space
* @param horizontal2d two reference points in the 2d space
* @param verticalRange two values marking the vertical range
* @param units the units used for the values.
* @return returns a RepoCalibration
*/
static RepoCalibration makeRepoCalibration(
const repo::lib::RepoUUID& projectId,
const repo::lib::RepoUUID& drawingId,
const repo::lib::RepoUUID& revisionId,
const std::vector<repo::lib::RepoVector3D>& horizontal3d,
const std::vector<repo::lib::RepoVector2D>& horizontal2d,
const std::vector<float>& verticalRange,
const std::string& units
);

/*
* -------------------- REPO NODES ------------------------
*/
Expand Down
10 changes: 10 additions & 0 deletions bouncer/src/repo/core/model/repo_model_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@
// Vertex/triangle map propeties
#define REPO_LABEL_MERGED_NODES "merged_nodes"

// Drawing calibration properties
#define REPO_LABEL_DRAWING "drawing"
#define REPO_LABEL_REVISION "revision"
#define REPO_LABEL_CREATEDAT "createdAt"
#define REPO_LABEL_CREATEDBY "createdBy"
#define REPO_LABEL_HORIZONTAL "horizontal"
#define REPO_LABEL_VERTICALRANGE "verticalRange"
#define REPO_LABEL_UNITS "units"

#define REPO_COMMAND_UPDATE "update"
#define REPO_COMMAND_UPDATES "updates"
#define REPO_COMMAND_DELETE "delete"
Expand All @@ -105,6 +114,7 @@
#define REPO_COLLECTION_SEQUENCE "sequences"
#define REPO_COLLECTION_TASK "activities"
#define REPO_COLLECTION_DRAWINGS "drawings.history"
#define REPO_COLLECTION_CALIBRATIONS "drawings.revisions.calibrations"

#define REPO_COLLECTION_SETTINGS "settings"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,50 @@ void FileProcessorDgn::importDrawing(OdDgDatabasePtr pDb, const ODCOLORREF* pPal
// to the 3D coordinates above. Add these to the appropriate schema when
// it is ready...

std::vector<OdGePoint3d> points;
points.push_back(worldToDeviceMatrix * a);
points.push_back(worldToDeviceMatrix * b);
points.push_back(worldToDeviceMatrix * c);
//std::vector<OdGePoint3d> points;
//points.push_back(worldToDeviceMatrix * a);
//points.push_back(worldToDeviceMatrix * b);
//points.push_back(worldToDeviceMatrix * c);

// Calculate points in SVG space
OdGePoint3d aS = worldToDeviceMatrix * a;
OdGePoint3d bS = worldToDeviceMatrix * b;

// Convert to 2D by dropping z component (note: have not thought about it. Just conceptually).
repo::lib::RepoVector2D aS2d = repo::lib::RepoVector2D(aS.x, aS.y);
repo::lib::RepoVector2D bS2d = repo::lib::RepoVector2D(bS.x, bS.y);

// Convert 3d vectors from ODA format to 3d repo format
repo::lib::RepoVector3D a3d = repo::lib::RepoVector3D(a.x, a.y, a.z);
repo::lib::RepoVector3D b3d = repo::lib::RepoVector3D(b.x, b.y, b.z);

// Assemble calibration outcome
std::vector<repo::lib::RepoVector3D> horizontal3d;
horizontal3d.push_back(a3d);
horizontal3d.push_back(b3d);

std::vector<repo::lib::RepoVector2D> horizontal2d;
horizontal2d.push_back(aS2d);
horizontal2d.push_back(bS2d);

repo::manipulator::modelutility::DrawingCalibration calibration;
calibration.horizontalCalibration3d = horizontal3d;
calibration.horizontalCalibration2d = horizontal2d;

calibration.verticalRange = { 0, 10 }; // TODO: how do I calculate that?

OdDgElementId elementActId = pDb->getActiveModelId();
OdDgModelPtr pModel = elementActId.safeOpenObject();

repo::manipulator::modelconvertor::ModelUnits units = determineModelUnits(pModel->getMasterUnit());

calibration.units = repo::manipulator::modelconvertor::toUnitsString(units);



// Pass calibration outcome to collector
drawingCollector->drawingCalibration = calibration;


// The call to update is what will create the svg in the memory stream

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@

#include "data_processor_dwg.h"

#include <DbObjectIterator.h>
#include <DbDimStyleTableRecord.h>

using namespace repo::manipulator::modelconvertor::odaHelper;

class VectoriseDeviceDwg : public OdGsBaseVectorizeDevice
Expand Down Expand Up @@ -84,7 +87,7 @@ class DeviceModuleDwg : public OdGsBaseModule
};
ODRX_DEFINE_PSEUDO_STATIC_MODULE(DeviceModuleDwg);

void importModel(OdDbDatabasePtr pDb, GeometryCollector* collector)
void FileProcessorDwg::importModel(OdDbDatabasePtr pDb)
{
// Create the vectorizer device that will render the DWG database. This will
// use the GeometryCollector underneath.
Expand All @@ -108,7 +111,7 @@ void importModel(OdDbDatabasePtr pDb, GeometryCollector* collector)
pGsModule.release();
}

void importDrawing(OdDbDatabasePtr pDb, repo::manipulator::modelutility::DrawingImageInfo* collector)
void FileProcessorDwg::importDrawing(OdDbDatabasePtr pDb)
{
OdGsModulePtr pModule = ::odrxDynamicLinker()->loadModule(OdSvgExportModuleName, false);
OdGsDevicePtr dev = pModule->createDevice();
Expand Down Expand Up @@ -142,8 +145,67 @@ void importDrawing(OdDbDatabasePtr pDb, repo::manipulator::modelutility::Drawing

pHelperDevice->onSize(OdGsDCRect(0, 1024, 768, 0));

// Here we can extract the calibration in the same way as file_processor_dgn when ready...
// This section extracts the view information which can be used to map
// betweeen the SVG and world coordinate systems.
// The graphics system (Gs) view https://docs.opendesign.com/tv/gs_OdGsView.html
// is used to derive points that map between the WCS of the drawing and
// the svg file.

const OdGsView* pGsView = pDeviceSvg->viewAt(0);

auto worldToDeviceMatrix = pGsView->worldToDeviceMatrix();
auto objectToDeviceMatrix = pGsView->objectToDeviceMatrix();

// Pick three points (two vectors) to describe the map. The transform
// can be computed from these each time from then on.

OdGePoint3d a(0, 0, 0);
OdGePoint3d b(1, 0, 0);
OdGePoint3d c(0, 1, 0);

// The following vector contains the points in the SVG file corresponding
// to the 3D coordinates above. Add these to the appropriate schema when
// it is ready...

//std::vector<OdGePoint3d> points;
//points.push_back(worldToDeviceMatrix * a);
//points.push_back(worldToDeviceMatrix * b);
//points.push_back(worldToDeviceMatrix * c);

// Calculate points in SVG space
OdGePoint3d aS = worldToDeviceMatrix * a;
OdGePoint3d bS = worldToDeviceMatrix * b;

// Convert to 2D by dropping z component (note: have not thought about it. Just conceptually).
repo::lib::RepoVector2D aS2d = repo::lib::RepoVector2D(aS.x, aS.y);
repo::lib::RepoVector2D bS2d = repo::lib::RepoVector2D(bS.x, bS.y);

// Convert 3d vectors from ODA format to 3d repo format
repo::lib::RepoVector3D a3d = repo::lib::RepoVector3D(a.x, a.y, a.z);
repo::lib::RepoVector3D b3d = repo::lib::RepoVector3D(b.x, b.y, b.z);

// Assemble calibration outcome
std::vector<repo::lib::RepoVector3D> horizontal3d;
horizontal3d.push_back(a3d);
horizontal3d.push_back(b3d);

std::vector<repo::lib::RepoVector2D> horizontal2d;
horizontal2d.push_back(aS2d);
horizontal2d.push_back(bS2d);

repo::manipulator::modelutility::DrawingCalibration calibration;
calibration.horizontalCalibration3d = horizontal3d;
calibration.horizontalCalibration2d = horizontal2d;

calibration.verticalRange = { 0, 10 }; // TODO: how do I calculate that?

repo::manipulator::modelconvertor::ModelUnits units = determineModelUnits(pDb->getINSUNITS());
calibration.units = repo::manipulator::modelconvertor::toUnitsString(units);

// Pass calibration outcome to collector
drawingCollector->drawingCalibration = calibration;


pHelperDevice->update();

// Copy the SVG contents into a string
Expand All @@ -161,7 +223,21 @@ void importDrawing(OdDbDatabasePtr pDb, repo::manipulator::modelutility::Drawing

// Provide the string to the collector as a vector

std::copy(svg.c_str(), svg.c_str() + svg.length(), std::back_inserter(collector->data));
std::copy(svg.c_str(), svg.c_str() + svg.length(), std::back_inserter(drawingCollector->data));
}
}

repo::manipulator::modelconvertor::ModelUnits FileProcessorDwg::determineModelUnits(const OdDb::UnitsValue units){
switch (units) {
case OdDb::kUnitsMeters: return ModelUnits::METRES;
case OdDb::kUnitsDecimeters: return ModelUnits::DECIMETRES;
case OdDb::kUnitsCentimeters: return ModelUnits::CENTIMETRES;
case OdDb::kUnitsMillimeters: return ModelUnits::MILLIMETRES;
case OdDb::kUnitsFeet: return ModelUnits::FEET;
case OdDb::kUnitsInches: return ModelUnits::INCHES;
default:
repoWarning << "Unrecognised unit measure: " << (int)units;
return ModelUnits::UNKNOWN;
}
}

Expand All @@ -187,12 +263,12 @@ uint8_t FileProcessorDwg::readFile()

if (collector)
{
importModel(pDb, collector);
importModel(pDb);
}

if (drawingCollector)
{
importDrawing(pDb, drawingCollector);
importDrawing(pDb);
}

pDb.release();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ namespace repo {

protected:
OdStaticRxObject<RepoDwgServices> svcs;

private:
void importModel(OdDbDatabasePtr pDb);
void importDrawing(OdDbDatabasePtr pDb);
ModelUnits determineModelUnits(const OdDb::UnitsValue units);
};
}
}
Expand Down
Loading

0 comments on commit 2ec278f

Please sign in to comment.