EgtExchange 2.7b2 :
- aggiunta importazione formato PLY - migliorata importazione formato OFF.
This commit is contained in:
Binary file not shown.
@@ -332,7 +332,9 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="ImportCsf.h" />
|
||||
<ClInclude Include="ImportDxf.h" />
|
||||
<ClInclude Include="ImportOff.h" />
|
||||
<ClInclude Include="ImportPly.h" />
|
||||
<ClInclude Include="ImportStl.h" />
|
||||
<ClInclude Include="miniply.h" />
|
||||
<ClInclude Include="pugiconfig.hpp" />
|
||||
<ClInclude Include="pugixml.hpp" />
|
||||
<ClInclude Include="resource.h" />
|
||||
@@ -375,8 +377,10 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="ImportDxfHeader.cpp" />
|
||||
<ClCompile Include="ImportDxfTabs.cpp" />
|
||||
<ClCompile Include="ImportOff.cpp" />
|
||||
<ClCompile Include="ImportPly.cpp" />
|
||||
<ClCompile Include="ImportPnt.cpp" />
|
||||
<ClCompile Include="ImportStl.cpp" />
|
||||
<ClCompile Include="miniply.cpp" />
|
||||
<ClCompile Include="pugixml.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
|
||||
@@ -381,6 +381,12 @@
|
||||
<ClInclude Include="..\Include\EExImportOff.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ImportPly.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="miniply.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
@@ -464,6 +470,12 @@
|
||||
<ClCompile Include="ImportOff.cpp">
|
||||
<Filter>File di origine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ImportPly.cpp">
|
||||
<Filter>File di origine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="miniply.cpp">
|
||||
<Filter>File di origine</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtExchange.rc">
|
||||
|
||||
+25
-5
@@ -116,6 +116,7 @@ ImportOff::ReadData( void)
|
||||
if ( ! StmFts.Start())
|
||||
return false ;
|
||||
// lettura delle facce
|
||||
int nBadFaces = 0 ;
|
||||
for ( int i = 0 ; i < nFaces ; ++ i) {
|
||||
if ( ! m_theScanner.GetLine( sLine))
|
||||
return false ;
|
||||
@@ -135,8 +136,12 @@ ImportOff::ReadData( void)
|
||||
return false ;
|
||||
Tria.SetP( j, vVert[nV]) ;
|
||||
}
|
||||
if ( ! Tria.Validate( true) || ! StmFts.AddTriangle( Tria))
|
||||
return false ;
|
||||
if ( Tria.Validate( true)) {
|
||||
if ( ! StmFts.AddTriangle( Tria))
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
++ nBadFaces ;
|
||||
}
|
||||
// se quadrilatero
|
||||
else if ( nFVs == 4) {
|
||||
@@ -150,9 +155,18 @@ ImportOff::ReadData( void)
|
||||
if ( j != 1)
|
||||
TriaB.SetP( ( j == 0 ? j : j - 1), vVert[nV]) ;
|
||||
}
|
||||
if ( ! TriaA.Validate( true) || ! TriaB.Validate( true) ||
|
||||
! StmFts.AddTriangle( TriaA) || ! StmFts.AddTriangle( TriaB))
|
||||
return false ;
|
||||
if ( TriaA.Validate( true)) {
|
||||
if ( ! StmFts.AddTriangle( TriaA))
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
++ nBadFaces ;
|
||||
if ( TriaB.Validate( true)) {
|
||||
if ( ! StmFts.AddTriangle( TriaB))
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
++ nBadFaces ;
|
||||
}
|
||||
// altrimenti poligono generico
|
||||
else {
|
||||
@@ -170,8 +184,14 @@ ImportOff::ReadData( void)
|
||||
if ( ! StmFts.AddSurfTriMesh( *pStm))
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
++ nBadFaces ;
|
||||
}
|
||||
}
|
||||
if ( nBadFaces > 0) {
|
||||
string sOut = " ImportOff : found " + ToString( nBadFaces) + " bad faces" ;
|
||||
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
||||
}
|
||||
|
||||
// Valido la superficie e calcolo le adiacenze
|
||||
if ( ! StmFts.End())
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
#include "/EgtDev/Include/EExImportOff.h"
|
||||
#include "/EgtDEv/Include/EGnScanner.h"
|
||||
|
||||
class Triangle3d ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class ImportOff : public IImportOff
|
||||
{
|
||||
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2025-2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ImportPLY.cpp Data : 28.02.25 Versione : 2.7b2
|
||||
// Contenuto : Implementazione della classe per l'importazione di PLY.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 28.02.25 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "ImportPly.h"
|
||||
#include "DllMain.h"
|
||||
#include "/EgtDev/Include/EExDllMain.h"
|
||||
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IImportPly*
|
||||
CreateImportPly( void)
|
||||
{
|
||||
// verifico la chiave e le opzioni
|
||||
if ( ! VerifyKey( KEYOPT_EEX_INPBASE))
|
||||
return nullptr ;
|
||||
// creo l'oggetto
|
||||
return static_cast<IImportPly*> ( new( nothrow) ImportPly) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ImportPly::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup, double dScaleFactor)
|
||||
{
|
||||
// verifico il DB geometrico
|
||||
if ( pGDB == nullptr) {
|
||||
LOG_ERROR( GetEExLogger(), "ImportPly : Error on GeomDB")
|
||||
return false ;
|
||||
}
|
||||
m_pGDB = pGDB ;
|
||||
|
||||
// verifico l'Id di gruppo
|
||||
if ( ! m_pGDB->ExistsObj( nIdGroup)) {
|
||||
LOG_ERROR( GetEExLogger(), "ImportPly : Error on IdGroup")
|
||||
return false ;
|
||||
}
|
||||
m_nIdGroup = nIdGroup ;
|
||||
|
||||
// verifico il fattore di scala
|
||||
if ( dScaleFactor < EPS_SMALL) {
|
||||
LOG_ERROR( GetEExLogger(), "ImportPly : Error on ScaleFactor too small (minimum 0.001).")
|
||||
return false ;
|
||||
}
|
||||
m_dScaleFactor = dScaleFactor ;
|
||||
|
||||
// inizializzo il lettore
|
||||
miniply::PLYReader TheReader( sFile.data()) ;
|
||||
if ( ! TheReader.valid()) {
|
||||
LOG_ERROR( GetEExLogger(), "ImportPly : Error on Init")
|
||||
return false ;
|
||||
}
|
||||
|
||||
// lettura dati
|
||||
return ReadData( TheReader) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ImportPly::ReadData( miniply::PLYReader& TheReader)
|
||||
{
|
||||
typedef std::vector<float> FLTVECTOR ; // vettore di float
|
||||
|
||||
uint32_t propIdxs[3] ;
|
||||
bool bGotVerts = false, bGotFaces = false ;
|
||||
|
||||
int nVerts = 0 ;
|
||||
FLTVECTOR vVert ;
|
||||
int nTrias = 0 ;
|
||||
INTVECTOR vTria ;
|
||||
while ( TheReader.has_element() && ( ! bGotVerts || ! bGotFaces)) {
|
||||
// Recupero i vertici
|
||||
if ( TheReader.element_is( miniply::kPLYVertexElement) && TheReader.load_element() && TheReader.find_pos( propIdxs)) {
|
||||
nVerts = TheReader.num_rows() ;
|
||||
vVert.resize( 3 * nVerts) ;
|
||||
TheReader.extract_properties( propIdxs, 3, miniply::PLYPropertyType::Float, vVert.data()) ;
|
||||
bGotVerts = true ;
|
||||
}
|
||||
// Recupero gli indici dei vertici dei triangoli delle facce
|
||||
else if ( TheReader.element_is( miniply::kPLYFaceElement) && TheReader.load_element() && TheReader.find_indices( propIdxs)) {
|
||||
bool bPolys = TheReader.requires_triangulation( propIdxs[0]) ;
|
||||
if ( bPolys && ! bGotVerts) {
|
||||
string sOut = " ImportPly : need vertex positions to triangulate faces" ;
|
||||
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
||||
return false ;
|
||||
}
|
||||
if ( bPolys) {
|
||||
nTrias = TheReader.num_triangles( propIdxs[0]) ;
|
||||
vTria.resize( 3 * nTrias) ;
|
||||
TheReader.extract_triangles( propIdxs[0], vVert.data(), nVerts, miniply::PLYPropertyType::Int, vTria.data()) ;
|
||||
}
|
||||
else {
|
||||
nTrias = TheReader.num_rows() ;
|
||||
vTria.resize( 3 * nTrias) ;
|
||||
TheReader.extract_list_property( propIdxs[0], miniply::PLYPropertyType::Int, vTria.data()) ;
|
||||
}
|
||||
bGotFaces = true ;
|
||||
}
|
||||
if ( bGotVerts && bGotFaces)
|
||||
break ;
|
||||
TheReader.next_element() ;
|
||||
}
|
||||
|
||||
// Controllo lettura effettiuata di vertici e facce
|
||||
if ( ! bGotVerts) {
|
||||
string sOut = " ImportPly : vertex positions not found" ;
|
||||
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
||||
return false ;
|
||||
}
|
||||
if ( ! bGotFaces) {
|
||||
string sOut = " ImportPly : face indices not found" ;
|
||||
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
||||
return false ;
|
||||
}
|
||||
|
||||
// Costruttore di trimesh da insieme disordinato di triangoli
|
||||
StmFromTriangleSoup StmFts ;
|
||||
if ( ! StmFts.Start())
|
||||
return false ;
|
||||
// ciclo sui triangoli
|
||||
int nBadTrias = 0 ;
|
||||
for ( int i = 0 ; i < nTrias ; ++ i) {
|
||||
int nT = 3 * i ;
|
||||
Triangle3d Tria ;
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nV = 3 * vTria[nT+j] ;
|
||||
Point3d ptP( vVert[nV], vVert[nV+1], vVert[nV+2]) ;
|
||||
ptP *= m_dScaleFactor ;
|
||||
Tria.SetP( j, ptP) ;
|
||||
}
|
||||
if ( Tria.Validate( true)) {
|
||||
if ( ! StmFts.AddTriangle( Tria)) {
|
||||
string sOut = " ImportPly : error adding triangle" ;
|
||||
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
else
|
||||
++ nBadTrias ;
|
||||
}
|
||||
if ( nBadTrias > 0) {
|
||||
string sOut = " ImportPly : found " + ToString( nBadTrias) + " bad triangles" ;
|
||||
LOG_ERROR( GetEExLogger(), sOut.c_str())
|
||||
}
|
||||
|
||||
// Valido la superficie e calcolo le adiacenze
|
||||
if ( ! StmFts.End())
|
||||
return false ;
|
||||
// inserisco l'oggetto nel DB geometrico
|
||||
PtrOwner<ISurfTriMesh> pSTM( StmFts.GetSurf()) ;
|
||||
int nIdNew = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nIdGroup, Release( pSTM)) ;
|
||||
if ( nIdNew == GDB_ID_NULL)
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2025-2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ImportPly.h Data : 28.02.25 Versione : 2.7b2
|
||||
// Contenuto : Dichiarazione della classe ImportPly.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 28.02.25 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "miniply.h"
|
||||
#include "/EgtDev/Include/EExImportPly.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class ImportPly : public IImportPly
|
||||
{
|
||||
public :
|
||||
virtual bool Import( const std::string& sFile, IGeomDB* pGDB, int nIdGroup, double dScaleFactor = 1) ;
|
||||
|
||||
private :
|
||||
bool ReadData( miniply::PLYReader& TheReader) ;
|
||||
|
||||
private :
|
||||
IGeomDB* m_pGDB ;
|
||||
int m_nIdGroup ;
|
||||
double m_dScaleFactor ;
|
||||
} ;
|
||||
+2058
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Vilya Harvey
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MINIPLY_H
|
||||
#define MINIPLY_H
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
/// miniply - A simple and fast parser for PLY files
|
||||
/// ================================================
|
||||
///
|
||||
/// For details about the PLY format see:
|
||||
/// * http://paulbourke.net/dataformats/ply/
|
||||
/// * https://en.wikipedia.org/wiki/PLY_(file_format)
|
||||
|
||||
namespace miniply {
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
|
||||
static constexpr uint32_t kInvalidIndex = 0xFFFFFFFFu;
|
||||
|
||||
// Standard PLY element names
|
||||
extern const char* kPLYVertexElement; // "vertex"
|
||||
extern const char* kPLYFaceElement; // "face"
|
||||
|
||||
|
||||
//
|
||||
// PLY Parsing types
|
||||
//
|
||||
|
||||
enum class PLYFileType {
|
||||
ASCII,
|
||||
Binary,
|
||||
BinaryBigEndian,
|
||||
};
|
||||
|
||||
|
||||
enum class PLYPropertyType {
|
||||
Char,
|
||||
UChar,
|
||||
Short,
|
||||
UShort,
|
||||
Int,
|
||||
UInt,
|
||||
Float,
|
||||
Double,
|
||||
|
||||
None, //!< Special value used in Element::listCountType to indicate a non-list property.
|
||||
};
|
||||
|
||||
|
||||
struct PLYProperty {
|
||||
std::string name;
|
||||
PLYPropertyType type = PLYPropertyType::None; //!< Type of the data. Must be set to a value other than None.
|
||||
PLYPropertyType countType = PLYPropertyType::None; //!< None indicates this is not a list type, otherwise it's the type for the list count.
|
||||
uint32_t offset = 0; //!< Byte offset from the start of the row.
|
||||
uint32_t stride = 0;
|
||||
|
||||
std::vector<uint8_t> listData;
|
||||
std::vector<uint32_t> rowCount; // Entry `i` is the number of items (*not* the number of bytes) in row `i`.
|
||||
};
|
||||
|
||||
|
||||
struct PLYElement {
|
||||
std::string name; //!< Name of this element.
|
||||
std::vector<PLYProperty> properties;
|
||||
uint32_t count = 0; //!< The number of items in this element (e.g. the number of vertices if this is the vertex element).
|
||||
bool fixedSize = true; //!< `true` if there are only fixed-size properties in this element, i.e. no list properties.
|
||||
uint32_t rowStride = 0; //!< The number of bytes from the start of one row to the start of the next, for this element.
|
||||
|
||||
void calculate_offsets();
|
||||
|
||||
/// Returns the index for the named property in this element, or `kInvalidIndex`
|
||||
/// if it can't be found.
|
||||
uint32_t find_property(const char* propName) const;
|
||||
|
||||
/// Return the indices for several properties in one go. Use it like this:
|
||||
/// ```
|
||||
/// uint32_t indexes[3];
|
||||
/// if (elem.find_properties(indexes, 3, "foo", "bar", "baz")) { ... }
|
||||
/// ```
|
||||
/// `propIdxs` is where the property indexes will be stored. `numIdxs` is
|
||||
/// the number of properties we will look up. There must be exactly
|
||||
/// `numIdxs` parameters after `numIdxs`; each of the is a c-style string
|
||||
/// giving the name of a property.
|
||||
///
|
||||
/// The return value will be true if all properties were found. If it was
|
||||
/// not true, you should not use any values from propIdxs.
|
||||
bool find_properties(uint32_t propIdxs[], uint32_t numIdxs, ...) const;
|
||||
|
||||
/// Same as `find_properties`, for when you already have a `va_list`. This
|
||||
/// is called internally by both `PLYElement::find_properties` and
|
||||
/// `PLYReader::find_properties`.
|
||||
bool find_properties_va(uint32_t propIdxs[], uint32_t numIdxs, va_list names) const;
|
||||
|
||||
/// Call this on the element at some point before you load its data, when
|
||||
/// you know that every row's list will have the same length. It will
|
||||
/// replace the single variable-size property with a set of new fixed-size
|
||||
/// properties: one for the list count, followed by one for each of the
|
||||
/// list values. This will allow miniply to load and extract the property
|
||||
/// data a lot more efficiently, giving a big performance increase.
|
||||
///
|
||||
/// After you've called this, you must use PLYReader's `extract_columns`
|
||||
/// method to get the data, rather than `extract_list_column`.
|
||||
///
|
||||
/// The `newPropIdxs` parameter must be an array with at least `listSize`
|
||||
/// entries. If the function returns true, this will have been populated
|
||||
/// with the indices of the new properties that represent the list values
|
||||
/// (i.e. not including the list count property, which will have the same
|
||||
/// index as the old list property).
|
||||
///
|
||||
/// The function returns false if the property index is invalid, or the
|
||||
/// property it refers to is not a list property. In these cases it will
|
||||
/// not modify anything. Otherwise it will return true.
|
||||
bool convert_list_to_fixed_size(uint32_t listPropIdx, uint32_t listSize, uint32_t newPropIdxs[]);
|
||||
};
|
||||
|
||||
|
||||
class PLYReader {
|
||||
public:
|
||||
PLYReader(const char* filename);
|
||||
~PLYReader();
|
||||
|
||||
bool valid() const;
|
||||
bool has_element() const;
|
||||
const PLYElement* element() const;
|
||||
bool load_element();
|
||||
void next_element();
|
||||
|
||||
PLYFileType file_type() const;
|
||||
int version_major() const;
|
||||
int version_minor() const;
|
||||
uint32_t num_elements() const;
|
||||
uint32_t find_element(const char* name) const;
|
||||
PLYElement* get_element(uint32_t idx);
|
||||
|
||||
/// Check whether the current element has the given name.
|
||||
bool element_is(const char* name) const;
|
||||
|
||||
/// Number of rows in the current element.
|
||||
uint32_t num_rows() const;
|
||||
|
||||
/// Returns the index for the named property in the current element, or
|
||||
/// `kInvalidIndex` if it can't be found.
|
||||
uint32_t find_property(const char* name) const;
|
||||
|
||||
/// Equivalent to calling `find_properties` on the current element.
|
||||
bool find_properties(uint32_t propIdxs[], uint32_t numIdxs, ...) const;
|
||||
|
||||
/// Copy the data for the specified properties into `dest`, which must be
|
||||
/// an array with at least enough space to hold all of the extracted column
|
||||
/// data. `propIdxs` is an array containing the indexes of the properties
|
||||
/// to copy; it has `numProps` elements.
|
||||
///
|
||||
/// `destType` specifies the data type for values stored in `dest`. All
|
||||
/// property values will be converted to this type if necessary.
|
||||
///
|
||||
/// This function does some checks up front to pick the most efficient code
|
||||
/// path for extracting the data. It considers:
|
||||
/// (a) whether any data conversion is required.
|
||||
/// (b) whether all property values to be extracted are in contiguous
|
||||
/// memory locations for any given item.
|
||||
/// (c) whether the data for all rows is contiguous in memory.
|
||||
/// In the best case it reduces to a single memcpy call. In the worst case
|
||||
/// we must iterate over all values to be copied, applying type conversions
|
||||
/// as we go.
|
||||
///
|
||||
/// Note that this function does not handle list-valued properties. Use
|
||||
/// `extract_list_column()` for those instead.
|
||||
bool extract_properties(const uint32_t propIdxs[], uint32_t numProps, PLYPropertyType destType, void* dest) const;
|
||||
|
||||
/// The same as `extract_properties`, but does not require rows in the
|
||||
/// destination to be contiguous: `destStride` is the number of bytes
|
||||
/// between the start of one row and the start of the next row in the
|
||||
/// destination memory.
|
||||
///
|
||||
/// This is useful for when your destination is an array of structs where
|
||||
/// you cannot extract all of the properties with a single
|
||||
/// `extract_properties` call, e.g. when not all of the struct members
|
||||
/// have the same type, or when the data you're extracting is only a
|
||||
/// subset of the columns in each destination row.
|
||||
///
|
||||
/// This is a tiny bit slower than `extract_properties`. Wherever possible
|
||||
/// you should use `extract_properties` in preference to this method.
|
||||
bool extract_properties_with_stride(const uint32_t propIdxs[], uint32_t numProps, PLYPropertyType destType, void* dest, uint32_t destStride) const;
|
||||
|
||||
/// Get the array of item counts for a list property. Entry `i` in this
|
||||
/// array is the number of items in the `i`th list.
|
||||
const uint32_t* get_list_counts(uint32_t propIdx) const;
|
||||
|
||||
/// Get the sum of all item counts for a list property. This can be useful
|
||||
/// to determine how big a destination array you'll need for a call to
|
||||
/// `extract_list_property`. It's equivalent to summing up all the values
|
||||
/// in the array returned by `get_list_counts`, but faster.
|
||||
uint32_t sum_of_list_counts(uint32_t propIdx) const;
|
||||
|
||||
const uint8_t* get_list_data(uint32_t propIdx) const;
|
||||
bool extract_list_property(uint32_t propIdx, PLYPropertyType destType, void* dest) const;
|
||||
|
||||
uint32_t num_triangles(uint32_t propIdx) const;
|
||||
bool requires_triangulation(uint32_t propIdx) const;
|
||||
bool extract_triangles(uint32_t propIdx, const float pos[], uint32_t numVerts, PLYPropertyType destType, void* dest) const;
|
||||
|
||||
bool find_pos(uint32_t propIdxs[3]) const;
|
||||
bool find_normal(uint32_t propIdxs[3]) const;
|
||||
bool find_texcoord(uint32_t propIdxs[2]) const;
|
||||
bool find_color(uint32_t propIdxs[3]) const;
|
||||
bool find_indices(uint32_t propIdxs[1]) const;
|
||||
|
||||
private:
|
||||
bool refill_buffer();
|
||||
bool rewind_to_safe_char();
|
||||
bool accept();
|
||||
bool advance();
|
||||
bool next_line();
|
||||
bool match(const char* str);
|
||||
bool which(const char* values[], uint32_t* index);
|
||||
bool which_property_type(PLYPropertyType* type);
|
||||
bool keyword(const char* kw);
|
||||
bool identifier(char* dest, size_t destLen);
|
||||
|
||||
template <class T> // T must be a type compatible with uint32_t.
|
||||
bool typed_which(const char* values[], T* index) {
|
||||
return which(values, reinterpret_cast<uint32_t*>(index));
|
||||
}
|
||||
|
||||
bool int_literal(int* value);
|
||||
bool float_literal(float* value);
|
||||
bool double_literal(double* value);
|
||||
|
||||
bool parse_elements();
|
||||
bool parse_element();
|
||||
bool parse_property(std::vector<PLYProperty>& properties);
|
||||
|
||||
bool load_fixed_size_element(PLYElement& elem);
|
||||
bool load_variable_size_element(PLYElement& elem);
|
||||
|
||||
bool load_ascii_scalar_property(PLYProperty& prop, size_t& destIndex);
|
||||
bool load_ascii_list_property(PLYProperty& prop);
|
||||
bool load_binary_scalar_property(PLYProperty& prop, size_t& destIndex);
|
||||
bool load_binary_list_property(PLYProperty& prop);
|
||||
bool load_binary_scalar_property_big_endian(PLYProperty& prop, size_t& destIndex);
|
||||
bool load_binary_list_property_big_endian(PLYProperty& prop);
|
||||
|
||||
bool ascii_value(PLYPropertyType propType, uint8_t value[8]);
|
||||
|
||||
private:
|
||||
FILE* m_f = nullptr;
|
||||
char* m_buf = nullptr;
|
||||
const char* m_bufEnd = nullptr;
|
||||
const char* m_pos = nullptr;
|
||||
const char* m_end = nullptr;
|
||||
bool m_inDataSection = false;
|
||||
bool m_atEOF = false;
|
||||
int64_t m_bufOffset = 0;
|
||||
|
||||
bool m_valid = false;
|
||||
|
||||
PLYFileType m_fileType = PLYFileType::ASCII; //!< Whether the file was ascii, binary little-endian, or binary big-endian.
|
||||
int m_majorVersion = 0;
|
||||
int m_minorVersion = 0;
|
||||
std::vector<PLYElement> m_elements; //!< Element descriptors for this file.
|
||||
|
||||
size_t m_currentElement = 0;
|
||||
bool m_elementLoaded = false;
|
||||
std::vector<uint8_t> m_elementData;
|
||||
|
||||
char* m_tmpBuf = nullptr;
|
||||
};
|
||||
|
||||
|
||||
/// Given a polygon with `n` vertices, where `n` > 3, triangulate it and
|
||||
/// store the indices for the resulting triangles in `dst`. The `pos`
|
||||
/// parameter is the array of all vertex positions for the mesh; `indices` is
|
||||
/// the list of `n` indices for the polygon we're triangulating; and `dst` is
|
||||
/// where we write the new indices to.
|
||||
///
|
||||
/// The triangulation will always produce `n - 2` triangles, so `dst` must
|
||||
/// have enough space for `3 * (n - 2)` indices.
|
||||
///
|
||||
/// If `n == 3`, we simply copy the input indices to `dst`. If `n < 3`,
|
||||
/// nothing gets written to dst.
|
||||
///
|
||||
/// The return value is the number of triangles.
|
||||
uint32_t triangulate_polygon(uint32_t n, const float pos[], uint32_t numVerts, const int indices[], int dst[]);
|
||||
|
||||
} // namespace miniply
|
||||
|
||||
#endif // MINIPLY_H
|
||||
Reference in New Issue
Block a user