3333
3434#include < stdio.h>
3535#include < vector>
36+ #include < float.h>
3637#include " io_pdal_PointView.h"
3738#include " JavaPipeline.hpp"
3839#include " JavaTriangularMeshIterator.hpp"
@@ -52,6 +53,8 @@ using pdal::Dimension::Id;
5253using pdal::PointId;
5354using pdal::DimTypeList;
5455using pdal::SpatialReference;
56+ using pdal::TriangularMesh;
57+ using pdal::Triangle;
5558using pdal::DimType;
5659using pdal::pdal_error;
5760
@@ -225,6 +228,172 @@ JNIEXPORT jobject JNICALL Java_io_pdal_PointView_getTriangularMesh
225228 return mi;
226229}
227230
231+ JNIEXPORT jdoubleArray JNICALL Java_io_pdal_PointView_rasterizeTriangularMesh
232+ (JNIEnv *env, jobject obj, jdoubleArray extent, jint cols, jint rows, jobject jDimType, jstring name)
233+ {
234+ std::string cname = std::string (env->GetStringUTFChars (name, 0 ));
235+
236+ PointViewRawPtr *pvrp = getHandle<PointViewRawPtr>(env, obj);
237+ PointViewPtr pv = pvrp->shared_pointer ;
238+ TriangularMesh *mesh = pv->mesh (cname);
239+
240+ if (mesh == NULL )
241+ {
242+ throwExecutionException (env, " No mesh was generated. Check that the appropriate filter is a part of a PDAL Pipeline." );
243+ return env->NewDoubleArray (0 );
244+ }
245+
246+ jclass cDimType = env->GetObjectClass (jDimType);
247+ jfieldID fid = env->GetFieldID (cDimType, " id" , " Ljava/lang/String;" );
248+ jstring jid = reinterpret_cast <jstring>(env->GetObjectField (jDimType, fid));
249+
250+ PointLayoutPtr pl = pv->layout ();
251+ DimType dimType = pl->findDimType (std::string (env->GetStringUTFChars (jid, 0 )));
252+ Id dimId = dimType.m_id ;
253+
254+ int size = mesh->size ();
255+
256+ int length = cols * rows;
257+
258+ jdouble *ext = env->GetDoubleArrayElements (extent, 0 );
259+
260+ double exmin = ext[0 ];
261+ double eymin = ext[1 ];
262+ double exmax = ext[2 ];
263+ double eymax = ext[3 ];
264+
265+ env->ReleaseDoubleArrayElements (extent, ext, JNI_ABORT);
266+
267+ double w = (exmax - exmin) / cols;
268+ double h = (eymax - eymin) / rows;
269+
270+ jdoubleArray result = env->NewDoubleArray (length);
271+
272+ double buffer[length];
273+ std::fill (buffer, buffer + sizeof (buffer) / sizeof (double ), strtod (" NaN" , NULL ));
274+
275+ for (int id = 0 ; id < size; id++)
276+ {
277+ const Triangle& tri = (*mesh)[id];
278+ PointId a = tri.m_a ;
279+ PointId b = tri.m_b ;
280+ PointId c = tri.m_c ;
281+
282+ double v1x = pv->getFieldAs <double >(Id::X, a);
283+ double v1y = pv->getFieldAs <double >(Id::Y, a);
284+ double v1z = pv->getFieldAs <double >(dimId, a);
285+ double s1x = pv->getFieldAs <double >(Id::X, c);
286+ double s1y = pv->getFieldAs <double >(Id::Y, c);
287+
288+ double v2x = pv->getFieldAs <double >(Id::X, b);
289+ double v2y = pv->getFieldAs <double >(Id::Y, b);
290+ double v2z = pv->getFieldAs <double >(dimId, b);
291+ double s2x = pv->getFieldAs <double >(Id::X, a);
292+ double s2y = pv->getFieldAs <double >(Id::Y, a);
293+
294+ double v3x = pv->getFieldAs <double >(Id::X, c);
295+ double v3y = pv->getFieldAs <double >(Id::Y, c);
296+ double v3z = pv->getFieldAs <double >(dimId, c);
297+ double s3x = pv->getFieldAs <double >(Id::X, b);
298+ double s3y = pv->getFieldAs <double >(Id::Y, b);
299+
300+ double determinant = (v2y - v3y) * (v1x - v3x) + (v3x - v2x) * (v1y - v3y);
301+
302+ double ymin = std::min (v1y, std::min (v2y, v3y));
303+ double ymax = std::max (v1y, std::max (v2y, v3y));
304+
305+ double scanrow0 = std::max (std::ceil ((ymin - eymin) / h - 0.5 ), 0.0 );
306+ double scany = eymin + scanrow0 * h + h / 2.0 ;
307+
308+ while (scany < eymax && scany < ymax)
309+ {
310+ // get x at y for edge
311+ double xmin = -DBL_MAX;
312+ double xmax = DBL_MAX;
313+
314+ if (s1y != v1y)
315+ {
316+ double t = (scany - v1y) / (s1y - v1y);
317+ double xAtY1 = v1x + t * (s1x - v1x);
318+
319+ if (v1y < s1y)
320+ {
321+ // Lefty
322+ if (xmin < xAtY1) { xmin = xAtY1; }
323+ }
324+ else
325+ {
326+ // Righty
327+ if (xAtY1 < xmax) { xmax = xAtY1; }
328+ }
329+ }
330+
331+ if (s2y != v2y)
332+ {
333+ double t = (scany - v2y) / (s2y - v2y);
334+ double xAtY2 = v2x + t * (s2x - v2x);
335+
336+ if (v2y < s2y)
337+ {
338+ // Lefty
339+ if (xmin < xAtY2) { xmin = xAtY2; }
340+ }
341+ else
342+ {
343+ // Righty
344+ if (xAtY2 < xmax) { xmax = xAtY2; }
345+ }
346+ }
347+
348+ if (s3y != v3y)
349+ {
350+ double t = (scany - v3y) / (s3y - v3y);
351+ double xAtY3 = v3x + t * (s3x - v3x);
352+
353+ if (v3y < s3y)
354+ {
355+ // Lefty
356+ if (xmin < xAtY3) { xmin = xAtY3; }
357+ }
358+ else
359+ {
360+ // Righty
361+ if (xAtY3 < xmax) { xmax = xAtY3; }
362+ }
363+ }
364+
365+ double scancol0 = std::max (std::ceil ((xmin - exmin) / w - 0.5 ), 0.0 );
366+ double scanx = exmin + scancol0 * w + w / 2 ;
367+
368+ while (scanx < exmax && scanx < xmax)
369+ {
370+ int col = (int )((scanx - exmin) / w);
371+ int row = (int )((eymax - scany) / h);
372+
373+ if (0 <= col && col < cols && 0 <= row && row < rows)
374+ {
375+
376+ double lambda1 = ((v2y - v3y) * (scanx - v3x) + (v3x - v2x) * (scany - v3y)) / determinant;
377+ double lambda2 = ((v3y - v1y) * (scanx - v3x) + (v1x - v3x) * (scany - v3y)) / determinant;
378+ double lambda3 = 1.0 - lambda1 - lambda2;
379+
380+ double z = lambda1 * v1z + lambda2 * v2z + lambda3 * v3z;
381+
382+ buffer[row * cols + col] = z;
383+ }
384+
385+ scanx += w;
386+ }
387+
388+ scany += h;
389+ }
390+ }
391+
392+ env->SetDoubleArrayRegion (result, 0 , length, buffer);
393+
394+ return result;
395+ }
396+
228397JNIEXPORT void JNICALL Java_io_pdal_PointView_close
229398 (JNIEnv *env, jobject obj)
230399{
0 commit comments