-
Notifications
You must be signed in to change notification settings - Fork 12
Types are too specific #21
Comments
Thanks Steve! I started fixing your Obj importer and introducing parametric types, but it breaks isosurfaces so far. Best, |
@SimonDanisch I can help resolve isosurface breakage as necessary. @sjkelly has a good amount of momentum going, so I'd let him take the lead on how the Mesh type evolves for now. Is the Mesh type currently not parameterized over field type? What an oversight! I'm embarrassed. Might be worth a near term quick fix. |
I just created a pull request with half of the fixes ;) |
@SimonDanisch I started a branch with changes very similar to yours. I'll pull in the commit to my branch and try to adjust things as needed. @twadleigh mentioned Images.jl had a good system for extensible properties. I am looking into it now. For my slicing stuff anything more than triangles would lead to a perfomance increase, so supporting this is a priority for me. Would you need to triangulate for OpenGL.jl? I am thinking we could start with the following for faces, in a similar manner as Images: Implement Make A Also, @twadleigh do you think it would be a good time to tag a v0.0.4 release and bump to v0.1.x? These seem like these will be API breaking. |
I needed to take an impromteu vacation to move apartments. I am back now. I've tagged and published a v0.0.4 release so we can start working on this for the v0.1.x release. This issue will be top priority. |
Hi,
Code: immutable Mesh{Attributes}
data::Dict{Symbol, Any}
end
# Automatically creates a mesh with a dict [attributename => value]
# and with the correct parametric types
function Mesh(data...)
result = {}
meshattributes = (Symbol => Any)[]
for elem in data
push!(result, eltype(elem))
meshattributes[symbol(string(eltype(elem)))] = elem
end
#The parametric types should be sorted, so that we have a standardized order
Mesh{tuple(result...)}(meshattributes)
end
# These should be fixed size arrays, to have a more generic way of
# defining attributes of different dimensions
immutable Triangle{T}
v1::T
v2::T
v3::T
end
immutable Vertex3{T}
x::T
y::T
z::T
end
immutable TextureCoordinate2{T}
u::T
v::T
end
immutable Normal{T}
x::T
y::T
z::T
end
a = Triangle(1,2,3)
b = Vertex3(0,0,0)
c = TextureCoordinate2(0,0)
d = Normal(0,0,0)
Mesh([a], [b], [c], [d])
=> Mesh{(Triangle{Int64},Vertex3{Int64},TextureCoordinate2{Int64},Normal{Int64})}
([
:TextureCoordinate2{Int64}=>[TextureCoordinate2{Int64}(0,0)],
:Triangle{Int64}=>[Triangle{Int64}(1,2,3)],
:Vertex3{Int64}=>[Vertex3{Int64}(0,0,0)],
:Normal{Int64}=>[Normal{Int64}(0,0,0)]
]) |
@SimonDanisch I've been thinking about this for a couple of days. I really like your solution. The only thing I wish for is cleaner syntax for accessing properties. However, I don't think that will be immediately possible. I think once Julia enables overloading the "." operator this will be much better. I really like this since would encapsulate fairly complicated and extensible formats. I implemented AMF import (to some extent), since I see this as a more extreme case. The only other option I could see is a macro-generated type. This would only afford some brevity and cleaner access, but would sacrifice easy multiple-dispatch. Your code above seems to be a very good basis. If you don't mind, I can put this into a new branch and build out the concept. |
Cool sounds good to me! immutable Mesh{Attributes}
data::Dict{Symbol, Any}
end
immutable Triangle{T}
v1::T
v2::T
v3::T
end
immutable Vertex3{T}
x::T
y::T
z::T
end
immutable TextureCoordinate2{T}
u::T
v::T
end
immutable Normal{T}
x::T
y::T
z::T
end
function Mesh(data...)
result = (Symbol => DataType)[]
meshattributes = (Symbol => Any)[]
for elem in data
keyname = symbol(lowercase(replace(string(eltype(elem).name), r"\d", "")))
result[keyname] = eltype(elem)
meshattributes[keyname] = elem
end
#sorting of parameters... Solution a little ugly for my taste
result = sort(map(x->x, result))
Mesh{tuple(map(x->x[2],result)...)}(meshattributes)
end
Base.getindex(m::Mesh, key::Symbol) = m.data[key]
function Base.show(io::IO, m::Mesh)
println(io, "Mesh:")
maxnamelength = 0
maxtypelength = 0
names = map(m.data) do x
n = string(x[1])
t = string(eltype(x[2]).parameters...)
namelength = length(n)
typelength = length(t)
maxnamelength = maxnamelength < namelength ? namelength : maxnamelength
maxtypelength = maxtypelength < typelength ? typelength : maxtypelength
return (n, t, length(x[2]))
end
for elem in names
kname, tname, alength = elem
namespaces = maxnamelength - length(kname)
typespaces = maxtypelength - length(tname)
println(io, " ", kname, " "^namespaces, " : ", tname, " "^typespaces, ", length: ", alength)
end
end
a = Triangle(1,2,3)
b = Vertex3(0,0,0)
c = TextureCoordinate2(0,0)
d = Normal(0,0,0)
@show m = Mesh([a], [b], [c], [d])
@show m[:triangle]
#=
m = Mesh([a],[b],[c],[d]) => Mesh:
texturecoordinate : Int64, length: 1
triangle : Int64, length: 1
vertex : Int64, length: 1
normal : Int64, length: 1
m[:triangle] => [Triangle{Int64}(1,2,3)]
=# |
\me speechless!!! |
@SimonDanisch One of the design features I think are important is to have a way of maintaining association of "similar" or "analogous" element types. For instance, for boundary-integral operations the elements should support being embedded in spaces of dimension equal to or greater than their manifold dimension, calculation of normals, ... The mesh storage mechanism should allow for this association to be carried through, I think. P |
Preferably, everything mesh like is supported! |
I think this can be closed. We still need to make some functionality more generic though, but the types are more parametric. |
@SimonDanisch mentioned on Julia-users
The text was updated successfully, but these errors were encountered: