11# distutils: language = c++
22# cython: c_string_type=unicode, c_string_encoding=utf8
33
4+ import json
45from libcpp.vector cimport vector
56from libcpp.string cimport string
67from libc.stdint cimport int64_t
78from libcpp cimport bool
89from types import SimpleNamespace
10+
11+ import numpy as np
912cimport numpy as np
1013np.import_array()
1114
1215from cython.operator cimport dereference as deref, preincrement as inc
1316
17+
1418cdef extern from " pdal/pdal_config.hpp" namespace " pdal::Config" :
1519 cdef int versionMajor() except +
1620 cdef int versionMinor() except +
@@ -20,7 +24,6 @@ cdef extern from "pdal/pdal_config.hpp" namespace "pdal::Config":
2024 cdef string pluginInstallPath() except +
2125 cdef string versionString() except +
2226
23-
2427def getInfo ():
2528 return SimpleNamespace(
2629 version = versionString(),
@@ -33,20 +36,39 @@ def getInfo():
3336 )
3437
3538
39+ cdef extern from " PyDimension.hpp" :
40+ ctypedef struct Dimension:
41+ string name;
42+ string description;
43+ int size;
44+ string type ;
45+ # # string units; // Not defined by PDAL yet
46+ cdef vector[Dimension] getValidDimensions() except +
47+
48+ def getDimensions ():
49+ output = []
50+ for dim in getValidDimensions():
51+ output.append({
52+ ' name' : dim.name,
53+ ' description' : dim.description,
54+ ' dtype' : np.dtype(dim.type + str (dim.size))
55+ })
56+ return output
57+
58+
3659cdef extern from " PyArray.hpp" namespace " pdal::python" :
3760 cdef cppclass Array:
3861 Array(np.ndarray) except +
3962 void * getPythonArray() except +
4063
4164cdef extern from " PyMesh.hpp" namespace " pdal::python" :
4265 cdef cppclass Mesh:
43- Mesh(np.ndarray) except +
4466 void * getPythonArray() except +
4567
4668cdef extern from " PyPipeline.hpp" namespace " pdal::python" :
47- cdef cppclass Pipeline :
48- Pipeline (const char * ) except +
49- Pipeline (const char * , vector[Array* ]& ) except +
69+ cdef cppclass PyPipelineExecutor :
70+ PyPipelineExecutor (const char * ) except +
71+ PyPipelineExecutor (const char * , vector[Array* ]& ) except +
5072 int64_t execute() except +
5173 bool validate() except +
5274 string getPipeline() except +
@@ -58,118 +80,90 @@ cdef extern from "PyPipeline.hpp" namespace "pdal::python":
5880 int getLogLevel()
5981 void setLogLevel(int )
6082
61- cdef extern from " PyDimension.hpp" :
62- ctypedef struct Dimension:
63- string name;
64- string description;
65- int size;
66- string type ;
67- # # string units; // Not defined by PDAL yet
68-
69- cdef vector[Dimension] getValidDimensions() except +
7083
71-
72- def getDimensions ():
73- cdef vector[Dimension] c_dims;
74- c_dims = getValidDimensions()
75- output = []
76- cdef vector[Dimension].iterator it = c_dims.begin()
77- while it != c_dims.end():
78- ptr = deref(it)
79- d = {}
80- d[' name' ] = ptr.name
81- d[' description' ] = ptr.description
82- kind = ptr.type + str (ptr.size)
83- d[' dtype' ] = np.dtype(kind)
84- ptr = deref(it)
85- output.append(d)
86- inc(it)
87- return output
88-
89-
90- cdef class PyPipeline:
91- cdef Pipeline * thisptr # hold a c++ instance which we're wrapping
92- cdef vector[Array * ] c_arrays;
84+ cdef class Pipeline:
85+ cdef PyPipelineExecutor* _executor
86+ cdef vector[Array * ] _arrays;
9387
9488 def __cinit__ (self , unicode json , list arrays = None ):
95- cdef char * x = NULL
96-
9789 if arrays is not None :
9890 for array in arrays:
99- self .c_arrays .push_back(new Array(array))
100- self .thisptr = new Pipeline (json.encode(' UTF-8' ), self .c_arrays )
91+ self ._arrays .push_back(new Array(array))
92+ self ._executor = new PyPipelineExecutor (json.encode(' UTF-8' ), self ._arrays )
10193 else :
102- self .thisptr = new Pipeline (json.encode(' UTF-8' ))
94+ self ._executor = new PyPipelineExecutor (json.encode(' UTF-8' ))
10395
10496 def __dealloc__ (self ):
105- for array in self .c_arrays :
97+ for array in self ._arrays :
10698 del array
107- del self .thisptr
99+ del self ._executor
108100
109101 property pipeline :
110102 def __get__ (self ):
111- return self .thisptr .getPipeline()
103+ return self ._executor .getPipeline()
112104
113105 property metadata :
114106 def __get__ (self ):
115- return self .thisptr .getMetadata()
107+ return self ._executor .getMetadata()
116108
117109 property loglevel :
118110 def __get__ (self ):
119- return self .thisptr .getLogLevel()
111+ return self ._executor .getLogLevel()
120112 def __set__ (self , v ):
121- self .thisptr .setLogLevel(v)
113+ self ._executor .setLogLevel(v)
122114
123115 property log :
124116 def __get__ (self ):
125-
126- return self .thisptr.getLog()
117+ return self ._executor.getLog()
127118
128119 property schema :
129120 def __get__ (self ):
130- import json
131-
132- j = self .thisptr.getSchema()
133- return json.loads(j)
121+ return json.loads(self ._executor.getSchema())
134122
135123 property arrays :
136-
137124 def __get__ (self ):
138- v = self .thisptr.getArrays()
139125 output = []
126+ v = self ._executor.getArrays()
140127 cdef vector[Array* ].iterator it = v.begin()
141- cdef Array* a
128+ cdef Array* ptr
142129 while it != v.end():
143130 ptr = deref(it)
144- a = ptr# .get()
145- o = a.getPythonArray()
146- output.append(< object > o)
131+ output.append(< object > ptr.getPythonArray())
147132 del ptr
148133 inc(it)
149134 return output
150135
151136 property meshes :
152-
153137 def __get__ (self ):
154- v = self .thisptr.getMeshes()
155138 output = []
139+ v = self ._executor.getMeshes()
156140 cdef vector[Mesh * ].iterator it = v.begin()
157- cdef Mesh* m
141+ cdef Mesh* ptr
158142 while it != v.end():
159143 ptr = deref(it)
160- m = ptr# .get()
161- o = m.getPythonArray()
162- output.append(< object > o)
144+ output.append(< object > ptr.getPythonArray())
163145 del ptr
164146 inc(it)
165147 return output
166148
167149 def execute (self ):
168- if not self .thisptr:
169- raise Exception (" C++ Pipeline object not constructed!" )
170- return self .thisptr.execute()
150+ return self ._executor.execute()
171151
172152 def validate (self ):
173- if not self .thisptr:
174- raise Exception (" C++ Pipeline object not constructed!" )
175- return self .thisptr.validate()
153+ return self ._executor.validate()
154+
155+ def get_meshio (self , idx ):
156+ try :
157+ from meshio import Mesh
158+ except ModuleNotFoundError:
159+ raise RuntimeError (
160+ " The get_meshio function can only be used if you have installed meshio. Try pip install meshio"
161+ )
162+ array = self .arrays[idx]
163+ mesh = self .meshes[idx]
164+ if len (mesh) == 0 :
165+ return None
166+ return Mesh(
167+ np.stack((array[" X" ], array[" Y" ], array[" Z" ]), 1 ),
168+ [(" triangle" , np.stack((mesh[" A" ], mesh[" B" ], mesh[" C" ]), 1 ))],
169+ )
0 commit comments