33// std
44#include < cassert>
55#include < iostream>
6+ #include < algorithm>
7+ #include < cctype>
68// anari
79#include < anari/anari_cpp.hpp>
810#include < anari/anari_cpp/ext/glm.h>
911// rply
1012#include " rply.h"
1113
14+ inline std::string toLower (const std::string& str) {
15+ std::string lower = str;
16+ std::transform (lower.begin (), lower.end (), lower.begin (),
17+ [](unsigned char c){ return std::tolower (c); });
18+ return lower;
19+ }
20+
1221inline int rplyReadVertexCallback (p_ply_argument arg)
1322{
1423 long axis;
@@ -41,6 +50,25 @@ inline int rplyReadColorCallback(p_ply_argument arg)
4150 return 1 ;
4251}
4352
53+ inline int rplyReadIntensityCallback (p_ply_argument arg)
54+ {
55+ long axis;
56+ void *pointer;
57+ ply_get_argument_user_data (arg, &pointer, &axis);
58+ auto **colors = (glm::vec3 **)pointer;
59+ float val = ply_get_argument_value (arg);
60+
61+ static unsigned long count = 0 ;
62+ // Normalize intensity to 0-1 range (assuming it's 0-255, adjust if needed)
63+ float normalized = val > 1 .0f ? val/255 .f : val;
64+ (*colors)[count][0 ] = normalized;
65+ (*colors)[count][1 ] = normalized;
66+ (*colors)[count][2 ] = normalized;
67+ count++;
68+
69+ return 1 ;
70+ }
71+
4472anari::Surface readPLY (anari::Device device, std::string fn, float radius)
4573{
4674 p_ply ply = ply_open (fn.c_str (), NULL , 0 , NULL );
@@ -50,14 +78,58 @@ anari::Surface readPLY(anari::Device device, std::string fn, float radius)
5078 }
5179
5280 glm::vec3 *positions = nullptr , *colors = nullptr ;
53-
81+
82+ // Detect what color data is available
83+ bool hasVertexColors = false ;
84+ std::string intensityPropertyName;
85+
86+ // Check for vertex colors (red, green, blue)
87+ p_ply_element element = nullptr ;
88+ while ((element = ply_get_next_element (ply, element))) {
89+ const char *elemName;
90+ long nInstances;
91+ ply_get_element_info (element, &elemName, &nInstances);
92+
93+ if (std::string (elemName) == " vertex" ) {
94+ p_ply_property property = nullptr ;
95+ bool hasRed = false , hasGreen = false , hasBlue = false ;
96+
97+ while ((property = ply_get_next_property (element, property))) {
98+ const char *propName;
99+ ply_get_property_info (property, &propName, nullptr , nullptr , nullptr );
100+ std::string propNameStr (propName);
101+
102+ if (propNameStr == " red" ) hasRed = true ;
103+ if (propNameStr == " green" ) hasGreen = true ;
104+ if (propNameStr == " blue" ) hasBlue = true ;
105+
106+ // Check for intensity property (case-insensitive)
107+ if (intensityPropertyName.empty () &&
108+ toLower (propNameStr).find (" intensity" ) != std::string::npos) {
109+ intensityPropertyName = propNameStr;
110+ }
111+ }
112+
113+ hasVertexColors = hasRed && hasGreen && hasBlue;
114+ break ;
115+ }
116+ }
117+
54118 long numSpheres = ply_set_read_cb (ply, " vertex" , " x" , rplyReadVertexCallback, &positions, 0 );
55119 ply_set_read_cb (ply, " vertex" , " y" , rplyReadVertexCallback, &positions, 1 );
56120 ply_set_read_cb (ply, " vertex" , " z" , rplyReadVertexCallback, &positions, 2 );
57121
58- ply_set_read_cb (ply, " vertex" , " red" , rplyReadColorCallback, &colors, 0 );
59- ply_set_read_cb (ply, " vertex" , " green" , rplyReadColorCallback, &colors, 1 );
60- ply_set_read_cb (ply, " vertex" , " blue" , rplyReadColorCallback, &colors, 2 );
122+ // Set up color callbacks based on what's available
123+ if (hasVertexColors) {
124+ std::cout << " ANARI::Using vertex colors from PLY file.\n " ;
125+ ply_set_read_cb (ply, " vertex" , " red" , rplyReadColorCallback, &colors, 0 );
126+ ply_set_read_cb (ply, " vertex" , " green" , rplyReadColorCallback, &colors, 1 );
127+ ply_set_read_cb (ply, " vertex" , " blue" , rplyReadColorCallback, &colors, 2 );
128+ } else if (!intensityPropertyName.empty ()) {
129+ std::cout << " ANARI::Using intensity property '" << intensityPropertyName << " ' for grayscale colors from PLY file.\n " ;
130+ ply_set_read_cb (ply, " vertex" , intensityPropertyName.c_str (),
131+ rplyReadIntensityCallback, &colors, 0 );
132+ }
61133
62134 auto positionsArray =
63135 anari::newArray1D (device, ANARI_FLOAT32_VEC3 , numSpheres);
@@ -68,6 +140,14 @@ anari::Surface readPLY(anari::Device device, std::string fn, float radius)
68140 positions = anari::map<glm::vec3>(device, positionsArray);
69141 colors = anari::map<glm::vec3>(device, colorsArray);
70142
143+ // If no color data will be read, initialize with medium gray
144+ if (!hasVertexColors && intensityPropertyName.empty ()) {
145+ std::cout << " ANARI::No color information found in PLY file. Using default gray color.\n " ;
146+ for (long i = 0 ; i < numSpheres; ++i) {
147+ colors[i] = glm::vec3 (0 .5f , 0 .5f , 0 .5f );
148+ }
149+ }
150+
71151 if (!ply_read (ply)) {
72152 std::cerr << " Cound not read file: " << fn << ' \n ' ;
73153 return nullptr ;
0 commit comments