Skip to content

Commit 270dfed

Browse files
committed
dev 25 Fixed Mesh tree system
1 parent ca01a29 commit 270dfed

File tree

13 files changed

+258
-124
lines changed

13 files changed

+258
-124
lines changed

Loxoc/core.pxd

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,51 @@ from libcpp.vector cimport vector
33
from libcpp.string cimport string
44
from libcpp.map cimport map
55

6+
cdef extern from "<variant>" namespace "std" nogil:
7+
cdef cppclass variant:
8+
variant& operator=(variant&)
9+
10+
# value status
11+
bint valueless_by_exception()
12+
size_t index()
13+
14+
cdef struct monostate:
15+
pass
16+
17+
cdef T get_if[T](...)
18+
19+
cdef T get[T](...)
20+
21+
cdef Z holds_alternative[Z](...)
22+
23+
cdef extern from "../src/util.h" namespace "std" nogil:
24+
cdef cppclass variant2[T,A]:
25+
variant2() except +
26+
variant2(T) except +
27+
variant2(A) except +
28+
variant2[T,A]& operator=(variant2[T,A]&)
29+
30+
# value status
31+
bint valueless_by_exception()
32+
size_t index()
33+
34+
cdef struct monostate:
35+
pass
36+
37+
cdef Z get_if[Z](...)
38+
39+
cdef Z get[Z](...)
40+
41+
cdef Z holds_alternative[Z](...)
42+
643
cdef extern from "../src/RC.h":
744
cdef cppclass RC[T]:
845
RC() except +
946
RC(T data) except +
1047
T inc()
1148
void dec()
1249
T data
50+
int refcount
1351

1452
cdef void RC_collect[T](RC[T*]* rc)
1553

@@ -57,18 +95,7 @@ cdef class Shader:
5795
cdef shader* c_class
5896

5997

60-
cdef extern from "<variant>" namespace "std" nogil:
61-
cdef cppclass variant:
62-
variant& operator=(variant&)
63-
64-
# value status
65-
bint valueless_by_exception()
66-
size_t index()
67-
68-
cdef struct monostate:
69-
pass
7098

71-
cdef T* get_if[T](...)
7299

73100
cdef extern from "../src/Material.h":
74101

@@ -383,6 +410,7 @@ cdef Vec2 vec2_from_cpp(vec2 cppinst)
383410

384411

385412
cdef extern from "../src/Mesh.h":
413+
386414
cdef enum illum_model:
387415
CONSTANT_COLOR,
388416
DIFFUSE,
@@ -404,7 +432,7 @@ cdef extern from "../src/Mesh.h":
404432
mesh(const mesh& rhs) except +
405433
mesh(vector[mesh_material*] materials, vector[vec3]* vertexes, vector[vec3]* diffuse_coordinates, vector[vec3]* vertex_normals, vector[tup3ui]* faces, vec3 transform, vector[RC[texture*]*] diffuse_textures, vector[RC[texture*]*] specular_textures, vector[RC[texture*]*] normals_textures) except +
406434
@staticmethod
407-
mesh_dict from_file(string file_path) except +
435+
RC[mesh_dict*]* from_file(string file_path) except +
408436
string name
409437
vector[mesh_material*] materials
410438
vector[vec3]* vertexes
@@ -416,36 +444,35 @@ cdef extern from "../src/Mesh.h":
416444
vector[RC[texture*]*] specular_textures
417445
vector[RC[texture*]*] normals_textures
418446

419-
447+
448+
ctypedef variant2[RC[mesh*]*, RC[mesh_dict*]*] mesh_dict_child
420449

421450
cdef cppclass mesh_dict:
422-
ctypedef map[string, vector[RC[mesh*]*]].iterator meshmap_iterator
423-
ctypedef map[string, vector[RC[mesh*]*]].const_iterator const_meshmap_iterator
424-
451+
ctypedef map[string, mesh_dict_child].iterator meshmap_iterator
452+
ctypedef map[string, mesh_dict_child].const_iterator const_meshmap_iterator
453+
#
425454
mesh_dict() except +
426-
mesh_dict(map[string, vector[RC[mesh*]*]] data) except +
455+
mesh_dict(string name, map[string, mesh_dict_child] data) except +
427456
mesh_dict(mesh_dict& rhs) except +
428-
void insert(RC[mesh*]* m)
429-
vector[RC[mesh*]*] get(string name)
457+
void insert(mesh_dict_child m)
458+
mesh_dict_child get(string name)
430459
void remove(string name)
431-
vector[RC[mesh*]*] operator[](string name)
460+
mesh_dict_child operator[](string name)
432461
meshmap_iterator begin() noexcept
433462
const_meshmap_iterator cbegin() noexcept
434463
meshmap_iterator end() noexcept
435464
const_meshmap_iterator cend()
436-
437-
map[string, vector[RC[mesh*]*]] data
465+
string name
466+
map[string, mesh_dict_child] data
438467

439468
cdef class MeshDict:
440-
cdef mesh_dict* c_class
441-
cpdef void insert(self, Mesh m)
442-
cpdef list[Mesh] get(self, str name)
469+
cdef RC[mesh_dict*]* c_class
443470
cpdef void remove(self, str name)
444471

445472
@staticmethod
446473
cdef MeshDict from_cpp(mesh_dict cppinst)
447474
@staticmethod
448-
cdef MeshDict from_cpp_ptr(mesh_dict* cppinst)
475+
cdef MeshDict from_cpp_ptr(RC[mesh_dict*]* cppinst)
449476

450477

451478
cdef class Mesh:
@@ -462,9 +489,9 @@ cpdef MeshDict mesh_from_file(str file_path)
462489
cdef extern from "../src/Object3d.h":
463490
cdef cppclass object3d:
464491
object3d() except +
465-
object3d(mesh_dict* mesh, vec3* position, quaternion* rotation, vec3* scale) except +
466-
object3d(mesh_dict* mesh, vec3* position, quaternion* rotation, vec3* scale, material* mat) except +
467-
mesh_dict* mesh_data
492+
object3d(RC[mesh_dict*]* mesh, vec3* position, quaternion* rotation, vec3* scale) except +
493+
object3d(RC[mesh_dict*]* mesh, vec3* position, quaternion* rotation, vec3* scale, material* mat) except +
494+
RC[mesh_dict*]* mesh_data
468495
vec3* position
469496
quaternion* rotation
470497
vec3* scale

Loxoc/core.pyi

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,40 @@ class Mesh:
6565

6666
class MeshDict:
6767
"""
68-
A fast :class:`Mesh` container that can be used like a statically typed dict.
68+
:class:`Loxoc.MeshDict` is a datastructure that acts like a statically typed dictionary storing each :class:`Mesh<Loxoc.Mesh>` by name.
69+
This is nessicary because 3D asset files can have more than one :class:`Mesh<Loxoc.Mesh>` in them. If you have a 3D
70+
asset file with more than one :class:`Mesh<Loxoc.Mesh>` inside of it, you can extract them from their :class:`MeshDict<Loxoc.MeshDict>`
71+
to new individual :class:`MeshDict<Loxoc.MeshDict>` s to be used in :class:`Object3D<Loxoc.Object3D>` s like so:
72+
73+
.. code-block:: python
74+
75+
my_assets: MeshDict = Mesh.from_file("./assets/models/model_name/model_name.gltf")
76+
# Import the 3D asset file.
77+
78+
player_model = MeshDict([my_assets["player_model"]])
79+
# Extract the Mesh into its own group/MeshDict
80+
81+
player_object = Object3D(player_model, Vec3(0.0, 0.0, 20.0), vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0))
82+
# Now our model is ready to be used.
83+
84+
We can extract the :class:`Mesh` s we need from the ``my_assets`` :class:`MeshDict` by name.
85+
Hence we use ``my_assets["player_model"]``. This is assuming your desired :class:`Mesh`
86+
is at the top level of your imported 3D file/asset's heirarchy. if it is in a group inside
87+
the 3D file/asset you imported you could do something like:
88+
``my_assets["group_name"]["player_model"]``
6989
"""
7090

71-
def __init__(self, meshes: list[Mesh]) -> None:
91+
def __init__(self, meshes: list[Mesh|MeshDict]) -> None:
7292
"""
7393
A fast :class:`Mesh` container that can be used like a statically typed dict.
7494
"""
7595

76-
def insert(self, m: Mesh) -> None:
96+
def insert(self, m: Mesh|MeshDict) -> None:
7797
"""
7898
Insert a Mesh. It will use the Mesh name as a key.
7999
"""
80100

81-
def get(self, name: str) -> list[Mesh]:
101+
def get(self, name: str) -> Mesh|MeshDict:
82102
"""
83103
Get a Mesh from the dict by name.
84104
"""
@@ -88,12 +108,12 @@ class MeshDict:
88108
Remove a Mesh from the dict by name.
89109
"""
90110

91-
def __iter__(self) -> Generator[tuple[str, list[Mesh]], None, None]:
111+
def __iter__(self) -> Generator[tuple[str, Mesh|MeshDict], None, None]:
92112
"""
93113
Itterates through the key value pairs of the dict.
94114
"""
95115

96-
def __getitem__(self, key: str) -> list[Mesh]:
116+
def __getitem__(self, key: str) -> Mesh|MeshDict:
97117
"""
98118
Get a Mesh from the dict by name.
99119
"""

Loxoc/core.pyx

Lines changed: 78 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -71,76 +71,114 @@ cdef class Camera:
7171
self._rotation = value
7272
self.c_class.rotation = self._rotation.c_class
7373

74+
ctypedef mesh_dict* mesh_dict_ptr
75+
ctypedef RC[mesh*]* rc_mesh
76+
ctypedef RC[mesh_dict*]* rc_mesh_dict
77+
ctypedef mesh* mesh_ptr
78+
7479
cdef class MeshDict:
7580

76-
def __init__(self, list[Mesh] meshes) -> None:
81+
def __init__(self, str name, meshes:list[Mesh | MeshDict]) -> None:
7782
cdef:
7883
Mesh m
7984
mesh_dict md = mesh_dict()
8085
for m in meshes:
81-
md.insert(m.c_class)
86+
md.insert(mesh_dict_child(m.c_class))
87+
88+
md.name = name.encode()
8289

83-
self.c_class = new mesh_dict(md)
90+
self.c_class = new RC[mesh_dict_ptr](new mesh_dict(md))
8491

8592
def __repr__(self) -> str:
86-
return "\n".join([
93+
return "".join([
8794
"MeshDict {",
88-
*["\t{}: {}".format(m_n, m) for m_n, m in self],
95+
*["{}: {}".format(m_n, m) for m_n, m in self],
8996
"}"
9097
])
9198

9299
def __dealloc__(self):
93100
# Collect the mesh_dict and decrement each mesh's refcount
94101
cdef:
95-
pair[string, vector[RC[mesh*]*]] _pair
96-
RC[mesh*]* m
97-
for _pair in self.c_class.data:
98-
for m in _pair.second:
99-
RC_collect(m)
100-
del self.c_class
101-
102-
cpdef void insert(self, Mesh m):
103-
self.c_class.insert(m.c_class)
102+
pair[string, mesh_dict_child] _pair
103+
mesh_dict_child m
104+
rc_mesh _m
105+
rc_mesh_dict _m_d
106+
RC_collect(self.c_class)
107+
104108

105-
cpdef list[Mesh] get(self, str name):
109+
def insert(self, m: Mesh | MeshDict) -> None:
106110
cdef:
107-
RC[mesh*]* m
108-
list[Mesh] ret = []
109-
for m in self.c_class.get(name.encode()):
110-
ret.append(Mesh.from_cpp(m))
111-
return ret
111+
Mesh msh
112+
MeshDict msh_d
113+
if isinstance(m, Mesh):
114+
msh = m
115+
msh.c_class.inc()
116+
self.c_class.data.insert(mesh_dict_child(msh.c_class))
117+
elif isinstance(m, MeshDict):
118+
msh_d = m
119+
msh_d.c_class.inc()
120+
self.c_class.data.insert(mesh_dict_child(msh_d.c_class))
121+
122+
def get(self, str name) -> Mesh|MeshDict :
123+
cdef:
124+
mesh_dict_child m = self.c_class.data.get(name.encode())
125+
RC[mesh*]* _m
126+
RC[mesh_dict*]* _m_d
127+
if holds_alternative[rc_mesh](m):
128+
_m = get[rc_mesh](m)
129+
return Mesh.from_cpp(_m)
130+
elif holds_alternative[rc_mesh_dict](m):
131+
_m_d = get[rc_mesh_dict](m)
132+
return MeshDict.from_cpp_ptr(_m_d)
112133

113134
cpdef void remove(self, str name):
114-
self.c_class.remove(name.encode())
115-
116-
def __iter__(self) -> Generator[(str, list[Mesh]), None, None]:
117135
cdef:
118-
pair[string, vector[RC[mesh*]*]] _pair
119-
RC[mesh*]* m
120-
Mesh M
121-
list[Mesh] M_list = []
122-
for _pair in self.c_class.data:
123-
for m in _pair.second:
124-
M = Mesh.from_cpp(m)
125-
M_list.append(M)
126-
yield (
127-
bytes(_pair.first).decode(),
128-
M_list
129-
)
136+
mesh_dict_child m = self.c_class.data.data[name]
137+
RC[mesh*]* _m
138+
RC[mesh_dict*]* _m_d
139+
self.c_class.data.remove(name.encode())
140+
if holds_alternative[rc_mesh](m):
141+
_m = get[rc_mesh](m)
142+
_m.dec()
143+
elif holds_alternative[rc_mesh_dict](m):
144+
_m_d = get[rc_mesh_dict](m)
145+
_m_d.dec()
146+
147+
def __iter__(self) -> Generator[(str, Mesh|MeshDict), None, None]:
148+
cdef:
149+
pair[string, mesh_dict_child] _pair
150+
RC[mesh*]* _m
151+
RC[mesh_dict*]* _m_d
152+
mesh_dict_child m
153+
for _pair in self.c_class.data[0]:
154+
m = _pair.second
155+
if holds_alternative[rc_mesh](m):
156+
_m = get[rc_mesh](m)
157+
yield (
158+
bytes(_pair.first).decode(),
159+
Mesh.from_cpp(_m)
160+
)
161+
elif holds_alternative[rc_mesh_dict](m):
162+
_m_d = get[rc_mesh_dict](m)
163+
yield (
164+
bytes(_pair.first).decode(),
165+
MeshDict.from_cpp_ptr(_m_d)
166+
)
130167

131168
def __getitem__(self, str key) -> list[Mesh]:
132169
return self.get(key)
133170

134171
@staticmethod
135172
cdef MeshDict from_cpp(mesh_dict cppinst):
136173
cdef MeshDict ret = MeshDict.__new__(MeshDict)
137-
ret.c_class = new mesh_dict(cppinst)
174+
ret.c_class = new RC[mesh_dict_ptr](new mesh_dict(cppinst))
138175
return ret
139176

140177
@staticmethod
141-
cdef MeshDict from_cpp_ptr(mesh_dict* cppinst):
178+
cdef MeshDict from_cpp_ptr(RC[mesh_dict*]* cppinst):
142179
cdef MeshDict ret = MeshDict.__new__(MeshDict)
143180
ret.c_class = cppinst
181+
ret.c_class.inc()
144182
return ret
145183

146184
cdef class Mesh:
@@ -183,7 +221,7 @@ cdef class Mesh:
183221
for _tex in ret.c_class.data.specular_textures:
184222
tex_spec = Texture.__new__(Texture)
185223
tex_spec.c_class = _tex
186-
tex_diff.c_class.inc()
224+
tex_spec.c_class.inc()
187225
specular_textures.append(tex_spec)
188226

189227
ret.specular_textures = specular_textures
@@ -192,19 +230,18 @@ cdef class Mesh:
192230
for _tex in ret.c_class.data.normals_textures:
193231
tex_norm = Texture.__new__(Texture)
194232
tex_norm.c_class = _tex
195-
tex_diff.c_class.inc()
233+
tex_norm.c_class.inc()
196234
normals_textures.append(tex_norm)
197235

198236
ret.normals_textures = normals_textures
199-
200237
return ret
201238

202239
@staticmethod
203240
def from_file(file_path:str) -> MeshDict:
204241
return mesh_from_file(file_path)
205242

206243
cpdef MeshDict mesh_from_file(str file_path):
207-
return MeshDict.from_cpp(mesh.from_file(file_path.encode()))
244+
return MeshDict.from_cpp_ptr(mesh.from_file(file_path.encode()))
208245

209246
cdef class Object3D:
210247
def __init__(self, MeshDict mesh_data, Vec3 position = Vec3(0.0,0.0,0.0),

0 commit comments

Comments
 (0)