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

Issue 391: Adding BIM3 support to bouncer #402

Merged
merged 61 commits into from
Dec 14, 2020
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
505fa8c
ISSUE #391 Merge branch 'staging' into ISSUE_391
Nov 6, 2020
ad0b07f
ISSUE #391 Adding is C++ style static casts
Nov 6, 2020
d3252c1
ISSUE #391 Adding unit test file to repo + Cmake lists (via updatesou…
Nov 6, 2020
db73347
ISSUE #391 This was causing a compilor error due to missing declarati…
Nov 10, 2020
8706835
ISSUE #391 Updating the unit test to generate scene
Nov 10, 2020
086c7e7
ISSUE #391 fixing bug with an incorrectly sized, non-null terminated …
Nov 10, 2020
0357d5e
ISSUE #391 Comments and formatting for clarity
Nov 11, 2020
afcb0e0
ISSUE #391 Renaming/Commenting the fileMeta struct members for clarity
Nov 11, 2020
27e3101
ISSUE #391 brackets...
Nov 11, 2020
7c8e8b4
ISSUE #391 removing unused variable
Nov 12, 2020
9499a4a
ISSUE #391 deleting irrelevant comment
Nov 12, 2020
4f33a07
ISSUE #391 Reformatting and commenting for clarity (no code changes)
Nov 12, 2020
de3789a
ISSUE #391 renaming variable
Nov 12, 2020
057a1e2
ISSUE #391 renaming variable
Nov 12, 2020
f60bfaf
ISSUE #391 commenting
Nov 12, 2020
68f5982
ISSUE #391 variable name change
Nov 12, 2020
5fbfd3e
ISSUE #391 formatting
Nov 12, 2020
4515140
ISSUE #391 formatting & comments
Nov 12, 2020
4024742
ISSUE #391 updating for new BIM version string/fileMeta
Nov 12, 2020
22ac752
ISSUE #391 adding file meta updates to debug output
Nov 12, 2020
45835ba
ISSUE #391 fixing slashes for travis build
Nov 12, 2020
e88e232
ISSUE #391 adding required intermediary variables for loading in text…
Nov 12, 2020
4806dbf
ISSUE #391 switching to the ptree method of loading JSON nodes (doesn…
Nov 12, 2020
68b6e97
ISSUE #391 Correcting issues with TextureNode list
Nov 12, 2020
4181050
ISSUE #391 shifting the loading of binary data to before the JSON nod…
Nov 12, 2020
b1062f4
ISSUE #391 Writing function to decode textures
Nov 12, 2020
0b0cedf
ISSUE #391 updating the texture parent UUIDs
Nov 12, 2020
f5bb351
ISSUE #391 inserting all the parent UUIDs
Nov 12, 2020
5c35e48
ISSUE #391 invalidating fileMeta struct
Nov 12, 2020
d0f922f
ISSUE #391 comment
Nov 12, 2020
4e440ae
ISSUE #391 reporting
Nov 12, 2020
15d64be
ISSUE #391 variable rename
Nov 12, 2020
b95a30b
ISSUE #391 tying the textures up to their (material) parents the prop…
Nov 12, 2020
ed80edc
ISSUE #391 fixing bug with shared id instead of unique id
Nov 12, 2020
ebc367e
ISSUE #391 removing unrequired constant
Nov 12, 2020
9a66527
ISSUE #391 adding todo
Nov 12, 2020
a2d0bfe
ISSUE #391 updating test for both bim formats
Nov 12, 2020
357e9aa
ISSUE #391 Added some logging functions to help out with printing dur…
Nov 13, 2020
b985bca
ISSUE #391 pulled out core test into its own function for use across …
Nov 13, 2020
f229aa1
ISSUE #391 formatting
Nov 13, 2020
eb7d05a
ISSUE #391 adding dummy tests for other use cases. using the helper f…
Nov 13, 2020
7d72f67
ISSUE #391 removing BIM001 from supported file list
Nov 13, 2020
392a3ed
ISSUE #391 Added a function to print errors based on errorcode
Nov 13, 2020
7709b25
ISSUE #391 removing processing support for BIM001
Nov 13, 2020
6f53060
ISSUE #391 Adding data files to new tests
Nov 13, 2020
7eb1d15
ISSUE #391 tweaking test functions
Nov 13, 2020
555b9c5
ISSUE #391 making changes to pass the units tests
Nov 13, 2020
477b5c9
ISSUE #391 Added system tests for 3drepo client BIM processing
Nov 17, 2020
4a3a63a
ISSUE #391 Adding support for uv channels from the new BIM format
Nov 27, 2020
95d25b3
ISSUE #391 keeping track of parent bim id for easier debugging
Nov 27, 2020
f72052f
ISSUE #391 Beefing up test function for debugging
Nov 27, 2020
a21d698
ISSUE #391 Merge branch 'staging' into ISSUE_391
Nov 30, 2020
14c2ee4
ISSUE #391 Updating unit test with the new UV channel changes. Adapti…
Nov 30, 2020
5607d6d
ISSUE #391 updating st tests with new files (post BIM3 uv fixes)
Nov 30, 2020
6f5db15
ISSUE #391 Removing print outs from st/ut and related functios from t…
Dec 1, 2020
29117f0
ISSUE #391 General clean up for code review: https://github.com/3drep…
Dec 11, 2020
b18dead
ISSUE #391 Updating BSON factory method that produces a texture node …
Dec 11, 2020
490c113
ISSUE #391 catering to changes from review : https://github.com/3drep…
Dec 14, 2020
6ec0e11
ISSUE #391 fix compilation on ODA, change function call to not pass i…
carmenfan Dec 14, 2020
73321e6
ISSUE #391 fix file location
carmenfan Dec 14, 2020
e4419f0
ISSUE #391 remove unncessary import
carmenfan Dec 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "../../../core/model/bson/repo_node_mesh.h"
#include "../../../core/model/bson/repo_node_metadata.h"
#include "../../../core/model/bson/repo_node_transformation.h"
#include "../../../core/model/bson/repo_node_texture.h"

namespace repo {
namespace manipulator {
Expand All @@ -47,82 +48,113 @@ namespace repo {
const std::string REPO_IMPORT_METADATA = "metadata";
const std::string REPO_IMPORT_GEOMETRY = "geometry";
const std::string REPO_IMPORT_MATERIAL = "material";

const std::string REPO_IMPORT_VERTICES = "vertices";
const std::string REPO_IMPORT_NORMALS = "normals";
const std::string REPO_IMPORT_INDICES = "indices";
const std::string REPO_IMPORT_UV = "uv";
const std::string REPO_IMPORT_NORMALS = "normals";
const std::string REPO_IMPORT_INDICES = "indices";

const std::string REPO_IMPORT_BBOX = "bbox";

const std::string REPO_V1 = "BIM001";
const std::string REPO_V2 = "BIM002";

const std::set<std::string> supportedFileVersions = { REPO_V1, REPO_V2 };
const static int REPO_VERSION_LENGTH = 6;

class RepoModelImport : public AbstractModelImport
{
private:
std::vector<repo::core::model::RepoNode *> node_map;
std::vector<repo::lib::RepoMatrix> trans_map;
bool is32Bit = false;

void createObject(const boost::property_tree::ptree& tree);
const std::string REPO_V1 = "BIM001";
const std::string REPO_V2 = "BIM002";
const std::string REPO_V3 = "BIM003";
const std::set<std::string> supportedFileVersions =
{
REPO_V2,
REPO_V3
};

char *geomBuf;
std::ifstream *finCompressed;
boost::iostreams::filtering_streambuf<boost::iostreams::input> *inbuf;
std::istream *fin;
const int REPO_V1_FILEMETA_BYTE_LEN = 56;
const int REPO_V2_FILEMETA_BYTE_LEN = REPO_V1_FILEMETA_BYTE_LEN;
const int REPO_V3_FILEMETA_BYTE_LEN = 72;

typedef struct
{
int64_t headerSize;
int64_t geometrySize;
int64_t sizesStart;
int64_t sizesSize;
int64_t matStart;
int64_t matSize;
int64_t numChildren;
int64_t jsonSize = -1; //!< Size of the entire JSON segment
int64_t dataSize = -1; //!< Size of the entire binary footer segment
int64_t sizesStart = -1; //!< Starting location of the JSON sizes array from the top of file in bytes
int64_t sizesSize = -1; //!< Length of the JSON sizes array in bytes
int64_t matStart = -1; //!< Starting location of the JSON materials array from the top of the file in bytes
int64_t matSize = -1; //!< Size of the JSON materials array in bytes
int64_t numChildren = -1; //!< Number of children of the root node
int64_t textureStart = -1; //!< Starting location of the JSON textures array from the top of the file in bytes
int64_t textureSize = -1; //!< Size of the JSON textures array in bytes
} fileMeta;

struct mesh_data_t {
struct mesh_data_t
{
int parentBimId;
std::vector<repo::lib::RepoVector3D64> rawVertices;
std::vector<repo::lib::RepoVector3D> normals;
std::vector<std::vector<repo::lib::RepoVector2D>> uvChannels;
std::vector<repo_face_t> faces;
std::vector<std::vector<double>> boundingBox;
repo::lib::RepoUUID parent;
repo::lib::RepoUUID sharedID;
};

fileMeta file_meta;

std::vector<long> sizes;

repo::core::model::MaterialNode* parseMaterial(const boost::property_tree::ptree &pt);

void parseMaterial(const boost::property_tree::ptree& pt);
void parseTexture(const boost::property_tree::ptree& textureTree, char * dataBuffer);
repo::core::model::MetadataNode* createMetadataNode(const boost::property_tree::ptree &metadata, const std::string &parentName, const repo::lib::RepoUUID &parentID);
mesh_data_t createMeshRecord(const boost::property_tree::ptree &geometry, const std::string &parentName, const repo::lib::RepoUUID &parentID, const repo::lib::RepoMatrix &trans);
mesh_data_t createMeshRecord(int parentBimId, const boost::property_tree::ptree &geometry, const std::string &parentName, const repo::lib::RepoUUID &parentID, const repo::lib::RepoMatrix &trans);

/**
* @brief Creates a property tree from the current
* position in the fine input stream (fin)
* @param number of chars to read
* @return boost poperty tree
*/
boost::property_tree::ptree getNextJSON(long jsonSize);
void skipAheadInFile(long amount);

std::vector<repo::core::model::MaterialNode *> matNodeList;
std::vector<std::vector<repo::lib::RepoUUID>> matParents;

std::vector<mesh_data_t> meshEntries;
repo::core::model::RepoNodeSet cameras; //!< Cameras
repo::core::model::RepoNodeSet materials; //!< Materials
repo::core::model::RepoNodeSet metadata; //!< Metadata
repo::core::model::RepoNodeSet transformations; //!< Transformations
repo::core::model::RepoNodeSet textures;
/**
* @brief Creates relevant nodes for given child
* of the root node in the BIM file
* Directly updates:
* trans_matrix_map
* node_map
* transformations
* @param tree
*/
void createObject(const boost::property_tree::ptree& tree);

// File handling variables
std::string orgFile;
std::ifstream *finCompressed;
boost::iostreams::filtering_streambuf<boost::iostreams::input> *inbuf;
std::istream *fin;

// Source file meta data storage
fileMeta file_meta;
std::vector<long> sizes; //!< Sizes of the nodes component, used for navigation.
char *dataBuffer;
bool missingTextures = false;

// Intermediary variables used to keep track of node hierarchy
std::vector<repo::core::model::RepoNode *> node_map; //!< List of all transform nodes in order of decoding
std::vector<repo::lib::RepoMatrix> trans_matrix_map; //!< List of all transformation matrices in same order as node_map
std::vector<repo::core::model::MaterialNode *> matNodeList; //!< Stores a list of materials
std::vector<std::vector<repo::lib::RepoUUID>> matParents; //!< Stores the UUIDs of all parents of a given material node in the same order matNodeList
std::map<int, std::vector<repo::lib::RepoUUID>> textureIdToParents; //!< Maps a texture to the UUID of all the parents that reference it
std::vector<mesh_data_t> meshEntries;

// Variables directly used to instantiate the RepoScene
repo::core::model::RepoNodeSet cameras;
repo::core::model::RepoNodeSet materials;
repo::core::model::RepoNodeSet metadata;
repo::core::model::RepoNodeSet transformations;
repo::core::model::RepoNodeSet textures;
std::vector<double> offset;

public:

/**
* Create IFCModelImport with specific settings
* Create RepoModelImport with specific settings
* NOTE: The destructor will destroy the settings object referenced
* in this object!
* @param settings
Expand All @@ -145,9 +177,10 @@ namespace repo {
virtual repo::core::model::RepoScene* generateRepoScene(uint8_t &errMsg);

/**
* Import model from a given file
* Import model from a given file.
* Loads material nodes.
* This does not generate the Repo Scene Graph
* Use getRepoScene() to generate a Repo Scene Graph.
* Use generateRepoScene() to generate a Repo Scene Graph.
* @param path to the file
* @param error message if failed
* @return returns true upon success
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "../../../core/model/bson/repo_node_metadata.h"
#include "../../../core/model/bson/repo_node_transformation.h"
#include "../../../lib/repo_property_tree.h"
#include "../../../3drepobouncer/bouncer/src/repo/error_codes.h"

namespace repo {
namespace manipulator {
Expand Down
55 changes: 55 additions & 0 deletions test/src/system/st_3drepobouncerClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,61 @@ TEST(RepoClientTest, UploadTestMissingNodes)
EXPECT_TRUE(projectExists(db, "missing"));
}

TEST(RepoClientTest, UploadTestBIM)
{
repo::test::TestLogging::printTestTitleString(
"BIM format system tests",
"Confirming the correct response from bouncer client for BIM files");

////this ensures we can run processes
ASSERT_TRUE(system(nullptr));

auto testUpload = [](
std::string mongoDbName,
std::string projectName,
std::string fileName
)-> int
{
std::string bimUpload = produceUploadArgs(
mongoDbName,
projectName,
getDataPath(fileName));

int errCode = runProcess(bimUpload);
;
repoInfo << "Error code from bouncer client: " << errCode
<< ", " << repo::test::TestLogging::getStringFromRepoErrorCode(errCode);
return errCode;
};

std::string mongoDbName = "stUpload";

repo::test::TestLogging::printSubTestTitleString("OK BIM003 file with textures");
std::string okBim3PrjName = "okBIM3Test";
EXPECT_EQ(REPOERR_OK, testUpload(mongoDbName, okBim3PrjName, "RepoModelImport/BrickWalls_bim3.bim"));
EXPECT_TRUE(projectExists(mongoDbName, okBim3PrjName));

repo::test::TestLogging::printSubTestTitleString("OK BIM002 file with no textures");
std::string okBim2PrjName = "okBIM2Test";
EXPECT_EQ(REPOERR_OK, testUpload(mongoDbName, okBim2PrjName, "RepoModelImport/cube_bim2_navis_2021_repo_4.6.1.bim"));
EXPECT_TRUE(projectExists(mongoDbName, okBim2PrjName));

repo::test::TestLogging::printSubTestTitleString("Spoofed BIM001");
std::string spoofedBim1PrjName = "spoofedBIM1Test";
EXPECT_EQ(REPOERR_UNSUPPORTED_BIM_VERSION, testUpload(mongoDbName, spoofedBim1PrjName, "RepoModelImport/cube_bim1_spoofed.bim"));
EXPECT_FALSE(projectExists(mongoDbName, spoofedBim1PrjName));

repo::test::TestLogging::printSubTestTitleString("Corrupt BIM003 - Missing \"numImageBytes\" field");
std::string corrTxtrBim3PrjName = "corruptedTextureBIM3Test";
EXPECT_EQ(REPOERR_LOAD_SCENE_MISSING_TEXTURE, testUpload(mongoDbName, corrTxtrBim3PrjName, "RepoModelImport/BrickWalls_bim3_CorruptedTextureField.bim"));
EXPECT_TRUE(projectExists(mongoDbName, corrTxtrBim3PrjName));

repo::test::TestLogging::printSubTestTitleString("Corrupt BIM003 - Material references a texture id not included in file");
std::string corrMatBim3PrjName = "corruptedMaterialBIM3Test";
EXPECT_EQ(REPOERR_LOAD_SCENE_MISSING_NODES, testUpload(mongoDbName, corrMatBim3PrjName, "RepoModelImport/BrickWalls_bim3_MissingTexture.bim"));
EXPECT_TRUE(projectExists(mongoDbName, corrMatBim3PrjName));
}

TEST(RepoClientTest, UploadTestIFC)
{
//this ensures we can run processes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

set(TEST_SOURCES
${TEST_SOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/ut_repo_model_import_3drepo.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ut_repo_model_import_synchro.cpp
CACHE STRING "TEST_SOURCES" FORCE)

Loading