33#include " MMVII_Geom3D.h"
44#include " ../Mesh/happly.h"
55#include < functional>
6+ #include < E57Format/E57SimpleReader.h>
67
78/* *
89 \file importStaticScan.cpp
@@ -31,7 +32,11 @@ public :
3132
3233
3334 void readPlyPoints (std::string aPlyFileName);
35+ #if (USE_LIBE57FORMAT)
36+ void readE57Points (std::string aE57FileName);
37+ #endif
3438 void convertToThetaPhiDist ();
39+ void convertToXYZ ();
3540 void getAnglesMinMax ();
3641 void estimatePhiStep ();
3742 void computeLineCol ();
@@ -48,6 +53,11 @@ private :
4853 bool mNoMiss ; // are every point present in cloud, even when no response?
4954
5055 // data
56+ bool mHasCartesian ; // in original read data
57+ bool mHasIntensity ; // in original read data
58+ bool mHasSpherical ; // in original read data
59+ bool mHasRowCol ; // in original read data
60+
5161 tREAL8 mDistMinToExist ; // boundary to check if no response points are present
5262 std::vector<cPt3dr> mVectPtsXYZ ;
5363 std::vector<tREAL8> mVectPtsIntens ;
@@ -99,12 +109,26 @@ cPt3dr cart2spher(const cPt3dr & aPtCart)
99109 return {theta, phi, dist};
100110}
101111
112+ cPt3dr spher2cart (const cPt3dr & aPtspher)
113+ {
114+ tREAL8 dhz = aPtspher.z ()*cos (aPtspher.y ());
115+ tREAL8 x = dhz* cos (aPtspher.x ());
116+ tREAL8 y = dhz* sin (aPtspher.x ());
117+ tREAL8 z = aPtspher.z ()*sin (aPtspher.y ());
118+ return {x, y, z};
119+ }
120+
121+
102122using namespace happly ;
103123
104124void cAppli_ImportStaticScan::readPlyPoints (std::string aPlyFileName)
105125{
126+ StdOut () << " Read ply file " << aPlyFileName << " ..." << std::endl;
106127 mVectPtsXYZ .clear ();
128+ mVectPtsTPD .clear ();
107129 mVectPtsIntens .clear ();
130+ mVectPtsCol .clear ();
131+ mVectPtsLine .clear ();
108132 try
109133 {
110134 PLYData aPlyF (aPlyFileName,false );
@@ -119,13 +143,19 @@ void cAppli_ImportStaticScan::readPlyPoints(std::string aPlyFileName)
119143 }
120144 }
121145
146+ mHasCartesian = true ;
147+ mHasIntensity = false ;
148+ mHasSpherical = false ;
149+ mHasRowCol = false ;
150+
122151 // try to fill points attribute with any "i", "I" or "*intens*" property
123152 auto aVertProps = aPlyF.getElement (" vertex" ).getPropertyNames ();
124153 auto aPropIntensityName = std::find_if (aVertProps.begin (), aVertProps.end (), [](const std::string &s){
125154 return (ToLower (s)==" i" ) || (ToLower (s).find (" intens" ) != std::string::npos);
126155 });
127156 if (aPropIntensityName!= aVertProps.end ())
128157 {
158+ mHasIntensity = true ;
129159 mVectPtsIntens = aPlyF.getElement (" vertex" ).getProperty <tREAL8>(*aPropIntensityName);
130160 }
131161
@@ -136,6 +166,86 @@ void cAppli_ImportStaticScan::readPlyPoints(std::string aPlyFileName)
136166 }
137167}
138168
169+ #if (USE_LIBE57FORMAT)
170+ void cAppli_ImportStaticScan::readE57Points (std::string aE57FileName)
171+ {
172+ StdOut () << " Read e57 file " << aE57FileName << " ..." << std::endl;
173+ mVectPtsXYZ .clear ();
174+ mVectPtsTPD .clear ();
175+ mVectPtsIntens .clear ();
176+ mVectPtsCol .clear ();
177+ mVectPtsLine .clear ();
178+ try
179+ {
180+ e57 ::Reader reader ( aE57FileName, {});
181+ MMVII_INTERNAL_ASSERT_tiny (reader.IsOpen (), " Error: unable to open file " + aE57FileName)
182+ StdOut () << " Image2DCount: " << reader.GetImage2DCount () << " \n " ;
183+ StdOut () << " Data3DCount: " << reader.GetData3DCount () << " \n " ;
184+ MMVII_INTERNAL_ASSERT_tiny (reader.GetData3DCount ()==1 , " Error: File should have exactly 1 scan for now" )
185+ e57 ::E57Root fileHeader;
186+ reader.GetE57Root ( fileHeader );
187+ /* StdOut() << fileHeader.formatName << " =? " << "ASTM E57 3D Imaging Data File" << std::endl;
188+ StdOut() << fileHeader.versionMajor << " =? " << 1 << std::endl;
189+ StdOut() << fileHeader.versionMinor << " =? " << 0 << std::endl;
190+ StdOut() << fileHeader.guid << " =? " << "Zero Points GUID" << std::endl;*/
191+ e57 ::Data3D data3DHeader;
192+ reader.ReadData3D ( 0 , data3DHeader );
193+ // data3DHeader.indexBounds is not correct
194+ const uint64_t cNumPoints = data3DHeader.pointCount ;
195+ e57 ::Data3DPointsFloat pointsData ( data3DHeader );
196+ auto vectorReader = reader.SetUpData3DPointsData ( 0 , cNumPoints, pointsData );
197+ const uint64_t cNumRead = vectorReader.read ();
198+ MMVII_INTERNAL_ASSERT_tiny (cNumPoints==cNumRead, " Error: cNumPoints!=cNumRead" )
199+
200+ mHasCartesian = pointsData.cartesianX && pointsData.cartesianY && pointsData.cartesianZ ;
201+ mHasIntensity = pointsData.intensity ;
202+ mHasSpherical = pointsData.sphericalAzimuth && pointsData.sphericalElevation && pointsData.sphericalRange ;
203+ mHasRowCol = pointsData.columnIndex && pointsData.rowIndex ;
204+
205+ if (mHasCartesian ){
206+ mVectPtsXYZ .resize (cNumRead);
207+ for (uint64_t i=0 ;i<cNumRead;++i)
208+ mVectPtsXYZ [i] = {pointsData.cartesianX [i], pointsData.cartesianY [i], pointsData.cartesianZ [i]};
209+ }
210+ if (mHasSpherical ){
211+ mVectPtsTPD .resize (cNumRead);
212+ for (uint64_t i=0 ;i<cNumRead;++i)
213+ mVectPtsTPD [i] = {pointsData.sphericalAzimuth [i], pointsData.sphericalElevation [i], pointsData.sphericalRange [i]};
214+ }
215+ if (mHasIntensity ){
216+ mVectPtsIntens .resize (cNumRead);
217+ for (uint64_t i=0 ;i<cNumRead;++i)
218+ mVectPtsIntens [i] = pointsData.intensity [i];
219+ }
220+ if (mHasRowCol ){
221+ mVectPtsLine .resize (cNumRead);
222+ mVectPtsCol .resize (cNumRead);
223+ mSL_data .mMaxLine = 0 ;
224+ for (uint64_t i=0 ;i<cNumRead;++i)
225+ {
226+ mVectPtsLine [i] = pointsData.rowIndex [i];
227+ if (pointsData.rowIndex [i]>mSL_data .mMaxLine )
228+ mSL_data .mMaxLine = pointsData.rowIndex [i];
229+ }
230+ mSL_data .mMaxCol = 0 ;
231+ for (uint64_t i=0 ;i<cNumRead;++i)
232+ {
233+ mVectPtsCol [i] = pointsData.columnIndex [i];
234+ if (pointsData.columnIndex [i]>mSL_data .mMaxCol )
235+ mSL_data .mMaxCol = pointsData.columnIndex [i];
236+ }
237+ }
238+
239+ vectorReader.close ();
240+
241+ }
242+ catch (const std::runtime_error &e)
243+ {
244+ MMVII_UserError (eTyUEr::eReadFile, std::string (" Error reading E57 file \" " ) + aE57FileName + " \" : " + e.what ());
245+ }
246+ }
247+ #endif
248+
139249void cAppli_ImportStaticScan::convertToThetaPhiDist ()
140250{
141251 mNoMiss = false ;
@@ -166,6 +276,37 @@ void cAppli_ImportStaticScan::convertToThetaPhiDist()
166276 << mSL_data .mPhiMin << " , " << mSL_data .mPhiMax << " \n " ;
167277}
168278
279+
280+ void cAppli_ImportStaticScan::convertToXYZ ()
281+ {
282+ mNoMiss = false ;
283+ mVectPtsXYZ .resize (mVectPtsTPD .size ());
284+ size_t aNbPtsNul = 0 ;
285+ for (size_t i=0 ; i<mVectPtsTPD .size (); ++i)
286+ {
287+ mVectPtsXYZ [i] = spher2cart (mVectPtsTPD [i]);
288+ if (mVectPtsTPD [i].z ()<mDistMinToExist )
289+ aNbPtsNul++;
290+ }
291+ StdOut () << aNbPtsNul << " null points\n " ;
292+ mNoMiss = aNbPtsNul>0 ;
293+
294+ // get min max theta phi
295+ cWhichMinMax<int , tREAL8> aMinMaxTheta;
296+ cWhichMinMax<int , tREAL8> aMinMaxPhi;
297+ for (const auto & aPtAng: mVectPtsTPD )
298+ {
299+ aMinMaxTheta.Add (0 ,aPtAng.x ());
300+ aMinMaxPhi.Add (0 ,aPtAng.y ());
301+ }
302+ mSL_data .mThetaMin = aMinMaxTheta.Min ().ValExtre ();
303+ mSL_data .mThetaMax = aMinMaxTheta.Max ().ValExtre ();
304+ mSL_data .mPhiMin = aMinMaxPhi.Min ().ValExtre ();
305+ mSL_data .mPhiMax = aMinMaxPhi.Max ().ValExtre ();
306+ StdOut () << " Box: theta " << mSL_data .mThetaMin << " , " << mSL_data .mThetaMax << " phi "
307+ << mSL_data .mPhiMin << " , " << mSL_data .mPhiMax << " \n " ;
308+ }
309+
169310void cAppli_ImportStaticScan::estimatePhiStep ()
170311{
171312 // find phi min diff
@@ -197,6 +338,8 @@ void cAppli_ImportStaticScan::estimatePhiStep()
197338
198339void cAppli_ImportStaticScan::computeLineCol ()
199340{
341+ if (mHasRowCol )
342+ return ; // nothing to do
200343 tREAL8 aColChangeDetectorInPhistep = 100 ;
201344
202345 // compute line and col for each point
@@ -387,51 +530,76 @@ tREAL8 cAppli_ImportStaticScan::doVerticalize()
387530int cAppli_ImportStaticScan::Exe ()
388531{
389532 mPhProj .FinishInit ();
390- readPlyPoints (mNameFile );
533+ std::string aPostFix = ToLower (LastPostfix (mNameFile ));
534+ if (aPostFix==" ply" )
535+ {
536+ readPlyPoints (mNameFile );
537+ } else if (aPostFix==" e57" ) {
538+ #if (USE_LIBE57FORMAT)
539+ readE57Points (mNameFile );
540+ #else
541+ MMVII_INTERNAL_ASSERT_tiny (false , " Error: missing libe57format" );
542+ #endif
543+ } else
544+ MMVII_INTERNAL_ASSERT_tiny (false , " Error: unknown file format for " +mNameFile );
545+
546+ StdOut () << " Read data: " ;
547+ if (mHasCartesian )
548+ StdOut () << mVectPtsXYZ .size () << " cartesian points" ;
549+ if (mHasSpherical )
550+ StdOut () << mVectPtsTPD .size () << " spherical points" ;
551+ if (mHasIntensity )
552+ StdOut () << " with intensity" ;
553+ if (mHasRowCol )
554+ StdOut () << " with row-col" ;
555+ StdOut () << " \n " ;
556+
557+ if (mHasCartesian && !mHasSpherical )
558+ {
559+ cRotation3D<tREAL8> aRotFrame = cRotation3D<tREAL8>::RotFromCanonicalAxes (mTransfoIJK );
560+ // apply rotframe to original points
561+ for (auto & aPtXYZ : mVectPtsXYZ )
562+ {
563+ aPtXYZ = aRotFrame.Value (aPtXYZ);
564+ }
565+ convertToThetaPhiDist ();
566+ } else if (!mHasCartesian && mHasSpherical ) // mTransfoIJK not used if spherical
567+ {
568+ convertToXYZ ();
569+ }
391570
392- StdOut () << " Got " << mVectPtsXYZ .size () << " points.\n " ;
393571 MMVII_INTERNAL_ASSERT_tiny (!mVectPtsXYZ .empty ()," Error reading " +mNameFile );
394- if (! mVectPtsIntens . empty () )
572+ if (mHasIntensity )
395573 {
396- StdOut () << " Intensity found.\n " ;
397574 MMVII_INTERNAL_ASSERT_tiny (mVectPtsXYZ .size ()==mVectPtsIntens .size ()," Error reading " +mNameFile );
398575 }
399576
400- StdOut () << " Sample :\n " ;
577+ StdOut () << " Cartesian sample :\n " ;
401578 for (size_t i=0 ; (i<10 )&&(i<mVectPtsXYZ .size ()); ++i)
402579 {
403580 StdOut () << mVectPtsXYZ .at (i);
404- if (! mVectPtsIntens . empty () )
581+ if (mHasIntensity )
405582 StdOut () << " " << mVectPtsIntens .at (i);
406583 StdOut () << " \n " ;
407584 }
408585 StdOut () << " ...\n " ;
409586
410- cRotation3D<tREAL8> aRotFrame = cRotation3D<tREAL8>::RotFromCanonicalAxes (mTransfoIJK );
411- // apply rotframe to original points
412- for (auto & aPtXYZ : mVectPtsXYZ )
413- {
414- aPtXYZ = aRotFrame.Value (aPtXYZ);
415- }
416-
417- convertToThetaPhiDist ();
418-
419587 // check theta-phi :
420588 StdOut () << " Spherical sample:\n " ;
421589 for (size_t i=0 ; (i<10 )&&(i<mVectPtsTPD .size ()); ++i)
422590 {
423591 StdOut () << mVectPtsTPD [i];
424592 StdOut () << " \n " ;
425593 }
426- StdOut () << " ...\n " ;
594+ StdOut () << " ..." << std::endl ;
427595
428596 estimatePhiStep ();
429-
430597 computeLineCol ();
431598
432599 // fill rasters
433600 /* fillRaster<tU_INT1>("totoMask.png", [this](int i){auto aPtAng = mVectPtsTPD[i];return (aPtAng.z()<mDistMinToExist)?0:255;} );
434- fillRaster<tU_INT1>("totoIntens.png", [this](int i){return mVectPtsIntens[i]*255;} );
601+ if (mHasIntensity)
602+ fillRaster<tU_INT1>("totoIntens.png", [this](int i){return mVectPtsIntens[i]*255;} );
435603 fillRaster<tU_INT4>("totoIndex.png", [](int i){return i;} );
436604 fillRaster<float>("totoDist.tif", [this](int i){auto aPtAng = mVectPtsTPD[i];return aPtAng.z();} );
437605 fillRaster<float>("totoTheta.tif", [this](int i){auto aPtAng = mVectPtsTPD[i];return aPtAng.x();} );
@@ -444,7 +612,7 @@ int cAppli_ImportStaticScan::Exe()
444612 for (size_t i=0 ; (i<10 )&&(i<mVectPtsXYZ .size ()); ++i)
445613 {
446614 StdOut () << mVectPtsXYZ .at (i);
447- if (! mVectPtsIntens . empty () )
615+ if (mHasIntensity )
448616 StdOut () << " " << mVectPtsIntens .at (i);
449617 StdOut () << " \n " ;
450618 }
@@ -490,7 +658,8 @@ int cAppli_ImportStaticScan::Exe()
490658 mSL_data .mRasterMask = mPhProj .DPStaticLidar ().FullDirOut () + mSL_data .mStationName + " _" + mSL_data .mScanName + " _mask.tif" ;
491659
492660 fillRaster<tU_INT1>(mSL_data .mRasterMask , [this ](int i){auto aPtAng = mVectPtsTPD [i];return (aPtAng.z ()<mDistMinToExist )?0 :255 ;} );
493- fillRaster<tU_INT1>( mSL_data .mRasterIntensity , [this ](int i){return mVectPtsIntens [i]*255 ;} );
661+ if (mHasIntensity )
662+ fillRaster<tU_INT1>( mSL_data .mRasterIntensity , [this ](int i){return mVectPtsIntens [i]*255 ;} );
494663 fillRaster<float >(mSL_data .mRasterDistance , [this ](int i){auto aPtAng = mVectPtsTPD [i];return aPtAng.z ();} );
495664
496665 fillRaster<tU_INT4>(" titiIndex.png" , [](int i){return i;} );
0 commit comments