24using namespace helios;
29 contextUUIDs_build.clear();
30 colorPrimitives_UUIDs.clear();
31 colorPrimitives_objIDs.clear();
32 contextUUIDs_build.clear();
33 depth_buffer_data.clear();
43 std::vector<vec3> vertices;
49 vertices.at(0) = center + v0;
54 vertices.at(1) = center + v1;
59 vertices.at(2) = center + v2;
64 vertices.at(3) = center + v3;
70 std::vector<vec3> vertices;
76 vertices.at(0) = center + v0;
81 vertices.at(1) = center + v1;
86 vertices.at(2) = center + v2;
91 vertices.at(3) = center + v3;
97 std::vector<vec3> vertices;
103 vertices.at(0) = center + v0;
108 vertices.at(1) = center + v1;
113 vertices.at(2) = center + v2;
118 vertices.at(3) = center + v3;
124 std::vector<vec3> vertices;
130 vertices.at(0) = center + v0;
135 vertices.at(1) = center + v1;
140 vertices.at(2) = center + v2;
145 vertices.at(3) = center + v3;
158 for (
auto vertex: vertices) {
159 if (vertex.x < 0.f || vertex.x > 1.f) {
161 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `x' position ( " << vertex.x <<
" ) is outside of drawable area." << std::endl;
163 }
else if (vertex.y < 0.f || vertex.y > 1.f) {
165 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `y' position ( " << vertex.y <<
" ) is outside of drawable area." << std::endl;
167 }
else if (vertex.z < -1.f || vertex.z > 1.f) {
169 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `z' position ( " << vertex.z <<
" ) is outside of drawable area." << std::endl;
176 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_RECTANGLE, vertices, color, {}, -1,
false,
false, coordFlag,
true,
false);
181 const std::vector<vec2> uvs{{0, 0}, {1, 0}, {1, 1}, {0, 1}};
189 for (
auto vertex: vertices) {
190 if (vertex.x < 0.f || vertex.x > 1.f) {
192 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `x' position ( " << vertex.x <<
" ) is outside of drawable area." << std::endl;
194 }
else if (vertex.y < 0.f || vertex.y > 1.f) {
196 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `y' position ( " << vertex.y <<
" ) is outside of drawable area." << std::endl;
198 }
else if (vertex.z < -1.f || vertex.z > 1.f) {
200 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `z' position ( " << vertex.z <<
" ) is outside of drawable area." << std::endl;
206 uint textureID = registerTextureImage(texture_file);
209 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_RECTANGLE, vertices, RGBA::black, uvs, textureID,
false,
false, coordFlag,
true,
false);
214 const std::vector<vec2> uvs{{0, 0}, {1, 0}, {1, 1}, {0, 1}};
222 for (
auto vertex: vertices) {
223 if (vertex.x < 0.f || vertex.x > 1.f) {
225 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `x' position ( " << vertex.x <<
" ) is outside of drawable area." << std::endl;
227 }
else if (vertex.y < 0.f || vertex.y > 1.f) {
229 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `y' position ( " << vertex.y <<
" ) is outside of drawable area." << std::endl;
231 }
else if (vertex.z < -1.f || vertex.z > 1.f) {
233 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `z' position ( " << vertex.z <<
" ) is outside of drawable area." << std::endl;
239 uint textureID = registerTextureImage(texture_file);
242 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_RECTANGLE, vertices,
make_RGBAcolor(color, 1.f), uvs, textureID,
false,
false, coordFlag,
true,
false);
254 for (
auto vertex: vertices) {
255 if (vertex.x < 0.f || vertex.x > 1.f) {
257 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `x' position ( " << vertex.x <<
" ) is outside of drawable area." << std::endl;
259 }
else if (vertex.y < 0.f || vertex.y > 1.f) {
261 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `y' position ( " << vertex.y <<
" ) is outside of drawable area." << std::endl;
263 }
else if (vertex.z < -1.f || vertex.z > 1.f) {
265 std::cerr <<
"WARNING (Visualizer::addRectangleByVertices): Rectangle `z' position ( " << vertex.z <<
" ) is outside of drawable area." << std::endl;
271 uint textureID = registerTextureGlyph(glyph);
273 const std::vector<vec2> uvs{{0, 0}, {1, 0}, {1, 1}, {0, 1}};
278 coordFlag2 = scast<CoordinateSystem>(2);
282 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_RECTANGLE, vertices, color, uvs, textureID,
true,
true, coordFlag2,
true,
false);
291 const std::vector<vec3> vertices{vertex0, vertex1, vertex2};
293 if (coordFlag == 0) {
296 for (
const auto &vertex: vertices) {
297 if (vertex.x < 0.f || vertex.x > 1.f) {
299 std::cerr <<
"WARNING (Visualizer::addTriangle): Triangle `x' position ( " << vertex.
x <<
" ) is outside of drawable area." << std::endl;
301 }
else if (vertex.y < 0.f || vertex.y > 1.f) {
303 std::cerr <<
"WARNING (Visualizer::addTriangle): Triangle `y' position ( " << vertex.y <<
" ) is outside of drawable area." << std::endl;
305 }
else if (vertex.z < -1.f || vertex.z > 1.f) {
307 std::cerr <<
"WARNING (Visualizer::addTriangle): Triangle `z' position ( " << vertex.z <<
" ) is outside of drawable area." << std::endl;
314 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_TRIANGLE, vertices, color, {}, -1,
false,
false, coordFlag,
true,
false);
319 const std::vector<vec3> vertices{vertex0, vertex1, vertex2};
320 const std::vector<vec2> uvs{uv0, uv1, uv2};
322 if (coordFlag == 0) {
325 for (
auto &vertex: vertices) {
326 if (vertex.x < 0.f || vertex.x > 1.f) {
328 std::cerr <<
"WARNING (Visualizer::addTriangle): Triangle `x' position ( " << vertex.
x <<
" ) is outside of drawable area." << std::endl;
330 }
else if (vertex.y < 0.f || vertex.y > 1.f) {
332 std::cerr <<
"WARNING (Visualizer::addTriangle): Triangle `y' position ( " << vertex.y <<
" ) is outside of drawable area." << std::endl;
334 }
else if (vertex.z < -1.f || vertex.z > 1.f) {
336 std::cerr <<
"WARNING (Visualizer::addTriangle): Triangle `z' position ( " << vertex.z <<
" ) is outside of drawable area." << std::endl;
342 uint textureID = registerTextureImage(texture_file);
345 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_TRIANGLE, vertices, RGBA::black, uvs, textureID,
false,
false, coordFlag,
true,
false);
350 const std::vector<vec3> vertices{vertex0, vertex1, vertex2};
351 const std::vector<vec2> uvs{uv0, uv1, uv2};
353 if (coordFlag == 0) {
356 for (
const auto &tri_vertex: vertices) {
357 if (tri_vertex.x < 0.f || tri_vertex.x > 1.f) {
359 std::cerr <<
"WARNING (Visualizer::addTriangle): Triangle `x' position ( " << tri_vertex.
x <<
" ) is outside of drawable area." << std::endl;
361 }
else if (tri_vertex.y < 0.f || tri_vertex.y > 1.f) {
363 std::cerr <<
"WARNING (Visualizer::addTriangle): Triangle `y' position ( " << tri_vertex.y <<
" ) is outside of drawable area." << std::endl;
365 }
else if (tri_vertex.z < -1.f || tri_vertex.z > 1.f) {
367 std::cerr <<
"WARNING (Visualizer::addTriangle): Triangle `z' position ( " << tri_vertex.z <<
" ) is outside of drawable area." << std::endl;
373 uint textureID = registerTextureImage(texture_file);
376 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_TRIANGLE, vertices, color, uvs, textureID,
true,
false, coordFlag,
true,
false);
389 std::vector<size_t> UUIDs(6);
403 const vec3 c4 = center +
make_vec3(0.f, 0.f, -0.5f * size.
z) + eps;
406 const vec3 c5 = center +
make_vec3(0.f, 0.f, 0.5f * size.
z) + eps;
417 const std::vector<vec3> vertices{start, end};
420 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_LINE, vertices, color, {}, -1,
false,
false, coordFlag,
true,
false);
430 if (line_width <= 0.0f) {
431 std::cerr <<
"WARNING (Visualizer::addLine): Line width must be positive. Setting to 1.0." << std::endl;
435 const std::vector<vec3> vertices{start, end};
438 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_LINE, vertices, color, {}, -1,
false,
false, coordFlag,
true,
false,
static_cast<int>(line_width));
448 if (!headless && window !=
nullptr) {
451 const float MIN_POINT_SIZE = 1.0f;
452 const float MAX_POINT_SIZE = 64.0f;
454 if (pointsize < MIN_POINT_SIZE || pointsize > MAX_POINT_SIZE) {
455 std::cerr <<
"WARNING (Visualizer::addPoint): Point size ( " << pointsize <<
" ) is outside of supported range ( " << MIN_POINT_SIZE <<
", " << MAX_POINT_SIZE <<
" ). Clamping value.." << std::endl;
456 if (pointsize < MIN_POINT_SIZE) {
457 pointsize = MIN_POINT_SIZE;
459 pointsize = MAX_POINT_SIZE;
463 this->point_width = pointsize;
466 geometry_handler.
addGeometry(UUID, GeometryHandler::GEOMETRY_TYPE_POINT, {position}, color, {}, -1,
false,
false, coordinate_system,
true,
false, pointsize);
475 float dtheta =
PI_F / scast<float>(Ndivisions);
476 float dphi = 2.f *
PI_F / scast<float>(Ndivisions);
478 std::vector<size_t> UUIDs;
479 UUIDs.reserve(2 * Ndivisions + 2 * (Ndivisions - 2) * (Ndivisions - 1));
482 for (
int j = 0; j < Ndivisions; j++) {
483 float phi = scast<float>(j) * dphi;
484 float phi_plus = scast<float>(j + 1) * dphi;
490 UUIDs.push_back(
addTriangle(v0, v1, v2, color, coordinate_system));
494 for (
int j = 0; j < Ndivisions; j++) {
495 float phi = scast<float>(j) * dphi;
496 float phi_plus = scast<float>(j + 1) * dphi;
502 UUIDs.push_back(
addTriangle(v2, v1, v0, color, coordinate_system));
506 for (
int j = 0; j < Ndivisions; j++) {
507 float phi = scast<float>(j) * dphi;
508 float phi_plus = scast<float>(j + 1) * dphi;
509 for (
int i = 1; i < Ndivisions - 1; i++) {
510 float theta = -0.5f *
PI_F + scast<float>(i) * dtheta;
511 float theta_plus = -0.5f *
PI_F + scast<float>(i + 1) * dtheta;
518 UUIDs.push_back(
addTriangle(v0, v1, v2, color, coordinate_system));
519 UUIDs.push_back(
addTriangle(v0, v2, v3, color, coordinate_system));
531 float thetaStart = -0.1f *
PI_F;
533 float dtheta = (0.5f *
PI_F - thetaStart) /
float(Ndivisions - 1);
534 float dphi = 2.f *
PI_F / float(Ndivisions - 1);
536 std::vector<size_t> UUIDs;
537 UUIDs.reserve(2u * Ndivisions * Ndivisions);
542 for (
int j = 0; j < scast<int>(Ndivisions - 1); j++) {
544 vec3 v0 = center + radius * cart;
546 vec3 v1 = center + radius * cart;
548 vec3 v2 = center + radius * cart;
550 vec3 n0 = v0 - center;
552 vec3 n1 = v1 - center;
554 vec3 n2 = v2 - center;
557 vec2 uv0 =
make_vec2(1.f - atan2f(sinf((
float(j) + 0.5f) * dphi), -cosf((
float(j) + 0.5f) * dphi)) / (2.f *
PI_F) - 0.5f, 1.f - n0.
z * 0.5f - 0.5f);
558 vec2 uv1 =
make_vec2(1.f - atan2f(n1.
x, -n1.
y) / (2.f *
PI_F) - 0.5f, 1.f - n1.
z * 0.5f - 0.5f);
559 vec2 uv2 =
make_vec2(1.f - atan2f(n2.
x, -n2.
y) / (2.f *
PI_F) - 0.5f, 1.f - n2.
z * 0.5f - 0.5f);
561 if (j == scast<int>(Ndivisions - 2)) {
565 UUIDs.push_back(
addTriangle(v0, v1, v2, texture_file, uv0, uv1, uv2, scast<CoordinateSystem>(2)));
569 for (
int j = 0; j < scast<int>(Ndivisions - 1); j++) {
570 for (
int i = 0; i < scast<int>(Ndivisions - 1); i++) {
572 vec3 v0 = center + radius * cart;
574 vec3 v1 = center + radius * cart;
576 vec3 v2 = center + radius * cart;
578 vec3 v3 = center + radius * cart;
580 vec3 n0 = v0 - center;
582 vec3 n1 = v1 - center;
584 vec3 n2 = v2 - center;
586 vec3 n3 = v3 - center;
589 vec2 uv0 =
make_vec2(1.f - atan2f(n0.
x, -n0.
y) / (2.f *
PI_F) - 0.5f, 1.f - n0.
z * 0.5f - 0.5f);
590 vec2 uv1 =
make_vec2(1.f - atan2f(n1.
x, -n1.
y) / (2.f *
PI_F) - 0.5f, 1.f - n1.
z * 0.5f - 0.5f);
591 vec2 uv2 =
make_vec2(1.f - atan2f(n2.
x, -n2.
y) / (2.f *
PI_F) - 0.5f, 1.f - n2.
z * 0.5f - 0.5f);
592 vec2 uv3 =
make_vec2(1.f - atan2f(n3.
x, -n3.
y) / (2.f *
PI_F) - 0.5f, 1.f - n3.
z * 0.5f - 0.5f);
594 if (j == scast<int>(Ndivisions - 2)) {
599 UUIDs.push_back(
addTriangle(v0, v1, v2, texture_file, uv0, uv1, uv2, scast<CoordinateSystem>(2)));
600 UUIDs.push_back(
addTriangle(v0, v2, v3, texture_file, uv0, uv2, uv3, scast<CoordinateSystem>(2)));
612 if (FT_Init_FreeType(&ft) != 0) {
613 helios_runtime_error(
"ERROR (Visualizer::addTextboxByCenter): Could not init freetype library");
616 std::vector<std::vector<unsigned char>> maskData;
622 auto error = FT_New_Face(ft, font.c_str(), 0, &face);
626 case FT_Err_Cannot_Open_Resource:
628 case FT_Err_Unknown_File_Format:
630 case FT_Err_Invalid_File_Format:
632 case FT_Err_Invalid_Version:
634 case FT_Err_Lower_Module_Version:
636 case FT_Err_Invalid_Argument:
638 case FT_Err_Unimplemented_Feature:
640 case FT_Err_Invalid_Table:
642 case FT_Err_Invalid_Offset:
644 case FT_Err_Array_Too_Large:
646 case FT_Err_Missing_Module:
648 case FT_Err_Out_Of_Memory:
650 case FT_Err_Invalid_Face_Handle:
652 case FT_Err_Invalid_Size_Handle:
654 case FT_Err_Invalid_Slot_Handle:
656 case FT_Err_Invalid_CharMap_Handle:
658 case FT_Err_Invalid_Glyph_Index:
660 case FT_Err_Invalid_Character_Code:
662 case FT_Err_Invalid_Glyph_Format:
664 case FT_Err_Cannot_Render_Glyph:
666 case FT_Err_Invalid_Outline:
668 case FT_Err_Invalid_Composite:
670 case FT_Err_Too_Many_Hints:
672 case FT_Err_Invalid_Pixel_Size:
674 case FT_Err_Invalid_Library_Handle:
676 case FT_Err_Invalid_Stream_Handle:
678 case FT_Err_Invalid_Frame_Operation:
680 case FT_Err_Nested_Frame_Access:
682 case FT_Err_Invalid_Frame_Read:
684 case FT_Err_Raster_Uninitialized:
686 case FT_Err_Raster_Corrupted:
688 case FT_Err_Raster_Overflow:
690 case FT_Err_Raster_Negative_Height:
692 case FT_Err_Too_Many_Caches:
694 case FT_Err_Invalid_Opcode:
696 case FT_Err_Too_Few_Arguments:
698 case FT_Err_Stack_Overflow:
700 case FT_Err_Stack_Underflow:
704 case FT_Err_No_Unicode_Glyph_Name:
706 case FT_Err_Missing_Property:
713 helios_runtime_error(
"ERROR (Visualizer::addTextboxByCenter): Could not open font '" + std::string(fontname) +
"'");
717 FT_Set_Pixel_Sizes(face, 0, fontsize);
720 float sx = 1.f / float(Wdisplay);
721 float sy = 1.f / float(Hdisplay);
723 FT_GlyphSlot gg = face->glyph;
729 const char *textt = textstring;
730 for (
const char *p = textt; *p; p++) {
731 if (FT_Load_Char(face, *p, FT_LOAD_RENDER))
734 if (strncmp(p,
"_", 1) == 0) {
737 }
else if (strncmp(p,
"^", 1) == 0) {
741 wtext += gg->bitmap.width * sx * scale;
742 htext = std::max(gg->bitmap.rows * sy, htext);
746 float xt = center.
x - 0.5f * wtext;
747 float yt = center.
y - 0.5f * htext;
751 if (xt < 0 || xt > 1) {
753 std::cerr <<
"WARNING (Visualizer::addTextboxByCenter): text x-coordinate is outside of window area" << std::endl;
756 if (yt < 0 || yt > 1) {
758 std::cerr <<
"WARNING (Visualizer::addTextboxByCenter): text y-coordinate is outside of window area" << std::endl;
764 FT_GlyphSlot g = face->glyph;
766 std::vector<size_t> UUIDs;
767 UUIDs.reserve(std::strlen(textstring));
769 const char *text = textstring;
773 for (
const char *p = text; *p; p++) {
775 if (FT_Load_Char(face, *p, FT_LOAD_RENDER))
778 if (strncmp(p,
"_", 1) == 0) {
782 }
else if (strncmp(p,
"^", 1) == 0) {
789 uint2 tsize(g->bitmap.width, g->bitmap.rows);
790 maskData.resize(tsize.
y);
791 for (
int j = 0; j < tsize.
y; j++) {
792 maskData.at(j).resize(tsize.
x);
793 for (
int i = 0; i < tsize.
x; i++) {
794 maskData.at(j).at(i) = g->bitmap.buffer[i + j * tsize.
x];
799 vec2 lettersize =
make_vec2(g->bitmap.width * scale * sx, g->bitmap.rows * scale * sy);
802 vec3 letterposition =
make_vec3(xt + g->bitmap_left * sx + 0.5 * lettersize.
x, yt + g->bitmap_top * (sy + offset) - 0.5 * lettersize.
y, center.
z);
805 xt += (g->advance.x >> 6) * sx * scale;
806 yt += (g->advance.y >> 6) * sy * scale;
812 if (lettersize.
x == 0 || lettersize.
y == 0) {
816 Glyph glyph(tsize, maskData);
823 FT_Done_FreeType(ft);
829 if (geometry_handler.doesGeometryExist(geometry_id)) {
839 std::vector<size_t> UUIDs;
840 UUIDs.reserve(Ndivs + 2 * Nticks + 20);
842 if (!colorbar_ticks.empty()) {
843 Nticks = colorbar_ticks.size();
846 float dx = size.
x / float(Ndivs);
848 float cmin =
clamp(colormap.getLowerLimit(), -1e7f, 1e7f);
849 float cmax =
clamp(colormap.getUpperLimit(), -1e7f, 1e7f);
851 for (
uint i = 0; i < Ndivs; i++) {
852 float x = center.
x - 0.5f * size.
x + (float(i) + 0.5f) * dx;
854 RGBcolor color = colormap.query(cmin +
float(i) / float(Ndivs) * (cmax - cmin));
859 std::vector<vec3> border;
861 border.push_back(
make_vec3(center.
x - 0.5f * size.
x, center.
y + 0.25f * size.
y, center.
z - 0.001f));
862 border.push_back(
make_vec3(center.
x + 0.5f * size.
x, center.
y + 0.25f * size.
y, center.
z - 0.001f));
863 border.push_back(
make_vec3(center.
x + 0.5f * size.
x, center.
y - 0.25f * size.
y, center.
z - 0.001f));
864 border.push_back(
make_vec3(center.
x - 0.5f * size.
x, center.
y - 0.25f * size.
y, center.
z - 0.001f));
865 border.push_back(
make_vec3(center.
x - 0.5f * size.
x, center.
y + 0.25f * size.
y, center.
z - 0.001f));
867 for (
uint i = 0; i < border.size() - 1; i++) {
871 dx = size.
x / float(Nticks - 1);
873 std::vector<vec3> ticks;
875 for (
uint i = 0; i < Nticks; i++) {
877 char textstr[10], precision[10];
881 if (colorbar_ticks.empty()) {
882 x = center.
x - 0.5f * size.
x + float(i) * dx;
883 value = cmin + float(i) / float(Nticks - 1) * (cmax - cmin);
885 value = colorbar_ticks.at(i);
886 x = center.
x - 0.5f * size.
x + (value - cmin) / (cmax - cmin) * size.
x;
889 if (std::fabs(floor(value) - value) < 1e-4) {
890 std::snprintf(precision, 10,
"%%d");
891 std::snprintf(textstr, 10, precision,
int(floor(value)));
892 }
else if (value != 0.f) {
894 int d1 = floor(log10(std::fabs(value)));
899 std::snprintf(precision, 10,
"%%%u.%uf", (
char) abs(d1) + 1, (
char) d2);
900 std::snprintf(textstr, 10, precision, value);
905 UUIDs.insert(UUIDs.end(), UUIDs_text.begin(), UUIDs_text.end());
907 if (i > 0 && i < Nticks - 1) {
908 ticks[0] =
make_vec3(x, center.
y - 0.25f * size.
y, center.
z - 0.001f);
909 ticks[1] =
make_vec3(x, center.
y - 0.25f * size.
y + 0.05f * size.
y, center.
z - 0.001f);
911 ticks[0] =
make_vec3(x, center.
y + 0.25f * size.
y, center.
z - 0.001f);
912 ticks[1] =
make_vec3(x, center.
y + 0.25f * size.
y - 0.05f * size.
y, center.
z - 0.001f);
919 UUIDs.insert(UUIDs.end(), UUIDs_text.begin(), UUIDs_text.end());
930 if (sign ==
"both") {
938 std::vector<size_t> UUIDs, UUIDs_text;
946 UUIDs.insert(UUIDs.end(), UUIDs_text.begin(), UUIDs_text.end());
954 UUIDs.insert(UUIDs.end(), UUIDs_text.begin(), UUIDs_text.end());
962 UUIDs.insert(UUIDs.end(), UUIDs_text.begin(), UUIDs_text.end());
965 this->coordinate_axes_IDs = UUIDs;
969 if (!coordinate_axes_IDs.empty()) {
978 float spacing_x = size.
x / scast<float>(subdiv.
x);
979 float spacing_y = size.
y / scast<float>(subdiv.
y);
980 float spacing_z = size.
z / scast<float>(subdiv.
z);
982 std::vector<size_t> UUIDs;
983 UUIDs.reserve(subdiv.
x * subdiv.
y + subdiv.
y * subdiv.
z + subdiv.
x * subdiv.
z);
985 for (
int i = 0; i <= subdiv.
x; i++) {
986 for (
int j = 0; j <= subdiv.
y; j++) {
991 for (
int i = 0; i <= subdiv.
z; i++) {
992 for (
int j = 0; j <= subdiv.
y; j++) {
997 for (
int i = 0; i <= subdiv.
x; i++) {
998 for (
int j = 0; j <= subdiv.
z; j++) {
1003 if (primitiveColorsNeedUpdate) {