Skip to content

Commit 9f49c0d

Browse files
authoredOct 5, 2021
MDAL update & FLO-2D bug fix (#45349)
API for edges edits data on volumes for dynamic drivers WRITE support for PLY Fix loading FLO-2D
1 parent dd95ea5 commit 9f49c0d

19 files changed

+2631
-291
lines changed
 

‎external/mdal/3rdparty/libplyxx.h

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
/*
2+
This file forked from https://github.com/srajotte/libplyxx
3+
4+
Copyright (c) 2016 Simon Rajotte
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
24+
Updated (c) 2021 Runette Software Ltd to make multiplatform, to complete the typemaps and add to voxel types.
25+
26+
Permission is hereby granted, free of charge, to any person obtaining a copy
27+
of this software and associated documentation files (the "Software"), to deal
28+
in the Software without restriction, including without limitation the rights
29+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30+
copies of the Software, and to permit persons to whom the Software is
31+
furnished to do so, subject to the following conditions:
32+
33+
The above copyright notice and this permission notice shall be included in all
34+
copies or substantial portions of the Software.
35+
36+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
42+
SOFTWARE.
43+
44+
*/
45+
46+
#pragma once
47+
48+
#include <vector>
49+
#include <array>
50+
#include <map>
51+
#include <unordered_map>
52+
#include <type_traits>
53+
#include <cassert>
54+
#include <memory>
55+
#include <functional>
56+
57+
#include "textio.h"
58+
59+
namespace libply
60+
{
61+
enum class Type
62+
{
63+
INT8,
64+
UINT8,
65+
INT16,
66+
UINT16,
67+
INT32,
68+
UINT32,
69+
FLOAT32,
70+
FLOAT64
71+
};
72+
73+
class IProperty
74+
{
75+
public:
76+
virtual ~IProperty() = default;
77+
78+
virtual IProperty &operator=( unsigned int value ) = 0;
79+
virtual IProperty &operator=( int value ) = 0;
80+
virtual IProperty &operator=( float value ) = 0;
81+
virtual IProperty &operator=( double value ) = 0;
82+
83+
virtual operator unsigned int() = 0;
84+
virtual operator int() = 0;
85+
virtual operator float() = 0;
86+
virtual operator double() = 0;
87+
88+
virtual bool isList() = 0;
89+
90+
};
91+
92+
template<typename InternalType>
93+
class ScalarProperty: public IProperty
94+
{
95+
public :
96+
97+
virtual ~ScalarProperty() = default;
98+
99+
virtual ScalarProperty &operator=( unsigned int value ) override
100+
{
101+
m_value = static_cast<InternalType>( value );
102+
return *this;
103+
};
104+
virtual ScalarProperty &operator=( int value ) override
105+
{
106+
m_value = static_cast<InternalType>( value );
107+
return *this;
108+
};
109+
virtual ScalarProperty &operator=( float value ) override
110+
{
111+
m_value = static_cast<InternalType>( value );
112+
return *this;
113+
};
114+
virtual ScalarProperty &operator=( double value ) override
115+
{
116+
m_value = static_cast<InternalType>( value );
117+
return *this;
118+
};
119+
120+
virtual operator unsigned int() override
121+
{
122+
return static_cast<unsigned int>( m_value );
123+
};
124+
virtual operator int() override
125+
{
126+
return static_cast<int>( m_value );
127+
};
128+
virtual operator float() override
129+
{
130+
return static_cast<float>( m_value );
131+
};
132+
virtual operator double() override
133+
{
134+
return static_cast<double>( m_value );
135+
};
136+
137+
virtual bool isList() override { return false; }
138+
139+
public:
140+
InternalType value() const { return m_value; };
141+
142+
private :
143+
InternalType m_value;
144+
};
145+
146+
class ListProperty : public IProperty
147+
{
148+
public:
149+
150+
IProperty &operator=( unsigned int ) override { return *this; };
151+
IProperty &operator=( int ) override { return *this; };
152+
IProperty &operator=( float ) override { return *this; };
153+
IProperty &operator=( double ) override { return *this; };
154+
155+
operator unsigned int() override { return 0; };
156+
operator int() override { return 0; };
157+
operator float() override { return 0; };
158+
operator double() override { return 0; };
159+
160+
bool isList() override { return true; }
161+
162+
void define( Type type, size_t size );
163+
size_t size() const { return list.size(); }
164+
165+
IProperty &value( size_t index );
166+
167+
private:
168+
std::vector<std::unique_ptr<IProperty>> list;
169+
std::unique_ptr<IProperty> getScalarProperty( Type type );
170+
};
171+
172+
struct ElementDefinition;
173+
174+
class ElementBuffer
175+
{
176+
public:
177+
ElementBuffer() = default;
178+
ElementBuffer( const ElementDefinition &definition );
179+
180+
public:
181+
size_t size() const { return properties.size(); };
182+
IProperty &operator[]( size_t index );
183+
184+
private:
185+
void appendScalarProperty( Type type );
186+
void appendListProperty( Type type );
187+
std::unique_ptr<IProperty> getScalarProperty( Type type );
188+
189+
private:
190+
std::vector<std::unique_ptr<IProperty>> properties;
191+
};
192+
193+
struct Property
194+
{
195+
Property( const std::string &name, Type type, bool isList )
196+
: name( name ), type( type ), isList( isList ) {};
197+
198+
std::string name;
199+
Type type;
200+
bool isList;
201+
size_t listCount;
202+
};
203+
204+
typedef std::size_t ElementSize;
205+
206+
struct Element
207+
{
208+
Element( const std::string &name, ElementSize size, const std::vector<Property> &properties )
209+
: name( name ), size( size ), properties( properties ) {};
210+
211+
std::string name;
212+
ElementSize size;
213+
std::vector<Property> properties;
214+
};
215+
216+
typedef std::function< void( ElementBuffer & ) > ElementReadCallback;
217+
218+
class FileParser;
219+
220+
typedef std::vector<Element> ElementsDefinition;
221+
typedef std::unordered_map<std::string, std::string> Metadata;
222+
223+
class File
224+
{
225+
public:
226+
File( const std::string &filename );
227+
~File();
228+
229+
ElementsDefinition definitions() const;
230+
Metadata metadata() const;
231+
void setElementReadCallback( std::string elementName, ElementReadCallback &readCallback );
232+
void read();
233+
234+
public:
235+
enum class Format
236+
{
237+
ASCII,
238+
BINARY_LITTLE_ENDIAN,
239+
BINARY_BIG_ENDIAN
240+
};
241+
242+
private:
243+
std::string m_filename;
244+
std::unique_ptr<FileParser> m_parser;
245+
};
246+
247+
248+
typedef std::function< void( ElementBuffer &, size_t index ) > ElementWriteCallback;
249+
250+
class FileOut
251+
{
252+
public:
253+
FileOut( const std::string &filename, File::Format format );
254+
255+
void setElementsDefinition( const ElementsDefinition &definitions );
256+
void setElementWriteCallback( const std::string &elementName, ElementWriteCallback &writeCallback );
257+
void write();
258+
Metadata metadata;
259+
260+
private:
261+
void createFile();
262+
void writeHeader();
263+
void writeData();
264+
265+
private:
266+
std::string m_filename;
267+
File::Format m_format;
268+
ElementsDefinition m_definitions;
269+
std::map<std::string, ElementWriteCallback> m_writeCallbacks;
270+
};
271+
}

‎external/mdal/3rdparty/libplyxx/libplyxx.cpp

Lines changed: 708 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 357 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,357 @@
1+
/*
2+
This file forked from https://github.com/srajotte/libplyxx
3+
4+
Copyright (c) 2016 Simon Rajotte
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
24+
Updated (c) 2021 Runette Software Ltd to make multiplatform, to complete the typemaps and add to voxel types.
25+
26+
Permission is hereby granted, free of charge, to any person obtaining a copy
27+
of this software and associated documentation files (the "Software"), to deal
28+
in the Software without restriction, including without limitation the rights
29+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30+
copies of the Software, and to permit persons to whom the Software is
31+
furnished to do so, subject to the following conditions:
32+
33+
The above copyright notice and this permission notice shall be included in all
34+
copies or substantial portions of the Software.
35+
36+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
42+
SOFTWARE.
43+
44+
*/
45+
46+
#pragma once
47+
48+
#include "libplyxx.h"
49+
#include <sstream>
50+
51+
// a custom specialisation (and yes, you are allowed (and have to) put this in std)
52+
// from http://www.cplusplus.com/forum/general/238538/
53+
namespace std
54+
{
55+
template<>
56+
struct hash<libply::Type>
57+
{
58+
using argument_type = libply::Type;
59+
using result_type = int;
60+
61+
result_type operator()( argument_type a ) const
62+
{
63+
return static_cast<result_type>( a );
64+
}
65+
};
66+
}
67+
68+
namespace libply
69+
{
70+
typedef std::unordered_map<std::string, Type> TypeMap;
71+
const TypeMap TYPE_MAP =
72+
{
73+
{ "char", Type::INT8 },
74+
{ "uchar", Type::UINT8 },
75+
{ "short", Type::INT16 },
76+
{ "ushort", Type::UINT16},
77+
{ "int", Type::INT32 },
78+
{ "uint", Type::UINT32},
79+
{ "float", Type::FLOAT32 },
80+
{ "double", Type::FLOAT64 },
81+
{ "int8", Type::INT8 },
82+
{ "uint8", Type::UINT8 },
83+
{ "int16", Type::INT16 },
84+
{ "uint16", Type::UINT16},
85+
{ "int32", Type::INT32 },
86+
{ "uint32", Type::UINT32},
87+
{ "float32", Type::FLOAT32 },
88+
{ "float64", Type::FLOAT64 }
89+
};
90+
91+
typedef std::unordered_map<Type, unsigned int> TypeSizeMap;
92+
const TypeSizeMap TYPE_SIZE_MAP =
93+
{
94+
{ Type::INT8, 1 },
95+
{ Type::UINT8, 1},
96+
{ Type::INT16, 2},
97+
{ Type::UINT16, 2},
98+
{ Type::INT32, 4},
99+
{ Type::UINT32, 4},
100+
{ Type::FLOAT32, 4},
101+
{ Type::FLOAT64, 8}
102+
};
103+
104+
/// Type conversion functions.
105+
106+
inline void convert_UINT( const textio::SubString &token, IProperty &property )
107+
{
108+
property = textio::stoi<int>( token );
109+
}
110+
111+
inline void convert_INT( const textio::SubString &token, IProperty &property )
112+
{
113+
property = textio::stoi<int>( token );
114+
}
115+
116+
inline void convert_FLOAT( const textio::SubString &token, IProperty &property )
117+
{
118+
property = textio::stor<float>( token );
119+
}
120+
121+
inline void convert_DOUBLE( const textio::SubString &token, IProperty &property )
122+
{
123+
property = textio::stor<double>( token );
124+
}
125+
126+
typedef void( *ConversionFunction )( const textio::SubString &, IProperty & );
127+
typedef std::unordered_map<Type, ConversionFunction> ConversionFunctionMap;
128+
129+
const ConversionFunctionMap CONVERSION_MAP =
130+
{
131+
{ Type::INT8, convert_INT },
132+
{ Type::UINT8, convert_UINT },
133+
{ Type::INT16, convert_INT },
134+
{ Type::UINT16, convert_UINT },
135+
{ Type::INT32, convert_INT },
136+
{ Type::UINT32, convert_UINT },
137+
{ Type::FLOAT32, convert_FLOAT },
138+
{ Type::FLOAT64, convert_DOUBLE }
139+
};
140+
141+
/// Type casting functions.
142+
143+
inline void cast_UINT8( char *buffer, IProperty &property )
144+
{
145+
property = *reinterpret_cast<unsigned char *>( buffer );
146+
}
147+
148+
inline void cast_INT8( char *buffer, IProperty &property )
149+
{
150+
property = *reinterpret_cast< char *>( buffer );
151+
}
152+
153+
inline void cast_UINT16( char *buffer, IProperty &property )
154+
{
155+
property = *reinterpret_cast<unsigned short *>( buffer );
156+
}
157+
158+
inline void cast_INT16( char *buffer, IProperty &property )
159+
{
160+
property = *reinterpret_cast<short *>( buffer );
161+
}
162+
163+
inline void cast_UINT32( char *buffer, IProperty &property )
164+
{
165+
property = *reinterpret_cast<unsigned int *>( buffer );
166+
}
167+
168+
inline void cast_INT32( char *buffer, IProperty &property )
169+
{
170+
property = *reinterpret_cast<int *>( buffer );
171+
}
172+
173+
inline void cast_FLOAT( char *buffer, IProperty &property )
174+
{
175+
property = *reinterpret_cast<float *>( buffer );
176+
}
177+
178+
inline void cast_DOUBLE( char *buffer, IProperty &property )
179+
{
180+
property = *reinterpret_cast<double *>( buffer );
181+
}
182+
183+
typedef void( *CastFunction )( char *buffer, IProperty & );
184+
typedef std::unordered_map<Type, CastFunction> CastFunctionMap;
185+
186+
const CastFunctionMap CAST_MAP =
187+
{
188+
{ Type::INT8, cast_INT8 },
189+
{ Type::UINT8, cast_UINT8 },
190+
{ Type::INT16, cast_INT16 },
191+
{ Type::UINT16, cast_UINT16 },
192+
{ Type::INT32, cast_INT32 },
193+
{ Type::UINT32, cast_UINT32 },
194+
{ Type::FLOAT32, cast_FLOAT },
195+
{ Type::FLOAT64, cast_DOUBLE }
196+
};
197+
198+
inline std::stringstream &write_convert_UINT( IProperty &property, std::stringstream &ss )
199+
{
200+
ss << static_cast<unsigned int>( property );
201+
return ss;
202+
}
203+
204+
inline std::stringstream &write_convert_INT( IProperty &property, std::stringstream &ss )
205+
{
206+
ss << static_cast<int>( property );
207+
return ss;
208+
}
209+
210+
inline std::stringstream &write_convert_FLOAT( IProperty &property, std::stringstream &ss )
211+
{
212+
ss << static_cast<float>( property );
213+
return ss;
214+
}
215+
216+
inline std::stringstream &write_convert_DOUBLE( IProperty &property, std::stringstream &ss )
217+
{
218+
ss << static_cast<double>( property );
219+
return ss;
220+
}
221+
222+
typedef std::stringstream &( *WriteConvertFunction )( IProperty &, std::stringstream & );
223+
typedef std::unordered_map<Type, WriteConvertFunction> WriteConvertFunctionMap;
224+
225+
const WriteConvertFunctionMap WRITE_CONVERT_MAP =
226+
{
227+
{ Type::INT8, write_convert_INT },
228+
{ Type::UINT8, write_convert_UINT },
229+
{ Type::INT16, write_convert_INT },
230+
{ Type::UINT16, write_convert_UINT },
231+
{ Type::INT32, write_convert_INT },
232+
{ Type::UINT32, write_convert_UINT },
233+
{ Type::FLOAT32, write_convert_FLOAT },
234+
{ Type::FLOAT64, write_convert_DOUBLE }
235+
};
236+
237+
inline void write_cast_UINT( IProperty &property, char *buffer, size_t &size )
238+
{
239+
*reinterpret_cast<unsigned int *>( buffer ) = static_cast<unsigned int>( property );
240+
size = sizeof( unsigned char );
241+
}
242+
243+
inline void write_cast_INT( IProperty &property, char *buffer, size_t &size )
244+
{
245+
*reinterpret_cast<int *>( buffer ) = static_cast<int>( property );
246+
size = sizeof( int );
247+
}
248+
249+
inline void write_cast_FLOAT( IProperty &property, char *buffer, size_t &size )
250+
{
251+
*reinterpret_cast<float *>( buffer ) = static_cast<float>( property );
252+
size = sizeof( float );
253+
}
254+
255+
inline void write_cast_DOUBLE( IProperty &property, char *buffer, size_t &size )
256+
{
257+
*reinterpret_cast<double *>( buffer ) = static_cast<double>( property );
258+
size = sizeof( double );
259+
}
260+
261+
typedef void( *WriteCastFunction )( IProperty &property, char *buffer, size_t &size );
262+
typedef std::unordered_map<Type, WriteCastFunction> WriteCastFunctionMap;
263+
264+
const WriteCastFunctionMap WRITE_CAST_MAP =
265+
{
266+
{ Type::INT8, write_cast_INT },
267+
{ Type::UINT8, write_cast_UINT },
268+
{ Type::INT16, write_cast_INT },
269+
{ Type::UINT16, write_cast_UINT },
270+
{ Type::INT32, write_cast_INT },
271+
{ Type::UINT32, write_cast_UINT },
272+
{ Type::FLOAT32, write_cast_FLOAT },
273+
{ Type::FLOAT64, write_cast_DOUBLE }
274+
};
275+
276+
struct PropertyDefinition
277+
{
278+
PropertyDefinition( const std::string &name, Type type, bool isList, Type listLengthType = Type::UINT8 )
279+
: name( name ), type( type ), isList( isList ), listLengthType( listLengthType ),
280+
conversionFunction( CONVERSION_MAP.at( type ) ),
281+
castFunction( CAST_MAP.at( type ) ),
282+
writeConvertFunction( WRITE_CONVERT_MAP.at( type ) ),
283+
writeCastFunction( WRITE_CAST_MAP.at( type ) )
284+
{};
285+
PropertyDefinition( const Property &p )
286+
: PropertyDefinition( p.name, p.type, p.isList )
287+
{};
288+
289+
Property getProperty() const;
290+
291+
std::string name;
292+
Type type;
293+
bool isList;
294+
Type listLengthType;
295+
ConversionFunction conversionFunction;
296+
CastFunction castFunction;
297+
WriteConvertFunction writeConvertFunction;
298+
WriteCastFunction writeCastFunction;
299+
};
300+
301+
struct ElementDefinition
302+
{
303+
ElementDefinition() : ElementDefinition( "", 0, 0 ) {};
304+
ElementDefinition( const std::string &name, ElementSize size, std::size_t startLine )
305+
: name( name ), size( size ), startLine( startLine ) {};
306+
ElementDefinition( const Element &e )
307+
: name( e.name ), size( e.size )
308+
{
309+
for ( const auto &p : e.properties )
310+
{
311+
properties.emplace_back( p );
312+
}
313+
};
314+
315+
Element getElement() const;
316+
317+
std::string name;
318+
ElementSize size;
319+
std::vector<PropertyDefinition> properties;
320+
std::size_t startLine;
321+
};
322+
323+
class FileParser
324+
{
325+
public:
326+
explicit FileParser( const std::string &filename );
327+
FileParser( const FileParser &other ) = delete;
328+
~FileParser();
329+
330+
std::vector<Element> definitions() const;
331+
Metadata metadata;
332+
//void setElementInserter(std::string elementName, IElementInserter* inserter);
333+
void setElementReadCallback( std::string elementName, ElementReadCallback &readCallback );
334+
void read();
335+
336+
private:
337+
void readHeader();
338+
void parseLine( const textio::SubString &substr, const ElementDefinition &elementDefinition, ElementBuffer &buffer );
339+
void readBinaryElement( std::ifstream &fs, const ElementDefinition &elementDefinition, ElementBuffer &buffer );
340+
341+
private:
342+
typedef std::map<std::string, ElementReadCallback> CallbackMap;
343+
344+
private:
345+
std::string m_filename;
346+
File::Format m_format;
347+
std::streamsize m_dataOffset;
348+
textio::LineReader m_lineReader;
349+
textio::Tokenizer m_lineTokenizer;
350+
textio::Tokenizer::TokenList m_tokens;
351+
std::vector<ElementDefinition> m_elements;
352+
CallbackMap m_readCallbackMap;
353+
};
354+
355+
std::string formatString( File::Format format );
356+
std::string typeString( Type type );
357+
}

‎external/mdal/3rdparty/textio.h

Lines changed: 409 additions & 0 deletions
Large diffs are not rendered by default.

‎external/mdal/api/mdal.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,22 @@ MDAL_EXPORT void MDAL_M_addFaces( MDAL_MeshH mesh,
331331
int *faceSizes,
332332
int *vertexIndices );
333333

334+
/**
335+
* Adds edges to the mesh
336+
* \param mesh the mesh which the faces are added
337+
* \param edgeCount the count of edges
338+
* \param startVertexIndices must be allocated to edgesCount items to store start vertex indices for edges
339+
* \param endVertexIndices must be allocated to edgesCount items to store end vertex indices for edges
340+
*
341+
* \note to avoid incompatible datasets, adding edges removes all the existing dataset group
342+
*
343+
* \since MDAL 0.9.0
344+
*/
345+
MDAL_EXPORT void MDAL_M_addEdges( MDAL_MeshH mesh,
346+
int edgesCount,
347+
int *startVertexIndices,
348+
int *endVertexIndices );
349+
334350
/**
335351
* Returns vertex count for the mesh
336352
*/
@@ -368,15 +384,15 @@ MDAL_EXPORT void MDAL_M_LoadDatasets( MDAL_MeshH mesh, const char *datasetFile )
368384
MDAL_EXPORT int MDAL_M_metadataCount( MDAL_MeshH mesh );
369385

370386
/**
371-
* Returns dataset metadata key
387+
* Returns mesh metadata key
372388
* not thread-safe and valid only till next call
373389
*
374390
* \since MDAL 0.9.0
375391
*/
376392
MDAL_EXPORT const char *MDAL_M_metadataKey( MDAL_MeshH mesh, int index );
377393

378394
/**
379-
* Returns dataset metadata value
395+
* Returns mesh metadata value
380396
* not thread-safe and valid only till next call
381397
*
382398
* \since MDAL 0.9.0
@@ -647,6 +663,8 @@ MDAL_EXPORT MDAL_DatasetH MDAL_G_addDataset(
647663
* \param verticalExtrusion Double Array holding the vertical level values for the voxels
648664
* Size must be Face count + Volume count
649665
* \returns empty pointer if not possible to create dataset (e.g. group opened in read mode), otherwise handle to new dataset
666+
*
667+
* \since MDAL 0.9.0
650668
*/
651669

652670
MDAL_EXPORT MDAL_DatasetH MDAL_G_addDataset3D(

‎external/mdal/cmake_templates/mdal_config.hpp.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
#cmakedefine HAVE_SQLITE3
1515

16+
#cmakedefine BUILD_PLY
17+
1618
#endif // MDAL_CONFIG_HPP
1719

1820

‎external/mdal/frmts/mdal_dynamic_driver.cpp

100644100755
Lines changed: 146 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ bool MDAL::MeshDynamicDriver::populateDatasetGroups()
218218
group->setDataLocation( MDAL_DataLocation::DataOnFaces );
219219
break;
220220
case 3:
221+
group->setDataLocation( MDAL_DataLocation::DataOnVolumes );
222+
break;
223+
case 4:
221224
group->setDataLocation( MDAL_DataLocation::DataOnEdges );
222225
break;
223226
default:
@@ -238,20 +241,51 @@ bool MDAL::MeshDynamicDriver::populateDatasetGroups()
238241

239242
for ( int d = 0; d < datasetCount ; ++d )
240243
{
241-
std::shared_ptr<DatasetDynamicDriver> dataset = std::make_shared<DatasetDynamicDriver>( group.get(), mId, i, d, mLibrary );
242-
dataset->setSupportsActiveFlag( mDatasetSupportActiveFlagFunction( mId, i, d ) );
243-
if ( !dataset->loadSymbol() )
244-
return false;
244+
std::shared_ptr<Dataset> dataset;
245+
246+
switch ( group->dataLocation() )
247+
{
248+
case DataInvalidLocation:
249+
continue;
250+
break;
251+
case DataOnVertices:
252+
case DataOnEdges:
253+
case DataOnFaces:
254+
{
255+
std::shared_ptr<DatasetDynamicDriver2D> dataset2D = std::make_shared<DatasetDynamicDriver2D>( group.get(), mId, i, d, mLibrary );
256+
dataset2D->setSupportsActiveFlag( mDatasetSupportActiveFlagFunction( mId, i, d ) );
257+
258+
if ( !dataset2D->loadSymbol() )
259+
return false;
260+
261+
dataset2D->setStatistics( MDAL::calculateStatistics( dataset2D ) );
262+
dataset2D->unloadData();
263+
dataset = dataset2D;
264+
}
265+
break;
266+
case DataOnVolumes:
267+
{
268+
size_t maxVerticalLevelCount = mDataset3DMaximumVerticalLevelCount( mId, i, d );
269+
size_t volumesCount = mDataset3DVolumeCount( mId, i, d );
270+
std::shared_ptr<DatasetDynamicDriver3D> dataset3D =
271+
std::make_shared<DatasetDynamicDriver3D>( group.get(), mId, i, d, volumesCount, maxVerticalLevelCount, mLibrary );
272+
273+
if ( ! dataset3D->loadSymbol() )
274+
return false;
275+
276+
dataset3D->setStatistics( MDAL::calculateStatistics( dataset3D ) );
277+
dataset3D->unloadData();
278+
dataset = dataset3D;
279+
}
280+
break;
281+
}
245282

246283
bool ok = true;
247284
double time = mDatasetTimeFunction( mId, i, d, &ok );
248285
if ( !ok )
249286
return false;
250287
dataset->setTime( RelativeTimestamp( time, RelativeTimestamp::hours ) );
251288

252-
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
253-
dataset->unloadData();
254-
255289
group->datasets.push_back( dataset );
256290
}
257291

@@ -277,6 +311,8 @@ bool MDAL::MeshDynamicDriver::loadSymbol()
277311
mDatasetTimeFunction = mLibrary.getSymbol<double, int, int, int, bool *>( "MDAL_DRIVER_D_time" );
278312
mDatasetDescriptionFunction = mLibrary.getSymbol<bool, int, int, bool *, int *, int *>( "MDAL_DRIVER_G_datasetsDescription" );
279313
mDatasetSupportActiveFlagFunction = mLibrary.getSymbol<bool, int, int, int>( "MDAL_DRIVER_D_hasActiveFlagCapability" );
314+
mDataset3DMaximumVerticalLevelCount = mLibrary.getSymbol<int, int, int, int>( "MDAL_DRIVER_D_maximumVerticalLevelCount" );
315+
mDataset3DVolumeCount = mLibrary.getSymbol<int, int, int, int>( "MDAL_DRIVER_D_volumeCount" );
280316
mCloseMeshFunction = mLibrary.getSymbol<void, int>( "MDAL_DRIVER_closeMesh" );
281317

282318
if ( mMeshVertexCountFunction == nullptr ||
@@ -395,31 +431,89 @@ size_t MDAL::MeshEdgeIteratorDynamicDriver::next( size_t edgeCount, int *startVe
395431
return effectiveEdgesCount;
396432
}
397433

398-
MDAL::DatasetDynamicDriver::DatasetDynamicDriver( MDAL::DatasetGroup *parentGroup, int meshId, int groupIndex, int datasetIndex, const MDAL::Library &library ):
399-
Dataset2D( parentGroup )
400-
, mMeshId( meshId )
434+
435+
MDAL::DatasetDynamicDriver::DatasetDynamicDriver( int meshId, int groupIndex, int datasetIndex, const MDAL::Library &library )
436+
: mMeshId( meshId )
401437
, mGroupIndex( groupIndex )
402438
, mDatasetIndex( datasetIndex )
403439
, mLibrary( library )
404440
{}
405441

406-
size_t MDAL::DatasetDynamicDriver::scalarData( size_t indexStart, size_t count, double *buffer )
442+
MDAL::DatasetDynamicDriver::~DatasetDynamicDriver() = default;
443+
444+
MDAL::DatasetDynamicDriver2D::DatasetDynamicDriver2D( MDAL::DatasetGroup *parentGroup, int meshId, int groupIndex, int datasetIndex, const MDAL::Library &library )
445+
: Dataset2D( parentGroup )
446+
, DatasetDynamicDriver( meshId, groupIndex, datasetIndex, library )
447+
{}
448+
449+
MDAL::DatasetDynamicDriver2D::~DatasetDynamicDriver2D() = default;
450+
451+
452+
MDAL::DatasetDynamicDriver3D::DatasetDynamicDriver3D( MDAL::DatasetGroup *parentGroup, int meshId, int groupIndex, int datasetIndex, size_t volumes, size_t maxVerticalLevelCount, const MDAL::Library &library )
453+
: Dataset3D( parentGroup, volumes, maxVerticalLevelCount )
454+
, DatasetDynamicDriver( meshId, groupIndex, datasetIndex, library )
455+
{}
456+
457+
MDAL::DatasetDynamicDriver3D::~DatasetDynamicDriver3D() = default;
458+
459+
size_t MDAL::DatasetDynamicDriver3D::verticalLevelCountData( size_t indexStart, size_t count, int *buffer )
460+
{
461+
if ( !mVerticalLevelCountDataFunction )
462+
return 0;
463+
464+
return mVerticalLevelCountDataFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
465+
}
466+
467+
size_t MDAL::DatasetDynamicDriver3D::verticalLevelData( size_t indexStart, size_t count, double *buffer )
468+
{
469+
if ( !mVerticalLevelDataFunction )
470+
return 0;
471+
472+
return mVerticalLevelDataFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
473+
}
474+
475+
size_t MDAL::DatasetDynamicDriver3D::faceToVolumeData( size_t indexStart, size_t count, int *buffer )
476+
{
477+
if ( !mFaceToVolumeDataFunction )
478+
return 0;
479+
480+
return mFaceToVolumeDataFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
481+
}
482+
483+
size_t MDAL::DatasetDynamicDriver3D::scalarVolumesData( size_t indexStart, size_t count, double *buffer )
407484
{
408485
if ( !mDataFunction )
409486
return 0;
410487

411488
return mDataFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
412489
}
413490

414-
size_t MDAL::DatasetDynamicDriver::vectorData( size_t indexStart, size_t count, double *buffer )
491+
size_t MDAL::DatasetDynamicDriver3D::vectorVolumesData( size_t indexStart, size_t count, double *buffer )
415492
{
416493
if ( !mDataFunction )
417494
return 0;
418495

419496
return mDataFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
420497
}
421498

422-
size_t MDAL::DatasetDynamicDriver::activeData( size_t indexStart, size_t count, int *buffer )
499+
500+
size_t MDAL::DatasetDynamicDriver2D::scalarData( size_t indexStart, size_t count, double *buffer )
501+
{
502+
if ( !mDataFunction )
503+
return 0;
504+
505+
return mDataFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
506+
}
507+
508+
size_t MDAL::DatasetDynamicDriver2D::vectorData( size_t indexStart, size_t count, double *buffer )
509+
{
510+
if ( !mDataFunction )
511+
return 0;
512+
513+
return mDataFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
514+
}
515+
516+
size_t MDAL::DatasetDynamicDriver2D::activeData( size_t indexStart, size_t count, int *buffer )
423517
{
424518
if ( !supportsActiveFlag() )
425519
return Dataset2D::activeData( indexStart, count, buffer );
@@ -434,12 +528,47 @@ bool MDAL::DatasetDynamicDriver::loadSymbol()
434528
{
435529
mDataFunction = mLibrary.getSymbol<int, int, int, int, int, int, double *>( "MDAL_DRIVER_D_data" );
436530
mUnloadFunction = mLibrary.getSymbol<void, int, int, int>( "MDAL_DRIVER_D_unload" );
531+
532+
if ( mDataFunction == nullptr ||
533+
mUnloadFunction == nullptr )
534+
{
535+
MDAL::Log::error( MDAL_Status::Err_MissingDriver, "Driver is not valid" );
536+
return false;
537+
}
538+
539+
return true;
540+
}
541+
542+
bool MDAL::DatasetDynamicDriver2D::loadSymbol()
543+
{
544+
if ( !MDAL::DatasetDynamicDriver::loadSymbol() )
545+
return false;
546+
437547
if ( supportsActiveFlag() )
438548
mActiveFlagsFunction = mLibrary.getSymbol<int, int, int, int, int, int, int *>( "MDAL_DRIVER_D_activeFlags" );
439549

440-
if ( mDataFunction == nullptr ||
441-
mUnloadFunction == nullptr ||
442-
( supportsActiveFlag() && mActiveFlagsFunction == nullptr ) )
550+
if ( supportsActiveFlag() && mActiveFlagsFunction == nullptr )
551+
{
552+
MDAL::Log::error( MDAL_Status::Err_MissingDriver, "Driver is not valid" );
553+
return false;
554+
}
555+
556+
return true;
557+
}
558+
559+
560+
bool MDAL::DatasetDynamicDriver3D::loadSymbol()
561+
{
562+
if ( !MDAL::DatasetDynamicDriver::loadSymbol() )
563+
return false;
564+
565+
mVerticalLevelCountDataFunction = mLibrary.getSymbol<int, int, int, int, int, int, int *>( "MDAL_DRIVER_D_verticalLevelCountData" );
566+
mVerticalLevelDataFunction = mLibrary.getSymbol<int, int, int, int, int, int, double *>( "MDAL_DRIVER_D_verticalLevelData" );
567+
mFaceToVolumeDataFunction = mLibrary.getSymbol<int, int, int, int, int, int, int *>( "MDAL_DRIVER_D_faceToVolumeData" );
568+
569+
if ( mVerticalLevelCountDataFunction == nullptr ||
570+
mVerticalLevelDataFunction == nullptr ||
571+
mFaceToVolumeDataFunction == nullptr )
443572
{
444573
MDAL::Log::error( MDAL_Status::Err_MissingDriver, "Driver is not valid" );
445574
return false;
@@ -455,3 +584,4 @@ void MDAL::DatasetDynamicDriver::unloadData()
455584

456585
mUnloadFunction( mMeshId, mGroupIndex, mDatasetIndex );
457586
}
587+

‎external/mdal/frmts/mdal_dynamic_driver.hpp

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,36 +102,80 @@ namespace MDAL
102102
std::function<int ( int, int, int, int *, int * )> mEdgesFunction;
103103
};
104104

105-
class DatasetDynamicDriver: public Dataset2D
105+
106+
class DatasetDynamicDriver
106107
{
107108
public:
108-
DatasetDynamicDriver( DatasetGroup *parentGroup,
109-
int meshId,
109+
DatasetDynamicDriver( int meshId,
110110
int groupIndex,
111111
int datasetIndex,
112112
const Library &library );
113+
virtual ~DatasetDynamicDriver();
113114

114-
size_t scalarData( size_t indexStart, size_t count, double *buffer ) override;
115-
size_t vectorData( size_t indexStart, size_t count, double *buffer ) override;
116-
size_t activeData( size_t indexStart, size_t count, int *buffer ) override;
117-
118-
bool loadSymbol();
115+
virtual bool loadSymbol();
119116

120117
//! Removes stored data in memory (for drivers that support lazy loading)
121118
void unloadData();
122119

123-
private:
120+
protected:
124121
int mMeshId = -1;
125122
int mGroupIndex = -1;
126123
int mDatasetIndex = -1;
127124
Library mLibrary;
128125

129126
//************************************
130127
std::function<int ( int, int, int, int, int, double * )> mDataFunction;
131-
std::function<int ( int, int, int, int, int, int * )> mActiveFlagsFunction;
132128
std::function<void( int, int, int )> mUnloadFunction;
133129
};
134130

131+
class DatasetDynamicDriver2D: public Dataset2D, public DatasetDynamicDriver
132+
{
133+
public:
134+
DatasetDynamicDriver2D( DatasetGroup *parentGroup,
135+
int meshId,
136+
int groupIndex,
137+
int datasetIndex,
138+
const Library &library );
139+
~DatasetDynamicDriver2D() override;
140+
141+
bool loadSymbol() override;
142+
143+
size_t scalarData( size_t indexStart, size_t count, double *buffer ) override;
144+
size_t vectorData( size_t indexStart, size_t count, double *buffer ) override;
145+
size_t activeData( size_t indexStart, size_t count, int *buffer ) override;
146+
147+
private:
148+
149+
std::function<int ( int, int, int, int, int, int * )> mActiveFlagsFunction;
150+
};
151+
152+
class DatasetDynamicDriver3D: public Dataset3D, public DatasetDynamicDriver
153+
{
154+
public:
155+
DatasetDynamicDriver3D( DatasetGroup *parentGroup,
156+
int meshId,
157+
int groupIndex,
158+
int datasetIndex,
159+
size_t volumes,
160+
size_t maxVerticalLevelCount,
161+
const Library &library );
162+
~DatasetDynamicDriver3D() override;
163+
bool loadSymbol() override;
164+
165+
size_t verticalLevelCountData( size_t indexStart, size_t count, int *buffer ) override;
166+
size_t verticalLevelData( size_t indexStart, size_t count, double *buffer ) override;
167+
size_t faceToVolumeData( size_t indexStart, size_t count, int *buffer ) override;
168+
size_t scalarVolumesData( size_t indexStart, size_t count, double *buffer ) override;
169+
size_t vectorVolumesData( size_t indexStart, size_t count, double *buffer ) override;
170+
171+
private:
172+
173+
std::function<int ( int, int, int, int, int, int * )> mVerticalLevelCountDataFunction;
174+
std::function<int ( int, int, int, int, int, double * )> mVerticalLevelDataFunction;
175+
std::function<int ( int, int, int, int, int, int * )> mFaceToVolumeDataFunction;
176+
177+
};
178+
135179
class MeshDynamicDriver: public Mesh
136180
{
137181
public:
@@ -178,6 +222,8 @@ namespace MDAL
178222
std::function < bool ( int, int, bool *, int *, int * )> mDatasetDescriptionFunction;
179223
std::function < double( int, int, int, bool * )> mDatasetTimeFunction;
180224
std::function<bool ( int, int, int )> mDatasetSupportActiveFlagFunction;
225+
std::function<int ( int, int, int )> mDataset3DMaximumVerticalLevelCount;
226+
std::function<int ( int, int, int )> mDataset3DVolumeCount;
181227

182228
std::function<void ( int )> mCloseMeshFunction;
183229
};

‎external/mdal/frmts/mdal_flo2d.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ MDAL::DriverFlo2D::DriverFlo2D()
996996
: Driver(
997997
"FLO2D",
998998
"Flo2D",
999-
"*.nc",
999+
"*.nc;;*.DAT",
10001000
Capability::ReadMesh | Capability::ReadDatasets | Capability::WriteDatasetsOnFaces )
10011001
{
10021002

‎external/mdal/frmts/mdal_ply.cpp

Lines changed: 578 additions & 239 deletions
Large diffs are not rendered by default.

‎external/mdal/frmts/mdal_ply.hpp

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,23 @@ namespace MDAL
2828
DriverPly *create() override;
2929

3030
bool canReadMesh( const std::string &uri ) override;
31+
int faceVerticesMaximumCount() const override {return 100;}
32+
3133
std::unique_ptr< Mesh > load( const std::string &meshFile, const std::string &meshName = "" ) override;
34+
void save( const std::string &fileName, const std::string &meshName, Mesh *mesh ) override;
35+
bool persist( DatasetGroup *group ) override;
36+
37+
std::string saveMeshOnFileSuffix() const override;
3238

3339
private:
3440
std::shared_ptr<DatasetGroup> addDatasetGroup( MDAL::Mesh *mesh, const std::string &name, const MDAL_DataLocation location, bool isScalar );
35-
void addDataset( MDAL::DatasetGroup *group, const std::vector<double> &values );
36-
37-
/*
38-
* Element specification. holds the name, size and arbitraily long vector of properties
39-
*/
40-
struct element
41-
{
42-
public:
43-
std::string name; // element name
44-
std::vector<std::string> properties; // the name of each property
45-
std::vector<std::string> types; // the type of each property
46-
std::vector<bool> list; // is the property a list
47-
size_t size; // element size
48-
49-
bool operator==( const std::string &rhs ) const
50-
{
51-
return name == rhs;
52-
}
53-
};
54-
55-
size_t getIndex( std::vector<std::string> v, std::string in );
41+
void addDataset2D( MDAL::DatasetGroup *group, const std::vector<double> &values );
42+
void addDataset3D( MDAL::DatasetGroup *group,
43+
const std::vector<double> &values,
44+
const std::vector<int> &valueIndexes,
45+
const std::vector<double> &levels,
46+
const std::vector<int> &levelIndexes );
47+
5648
};
5749

5850
} // namespace MDAL

‎external/mdal/mdal.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static const char *EMPTY_STR = "";
2121

2222
const char *MDAL_Version()
2323
{
24-
return "0.8.92";
24+
return "0.8.93";
2525
}
2626

2727
MDAL_Status MDAL_LastStatus()
@@ -522,6 +522,7 @@ MDAL_DatasetGroupH MDAL_M_datasetGroup( MDAL_MeshH mesh, int index )
522522
return nullptr;
523523
}
524524
size_t i = static_cast<size_t>( index );
525+
525526
return static_cast< MDAL_DatasetH >( m->datasetGroups[i].get() );
526527
}
527528

@@ -1495,3 +1496,28 @@ void MDAL_M_setProjection( MDAL_MeshH mesh, const char *projection )
14951496

14961497
static_cast<MDAL::Mesh *>( mesh )->setSourceCrsFromWKT( std::string( projection ) );
14971498
}
1499+
1500+
void MDAL_M_addEdges( MDAL_MeshH mesh,
1501+
int edgesCount,
1502+
int *startVertexIndices,
1503+
int *endVertexIndices )
1504+
{
1505+
MDAL::Log::resetLastStatus();
1506+
if ( !mesh )
1507+
{
1508+
MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, "Mesh is not valid (null)" );
1509+
return;
1510+
}
1511+
1512+
MDAL::Mesh *m = static_cast<MDAL::Mesh *>( mesh );
1513+
1514+
if ( ! m->isEditable() )
1515+
{
1516+
MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, "Mesh is not editable" );
1517+
}
1518+
1519+
m->datasetGroups.clear();
1520+
std::shared_ptr<MDAL::Driver> driver = MDAL::DriverManager::instance().driver( m->driverName() );
1521+
1522+
m->addEdges( edgesCount, startVertexIndices, endVertexIndices );
1523+
}

‎external/mdal/mdal_data_model.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,14 @@ void MDAL::Mesh::addFaces( size_t faceCount, size_t driverMaxVerticesPerFace, in
431431
MDAL_UNUSED( vertexIndices );
432432
}
433433

434+
void MDAL::Mesh::addEdges( size_t edgeCount, int *startVertexIndices, int *endVertexIndices )
435+
{
436+
MDAL_UNUSED( edgeCount );
437+
MDAL_UNUSED( startVertexIndices );
438+
MDAL_UNUSED( endVertexIndices );
439+
}
440+
441+
434442
MDAL::MeshVertexIterator::~MeshVertexIterator() = default;
435443

436444
MDAL::MeshFaceIterator::~MeshFaceIterator() = default;

‎external/mdal/mdal_data_model.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ namespace MDAL
279279

280280
virtual void addVertices( size_t vertexCount, double *coordinates );
281281
virtual void addFaces( size_t faceCount, size_t driverMaxVerticesPerFace, int *faceSizes, int *vertexIndices );
282+
virtual void addEdges( size_t edgeCount, int *startVertexIndices, int *endVertexIndices );
283+
282284

283285
protected:
284286
void setFaceVerticesMaximumCount( const size_t &faceVerticesMaximumCount );

‎external/mdal/mdal_driver_manager.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@
1111
#include "frmts/mdal_binary_dat.hpp"
1212
#include "frmts/mdal_selafin.hpp"
1313
#include "frmts/mdal_esri_tin.hpp"
14-
#include "frmts/mdal_ply.hpp"
1514
#include "frmts/mdal_dynamic_driver.hpp"
1615
#include "mdal_utils.hpp"
1716

17+
#ifdef BUILD_PLY
18+
#include "frmts/mdal_ply.hpp"
19+
#endif
20+
1821
#ifdef HAVE_HDF5
1922
#include "frmts/mdal_xmdf.hpp"
2023
#include "frmts/mdal_flo2d.hpp"
@@ -218,7 +221,10 @@ MDAL::DriverManager::DriverManager()
218221
mDrivers.push_back( std::make_shared<MDAL::DriverXmsTin>() );
219222
mDrivers.push_back( std::make_shared<MDAL::DriverSelafin>() );
220223
mDrivers.push_back( std::make_shared<MDAL::DriverEsriTin>() );
224+
225+
#ifdef BUILD_PLY
221226
mDrivers.push_back( std::make_shared<MDAL::DriverPly>() );
227+
#endif
222228

223229
#ifdef HAVE_HDF5
224230
mDrivers.push_back( std::make_shared<MDAL::DriverFlo2D>() );

‎external/mdal/mdal_memory_data_model.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,24 @@ void MDAL::MemoryMesh::addFaces( size_t faceCount, size_t driverMaxVerticesPerFa
328328
std::move( newFaces.begin(), newFaces.end(), std::back_inserter( mFaces ) );
329329
}
330330

331+
void MDAL::MemoryMesh::addEdges( size_t edgeCount, int *startVertexIndices, int *endVertexIndices )
332+
{
333+
int maxVertex = mVertices.size();
334+
for ( size_t edgeIndex = 0 ; edgeIndex < edgeCount; ++edgeIndex )
335+
{
336+
Edge edge;
337+
if ( startVertexIndices[edgeIndex] >= maxVertex || endVertexIndices[edgeIndex] >= maxVertex )
338+
{
339+
MDAL::Log::error( Err_InvalidData, "Invalid vertex index when adding edges" );
340+
return;
341+
}
342+
edge.startVertex = startVertexIndices[edgeIndex];
343+
edge.endVertex = endVertexIndices[edgeIndex];
344+
345+
mEdges.push_back( std::move( edge ) );
346+
}
347+
}
348+
331349
MDAL::MemoryMesh::~MemoryMesh() = default;
332350

333351
MDAL::MemoryMeshVertexIterator::MemoryMeshVertexIterator( const MDAL::MemoryMesh *mesh )

‎external/mdal/mdal_memory_data_model.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ namespace MDAL
320320
BBox extent() const override;
321321
void addVertices( size_t vertexCount, double *coordinates ) override;
322322
void addFaces( size_t faceCount, size_t driverMaxVerticesPerFace, int *faceSizes, int *vertexIndices ) override;
323+
void addEdges( size_t edgeCount, int *startVertexIndices, int *endVertexIndices ) override;
323324

324325
bool isEditable() const override {return true;}
325326

‎src/providers/mdal/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ if (WITH_INTERNAL_MDAL)
2727
include_directories(
2828
${CMAKE_SOURCE_DIR}/external/mdal
2929
${CMAKE_SOURCE_DIR}/external/mdal/api
30+
${CMAKE_SOURCE_DIR}/external/mdal/3rdparty
3031
)
3132

3233
set(MDAL_LIB_SRCS
@@ -47,6 +48,7 @@ if (WITH_INTERNAL_MDAL)
4748
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_esri_tin.cpp
4849
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_xms_tin.cpp
4950
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ply.cpp
51+
${CMAKE_SOURCE_DIR}/external/mdal/3rdparty/libplyxx/libplyxx.cpp
5052
)
5153

5254
set(MDAL_LIB_HDRS
@@ -65,6 +67,9 @@ if (WITH_INTERNAL_MDAL)
6567
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_esri_tin.hpp
6668
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_xms_tin.hpp
6769
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ply.hpp
70+
${CMAKE_SOURCE_DIR}/external/mdal/3rdparty/libplyxx.h
71+
${CMAKE_SOURCE_DIR}/external/mdal/3rdparty/libplyxx/libplyxx_internal.h
72+
${CMAKE_SOURCE_DIR}/external/mdal/3rdparty/textio.h
6873
)
6974

7075
if(HDF5_FOUND)
@@ -151,6 +156,7 @@ if (WITH_INTERNAL_MDAL)
151156

152157

153158
# create mdal_config.h
159+
set (BUILD_PLY TRUE)
154160
configure_file(${CMAKE_SOURCE_DIR}/external/mdal/cmake_templates/mdal_config.hpp.in ${CMAKE_BINARY_DIR}/mdal_config.hpp)
155161
include_directories(${CMAKE_BINARY_DIR})
156162

‎src/providers/mdal/qgsmdalprovider.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ void QgsMdalProvider::fileMeshExtensions( QStringList &fileMeshExtensions,
657657
for ( auto ext : extensions )
658658
{
659659
ext.remove( QStringLiteral( "*." ) );
660+
ext = ext.toLower();
660661
if ( isMeshDriver )
661662
fileMeshExtensions += ext;
662663
else

0 commit comments

Comments
 (0)
Please sign in to comment.