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

Zincjs tree exports #233

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
132 changes: 116 additions & 16 deletions src/graphics/render_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ class Render_graphics_opengl_threejs : public Render_graphics_opengl_vertex_buff
public:

std::list<Threejs_export *> exports_list;
std::map<char *, double *> scene_transformation_map;
char *file_prefix;
double begin_time, end_time;
int number_of_time_steps, current_time_frame;
Expand All @@ -583,6 +584,7 @@ class Render_graphics_opengl_threejs : public Render_graphics_opengl_vertex_buff
int morphVertices, morphColours, morphNormals, numberOfResources;
char **filenames;
int isInline;
unsigned int graphicsOrder;

/** @param outputStringsRef Reference to vector of strings to fill with the output strings */
Render_graphics_opengl_threejs(const char *file_prefix_in,
Expand All @@ -605,7 +607,8 @@ class Render_graphics_opengl_threejs : public Render_graphics_opengl_vertex_buff
morphNormals(morphNormalsIn),
numberOfResources(numberOfFilesIn),
filenames(filenamesIn),
isInline(isInlineIn)
isInline(isInlineIn),
graphicsOrder(0)
{
exports_list.clear();
}
Expand Down Expand Up @@ -640,23 +643,77 @@ class Render_graphics_opengl_threejs : public Render_graphics_opengl_vertex_buff
return size;
}

Json::Value *create_child_region_for_json_object(Json::Value *parent, std::string name)
{
if (!parent->isMember("Children"))
{
(*parent)["Children"] = Json::objectValue;
}
if (!(*parent)["Children"].isMember(name))
{
(*parent)["Children"][name] = Json::objectValue;
}

return &((*parent)["Children"][name]);
}

//create a json object for the region path
Json::Value *create_region_tree_for_json_object(Json::Value *parent,
std::string region_string)
{
if (region_string.empty())
{
return parent;
}
else
{
std::size_t found = region_string.find("/");
if (found == std::string::npos)
{
return this->create_child_region_for_json_object(parent, region_string);
}
else
{
std::string token = region_string.substr(0, found);
region_string.erase(0, found + 1);
return this->create_region_tree_for_json_object(
create_child_region_for_json_object(parent, token),
region_string);
}
}
return nullptr;
}

/* this will generate the meta data string */
std::string get_metadata_string()
{
Json::Value root = Json::arrayValue;
Json::Value root = Json::objectValue;
Json::Value regions = Json::objectValue;
int i = 1;
for (std::list<Threejs_export *>::iterator item = exports_list.begin();
item != exports_list.end(); item++)
{
if ((*item)->isValid())
{
Json::Value graphics_json;
Json::Value graphics_json = Json::objectValue;
graphics_json["MorphVertices"] = (*item)->getMorphVerticesExported();
graphics_json["MorphColours"] = (*item)->getMorphColoursExported();
graphics_json["MorphNormals"] = (*item)->getMorphNormalsExported();
graphics_json["Order"] = (*item)->getGraphicsOrder();
Threejs_export_glyph *glyph_export = dynamic_cast<Threejs_export_glyph*>(*item);
Threejs_export_line *line_export = dynamic_cast<Threejs_export_line*>(*item);
Threejs_export_point *point_export = dynamic_cast<Threejs_export_point*>(*item);

if (isInline)
{
graphics_json["Inline"]["URL"]= (*item)->getExportJson();
if (glyph_export)
{
graphics_json["Inline"]["URL"]= glyph_export->getGlyphTransformationExportJson();
}
else
{
graphics_json["Inline"]["URL"]= (*item)->getExportJson();
}
}
else
{
Expand All @@ -674,20 +731,14 @@ class Render_graphics_opengl_threejs : public Render_graphics_opengl_vertex_buff
const char *group_name = (*item)->getGroupName();
if (group_name)
graphics_json["GroupName"] = group_name;
const char *region_path = (*item)->getRegionPath();
if (region_path)
graphics_json["RegionPath"] = region_path;

Threejs_export_glyph *glyph_export = dynamic_cast<Threejs_export_glyph*>(*item);
Threejs_export_line *line_export = dynamic_cast<Threejs_export_line*>(*item);
Threejs_export_point *point_export = dynamic_cast<Threejs_export_point*>(*item);
if (glyph_export)
{
graphics_json["Type"]="Glyph";
i++;
if (isInline)
{
graphics_json["Inline"]["GlyphGeometriesURL"] = glyph_export->getGlyphTransformationExportJson();
graphics_json["Inline"]["GlyphGeometriesURL"] = glyph_export->getExportJson();
}
else
{
Expand Down Expand Up @@ -718,10 +769,43 @@ class Render_graphics_opengl_threejs : public Render_graphics_opengl_vertex_buff
graphics_json["Type"]="Surfaces";
}
i++;
root.append(graphics_json);
const char *region_path = (*item)->getRegionPath();
if (region_path)
{
Json::Value *object = this->create_region_tree_for_json_object(
&regions, std::string(region_path));
if (object)
{
(*object)["Primitives"].append(graphics_json);
}
}
}
}

for (std::map<char *, double *>::iterator iter = scene_transformation_map.begin();
iter != scene_transformation_map.end(); iter++)
{
Json::Value region_json;
const char *region_path = iter->first;
if (region_path)
{
if (iter->second)
{
Json::Value transformation = Json::arrayValue;
for (int i = 0; i < 16; i++)
{
transformation.append(iter->second[i]);
}
Json::Value *object = this->create_region_tree_for_json_object(
&regions, std::string(region_path));
if (object)
{
(*object)["Transformation"] = transformation;
}
}
}
}
root["Regions"] = regions;
root["Version"] = "2.0";
return Json::StyledWriter().write(root);
}

Expand All @@ -748,17 +832,33 @@ class Render_graphics_opengl_threejs : public Render_graphics_opengl_vertex_buff
return 1;
}

void clear_exports_list()
void clear_export_maps()
{
while (exports_list.size() > 0)
{
delete exports_list.back();
exports_list.pop_back();
}
for (std::map<char *, double *>::iterator iter = scene_transformation_map.begin();
iter != scene_transformation_map.end(); iter++)
{
char *name = iter->first;
DEALLOCATE(name);
delete[] iter->second;
}
scene_transformation_map.clear();
}

virtual int cmzn_scene_compile_members(cmzn_scene *scene)
{
double *transformation = 0;
if (cmzn_scene_has_transformation(scene))
{
transformation = new double[16];
scene->getTransformationMatrixRowMajor(transformation);
}
scene_transformation_map.insert(
std::make_pair(duplicate_string(this->region_path), transformation));
if (number_of_time_steps == 0)
{
cmzn_scene_compile_graphics(scene, this,/*force_rebuild*/0);
Expand Down Expand Up @@ -858,7 +958,7 @@ class Render_graphics_opengl_threejs : public Render_graphics_opengl_vertex_buff
const bool morphNormalsAllowed = graphicsIsTimeDependent && morphNormals;
threejs_export = new Threejs_export_class(new_file_prefix, number_of_time_steps, mode,
morphsVerticesAllowed, morphsColoursAllowed, morphNormalsAllowed, &textureSizes[0], group_name,
this->region_path, graphics);
this->region_path, graphics, ++this->graphicsOrder);
threejs_export->beginExport();
threejs_export->exportMaterial(material);
cmzn_material_destroy(&material);
Expand Down Expand Up @@ -941,7 +1041,7 @@ class Render_graphics_opengl_threejs : public Render_graphics_opengl_vertex_buff
int Scene_tree_execute(cmzn_scene *scene)
{
this->writeOutputStrings();
clear_exports_list();
clear_export_maps();
return 1;
}

Expand Down
26 changes: 17 additions & 9 deletions src/graphics/threejs_export.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Threejs_export
std::string facesString;
std::string outputString;
bool isEmpty;
unsigned int graphicsOrder;

void writeVertexBuffer(const char *output_variable_name,
GLfloat *vertex_buffer, unsigned int values_per_vertex,
Expand Down Expand Up @@ -75,7 +76,8 @@ class Threejs_export
cmzn_streaminformation_scene_io_data_type mode_in,
int morphVerticesIn, int morphColoursIn, int morphNormalsIn,
double *textureSizesIn, const char *groupNameIn,
const char *regionPathIn, cmzn_graphics *graphicsIn) :
const char *regionPathIn, cmzn_graphics *graphicsIn,
unsigned int graphicsOrderIn) :
filename(duplicate_string(filename_in)),
mode(mode_in),
morphVerticesExported(false),
Expand All @@ -87,7 +89,8 @@ class Threejs_export
number_of_time_steps(number_of_time_steps_in),
groupName(groupNameIn ? duplicate_string(groupNameIn) : nullptr),
regionPath(regionPathIn ? duplicate_string(regionPathIn) : nullptr),
graphics(graphicsIn)
graphics(graphicsIn),
graphicsOrder(graphicsOrderIn)
{
if (textureSizesIn)
{
Expand Down Expand Up @@ -135,7 +138,6 @@ class Threejs_export
return regionPath;
}


/* this return json format describing colours and transformation of the glyph */
Json::Value getExportJson();

Expand All @@ -161,6 +163,11 @@ class Threejs_export
return morphNormalsExported;
}

unsigned int getGraphicsOrder() const
{
return graphicsOrder;
}

};

/* class for export glyph into WebGL format, only
Expand Down Expand Up @@ -191,10 +198,11 @@ class Threejs_export_glyph : public Threejs_export
cmzn_streaminformation_scene_io_data_type mode_in,
int morphVerticesIn, int morphColoursIn, int morphNormalsIn,
double *textureSizesIn, const char *groupNameIn,
const char* regionPathIn, cmzn_graphics *graphicsIn) :
const char* regionPathIn, cmzn_graphics *graphicsIn,
unsigned int graphicsOrderIn) :
Threejs_export(filename_in, number_of_time_steps_in,
mode_in, morphVerticesIn, morphColoursIn, morphNormalsIn, textureSizesIn,
groupNameIn, regionPathIn, graphicsIn)
groupNameIn, regionPathIn, graphicsIn, graphicsOrderIn)
{
glyphTransformationString.clear();
glyphGeometriesURLName = 0;
Expand Down Expand Up @@ -228,10 +236,10 @@ class Threejs_export_point : public Threejs_export
cmzn_streaminformation_scene_io_data_type mode_in,
int morphVerticesIn, int morphColoursIn, int morphNormalsIn,
double *textureSizesIn, const char *groupNameIn, const char* regionPathIn,
cmzn_graphics *graphicsIn) :
cmzn_graphics *graphicsIn, unsigned int graphicsOrderIn) :
Threejs_export(filename_in, number_of_time_steps_in,
mode_in, morphVerticesIn, morphColoursIn, morphNormalsIn, textureSizesIn,
groupNameIn, regionPathIn, graphicsIn)
groupNameIn, regionPathIn, graphicsIn, graphicsOrderIn)
{
}

Expand All @@ -252,10 +260,10 @@ class Threejs_export_line : public Threejs_export_point
cmzn_streaminformation_scene_io_data_type mode_in,
int morphVerticesIn, int morphColoursIn, int morphNormalsIn,
double *textureSizesIn, const char *groupNameIn, const char* regionPathIn,
cmzn_graphics *graphicsIn) :
cmzn_graphics *graphicsIn, unsigned int graphicsOrderIn) :
Threejs_export_point(filename_in, number_of_time_steps_in,
mode_in, morphVerticesIn, morphColoursIn, morphNormalsIn, textureSizesIn,
groupNameIn, regionPathIn, graphicsIn)
groupNameIn, regionPathIn, graphicsIn, graphicsOrderIn)
{
}

Expand Down
12 changes: 10 additions & 2 deletions tests/graphics/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
#include <opencmiss/zinc/sceneviewer.hpp>
#include <opencmiss/zinc/spectrum.hpp>
#include <opencmiss/zinc/streamscene.hpp>

#include "test_resources.h"
#include "utilities/testenum.hpp"
#include "zinctestsetup.hpp"
Expand Down Expand Up @@ -790,6 +789,9 @@ TEST(cmzn_scene, threejs_export_region_cpp)
Scene s1 = r1.getScene();
EXPECT_TRUE(s1.isValid());

const double newMatrix1[16] = { 1, 2, 3, 0.1, 4, 5, 6, 0.2, 7, 8, 9, 0.3, -0.01, -0.02, -0.03, 1.0 };
EXPECT_EQ(RESULT_OK, result = s1.setTransformationMatrix(newMatrix1));

Fieldmodule fm = r1.getFieldmodule();
EXPECT_TRUE(fm.isValid());

Expand Down Expand Up @@ -836,7 +838,13 @@ TEST(cmzn_scene, threejs_export_region_cpp)
temp_char = strstr ( memory_buffer, "MorphVertices");
EXPECT_NE(static_cast<char *>(0), temp_char);

temp_char = strstr ( memory_buffer, "\"RegionPath\" : \"bob\"");
temp_char = strstr ( memory_buffer, "Regions");
EXPECT_NE(static_cast<char *>(0), temp_char);

temp_char = strstr ( memory_buffer, "bob");
EXPECT_NE(static_cast<char *>(0), temp_char);

temp_char = strstr ( memory_buffer, "Transformation");
EXPECT_NE(static_cast<char *>(0), temp_char);

result = memory_sr2.getBuffer((const void**)&memory_buffer, &size);
Expand Down